]> git.sur5r.net Git - freertos/commitdiff
Rename \FreeRTOS-Plus\Source\FreeRTOS-Plus-IoT-SDK to \FreeRTOS-Plus\Source\FreeRTOS...
authorgaurav-aws <gaurav-aws@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Tue, 23 Jul 2019 03:41:27 +0000 (03:41 +0000)
committergaurav-aws <gaurav-aws@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Tue, 23 Jul 2019 03:41:27 +0000 (03:41 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2696 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

90 files changed:
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/include/platform/iot_network_freertos.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/include/platform/iot_platform_types_freertos.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/iot_clock_freertos.c [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/iot_network_freertos.c [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/iot_threads_freertos.c [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/platform/iot_clock.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/platform/iot_metrics.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/platform/iot_network.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/platform/iot_threads.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/types/iot_platform_types.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/secure_sockets/freertos_plus_tcp/iot_secure_sockets.c [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/secure_sockets/include/iot_secure_sockets.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/secure_sockets/include/iot_secure_sockets_config_defaults.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/secure_sockets/include/iot_secure_sockets_wrapper_metrics.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_atomic.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_init.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_linear_containers.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_logging_setup.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_taskpool.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/private/iot_error.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/private/iot_lib_init.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/private/iot_logging.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/private/iot_static_memory.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/private/iot_taskpool_internal.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/types/iot_taskpool_types.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/logging/iot_logging.c [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/logging/iot_logging_task_dynamic_buffers.c [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/taskpool/iot_taskpool.c [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/taskpool/iot_taskpool_static_memory.c [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt_agent.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt_agent_config_defaults.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt_config_defaults.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt_lib.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/types/iot_mqtt_types.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_ble_mqtt_serialize.c [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_agent.c [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_api.c [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_network.c [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_operation.c [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_serialize.c [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_static_memory.c [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_subscription.c [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_validate.c [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/private/iot_mqtt_internal.h [new file with mode: 0644]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/freertos/include/platform/iot_network_freertos.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/freertos/include/platform/iot_platform_types_freertos.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/freertos/iot_clock_freertos.c [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/freertos/iot_network_freertos.c [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/freertos/iot_threads_freertos.c [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/include/platform/iot_clock.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/include/platform/iot_metrics.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/include/platform/iot_network.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/include/platform/iot_threads.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/include/types/iot_platform_types.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/secure_sockets/freertos_plus_tcp/iot_secure_sockets.c [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/secure_sockets/include/iot_secure_sockets.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/secure_sockets/include/iot_secure_sockets_config_defaults.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/secure_sockets/include/iot_secure_sockets_wrapper_metrics.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/iot_atomic.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/iot_init.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/iot_linear_containers.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/iot_logging_setup.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/iot_taskpool.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/private/iot_error.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/private/iot_lib_init.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/private/iot_logging.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/private/iot_static_memory.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/private/iot_taskpool_internal.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/types/iot_taskpool_types.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/logging/iot_logging.c [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/logging/iot_logging_task_dynamic_buffers.c [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/taskpool/iot_taskpool.c [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/taskpool/iot_taskpool_static_memory.c [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/include/iot_mqtt.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/include/iot_mqtt_agent.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/include/iot_mqtt_agent_config_defaults.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/include/iot_mqtt_config_defaults.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/include/iot_mqtt_lib.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/include/types/iot_mqtt_types.h [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_ble_mqtt_serialize.c [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_mqtt_agent.c [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_mqtt_api.c [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_mqtt_network.c [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_mqtt_operation.c [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_mqtt_serialize.c [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_mqtt_static_memory.c [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_mqtt_subscription.c [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_mqtt_validate.c [deleted file]
FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/private/iot_mqtt_internal.h [deleted file]

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/include/platform/iot_network_freertos.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/include/platform/iot_network_freertos.h
new file mode 100644 (file)
index 0000000..e4449ae
--- /dev/null
@@ -0,0 +1,140 @@
+/*\r
+ * Amazon FreeRTOS Platform V1.0.0\r
+ * Copyright (C) 2019 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_network_freertos.h\r
+ * @brief Declares the network stack functions specified in aws_iot_network.h for\r
+ * Amazon FreeRTOS Secure Sockets.\r
+ */\r
+\r
+#ifndef _IOT_NETWORK_AFR_H_\r
+#define _IOT_NETWORK_AFR_H_\r
+\r
+/* Standard includes. */\r
+#include <stdbool.h>\r
+\r
+/* Platform network include. */\r
+#include "platform/iot_network.h"\r
+\r
+/* Amazon FreeRTOS Secure Sockets include. */\r
+#include "iot_secure_sockets.h"\r
+\r
+/**\r
+ * @brief Represents a network connection that uses Amazon FreeRTOS Secure Sockets.\r
+ *\r
+ * This is an incomplete type. In application code, only pointers to this type\r
+ * should be used.\r
+ */\r
+typedef struct _networkConnection IotNetworkConnectionAfr_t;\r
+\r
+/**\r
+ * @brief Provides a default value for an #IotNetworkConnectionAfr_t.\r
+ *\r
+ * All instances of #IotNetworkConnectionAfr_t should be initialized with\r
+ * this constant.\r
+ *\r
+ * @warning Failing to initialize an #IotNetworkConnectionAfr_t with this\r
+ * initializer may result in undefined behavior!\r
+ * @note This initializer may change at any time in future versions, but its\r
+ * name will remain the same.\r
+ */\r
+#define IOT_NETWORK_CONNECTION_AFR_INITIALIZER     { 0 }\r
+\r
+/**\r
+ * @brief Generic initializer for an #IotNetworkServerInfo_t.\r
+ *\r
+ * @note This initializer may change at any time in future versions, but its\r
+ * name will remain the same.\r
+ */\r
+#define IOT_NETWORK_SERVER_INFO_AFR_INITIALIZER    { 0 }\r
+\r
+/**\r
+ * @brief Generic initializer for an #IotNetworkCredentials_t.\r
+ *\r
+ * @note This initializer may change at any time in future versions, but its\r
+ * name will remain the same.\r
+ */\r
+#define IOT_NETWORK_CREDENTIALS_AFR_INITIALIZER    { 0 }\r
+\r
+/**\r
+ * @brief Provides a pointer to an #IotNetworkInterface_t that uses the functions\r
+ * declared in this file.\r
+ */\r
+#define IOT_NETWORK_INTERFACE_AFR    ( &( IotNetworkAfr ) )\r
+\r
+/**\r
+ * @brief An implementation of #IotNetworkInterface_t::create for Amazon FreeRTOS\r
+ * Secure Sockets.\r
+ */\r
+IotNetworkError_t IotNetworkAfr_Create( void * pConnectionInfo,\r
+                                        void * pCredentialInfo,\r
+                                        void ** const pConnection );\r
+\r
+/**\r
+ * @brief An implementation of #IotNetworkInterface_t::setReceiveCallback for\r
+ * Amazon FreeRTOS Secure Sockets.\r
+ */\r
+IotNetworkError_t IotNetworkAfr_SetReceiveCallback( void * pConnection,\r
+                                                    IotNetworkReceiveCallback_t receiveCallback,\r
+                                                    void * pContext );\r
+\r
+/**\r
+ * @brief An implementation of #IotNetworkInterface_t::send for Amazon FreeRTOS\r
+ * Secure Sockets.\r
+ */\r
+size_t IotNetworkAfr_Send( void * pConnection,\r
+                           const uint8_t * pMessage,\r
+                           size_t messageLength );\r
+\r
+/**\r
+ * @brief An implementation of #IotNetworkInterface_t::receive for Amazon FreeRTOS\r
+ * Secure Sockets.\r
+ */\r
+size_t IotNetworkAfr_Receive( void * pConnection,\r
+                              uint8_t * pBuffer,\r
+                              size_t bytesRequested );\r
+\r
+/**\r
+ * @brief An implementation of #IotNetworkInterface_t::close for Amazon FreeRTOS\r
+ * Secure Sockets.\r
+ */\r
+IotNetworkError_t IotNetworkAfr_Close( void * pConnection );\r
+\r
+/**\r
+ * @brief An implementation of #IotNetworkInterface_t::destroy for Amazon FreeRTOS\r
+ * Secure Sockets.\r
+ */\r
+IotNetworkError_t IotNetworkAfr_Destroy( void * pConnection );\r
+\r
+/**\r
+ * @cond DOXYGEN_IGNORE\r
+ * Doxygen should ignore this section.\r
+ *\r
+ * Declaration of a network interface struct using the functions in this file.\r
+ */\r
+extern const IotNetworkInterface_t IotNetworkAfr;\r
+/** @endcond */\r
+\r
+#endif /* ifndef _IOT_NETWORK_AFR_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/include/platform/iot_platform_types_freertos.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/include/platform/iot_platform_types_freertos.h
new file mode 100644 (file)
index 0000000..e855343
--- /dev/null
@@ -0,0 +1,84 @@
+/*\r
+ * Amazon FreeRTOS Platform V1.0.0\r
+ * Copyright (C) 2019 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_platform_types_posix.h\r
+ * @brief Definitions of platform layer types on POSIX systems.\r
+ */\r
+\r
+#ifndef _IOT_PLATFORM_TYPES_AFR_H_\r
+#define _IOT_PLATFORM_TYPES_AFR_H_\r
+\r
+#include "timers.h"\r
+\r
+typedef struct iot_mutex_internal\r
+{\r
+    StaticSemaphore_t xMutex;      /**< FreeRTOS mutex. */\r
+    BaseType_t recursive;                /**< Type; used for indicating if this is reentrant or normal. */\r
+} iot_mutex_internal_t;\r
+\r
+/**\r
+ * @brief The native mutex type on AFR systems.\r
+ */\r
+typedef iot_mutex_internal_t _IotSystemMutex_t;\r
+\r
+typedef struct iot_sem_internal\r
+{\r
+    StaticSemaphore_t xSemaphore;       /**< FreeRTOS semaphore. */\r
+} iot_sem_internal_t;\r
+\r
+/**\r
+ * @brief The native semaphore type on AFR systems.\r
+ */\r
+typedef iot_sem_internal_t _IotSystemSemaphore_t;\r
+\r
+/**\r
+ * @brief Holds information about an active detached thread so that we can\r
+ *        delete the FreeRTOS task when it completes\r
+ */\r
+typedef struct threadInfo\r
+{\r
+    void * pArgument;                 /**< @brief Argument to `threadRoutine`. */\r
+    void ( *threadRoutine )( void * );/**< @brief Thread function to run. */\r
+} threadInfo_t;\r
+\r
+/**\r
+ * @brief Holds information about an active timer.\r
+ */\r
+typedef struct timerInfo\r
+{\r
+    TimerHandle_t timer;                    /**< @brief Underlying timer. */\r
+    void ( *threadRoutine )( void * );      /**< @brief Thread function to run on timer expiration. */\r
+    void * pArgument;                       /**< @brief First argument to threadRoutine. */\r
+    StaticTimer_t xTimerBuffer;             /**< Memory that holds the FreeRTOS timer. */\r
+    TickType_t xTimerPeriod;                /**< Period of this timer. */\r
+} timerInfo_t;\r
+\r
+/**\r
+ * @brief Represents an #IotTimer_t on AFR systems.\r
+ */\r
+typedef timerInfo_t _IotSystemTimer_t;\r
+\r
+#endif /* ifndef _IOT_PLATFORM_TYPES_POSIX_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/iot_clock_freertos.c b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/iot_clock_freertos.c
new file mode 100644 (file)
index 0000000..4d74b82
--- /dev/null
@@ -0,0 +1,224 @@
+/*\r
+ * Amazon FreeRTOS Platform V1.0.0\r
+ * Copyright (C) 2019 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_clock_freertos.c\r
+ * @brief Implementation of the functions in iot_clock.h for Amazon FreeRTOS systems.\r
+ */\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/* Standard includes. */\r
+#include <stdio.h>\r
+\r
+/* Platform clock include. */\r
+#include "platform/iot_platform_types_freertos.h"\r
+#include "platform/iot_clock.h"\r
+#include "task.h"\r
+\r
+/* Configure logs for the functions in this file. */\r
+#ifdef IOT_LOG_LEVEL_PLATFORM\r
+    #define LIBRARY_LOG_LEVEL        IOT_LOG_LEVEL_PLATFORM\r
+#else\r
+    #ifdef IOT_LOG_LEVEL_GLOBAL\r
+        #define LIBRARY_LOG_LEVEL    IOT_LOG_LEVEL_GLOBAL\r
+    #else\r
+        #define LIBRARY_LOG_LEVEL    IOT_LOG_NONE\r
+    #endif\r
+#endif\r
+\r
+#define LIBRARY_LOG_NAME    ( "CLOCK" )\r
+#include "iot_logging_setup.h"\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Time conversion constants.\r
+ */\r
+#define _MILLISECONDS_PER_SECOND    ( 1000 )                                          /**< @brief Milliseconds per second. */\r
+#define _MILLISECONDS_PER_TICK      ( _MILLISECONDS_PER_SECOND / configTICK_RATE_HZ ) /**< Milliseconds per FreeRTOS tick. */\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*  Private Callback function for timer expiry, delegate work to a Task to free\r
+ *  up the timer task for managing other timers */\r
+static void prvTimerCallback( TimerHandle_t xTimerHandle )\r
+{\r
+    _IotSystemTimer_t * pxTimer = ( _IotSystemTimer_t * ) pvTimerGetTimerID( xTimerHandle );\r
+\r
+    /* The value of the timer ID, set in timer_create, should not be NULL. */\r
+    configASSERT( pxTimer != NULL );\r
+\r
+    /* Restart the timer if it is periodic. */\r
+    if( pxTimer->xTimerPeriod > 0 )\r
+    {\r
+        xTimerChangePeriod( xTimerHandle, pxTimer->xTimerPeriod, 0 );\r
+    }\r
+\r
+    /* Call timer Callback from this task */\r
+    pxTimer->threadRoutine( ( void * ) pxTimer->pArgument );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+bool IotClock_GetTimestring( char * pBuffer,\r
+                             size_t bufferSize,\r
+                             size_t * pTimestringLength )\r
+{\r
+    uint64_t milliSeconds = IotClock_GetTimeMs();\r
+    int timestringLength = 0;\r
+\r
+    configASSERT( pBuffer != NULL );\r
+    configASSERT( pTimestringLength != NULL );\r
+\r
+    /* Convert the localTime struct to a string. */\r
+    timestringLength = snprintf( pBuffer, bufferSize, "%llu", milliSeconds );\r
+\r
+    /* Check for error from no string */\r
+    if( timestringLength == 0 )\r
+    {\r
+        return false;\r
+    }\r
+\r
+    /* Set the output parameter. */\r
+    *pTimestringLength = timestringLength;\r
+\r
+    return true;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+uint64_t IotClock_GetTimeMs( void )\r
+{\r
+    TimeOut_t xCurrentTime = { 0 };\r
+\r
+    /* This must be unsigned because the behavior of signed integer overflow is undefined. */\r
+    uint64_t ullTickCount = 0ULL;\r
+\r
+    /* Get the current tick count and overflow count. vTaskSetTimeOutState()\r
+     * is used to get these values because they are both static in tasks.c. */\r
+    vTaskSetTimeOutState( &xCurrentTime );\r
+\r
+    /* Adjust the tick count for the number of times a TickType_t has overflowed. */\r
+    ullTickCount = ( uint64_t ) ( xCurrentTime.xOverflowCount ) << ( sizeof( TickType_t ) * 8 );\r
+\r
+    /* Add the current tick count. */\r
+    ullTickCount += xCurrentTime.xTimeOnEntering;\r
+\r
+    /* Return the ticks converted to Milliseconds */\r
+    return ullTickCount * _MILLISECONDS_PER_TICK;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void IotClock_SleepMs( uint32_t sleepTimeMs )\r
+{\r
+    vTaskDelay( pdMS_TO_TICKS( sleepTimeMs ) );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+bool IotClock_TimerCreate( IotTimer_t * pNewTimer,\r
+                           IotThreadRoutine_t expirationRoutine,\r
+                           void * pArgument )\r
+{\r
+    _IotSystemTimer_t * pxTimer = ( _IotSystemTimer_t * ) pNewTimer;\r
+\r
+    configASSERT( pNewTimer != NULL );\r
+    configASSERT( expirationRoutine != NULL );\r
+\r
+    IotLogDebug( "Creating new timer %p.", pNewTimer );\r
+\r
+    /* Set the timer expiration routine, argument and period */\r
+    pxTimer->threadRoutine = expirationRoutine;\r
+    pxTimer->pArgument = pArgument;\r
+    pxTimer->xTimerPeriod = 0;\r
+\r
+    /* Create a new FreeRTOS timer. This call will not fail because the\r
+     * memory for it has already been allocated, so the output parameter is\r
+     * also set. */\r
+    pxTimer->timer = ( TimerHandle_t ) xTimerCreateStatic( "timer",                  /* Timer name. */\r
+                                                           portMAX_DELAY,            /* Initial timer period. Timers are created disarmed. */\r
+                                                           pdFALSE,                  /* Don't auto-reload timer. */\r
+                                                           ( void * ) pxTimer,       /* Timer id. */\r
+                                                           prvTimerCallback,         /* Timer expiration callback. */\r
+                                                           &pxTimer->xTimerBuffer ); /* Pre-allocated memory for timer. */\r
+\r
+    return true;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void IotClock_TimerDestroy( IotTimer_t * pTimer )\r
+{\r
+    _IotSystemTimer_t * pTimerInfo = ( _IotSystemTimer_t * ) pTimer;\r
+\r
+    configASSERT( pTimerInfo != NULL );\r
+    configASSERT( pTimerInfo->timer != NULL );\r
+\r
+    IotLogDebug( "Destroying timer %p.", pTimer );\r
+\r
+    if( xTimerIsTimerActive( pTimerInfo->timer ) == pdTRUE )\r
+    {\r
+        /* Stop the FreeRTOS timer. Because the timer is statically allocated, no call\r
+         * to xTimerDelete is necessary. The timer is stopped so that it's not referenced\r
+         * anywhere. xTimerStop will not fail when it has unlimited block time. */\r
+        ( void ) xTimerStop( pTimerInfo->timer, portMAX_DELAY );\r
+\r
+        /* Wait until the timer stop command is processed. */\r
+        while( xTimerIsTimerActive( pTimerInfo->timer ) == pdTRUE )\r
+        {\r
+            vTaskDelay( 1 );\r
+        }\r
+    }\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+bool IotClock_TimerArm( IotTimer_t * pTimer,\r
+                        uint32_t relativeTimeoutMs,\r
+                        uint32_t periodMs )\r
+{\r
+    _IotSystemTimer_t * pTimerInfo = ( _IotSystemTimer_t * ) pTimer;\r
+\r
+    configASSERT( pTimerInfo != NULL );\r
+\r
+    TimerHandle_t xTimerHandle = pTimerInfo->timer;\r
+\r
+    IotLogDebug( "Arming timer %p with timeout %llu and period %llu.",\r
+                 pTimer,\r
+                 relativeTimeoutMs,\r
+                 periodMs );\r
+\r
+    /* Set the timer period in ticks */\r
+    pTimerInfo->xTimerPeriod = pdMS_TO_TICKS( periodMs );\r
+\r
+    /* Set the timer to expire after relativeTimeoutMs, and restart it. */\r
+    ( void ) xTimerChangePeriod( xTimerHandle, pdMS_TO_TICKS( relativeTimeoutMs ), portMAX_DELAY );\r
+\r
+    return true;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/iot_network_freertos.c b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/iot_network_freertos.c
new file mode 100644 (file)
index 0000000..287a312
--- /dev/null
@@ -0,0 +1,627 @@
+/*\r
+ * Amazon FreeRTOS Platform V1.0.0\r
+ * Copyright (C) 2019 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_network_freertos.c\r
+ * @brief Implementation of the network-related functions from iot_network_freertos.h\r
+ * for Amazon FreeRTOS secure sockets.\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
+/* FreeRTOS includes. */\r
+#include "semphr.h"\r
+#include "event_groups.h"\r
+\r
+/* Error handling include. */\r
+#include "private/iot_error.h"\r
+\r
+/* Amazon FreeRTOS network include. */\r
+#include "platform/iot_network_freertos.h"\r
+\r
+/* Configure logs for the functions in this file. */\r
+#ifdef IOT_LOG_LEVEL_NETWORK\r
+    #define LIBRARY_LOG_LEVEL        IOT_LOG_LEVEL_NETWORK\r
+#else\r
+    #ifdef IOT_LOG_LEVEL_GLOBAL\r
+        #define LIBRARY_LOG_LEVEL    IOT_LOG_LEVEL_GLOBAL\r
+    #else\r
+        #define LIBRARY_LOG_LEVEL    IOT_LOG_NONE\r
+    #endif\r
+#endif\r
+\r
+#define LIBRARY_LOG_NAME    ( "NET" )\r
+#include "iot_logging_setup.h"\r
+\r
+/* Provide a default value for the number of milliseconds for a socket poll.\r
+ * This is a temporary workaround to deal with the lack of poll(). */\r
+#ifndef IOT_NETWORK_SOCKET_POLL_MS\r
+    #define IOT_NETWORK_SOCKET_POLL_MS    ( 1000 )\r
+#endif\r
+\r
+/**\r
+ * @brief The event group bit to set when a connection's socket is shut down.\r
+ */\r
+#define _FLAG_SHUTDOWN                ( 1 )\r
+\r
+/**\r
+ * @brief The event group bit to set when a connection's receive task exits.\r
+ */\r
+#define _FLAG_RECEIVE_TASK_EXITED     ( 2 )\r
+\r
+/**\r
+ * @brief The event group bit to set when the connection is destroyed from the\r
+ * receive task.\r
+ */\r
+#define _FLAG_CONNECTION_DESTROYED    ( 4 )\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+typedef struct _networkConnection\r
+{\r
+    Socket_t socket;                             /**< @brief Amazon FreeRTOS Secure Sockets handle. */\r
+    StaticSemaphore_t socketMutex;               /**< @brief Prevents concurrent threads from sending on a socket. */\r
+    StaticEventGroup_t connectionFlags;          /**< @brief Synchronizes with the receive task. */\r
+    TaskHandle_t receiveTask;                    /**< @brief Handle of the receive task, if any. */\r
+    IotNetworkReceiveCallback_t receiveCallback; /**< @brief Network receive callback, if any. */\r
+    void * pReceiveContext;                      /**< @brief The context for the receive callback. */\r
+    bool bufferedByteValid;                      /**< @brief Used to determine if the buffered byte is valid. */\r
+    uint8_t bufferedByte;                        /**< @brief A single byte buffered from a receive, since AFR Secure Sockets does not have poll(). */\r
+} _networkConnection_t;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/**\r
+ * @brief An #IotNetworkInterface_t that uses the functions in this file.\r
+ */\r
+const IotNetworkInterface_t IotNetworkAfr =\r
+{\r
+    .create             = IotNetworkAfr_Create,\r
+    .setReceiveCallback = IotNetworkAfr_SetReceiveCallback,\r
+    .send               = IotNetworkAfr_Send,\r
+    .receive            = IotNetworkAfr_Receive,\r
+    .close              = IotNetworkAfr_Close,\r
+    .destroy            = IotNetworkAfr_Destroy\r
+};\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/**\r
+ * @brief Destroys a network connection.\r
+ *\r
+ * @param[in] pNetworkConnection The connection to destroy.\r
+ */\r
+static void _destroyConnection( _networkConnection_t * pNetworkConnection )\r
+{\r
+    /* Call Secure Sockets close function to free resources. */\r
+    int32_t socketStatus = SOCKETS_Close( pNetworkConnection->socket );\r
+\r
+    if( socketStatus != SOCKETS_ERROR_NONE )\r
+    {\r
+        IotLogWarn( "Failed to destroy connection." );\r
+    }\r
+\r
+    /* Free the network connection. */\r
+    vPortFree( pNetworkConnection );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/**\r
+ * @brief Task routine that waits on incoming network data.\r
+ *\r
+ * @param[in] pArgument The network connection.\r
+ */\r
+static void _networkReceiveTask( void * pArgument )\r
+{\r
+    bool destroyConnection = false;\r
+    int32_t socketStatus = 0;\r
+    EventBits_t connectionFlags = 0;\r
+\r
+    /* Cast network connection to the correct type. */\r
+    _networkConnection_t * pNetworkConnection = pArgument;\r
+\r
+    while( true )\r
+    {\r
+        /* No buffered byte should be in the connection. */\r
+        configASSERT( pNetworkConnection->bufferedByteValid == false );\r
+\r
+        /* Block and wait for 1 byte of data. This simulates the behavior of poll().\r
+         * THIS IS A TEMPORARY WORKAROUND AND DOES NOT PROVIDE THREAD-SAFETY AGAINST\r
+         * MULTIPLE CALLS OF RECEIVE. */\r
+        do\r
+        {\r
+            socketStatus = SOCKETS_Recv( pNetworkConnection->socket,\r
+                                         &( pNetworkConnection->bufferedByte ),\r
+                                         1,\r
+                                         0 );\r
+\r
+            connectionFlags = xEventGroupGetBits( ( EventGroupHandle_t ) &( pNetworkConnection->connectionFlags ) );\r
+\r
+            if( ( connectionFlags & _FLAG_SHUTDOWN ) == _FLAG_SHUTDOWN )\r
+            {\r
+                socketStatus = SOCKETS_ECLOSED;\r
+            }\r
+\r
+            /* Check for timeout. Some ports return 0, some return EWOULDBLOCK. */\r
+        } while( ( socketStatus == 0 ) || ( socketStatus == SOCKETS_EWOULDBLOCK ) );\r
+\r
+        if( socketStatus <= 0 )\r
+        {\r
+            break;\r
+        }\r
+\r
+        pNetworkConnection->bufferedByteValid = true;\r
+\r
+        /* Invoke the network callback. */\r
+        pNetworkConnection->receiveCallback( pNetworkConnection,\r
+                                             pNetworkConnection->pReceiveContext );\r
+\r
+        /* Check if the connection was destroyed by the receive callback. This\r
+         * does not need to be thread-safe because the destroy connection function\r
+         * may only be called once (per its API doc). */\r
+        connectionFlags = xEventGroupGetBits( ( EventGroupHandle_t ) &( pNetworkConnection->connectionFlags ) );\r
+\r
+        if( ( connectionFlags & _FLAG_CONNECTION_DESTROYED ) == _FLAG_CONNECTION_DESTROYED )\r
+        {\r
+            destroyConnection = true;\r
+            break;\r
+        }\r
+    }\r
+\r
+    IotLogDebug( "Network receive task terminating." );\r
+\r
+    /* If necessary, destroy the network connection before exiting. */\r
+    if( destroyConnection == true )\r
+    {\r
+        _destroyConnection( pNetworkConnection );\r
+    }\r
+    else\r
+    {\r
+        /* Set the flag to indicate that the receive task has exited. */\r
+        ( void ) xEventGroupSetBits( ( EventGroupHandle_t ) &( pNetworkConnection->connectionFlags ),\r
+                                     _FLAG_RECEIVE_TASK_EXITED );\r
+    }\r
+\r
+    vTaskDelete( NULL );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/**\r
+ * @brief Set up a secured TLS connection.\r
+ *\r
+ * @param[in] pAfrCredentials Credentials for the secured connection.\r
+ * @param[in] tcpSocket An initialized socket to secure.\r
+ * @param[in] pHostName Remote server name for SNI.\r
+ * @param[in] hostnameLength The length of `pHostName`.\r
+ *\r
+ * @return #IOT_NETWORK_SUCCESS or #IOT_NETWORK_SYSTEM_ERROR.\r
+ */\r
+static IotNetworkError_t _tlsSetup( const IotNetworkCredentials_t * pAfrCredentials,\r
+                                    Socket_t tcpSocket,\r
+                                    const char * pHostName,\r
+                                    size_t hostnameLength )\r
+{\r
+    IOT_FUNCTION_ENTRY( IotNetworkError_t, IOT_NETWORK_SUCCESS );\r
+    int32_t socketStatus = SOCKETS_ERROR_NONE;\r
+\r
+    /* ALPN options for AWS IoT. */\r
+    const char * ppcALPNProtos[] = { socketsAWS_IOT_ALPN_MQTT };\r
+\r
+    /* Set secured option. */\r
+    socketStatus = SOCKETS_SetSockOpt( tcpSocket,\r
+                                       0,\r
+                                       SOCKETS_SO_REQUIRE_TLS,\r
+                                       NULL,\r
+                                       0 );\r
+\r
+    if( socketStatus != SOCKETS_ERROR_NONE )\r
+    {\r
+        IotLogError( "Failed to set secured option for new connection." );\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_SYSTEM_ERROR );\r
+    }\r
+\r
+    /* Set ALPN option. */\r
+    if( pAfrCredentials->pAlpnProtos != NULL )\r
+    {\r
+        socketStatus = SOCKETS_SetSockOpt( tcpSocket,\r
+                                           0,\r
+                                           SOCKETS_SO_ALPN_PROTOCOLS,\r
+                                           ppcALPNProtos,\r
+                                           sizeof( ppcALPNProtos ) / sizeof( ppcALPNProtos[ 0 ] ) );\r
+\r
+        if( socketStatus != SOCKETS_ERROR_NONE )\r
+        {\r
+            IotLogError( "Failed to set ALPN option for new connection." );\r
+            IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_SYSTEM_ERROR );\r
+        }\r
+    }\r
+\r
+    /* Set SNI option. */\r
+    if( pAfrCredentials->disableSni == false )\r
+    {\r
+        socketStatus = SOCKETS_SetSockOpt( tcpSocket,\r
+                                           0,\r
+                                           SOCKETS_SO_SERVER_NAME_INDICATION,\r
+                                           pHostName,\r
+                                           hostnameLength + 1 );\r
+\r
+        if( socketStatus != SOCKETS_ERROR_NONE )\r
+        {\r
+            IotLogError( "Failed to set SNI option for new connection." );\r
+            IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_SYSTEM_ERROR );\r
+        }\r
+    }\r
+\r
+    /* Set custom server certificate. */\r
+    if( pAfrCredentials->pRootCa != NULL )\r
+    {\r
+        socketStatus = SOCKETS_SetSockOpt( tcpSocket,\r
+                                           0,\r
+                                           SOCKETS_SO_TRUSTED_SERVER_CERTIFICATE,\r
+                                           pAfrCredentials->pRootCa,\r
+                                           pAfrCredentials->rootCaSize );\r
+\r
+        if( socketStatus != SOCKETS_ERROR_NONE )\r
+        {\r
+            IotLogError( "Failed to set server certificate option for new connection." );\r
+            IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_SYSTEM_ERROR );\r
+        }\r
+    }\r
+\r
+    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotNetworkError_t IotNetworkAfr_Create( void * pConnectionInfo,\r
+                                        void * pCredentialInfo,\r
+                                        void ** pConnection )\r
+{\r
+    IOT_FUNCTION_ENTRY( IotNetworkError_t, IOT_NETWORK_SUCCESS );\r
+    Socket_t tcpSocket = SOCKETS_INVALID_SOCKET;\r
+    int32_t socketStatus = SOCKETS_ERROR_NONE;\r
+    SocketsSockaddr_t serverAddress = { 0 };\r
+    EventGroupHandle_t pConnectionFlags = NULL;\r
+    SemaphoreHandle_t pConnectionMutex = NULL;\r
+    const TickType_t receiveTimeout = pdMS_TO_TICKS( IOT_NETWORK_SOCKET_POLL_MS );\r
+    _networkConnection_t * pNewNetworkConnection = NULL;\r
+\r
+    /* Cast function parameters to correct types. */\r
+    const IotNetworkServerInfo_t * pServerInfo = pConnectionInfo;\r
+    const IotNetworkCredentials_t * pAfrCredentials = pCredentialInfo;\r
+    _networkConnection_t ** pNetworkConnection = ( _networkConnection_t ** ) pConnection;\r
+\r
+    /* Check host name length against the maximum length allowed by Secure\r
+     * Sockets. */\r
+    const size_t hostnameLength = strlen( pServerInfo->pHostName );\r
+\r
+    if( hostnameLength > ( size_t ) securesocketsMAX_DNS_NAME_LENGTH )\r
+    {\r
+        IotLogError( "Host name length exceeds %d, which is the maximum allowed.",\r
+                     securesocketsMAX_DNS_NAME_LENGTH );\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_BAD_PARAMETER );\r
+    }\r
+\r
+    pNewNetworkConnection = pvPortMalloc( sizeof( _networkConnection_t ) );\r
+\r
+    if( pNewNetworkConnection == NULL )\r
+    {\r
+        IotLogError( "Failed to allocate memory for new network connection." );\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_NO_MEMORY );\r
+    }\r
+\r
+    /* Clear the connection information. */\r
+    ( void ) memset( pNewNetworkConnection, 0x00, sizeof( _networkConnection_t ) );\r
+\r
+    /* Create a new TCP socket. */\r
+    tcpSocket = SOCKETS_Socket( SOCKETS_AF_INET,\r
+                                SOCKETS_SOCK_STREAM,\r
+                                SOCKETS_IPPROTO_TCP );\r
+\r
+    if( tcpSocket == SOCKETS_INVALID_SOCKET )\r
+    {\r
+        IotLogError( "Failed to create new socket." );\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_SYSTEM_ERROR );\r
+    }\r
+\r
+    /* Set up connection encryption if credentials are provided. */\r
+    if( pAfrCredentials != NULL )\r
+    {\r
+        status = _tlsSetup( pAfrCredentials, tcpSocket, pServerInfo->pHostName, hostnameLength );\r
+\r
+        if( status != IOT_NETWORK_SUCCESS )\r
+        {\r
+            IOT_GOTO_CLEANUP();\r
+        }\r
+    }\r
+\r
+    /* Establish connection. */\r
+    serverAddress.ucSocketDomain = SOCKETS_AF_INET;\r
+    serverAddress.usPort = SOCKETS_htons( pServerInfo->port );\r
+    serverAddress.ulAddress = SOCKETS_GetHostByName( pServerInfo->pHostName );\r
+\r
+    /* Check for errors from DNS lookup. */\r
+    if( serverAddress.ulAddress == 0 )\r
+    {\r
+        IotLogError( "Failed to resolve %s.", pServerInfo->pHostName );\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_SYSTEM_ERROR );\r
+    }\r
+\r
+    socketStatus = SOCKETS_Connect( tcpSocket,\r
+                                    &serverAddress,\r
+                                    sizeof( SocketsSockaddr_t ) );\r
+\r
+    if( socketStatus != SOCKETS_ERROR_NONE )\r
+    {\r
+        IotLogError( "Failed to establish new connection." );\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_SYSTEM_ERROR );\r
+    }\r
+\r
+    /* Set a long timeout for receive. */\r
+    socketStatus = SOCKETS_SetSockOpt( tcpSocket,\r
+                                       0,\r
+                                       SOCKETS_SO_RCVTIMEO,\r
+                                       &receiveTimeout,\r
+                                       sizeof( TickType_t ) );\r
+\r
+    if( socketStatus != SOCKETS_ERROR_NONE )\r
+    {\r
+        IotLogError( "Failed to set socket receive timeout." );\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_SYSTEM_ERROR );\r
+    }\r
+\r
+    IOT_FUNCTION_CLEANUP_BEGIN();\r
+\r
+    /* Clean up on failure. */\r
+    if( status != IOT_NETWORK_SUCCESS )\r
+    {\r
+        if( tcpSocket != SOCKETS_INVALID_SOCKET )\r
+        {\r
+            SOCKETS_Close( tcpSocket );\r
+        }\r
+\r
+        /* Clear the connection information. */\r
+        if( pNewNetworkConnection != NULL )\r
+        {\r
+            vPortFree( pNewNetworkConnection );\r
+        }\r
+    }\r
+    else\r
+    {\r
+        /* Set the socket. */\r
+        pNewNetworkConnection->socket = tcpSocket;\r
+\r
+        /* Create the connection event flags and mutex. */\r
+        pConnectionFlags = xEventGroupCreateStatic( &( pNewNetworkConnection->connectionFlags ) );\r
+        pConnectionMutex = xSemaphoreCreateMutexStatic( &( pNewNetworkConnection->socketMutex ) );\r
+\r
+        /* Static event flags and mutex creation should never fail. The handles\r
+         * should point inside the connection object. */\r
+        configASSERT( pConnectionFlags == ( EventGroupHandle_t ) &( pNewNetworkConnection->connectionFlags ) );\r
+        configASSERT( pConnectionMutex == ( SemaphoreHandle_t ) &( pNewNetworkConnection->socketMutex ) );\r
+\r
+        /* Set the output parameter. */\r
+        *pNetworkConnection = pNewNetworkConnection;\r
+    }\r
+\r
+    IOT_FUNCTION_CLEANUP_END();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotNetworkError_t IotNetworkAfr_SetReceiveCallback( void * pConnection,\r
+                                                    IotNetworkReceiveCallback_t receiveCallback,\r
+                                                    void * pContext )\r
+{\r
+    IotNetworkError_t status = IOT_NETWORK_SUCCESS;\r
+\r
+    /* Cast network connection to the correct type. */\r
+    _networkConnection_t * pNetworkConnection = ( _networkConnection_t * ) pConnection;\r
+\r
+    /* Set the receive callback and context. */\r
+    pNetworkConnection->receiveCallback = receiveCallback;\r
+    pNetworkConnection->pReceiveContext = pContext;\r
+\r
+    /* No flags should be set. */\r
+    configASSERT( xEventGroupGetBits( ( EventGroupHandle_t ) &( pNetworkConnection->connectionFlags ) ) == 0 );\r
+\r
+    /* Create task that waits for incoming data. */\r
+    if( xTaskCreate( _networkReceiveTask,\r
+                     "NetRecv",\r
+                     IOT_NETWORK_RECEIVE_TASK_STACK_SIZE,\r
+                     pNetworkConnection,\r
+                     IOT_NETWORK_RECEIVE_TASK_PRIORITY,\r
+                     &( pNetworkConnection->receiveTask ) ) != pdPASS )\r
+    {\r
+        IotLogError( "Failed to create network receive task." );\r
+\r
+        status = IOT_NETWORK_SYSTEM_ERROR;\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+size_t IotNetworkAfr_Send( void * pConnection,\r
+                           const uint8_t * pMessage,\r
+                           size_t messageLength )\r
+{\r
+    size_t bytesSent = 0;\r
+    int32_t socketStatus = SOCKETS_ERROR_NONE;\r
+\r
+    /* Cast network connection to the correct type. */\r
+    _networkConnection_t * pNetworkConnection = ( _networkConnection_t * ) pConnection;\r
+\r
+    /* Only one thread at a time may send on the connection. Lock the socket\r
+     * mutex to prevent other threads from sending. */\r
+    if( xSemaphoreTake( ( QueueHandle_t ) &( pNetworkConnection->socketMutex ),\r
+                        portMAX_DELAY ) == pdTRUE )\r
+    {\r
+        socketStatus = SOCKETS_Send( pNetworkConnection->socket,\r
+                                     pMessage,\r
+                                     messageLength,\r
+                                     0 );\r
+\r
+        if( socketStatus > 0 )\r
+        {\r
+            bytesSent = ( size_t ) socketStatus;\r
+        }\r
+\r
+        xSemaphoreGive( ( QueueHandle_t ) &( pNetworkConnection->socketMutex ) );\r
+    }\r
+\r
+    return bytesSent;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+size_t IotNetworkAfr_Receive( void * pConnection,\r
+                              uint8_t * pBuffer,\r
+                              size_t bytesRequested )\r
+{\r
+    int32_t socketStatus = 0;\r
+    size_t bytesReceived = 0, bytesRemaining = bytesRequested;\r
+\r
+    /* Cast network connection to the correct type. */\r
+    _networkConnection_t * pNetworkConnection = ( _networkConnection_t * ) pConnection;\r
+\r
+    /* Write the buffered byte. THIS IS A TEMPORARY WORKAROUND AND ASSUMES THIS\r
+     * FUNCTION IS ALWAYS CALLED FROM THE RECEIVE CALLBACK. */\r
+    if( pNetworkConnection->bufferedByteValid == true )\r
+    {\r
+        *pBuffer = pNetworkConnection->bufferedByte;\r
+        bytesReceived = 1;\r
+        bytesRemaining--;\r
+        pNetworkConnection->bufferedByteValid = false;\r
+    }\r
+\r
+    /* Block and wait for incoming data. */\r
+    while( bytesRemaining > 0 )\r
+    {\r
+        socketStatus = SOCKETS_Recv( pNetworkConnection->socket,\r
+                                     pBuffer + bytesReceived,\r
+                                     bytesRemaining,\r
+                                     0 );\r
+\r
+        if( socketStatus == SOCKETS_EWOULDBLOCK )\r
+        {\r
+            /* The return value EWOULDBLOCK means no data was received within\r
+             * the socket timeout. Ignore it and try again. */\r
+            continue;\r
+        }\r
+        else if( socketStatus <= 0 )\r
+        {\r
+            IotLogError( "Error %ld while receiving data.", ( long int ) socketStatus );\r
+            break;\r
+        }\r
+        else\r
+        {\r
+            bytesReceived += ( size_t ) socketStatus;\r
+            bytesRemaining -= ( size_t ) socketStatus;\r
+\r
+            configASSERT( bytesReceived + bytesRemaining == bytesRequested );\r
+        }\r
+    }\r
+\r
+    if( bytesReceived < bytesRequested )\r
+    {\r
+        IotLogWarn( "Receive requested %lu bytes, but %lu bytes received instead.",\r
+                    ( unsigned long ) bytesRequested,\r
+                    ( unsigned long ) bytesReceived );\r
+    }\r
+    else\r
+    {\r
+        IotLogDebug( "Successfully received %lu bytes.",\r
+                     ( unsigned long ) bytesRequested );\r
+    }\r
+\r
+    return bytesReceived;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotNetworkError_t IotNetworkAfr_Close( void * pConnection )\r
+{\r
+    int32_t socketStatus = SOCKETS_ERROR_NONE;\r
+\r
+    /* Cast network connection to the correct type. */\r
+    _networkConnection_t * pNetworkConnection = ( _networkConnection_t * ) pConnection;\r
+\r
+    /* Call Secure Sockets shutdown function to close connection. */\r
+    socketStatus = SOCKETS_Shutdown( pNetworkConnection->socket,\r
+                                     SOCKETS_SHUT_RDWR );\r
+\r
+    if( socketStatus != SOCKETS_ERROR_NONE )\r
+    {\r
+        IotLogWarn( "Failed to close connection." );\r
+    }\r
+\r
+    /* Set the shutdown flag. */\r
+    ( void ) xEventGroupSetBits( ( EventGroupHandle_t ) &( pNetworkConnection->connectionFlags ),\r
+                                 _FLAG_SHUTDOWN );\r
+\r
+    return IOT_NETWORK_SUCCESS;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotNetworkError_t IotNetworkAfr_Destroy( void * pConnection )\r
+{\r
+    /* Cast network connection to the correct type. */\r
+    _networkConnection_t * pNetworkConnection = ( _networkConnection_t * ) pConnection;\r
+\r
+    /* Check if this function is being called from the receive task. */\r
+    if( xTaskGetCurrentTaskHandle() == pNetworkConnection->receiveTask )\r
+    {\r
+        /* Set the flag specifying that the connection is destroyed. */\r
+        ( void ) xEventGroupSetBits( ( EventGroupHandle_t ) &( pNetworkConnection->connectionFlags ),\r
+                                     _FLAG_CONNECTION_DESTROYED );\r
+    }\r
+    else\r
+    {\r
+        /* If a receive task was created, wait for it to exit. */\r
+        if( pNetworkConnection->receiveTask != NULL )\r
+        {\r
+            ( void ) xEventGroupWaitBits( ( EventGroupHandle_t ) &( pNetworkConnection->connectionFlags ),\r
+                                          _FLAG_RECEIVE_TASK_EXITED,\r
+                                          pdTRUE,\r
+                                          pdTRUE,\r
+                                          portMAX_DELAY );\r
+        }\r
+\r
+        _destroyConnection( pNetworkConnection );\r
+    }\r
+\r
+    return IOT_NETWORK_SUCCESS;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/iot_threads_freertos.c b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/iot_threads_freertos.c
new file mode 100644 (file)
index 0000000..f4a5f97
--- /dev/null
@@ -0,0 +1,364 @@
+/*\r
+ * Amazon FreeRTOS Platform V1.0.0\r
+ * Copyright (C) 2019 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_threads_freertos.c\r
+ * @brief Implementation of the functions in iot_threads.h for POSIX systems.\r
+ */\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+#include "semphr.h"\r
+\r
+/* Platform threads include. */\r
+#include "platform/iot_platform_types_freertos.h"\r
+#include "platform/iot_threads.h"\r
+#include "types/iot_platform_types.h"\r
+\r
+/* Configure logs for the functions in this file. */\r
+#ifdef IOT_LOG_LEVEL_PLATFORM\r
+    #define LIBRARY_LOG_LEVEL        IOT_LOG_LEVEL_PLATFORM\r
+#else\r
+    #ifdef IOT_LOG_LEVEL_GLOBAL\r
+        #define LIBRARY_LOG_LEVEL    IOT_LOG_LEVEL_GLOBAL\r
+    #else\r
+        #define LIBRARY_LOG_LEVEL    IOT_LOG_NONE\r
+    #endif\r
+#endif\r
+\r
+#define LIBRARY_LOG_NAME    ( "THREAD" )\r
+#include "iot_logging_setup.h"\r
+\r
+/*\r
+ * Provide default values for undefined memory allocation functions based on\r
+ * the usage of dynamic memory allocation.\r
+ */\r
+#ifndef IotThreads_Malloc\r
+    #include <stdlib.h>\r
+\r
+/**\r
+ * @brief Memory allocation. This function should have the same signature\r
+ * as [malloc](http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html).\r
+ */\r
+    #define IotThreads_Malloc    malloc\r
+#endif\r
+#ifndef IotThreads_Free\r
+    #include <stdlib.h>\r
+\r
+/**\r
+ * @brief Free memory. This function should have the same signature as\r
+ * [free](http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
+ */\r
+    #define IotThreads_Free    free\r
+#endif\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static void _threadRoutineWrapper( void * pArgument )\r
+{\r
+    threadInfo_t * pThreadInfo = ( threadInfo_t * ) pArgument;\r
+\r
+    /* Run the thread routine. */\r
+    pThreadInfo->threadRoutine( pThreadInfo->pArgument );\r
+    IotThreads_Free( pThreadInfo );\r
+\r
+    vTaskDelete( NULL );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+bool Iot_CreateDetachedThread( IotThreadRoutine_t threadRoutine,\r
+                               void * pArgument,\r
+                               int32_t priority,\r
+                               size_t stackSize )\r
+{\r
+    bool status = true;\r
+\r
+    configASSERT( threadRoutine != NULL );\r
+\r
+    IotLogDebug( "Creating new thread." );\r
+    threadInfo_t * pThreadInfo = IotThreads_Malloc( sizeof( threadInfo_t ) );\r
+\r
+    if( pThreadInfo == NULL )\r
+    {\r
+        IotLogDebug( "Unable to allocate memory for threadRoutine %p.", threadRoutine );\r
+        status = false;\r
+    }\r
+\r
+    /* Create the FreeRTOS task that will run the thread. */\r
+    if( status )\r
+    {\r
+        pThreadInfo->threadRoutine = threadRoutine;\r
+        pThreadInfo->pArgument = pArgument;\r
+\r
+        if( xTaskCreate( _threadRoutineWrapper,\r
+                         "iot_thread",\r
+                         ( configSTACK_DEPTH_TYPE ) stackSize,\r
+                         pThreadInfo,\r
+                         priority,\r
+                         NULL ) != pdPASS )\r
+        {\r
+            /* Task creation failed. */\r
+            IotLogWarn( "Failed to create thread." );\r
+            IotThreads_Free( pThreadInfo );\r
+            status = false;\r
+        }\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+bool IotMutex_Create( IotMutex_t * pNewMutex,\r
+                      bool recursive )\r
+{\r
+    _IotSystemMutex_t * internalMutex = ( _IotSystemMutex_t * ) pNewMutex;\r
+\r
+    configASSERT( internalMutex != NULL );\r
+\r
+    IotLogDebug( "Creating new mutex %p.", pNewMutex );\r
+\r
+    if( recursive )\r
+    {\r
+        ( void ) xSemaphoreCreateRecursiveMutexStatic( &internalMutex->xMutex );\r
+    }\r
+    else\r
+    {\r
+        ( void ) xSemaphoreCreateMutexStatic( &internalMutex->xMutex );\r
+    }\r
+\r
+    /* remember the type of mutex */\r
+    if( recursive )\r
+    {\r
+        internalMutex->recursive = pdTRUE;\r
+    }\r
+    else\r
+    {\r
+        internalMutex->recursive = pdFALSE;\r
+    }\r
+\r
+    return true;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void IotMutex_Destroy( IotMutex_t * pMutex )\r
+{\r
+    _IotSystemMutex_t * internalMutex = ( _IotSystemMutex_t * ) pMutex;\r
+\r
+    configASSERT( internalMutex != NULL );\r
+\r
+    vSemaphoreDelete( ( SemaphoreHandle_t ) &internalMutex->xMutex );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+bool prIotMutexTimedLock( IotMutex_t * pMutex,\r
+                          TickType_t timeout )\r
+{\r
+    _IotSystemMutex_t * internalMutex = ( _IotSystemMutex_t * ) pMutex;\r
+    BaseType_t lockResult;\r
+\r
+    configASSERT( internalMutex != NULL );\r
+\r
+    IotLogDebug( "Locking mutex %p.", internalMutex );\r
+\r
+    /* Call the correct FreeRTOS mutex take function based on mutex type. */\r
+    if( internalMutex->recursive == pdTRUE )\r
+    {\r
+        lockResult = xSemaphoreTakeRecursive( ( SemaphoreHandle_t ) &internalMutex->xMutex, timeout );\r
+    }\r
+    else\r
+    {\r
+        lockResult = xSemaphoreTake( ( SemaphoreHandle_t ) &internalMutex->xMutex, timeout );\r
+    }\r
+\r
+    return( lockResult == pdTRUE );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void IotMutex_Lock( IotMutex_t * pMutex )\r
+{\r
+    prIotMutexTimedLock( pMutex, portMAX_DELAY );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+bool IotMutex_TryLock( IotMutex_t * pMutex )\r
+{\r
+    return prIotMutexTimedLock( pMutex, 0 );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void IotMutex_Unlock( IotMutex_t * pMutex )\r
+{\r
+    _IotSystemMutex_t * internalMutex = ( _IotSystemMutex_t * ) pMutex;\r
+\r
+    configASSERT( internalMutex != NULL );\r
+\r
+    IotLogDebug( "Unlocking mutex %p.", internalMutex );\r
+\r
+    /* Call the correct FreeRTOS mutex unlock function based on mutex type. */\r
+    if( internalMutex->recursive == pdTRUE )\r
+    {\r
+        ( void ) xSemaphoreGiveRecursive( ( SemaphoreHandle_t ) &internalMutex->xMutex );\r
+    }\r
+    else\r
+    {\r
+        ( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &internalMutex->xMutex );\r
+    }\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+bool IotSemaphore_Create( IotSemaphore_t * pNewSemaphore,\r
+                          uint32_t initialValue,\r
+                          uint32_t maxValue )\r
+{\r
+    _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pNewSemaphore;\r
+\r
+    configASSERT( internalSemaphore != NULL );\r
+\r
+    IotLogDebug( "Creating new semaphore %p.", pNewSemaphore );\r
+\r
+    ( void ) xSemaphoreCreateCountingStatic( maxValue, initialValue, &internalSemaphore->xSemaphore );\r
+\r
+    return true;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+uint32_t IotSemaphore_GetCount( IotSemaphore_t * pSemaphore )\r
+{\r
+    _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;\r
+    UBaseType_t count = 0;\r
+\r
+    configASSERT( internalSemaphore != NULL );\r
+\r
+    count = uxSemaphoreGetCount( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore );\r
+\r
+    IotLogDebug( "Semaphore %p has count %d.", pSemaphore, count );\r
+\r
+    return ( uint32_t ) count;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void IotSemaphore_Destroy( IotSemaphore_t * pSemaphore )\r
+{\r
+    _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;\r
+\r
+    configASSERT( internalSemaphore != NULL );\r
+\r
+    IotLogDebug( "Destroying semaphore %p.", internalSemaphore );\r
+\r
+    vSemaphoreDelete( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void IotSemaphore_Wait( IotSemaphore_t * pSemaphore )\r
+{\r
+    _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;\r
+\r
+    configASSERT( internalSemaphore != NULL );\r
+\r
+    IotLogDebug( "Waiting on semaphore %p.", internalSemaphore );\r
+\r
+    /* Take the semaphore using the FreeRTOS API. */\r
+    if( xSemaphoreTake( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore,\r
+                        portMAX_DELAY ) != pdTRUE )\r
+    {\r
+        IotLogWarn( "Failed to wait on semaphore %p.",\r
+                    pSemaphore );\r
+\r
+        /* Assert here, debugging we always want to know that this happened because you think\r
+         *   that you are waiting successfully on the semaphore but you are not   */\r
+        configASSERT( false );\r
+    }\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+bool IotSemaphore_TryWait( IotSemaphore_t * pSemaphore )\r
+{\r
+    _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;\r
+\r
+    configASSERT( internalSemaphore != NULL );\r
+\r
+    IotLogDebug( "Attempting to wait on semaphore %p.", internalSemaphore );\r
+\r
+    return IotSemaphore_TimedWait( pSemaphore, 0 );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+bool IotSemaphore_TimedWait( IotSemaphore_t * pSemaphore,\r
+                             uint32_t timeoutMs )\r
+{\r
+    _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;\r
+\r
+    configASSERT( internalSemaphore != NULL );\r
+\r
+    /* Take the semaphore using the FreeRTOS API. Cast the calculation to 64 bit to avoid overflows*/\r
+    if( xSemaphoreTake( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore,\r
+                        pdMS_TO_TICKS( timeoutMs ) ) != pdTRUE )\r
+    {\r
+        /* Only warn if timeout > 0 */\r
+        if( timeoutMs > 0 )\r
+        {\r
+            IotLogWarn( "Timeout waiting on semaphore %p.",\r
+                        internalSemaphore );\r
+        }\r
+\r
+        return false;\r
+    }\r
+\r
+    return true;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void IotSemaphore_Post( IotSemaphore_t * pSemaphore )\r
+{\r
+    _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;\r
+\r
+    configASSERT( internalSemaphore != NULL );\r
+\r
+    IotLogDebug( "Posting to semaphore %p.", internalSemaphore );\r
+    /* Give the semaphore using the FreeRTOS API. */\r
+    BaseType_t result = xSemaphoreGive( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore );\r
+\r
+    if( result == pdFALSE )\r
+    {\r
+        IotLogDebug( "Unable to give semaphore over maximum", internalSemaphore );\r
+    }\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/platform/iot_clock.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/platform/iot_clock.h
new file mode 100644 (file)
index 0000000..93c7dcb
--- /dev/null
@@ -0,0 +1,216 @@
+/*\r
+ * Amazon FreeRTOS Platform V1.0.0\r
+ * Copyright (C) 2019 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_clock.h\r
+ * @brief Time-related functions used by libraries in this SDK.\r
+ */\r
+\r
+#ifndef IOT_CLOCK_H_\r
+#define IOT_CLOCK_H_\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/* Standard includes. */\r
+#include <stdbool.h>\r
+#include <stddef.h>\r
+#include <stdint.h>\r
+\r
+/* Platform layer types include. */\r
+#include "types/iot_platform_types.h"\r
+\r
+/**\r
+ * @functionspage{platform_clock,platform clock component,Clock}\r
+ * - @functionname{platform_clock_function_gettimestring}\r
+ * - @functionname{platform_clock_function_gettimems}\r
+ * - @functionname{platform_clock_function_sleepms}\r
+ * - @functionname{platform_clock_function_timercreate}\r
+ * - @functionname{platform_clock_function_timerdestroy}\r
+ * - @functionname{platform_clock_function_timerarm}\r
+ */\r
+\r
+/**\r
+ * @functionpage{IotClock_GetTimestring,platform_clock,gettimestring}\r
+ * @functionpage{IotClock_GetTimeMs,platform_clock,gettimems}\r
+ * @functionpage{IotClock_SleepMs,platform_clock,sleepms}\r
+ * @functionpage{IotClock_TimerCreate,platform_clock,timercreate}\r
+ * @functionpage{IotClock_TimerDestroy,platform_clock,timerdestroy}\r
+ * @functionpage{IotClock_TimerArm,platform_clock,timerarm}\r
+ */\r
+\r
+/**\r
+ * @brief Generates a human-readable timestring, such as "01 Jan 2018 12:00".\r
+ *\r
+ * This function uses the system clock to generate a human-readable timestring.\r
+ * This timestring is printed by the [logging functions](@ref logging_functions).\r
+ *\r
+ * @param[out] pBuffer A buffer to store the timestring in.\r
+ * @param[in] bufferSize The size of `pBuffer`.\r
+ * @param[out] pTimestringLength The actual length of the timestring stored in\r
+ * `pBuffer`.\r
+ *\r
+ * @return `true` if a timestring was successfully generated; `false` otherwise.\r
+ *\r
+ * @warning The implementation of this function must not call any [logging functions]\r
+ * (@ref logging_functions).\r
+ *\r
+ * <b>Example</b>\r
+ * @code{c}\r
+ * char timestring[ 32 ];\r
+ * size_t timestringLength = 0;\r
+ *\r
+ * if( IotClock_GetTimestring( timestring, 32, &timestringLength ) == true )\r
+ * {\r
+ *     printf( "Timestring: %.*s", timestringLength, timestring );\r
+ * }\r
+ * @endcode\r
+ */\r
+/* @[declare_platform_clock_gettimestring] */\r
+bool IotClock_GetTimestring( char * pBuffer,\r
+                             size_t bufferSize,\r
+                             size_t * pTimestringLength );\r
+/* @[declare_platform_clock_gettimestring] */\r
+\r
+/**\r
+ * @brief Returns a nonzero, monotonically-increasing system time in milliseconds.\r
+ *\r
+ * This function reads a millisecond-resolution system clock. The clock should\r
+ * always be monotonically-increasing; therefore, real-time clocks that may be\r
+ * set by another process are not suitable for this function's implementation.\r
+ *\r
+ * @return The value of the system clock. This function is not expected to fail.\r
+ *\r
+ * <b>Example</b>\r
+ * @code{c}\r
+ * // Get current time.\r
+ * uint64_t currentTime = IotClock_GetTimeMs();\r
+ * @endcode\r
+ */\r
+/* @[declare_platform_clock_gettimems] */\r
+uint64_t IotClock_GetTimeMs( void );\r
+/* @[declare_platform_clock_gettimems] */\r
+\r
+/**\r
+ * @brief Delay for the given number of milliseconds.\r
+ *\r
+ * This function suspends its calling thread for at least `sleepTimeMs` milliseconds.\r
+ *\r
+ * @param[in] sleepTimeMs Sleep time (in milliseconds).\r
+ */\r
+/* @[declare_platform_clock_sleepms] */\r
+void IotClock_SleepMs( uint32_t sleepTimeMs );\r
+/* @[declare_platform_clock_sleepms] */\r
+\r
+/**\r
+ * @brief Create a new timer.\r
+ *\r
+ * This function creates a new, unarmed timer. It must be called on an uninitialized\r
+ * #IotTimer_t. This function must not be called on an already-initialized #IotTimer_t.\r
+ *\r
+ * @param[out] pNewTimer Set to a new timer handle on success.\r
+ * @param[in] expirationRoutine The function to run when this timer expires. This\r
+ * function should be called in its own <i>detached</i> thread.\r
+ * @param[in] pArgument The argument to pass to `expirationRoutine`.\r
+ *\r
+ * @return `true` if the timer is successfully created; `false` otherwise.\r
+ *\r
+ * @see @ref platform_clock_function_timerdestroy, @ref platform_clock_function_timerarm\r
+ */\r
+/* @[declare_platform_clock_timercreate] */\r
+bool IotClock_TimerCreate( IotTimer_t * pNewTimer,\r
+                           IotThreadRoutine_t expirationRoutine,\r
+                           void * pArgument );\r
+/* @[declare_platform_clock_timercreate] */\r
+\r
+/**\r
+ * @brief Free resources used by a timer.\r
+ *\r
+ * This function frees resources used by a timer. It must be called on an initialized\r
+ * #IotTimer_t. No other timer functions should be called on `pTimer` after calling\r
+ * this function (unless the timer is re-created).\r
+ *\r
+ * This function will stop the `pTimer` if it is armed.\r
+ *\r
+ * @param[in] pTimer The timer to destroy.\r
+ *\r
+ * @see @ref platform_clock_function_timercreate, @ref platform_clock_function_timerarm\r
+ */\r
+/* @[declare_platform_clock_timerdestroy] */\r
+void IotClock_TimerDestroy( IotTimer_t * pTimer );\r
+/* @[declare_platform_clock_timerdestroy] */\r
+\r
+/**\r
+ * @brief Arm a timer to expire at the given relative timeout.\r
+ *\r
+ * This function arms a timer to run its expiration routine at the given time.\r
+ *\r
+ * If `periodMs` is nonzero, the timer should expire periodically at intervals\r
+ * such as:\r
+ * - `relativeTimeoutMs`\r
+ * - `relativeTimeoutMs + periodMs`\r
+ * - `relativeTimeoutMs + 2 * periodMs`\r
+ * - Etc. (subject to some jitter).\r
+ *\r
+ * Setting `periodMs` to `0` arms a one-shot, non-periodic timer.\r
+ *\r
+ * @param[in] pTimer The timer to arm.\r
+ * @param[in] relativeTimeoutMs When the timer should expire, relative to the time\r
+ * this function is called.\r
+ * @param[in] periodMs How often the timer should expire again after `relativeTimerMs`.\r
+ *\r
+ * @return `true` if the timer was successfully armed; `false` otherwise.\r
+ *\r
+ * @see @ref platform_clock_function_timercreate, @ref platform_clock_function_timerdestroy\r
+ *\r
+ * <b>Example</b>\r
+ * @code{c}\r
+ *\r
+ * void timerExpirationRoutine( void * pArgument );\r
+ *\r
+ * void timerExample( void )\r
+ * {\r
+ *     IotTimer_t timer;\r
+ *\r
+ *     if( IotClock_TimerCreate( &timer, timerExpirationRoutine, NULL ) == true )\r
+ *     {\r
+ *         // Set the timer to periodically expire every 10 seconds.\r
+ *         if( IotClock_TimerArm( &timer, 10000, 10000 ) == true )\r
+ *         {\r
+ *             // Wait for timer to expire.\r
+ *         }\r
+ *\r
+ *         IotClock_TimerDestroy( &timer );\r
+ *     }\r
+ * }\r
+ * @endcode\r
+ */\r
+/* @[declare_platform_clock_timerarm] */\r
+bool IotClock_TimerArm( IotTimer_t * pTimer,\r
+                        uint32_t relativeTimeoutMs,\r
+                        uint32_t periodMs );\r
+/* @[declare_platform_clock_timerarm] */\r
+\r
+#endif /* ifndef IOT_CLOCK_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/platform/iot_metrics.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/platform/iot_metrics.h
new file mode 100644 (file)
index 0000000..74eb4f6
--- /dev/null
@@ -0,0 +1,103 @@
+/*\r
+ * Amazon FreeRTOS Platform V1.0.0\r
+ * Copyright (C) 2019 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_metrics.h\r
+ * @brief Functions for retrieving [Device Defender](@ref defender) metrics.\r
+ *\r
+ * The functions in this header are only required by Device Defender. They do not\r
+ * need to be implemented if Device Defender is not used.\r
+ */\r
+\r
+#ifndef IOT_METRICS_H_\r
+#define IOT_METRICS_H_\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/* Standard includes. */\r
+#include <stdbool.h>\r
+\r
+/* Linear containers (lists and queues) include. */\r
+#include "iot_linear_containers.h"\r
+\r
+/**\r
+ * @functionspage{platform_metrics,platform metrics component,Metrics}\r
+ * - @functionname{platform_metrics_function_init}\r
+ * - @functionname{platform_metrics_function_cleanup}\r
+ * - @functionname{platform_metrics_function_gettcpconnections}\r
+ */\r
+\r
+/**\r
+ * @functionpage{IotMetrics_Init,platform_metrics,init}\r
+ * @functionpage{IotMetrics_Cleanup,platform_metrics,cleanup}\r
+ * @functionpage{IotMetrics_GetTcpConnections,platform_metrics,gettcpconnections}\r
+ */\r
+\r
+/**\r
+ * @brief One-time initialization function for the platform metrics component.\r
+ *\r
+ * This function initializes the platform metrics component. <b>It must be called\r
+ * once (and only once) before calling any other metrics or [Device Defender function]\r
+ * (@ref defender_functions).</b> Calling this function more than once without first\r
+ * calling @ref platform_metrics_function_cleanup may result in a crash.\r
+ *\r
+ * @return `true` is initialization succeeded; `false` otherwise.\r
+ *\r
+ * @warning No thread-safety guarantees are provided for this function.\r
+ */\r
+/* @[declare_platform_metrics_init] */\r
+bool IotMetrics_Init( void );\r
+/* @[declare_platform_metrics_init] */\r
+\r
+/**\r
+ * @brief One-time deinitialization function for the platform metrics component.\r
+ *\r
+ * This function frees resources taken in @ref platform_metrics_function_init.\r
+ * No other metrics or [Device Defender functions](@ref defender_functions) may\r
+ * be called unless @ref platform_metrics_function_init is called again.\r
+ *\r
+ * @warning No thread-safety guarantees are provided for this function.\r
+ */\r
+/* @[declare_platform_metrics_cleanup] */\r
+void IotMetrics_Cleanup( void );\r
+/* @[declare_platform_metrics_cleanup] */\r
+\r
+/**\r
+ * @brief Retrieve a list of active TCP connections from the system.\r
+ *\r
+ * The provided connections are reported by Device Defender.\r
+ *\r
+ * @param[in] pContext Context passed as the first parameter of `metricsCallback`.\r
+ * @param[in] metricsCallback Called by this function to provide the list of TCP\r
+ * connections. The list given by this function is should not be used after the\r
+ * callback returns.\r
+ */\r
+/* @[declare_platform_metrics_gettcpconnections] */\r
+void IotMetrics_GetTcpConnections( void * pContext,\r
+                                   void ( * metricsCallback )( void *, const IotListDouble_t * ) );\r
+/* @[declare_platform_metrics_gettcpconnections] */\r
+\r
+#endif /* ifndef IOT_METRICS_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/platform/iot_network.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/platform/iot_network.h
new file mode 100644 (file)
index 0000000..f52e4bb
--- /dev/null
@@ -0,0 +1,294 @@
+/*\r
+ * Amazon FreeRTOS Platform V1.0.0\r
+ * Copyright (C) 2019 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_network.h\r
+ * @brief Abstraction of network functions used by libraries in this SDK.\r
+ */\r
+\r
+#ifndef IOT_NETWORK_H_\r
+#define IOT_NETWORK_H_\r
+\r
+/* Standard includes. */\r
+#include <stdbool.h>\r
+#include <stdint.h>\r
+#include <stdlib.h>\r
+\r
+/**\r
+ * @ingroup platform_datatypes_enums\r
+ * @brief Return codes for [network functions](@ref platform_network_functions).\r
+ */\r
+typedef enum IotNetworkError\r
+{\r
+    IOT_NETWORK_SUCCESS = 0,   /**< Function successfully completed. */\r
+    IOT_NETWORK_FAILURE,       /**< Generic failure not covered by other values. */\r
+    IOT_NETWORK_BAD_PARAMETER, /**< At least one parameter was invalid. */\r
+    IOT_NETWORK_NO_MEMORY,     /**< Memory allocation failed. */\r
+    IOT_NETWORK_SYSTEM_ERROR   /**< An error occurred when calling a system API. */\r
+} IotNetworkError_t;\r
+\r
+/**\r
+ * @page platform_network_functions Networking\r
+ * @brief Functions of the network abstraction component.\r
+ *\r
+ * The network abstraction component does not declare functions, but uses function\r
+ * pointers instead. This allows multiple network stacks to be used at the same time.\r
+ * Libraries that require the network will request an #IotNetworkInterface_t\r
+ * parameter. The members of the #IotNetworkInterface_t will be called whenever\r
+ * the library interacts with the network.\r
+ *\r
+ * The following function pointers are associated with an #IotNetworkInterface_t.\r
+ * Together, they represent a network stack.\r
+ * - @functionname{platform_network_function_create}\r
+ * - @functionname{platform_network_function_setreceivecallback}\r
+ * - @functionname{platform_network_function_send}\r
+ * - @functionname{platform_network_function_receive}\r
+ * - @functionname{platform_network_function_close}\r
+ * - @functionname{platform_network_function_destroy}\r
+ * - @functionname{platform_network_function_receivecallback}\r
+ */\r
+\r
+/**\r
+ * @functionpage{IotNetworkInterface_t::create,platform_network,create}\r
+ * @functionpage{IotNetworkInterface_t::setReceiveCallback,platform_network,setreceivecallback}\r
+ * @functionpage{IotNetworkInterface_t::send,platform_network,send}\r
+ * @functionpage{IotNetworkInterface_t::receive,platform_network,receive}\r
+ * @functionpage{IotNetworkInterface_t::close,platform_network,close}\r
+ * @functionpage{IotNetworkInterface_t::destroy,platform_network,destroy}\r
+ * @functionpage{IotNetworkReceiveCallback_t,platform_network,receivecallback}\r
+ */\r
+\r
+/**\r
+ * @brief Provide an asynchronous notification of incoming network data.\r
+ *\r
+ * A function with this signature may be set with @ref platform_network_function_setreceivecallback\r
+ * to be invoked when data is available on the network.\r
+ *\r
+ * @param[in] pConnection The connection on which data is available, defined by\r
+ * the network stack.\r
+ * @param[in] pContext The third argument passed to @ref platform_network_function_setreceivecallback.\r
+ */\r
+/* @[declare_platform_network_receivecallback] */\r
+typedef void ( * IotNetworkReceiveCallback_t )( void * pConnection,\r
+                                                void * pContext );\r
+/* @[declare_platform_network_receivecallback] */\r
+\r
+/**\r
+ * @ingroup platform_datatypes_paramstructs\r
+ * @brief Represents the functions of a network stack.\r
+ *\r
+ * Functions that match these signatures should be implemented against a system's\r
+ * network stack. See the `platform` directory for existing implementations.\r
+ */\r
+typedef struct IotNetworkInterface\r
+{\r
+    /**\r
+     * @brief Create a new network connection.\r
+     *\r
+     * This function allocates resources and establishes a new network connection.\r
+     * @param[in] pConnectionInfo Represents information needed to set up the\r
+     * new connection, defined by the network stack.\r
+     * @param[in] pCredentialInfo Represents information needed to secure the\r
+     * new connection, defined by the network stack.\r
+     * @param[out] pConnection Set to represent a new connection, defined by the\r
+     * network stack.\r
+     *\r
+     * @return Any #IotNetworkError_t, as defined by the network stack.\r
+     */\r
+    /* @[declare_platform_network_create] */\r
+    IotNetworkError_t ( * create )( void * pConnectionInfo,\r
+                                    void * pCredentialInfo,\r
+                                    void ** pConnection );\r
+    /* @[declare_platform_network_create] */\r
+\r
+    /**\r
+     * @brief Register an @ref platform_network_function_receivecallback.\r
+     *\r
+     * Sets an @ref platform_network_function_receivecallback to be called\r
+     * asynchronously when data arrives on the network. The network stack\r
+     * should invoke this function "as if" it were the thread routine of a\r
+     * detached thread.\r
+     *\r
+     * Each network connection may only have one receive callback at any time.\r
+     * @ref platform_network_function_close is expected to remove any active\r
+     * receive callbacks.\r
+     *\r
+     * @param[in] pConnection The connection to associate with the receive callback.\r
+     * @param[in] receiveCallback The function to invoke for incoming network data.\r
+     * @param[in] pContext A value to pass as the first parameter to the receive callback.\r
+     *\r
+     * @return Any #IotNetworkError_t, as defined by the network stack.\r
+     *\r
+     * @see platform_network_function_receivecallback\r
+     */\r
+    /* @[declare_platform_network_setreceivecallback] */\r
+    IotNetworkError_t ( * setReceiveCallback )( void * pConnection,\r
+                                                IotNetworkReceiveCallback_t receiveCallback,\r
+                                                void * pContext );\r
+    /* @[declare_platform_network_setreceivecallback] */\r
+\r
+    /**\r
+     * @brief Send data over a return connection.\r
+     *\r
+     * Attempts to transmit `messageLength` bytes of `pMessage` across the\r
+     * connection represented by `pConnection`. Returns the number of bytes\r
+     * actually sent, `0` on failure.\r
+     *\r
+     * @param[in] pConnection The connection used to send data, defined by the\r
+     * network stack.\r
+     * @param[in] pMessage The message to send.\r
+     * @param[in] messageLength The length of `pMessage`.\r
+     *\r
+     * @return The number of bytes successfully sent, `0` on failure.\r
+     */\r
+    /* @[declare_platform_network_send] */\r
+    size_t ( * send )( void * pConnection,\r
+                       const uint8_t * pMessage,\r
+                       size_t messageLength );\r
+    /* @[declare_platform_network_send] */\r
+\r
+    /**\r
+     * @brief Block and wait for incoming network data.\r
+     *\r
+     * Wait for a message of size `bytesRequested` to arrive on the network and\r
+     * place it in `pBuffer`.\r
+     *\r
+     * @param[in] pConnection The connection to wait on, defined by the network\r
+     * stack.\r
+     * @param[out] pBuffer Where to place the incoming network data. This buffer\r
+     * must be at least `bytesRequested` in size.\r
+     * @param[in] bytesRequested How many bytes to wait for. `pBuffer` must be at\r
+     * least this size.\r
+     *\r
+     * @return The number of bytes successfully received. This should be\r
+     * `bytesRequested` when successful. Any other value may indicate an error.\r
+     */\r
+    /* @[declare_platform_network_receive] */\r
+    size_t ( * receive )( void * pConnection,\r
+                          uint8_t * pBuffer,\r
+                          size_t bytesRequested );\r
+    /* @[declare_platform_network_receive] */\r
+\r
+    /**\r
+     * @brief Close a network connection.\r
+     *\r
+     * This function closes the connection, but does not release the resources\r
+     * used by the connection. This allows calls to other networking functions\r
+     * to return an error and handle a closed connection without the risk of\r
+     * crashing. Once it can be guaranteed that `pConnection` will no longer be\r
+     * used, the connection can be destroyed with @ref platform_network_function_destroy.\r
+     *\r
+     * In addition to closing the connection, this function should also remove\r
+     * any active [receive callback](@ref platform_network_function_receivecallback).\r
+     *\r
+     * @param[in] pConnection The network connection to close, defined by the\r
+     * network stack.\r
+     *\r
+     * @return Any #IotNetworkError_t, as defined by the network stack.\r
+     *\r
+     * @note It must be safe to call this function on an already-closed connection.\r
+     */\r
+    /* @[declare_platform_network_close] */\r
+    IotNetworkError_t ( * close )( void * pConnection );\r
+    /* @[declare_platform_network_close] */\r
+\r
+    /**\r
+     * @brief Free resources used by a network connection.\r
+     *\r
+     * This function releases the resources of a closed connection. It should be\r
+     * called after @ref platform_network_function_close.\r
+     *\r
+     * @param[in] pConnection The network connection to destroy, defined by\r
+     * the network stack.\r
+     *\r
+     * @return Any #IotNetworkError_t, as defined by the network stack.\r
+     *\r
+     * @attention No function should be called on the network connection after\r
+     * calling this function. This function must be safe to call from a\r
+     * [receive callback](@ref platform_network_function_receivecallback).\r
+     */\r
+    /* @[declare_platform_network_destroy] */\r
+    IotNetworkError_t ( * destroy )( void * pConnection );\r
+    /* @[declare_platform_network_destroy] */\r
+} IotNetworkInterface_t;\r
+\r
+/**\r
+ * @ingroup platform_datatypes_paramstructs\r
+ * @brief Information on the remote server for connection setup.\r
+ *\r
+ * May be passed to #IotNetworkInterface_t.create as `pConnectionInfo`. This\r
+ * structure contains commonly-used parameters, but may be replaced with an\r
+ * alternative.\r
+ */\r
+typedef struct IotNetworkServerInfo\r
+{\r
+    const char * pHostName; /**< @brief Server host name. Must be NULL-terminated. */\r
+    uint16_t port;          /**< @brief Server port in host-order. */\r
+} IotNetworkServerInfo_t;\r
+\r
+/**\r
+ * @ingroup platform_datatypes_paramstructs\r
+ * @brief Contains the credentials necessary for connection setup.\r
+ *\r
+ * May be passed to #IotNetworkInterface_t.create as `pCredentialInfo`. This\r
+ * structure contains commonly-used parameters, but may be replaced with an\r
+ * alternative.\r
+ */\r
+typedef struct IotNetworkCredentials\r
+{\r
+    /**\r
+     * @brief Set this to a non-NULL value to use ALPN.\r
+     *\r
+     * This string must be NULL-terminated.\r
+     *\r
+     * See [this link]\r
+     * (https://aws.amazon.com/blogs/iot/mqtt-with-tls-client-authentication-on-port-443-why-it-is-useful-and-how-it-works/)\r
+     * for more information.\r
+     */\r
+    const char * pAlpnProtos;\r
+\r
+    /**\r
+     * @brief Set this to a non-zero value to use TLS max fragment length\r
+     * negotiation (TLS MFLN).\r
+     *\r
+     * @note The network stack may have a minimum value for this parameter and\r
+     * may return an error if this parameter is too small.\r
+     */\r
+    size_t maxFragmentLength;\r
+\r
+    /**\r
+     * @brief Disable server name indication (SNI) for a TLS session.\r
+     */\r
+    bool disableSni;\r
+\r
+    const char * pRootCa;     /**< @brief String representing a trusted server root certificate. */\r
+    size_t rootCaSize;        /**< @brief Size associated with #IotNetworkCredentials_t.pRootCa. */\r
+    const char * pClientCert; /**< @brief String representing the client certificate. */\r
+    size_t clientCertSize;    /**< @brief Size associated with #IotNetworkCredentials_t.pClientCert. */\r
+    const char * pPrivateKey; /**< @brief String representing the client certificate's private key. */\r
+    size_t privateKeySize;    /**< @brief Size associated with #IotNetworkCredentials_t.pPrivateKey. */\r
+} IotNetworkCredentials_t;\r
+\r
+#endif /* ifndef IOT_NETWORK_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/platform/iot_threads.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/platform/iot_threads.h
new file mode 100644 (file)
index 0000000..58571d8
--- /dev/null
@@ -0,0 +1,355 @@
+/*\r
+ * Amazon FreeRTOS Platform V1.0.0\r
+ * Copyright (C) 2019 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_threads.h\r
+ * @brief Threading and synchronization functions used by libraries in this SDK.\r
+ */\r
+\r
+#ifndef IOT_THREADS_H_\r
+#define IOT_THREADS_H_\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/* Standard includes. */\r
+#include <stdbool.h>\r
+#include <stdint.h>\r
+\r
+/* Platform layer types include. */\r
+#include "types/iot_platform_types.h"\r
+\r
+/**\r
+ * @functionspage{platform_threads,platform thread management,Thread Management}\r
+ * - @functionname{platform_threads_function_createdetachedthread}\r
+ * - @functionname{platform_threads_function_mutexcreate}\r
+ * - @functionname{platform_threads_function_mutexdestroy}\r
+ * - @functionname{platform_threads_function_mutexlock}\r
+ * - @functionname{platform_threads_function_mutextrylock}\r
+ * - @functionname{platform_threads_function_mutexunlock}\r
+ * - @functionname{platform_threads_function_semaphorecreate}\r
+ * - @functionname{platform_threads_function_semaphoredestroy}\r
+ * - @functionname{platform_threads_function_semaphoregetcount}\r
+ * - @functionname{platform_threads_function_semaphorewait}\r
+ * - @functionname{platform_threads_function_semaphoretrywait}\r
+ * - @functionname{platform_threads_function_semaphoretimedwait}\r
+ * - @functionname{platform_threads_function_semaphorepost}\r
+ */\r
+\r
+/**\r
+ * @functionpage{Iot_CreateDetachedThread,platform_threads,createdetachedthread}\r
+ * @functionpage{IotMutex_Create,platform_threads,mutexcreate}\r
+ * @functionpage{IotMutex_Destroy,platform_threads,mutexdestroy}\r
+ * @functionpage{IotMutex_Lock,platform_threads,mutexlock}\r
+ * @functionpage{IotMutex_TryLock,platform_threads,mutextrylock}\r
+ * @functionpage{IotMutex_Unlock,platform_threads,mutexunlock}\r
+ * @functionpage{IotSemaphore_Create,platform_threads,semaphorecreate}\r
+ * @functionpage{IotSemaphore_Destroy,platform_threads,semaphoredestroy}\r
+ * @functionpage{IotSemaphore_GetCount,platform_threads,semaphoregetcount}\r
+ * @functionpage{IotSemaphore_Wait,platform_threads,semaphorewait}\r
+ * @functionpage{IotSemaphore_TryWait,platform_threads,semaphoretrywait}\r
+ * @functionpage{IotSemaphore_TimedWait,platform_threads,semaphoretimedwait}\r
+ * @functionpage{IotSemaphore_Post,platform_threads,semaphorepost}\r
+ */\r
+\r
+/**\r
+ * @brief Create a new detached thread, i.e. a thread that cleans up after itself.\r
+ *\r
+ * This function creates a new thread. Threads created by this function exit\r
+ * upon returning from the thread routine. Any resources taken must be freed\r
+ * by the exiting thread.\r
+ *\r
+ * @param[in] threadRoutine The function this thread should run.\r
+ * @param[in] pArgument The argument passed to `threadRoutine`.\r
+ * @param[in] priority Represents the priority of the new thread, as defined by\r
+ * the system. The value #IOT_THREAD_DEFAULT_PRIORITY (i.e. `0`) must be used to\r
+ * represent the system default for thread priority.\r
+ * @param[in] stackSize Represents the stack size of the new thread, as defined\r
+ * by the system. The value #IOT_THREAD_DEFAULT_STACK_SIZE (i.e. `0`) must be used\r
+ * to represent the system default for stack size.\r
+ *\r
+ * @return `true` if the new thread was successfully created; `false` otherwise.\r
+ *\r
+ * @code{c}\r
+ * // Thread routine.\r
+ * void threadRoutine( void * pArgument );\r
+ *\r
+ * // Run threadRoutine in a detached thread, using default priority and stack size.\r
+ * if( Iot_CreateDetachedThread( threadRoutine,\r
+ *                               NULL,\r
+ *                               IOT_THREAD_DEFAULT_PRIORITY,\r
+ *                               IOT_THREAD_DEFAULT_STACK_SIZE ) == true )\r
+ * {\r
+ *     // Success\r
+ * }\r
+ * else\r
+ * {\r
+ *     // Failure, no thread was created.\r
+ * }\r
+ * @endcode\r
+ */\r
+/* @[declare_platform_threads_createdetachedthread] */\r
+bool Iot_CreateDetachedThread( IotThreadRoutine_t threadRoutine,\r
+                               void * pArgument,\r
+                               int32_t priority,\r
+                               size_t stackSize );\r
+/* @[declare_platform_threads_createdetachedthread] */\r
+\r
+/**\r
+ * @brief Create a new mutex.\r
+ *\r
+ * This function creates a new, unlocked mutex. It must be called on an uninitialized\r
+ * #IotMutex_t. This function must not be called on an already-initialized #IotMutex_t.\r
+ *\r
+ * @param[in] pNewMutex Pointer to the memory that will hold the new mutex.\r
+ * @param[in] recursive Set to `true` to create a recursive mutex, i.e. a mutex that\r
+ * may be locked multiple times by the same thread. If the system does not support\r
+ * recursive mutexes, this function should do nothing and return `false`.\r
+ *\r
+ * @return `true` if mutex creation succeeds; `false` otherwise.\r
+ *\r
+ * @see @ref platform_threads_function_mutexdestroy\r
+ *\r
+ * <b>Example</b>\r
+ * @code{c}\r
+ * IotMutex_t mutex;\r
+ *\r
+ * // Create non-recursive mutex.\r
+ * if( IotMutex_Create( &mutex, false ) == true )\r
+ * {\r
+ *     // Lock and unlock the mutex...\r
+ *\r
+ *     // Destroy the mutex when it's no longer needed.\r
+ *     IotMutex_Destroy( &mutex );\r
+ * }\r
+ * @endcode\r
+ */\r
+/* @[declare_platform_threads_mutexcreate] */\r
+bool IotMutex_Create( IotMutex_t * pNewMutex, bool recursive );\r
+/* @[declare_platform_threads_mutexcreate] */\r
+\r
+/**\r
+ * @brief Free resources used by a mutex.\r
+ *\r
+ * This function frees resources used by a mutex. It must be called on an initialized\r
+ * #IotMutex_t. No other mutex functions should be called on `pMutex` after calling\r
+ * this function (unless the mutex is re-created).\r
+ *\r
+ * @param[in] pMutex The mutex to destroy.\r
+ *\r
+ * @warning This function must not be called on a locked mutex.\r
+ * @see @ref platform_threads_function_mutexcreate\r
+ */\r
+/* @[declare_platform_threads_mutexdestroy] */\r
+void IotMutex_Destroy( IotMutex_t * pMutex );\r
+/* @[declare_platform_threads_mutexdestroy] */\r
+\r
+/**\r
+ * @brief Lock a mutex. This function should only return when the mutex is locked;\r
+ * it is not expected to fail.\r
+ *\r
+ * This function blocks and waits until a mutex is available. It waits forever\r
+ * (deadlocks) if `pMutex` is already locked and never unlocked.\r
+ *\r
+ * @param[in] pMutex The mutex to lock.\r
+ *\r
+ * @see @ref platform_threads_function_mutextrylock for a nonblocking lock.\r
+ */\r
+/* @[declare_platform_threads_mutexlock] */\r
+void IotMutex_Lock( IotMutex_t * pMutex );\r
+/* @[declare_platform_threads_mutexlock] */\r
+\r
+/**\r
+ * @brief Attempt to lock a mutex. Return immediately if the mutex is not available.\r
+ *\r
+ * If `pMutex` is available, this function immediately locks it and returns.\r
+ * Otherwise, this function returns without locking `pMutex`.\r
+ *\r
+ * @param[in] pMutex The mutex to lock.\r
+ *\r
+ * @return `true` if the mutex was successfully locked; `false` if the mutex was\r
+ * not available.\r
+ *\r
+ * @see @ref platform_threads_function_mutexlock for a blocking lock.\r
+ */\r
+/* @[declare_platform_threads_mutextrylock] */\r
+bool IotMutex_TryLock( IotMutex_t * pMutex );\r
+/* @[declare_platform_threads_mutextrylock] */\r
+\r
+/**\r
+ * @brief Unlock a mutex. This function should only return when the mutex is unlocked;\r
+ * it is not expected to fail.\r
+ *\r
+ * Unlocks a locked mutex. `pMutex` must have been locked by the thread calling\r
+ * this function.\r
+ *\r
+ * @param[in] pMutex The mutex to unlock.\r
+ *\r
+ * @note This function should not be called on a mutex that is already unlocked.\r
+ */\r
+/* @[declare_platform_threads_mutexunlock] */\r
+void IotMutex_Unlock( IotMutex_t * pMutex );\r
+/* @[declare_platform_threads_mutexunlock] */\r
+\r
+/**\r
+ * @brief Create a new counting semaphore.\r
+ *\r
+ * This function creates a new counting semaphore with a given intial and\r
+ * maximum value. It must be called on an uninitialized #IotSemaphore_t.\r
+ * This function must not be called on an already-initialized #IotSemaphore_t.\r
+ *\r
+ * @param[in] pNewSemaphore Pointer to the memory that will hold the new semaphore.\r
+ * @param[in] initialValue The semaphore should be initialized with this value.\r
+ * @param[in] maxValue The maximum value the semaphore will reach.\r
+ *\r
+ * @return `true` if semaphore creation succeeds; `false` otherwise.\r
+ *\r
+ * @see @ref platform_threads_function_semaphoredestroy\r
+ *\r
+ * <b>Example</b>\r
+ * @code{c}\r
+ * IotSemaphore_t sem;\r
+ *\r
+ * // Create a locked binary semaphore.\r
+ * if( IotSemaphore_Create( &sem, 0, 1 ) == true )\r
+ * {\r
+ *     // Unlock the semaphore.\r
+ *     IotSemaphore_Post( &sem );\r
+ *\r
+ *     // Destroy the semaphore when it's no longer needed.\r
+ *     IotSemaphore_Destroy( &sem );\r
+ * }\r
+ * @endcode\r
+ */\r
+/* @[declare_platform_threads_semaphorecreate] */\r
+bool IotSemaphore_Create( IotSemaphore_t * pNewSemaphore,\r
+                          uint32_t initialValue,\r
+                          uint32_t maxValue );\r
+/* @[declare_platform_threads_semaphorecreate] */\r
+\r
+/**\r
+ * @brief Free resources used by a semaphore.\r
+ *\r
+ * This function frees resources used by a semaphore. It must be called on an initialized\r
+ * #IotSemaphore_t. No other semaphore functions should be called on `pSemaphore` after\r
+ * calling this function (unless the semaphore is re-created).\r
+ *\r
+ * @param[in] pSemaphore The semaphore to destroy.\r
+ *\r
+ * @warning This function must not be called on a semaphore with waiting threads.\r
+ * @see @ref platform_threads_function_semaphorecreate\r
+ */\r
+/* @[declare_platform_threads_semaphoredestroy] */\r
+void IotSemaphore_Destroy( IotSemaphore_t * pSemaphore );\r
+/* @[declare_platform_threads_semaphoredestroy] */\r
+\r
+/**\r
+ * @brief Query the current count of the semaphore.\r
+ *\r
+ * This function queries a counting semaphore for its current value. A counting\r
+ * semaphore's value is always 0 or positive.\r
+ *\r
+ * @param[in] pSemaphore The semaphore to query.\r
+ *\r
+ * @return The current count of the semaphore. This function should not fail.\r
+ */\r
+/* @[declare_platform_threads_semaphoregetcount] */\r
+uint32_t IotSemaphore_GetCount( IotSemaphore_t * pSemaphore );\r
+/* @[declare_platform_threads_semaphoregetcount] */\r
+\r
+/**\r
+ * @brief Wait on (lock) a semaphore. This function should only return when the\r
+ * semaphore wait succeeds; it is not expected to fail.\r
+ *\r
+ * This function blocks and waits until a counting semaphore is positive. It\r
+ * waits forever (deadlocks) if `pSemaphore` has a count `0` that is never\r
+ * [incremented](@ref platform_threads_function_semaphorepost).\r
+ *\r
+ * @param[in] pSemaphore The semaphore to lock.\r
+ *\r
+ * @see @ref platform_threads_function_semaphoretrywait for a nonblocking wait;\r
+ * @ref platform_threads_function_semaphoretimedwait for a wait with timeout.\r
+ */\r
+/* @[declare_platform_threads_semaphorewait] */\r
+void IotSemaphore_Wait( IotSemaphore_t * pSemaphore );\r
+/* @[declare_platform_threads_semaphorewait] */\r
+\r
+/**\r
+ * @brief Attempt to wait on (lock) a semaphore. Return immediately if the semaphore\r
+ * is not available.\r
+ *\r
+ * If the count of `pSemaphore` is positive, this function immediately decrements\r
+ * the semaphore and returns. Otherwise, this function returns without decrementing\r
+ * `pSemaphore`.\r
+ *\r
+ * @param[in] pSemaphore The semaphore to lock.\r
+ *\r
+ * @return `true` if the semaphore wait succeeded; `false` if the semaphore has\r
+ * a count of `0`.\r
+ *\r
+ * @see @ref platform_threads_function_semaphorewait for a blocking wait;\r
+ * @ref platform_threads_function_semaphoretimedwait for a wait with timeout.\r
+ */\r
+/* @[declare_platform_threads_semaphoretrywait] */\r
+bool IotSemaphore_TryWait( IotSemaphore_t * pSemaphore );\r
+/* @[declare_platform_threads_semaphoretrywait] */\r
+\r
+/**\r
+ * @brief Attempt to wait on (lock) a semaphore with a timeout.\r
+ *\r
+ * This function blocks and waits until a counting semaphore is positive\r
+ * <i>or</i> its timeout expires (whichever is sooner). It decrements\r
+ * `pSemaphore` and returns `true` if the semaphore is positive at some\r
+ * time during the wait. If `pSemaphore` is always `0` during the wait,\r
+ * this function returns `false`.\r
+ *\r
+ * @param[in] pSemaphore The semaphore to lock.\r
+ * @param[in] timeoutMs Relative timeout of semaphore lock. This function returns\r
+ * false if the semaphore couldn't be locked within this timeout.\r
+ *\r
+ * @return `true` if the semaphore wait succeeded; `false` if it timed out.\r
+ *\r
+ * @see @ref platform_threads_function_semaphoretrywait for a nonblocking wait;\r
+ * @ref platform_threads_function_semaphorewait for a blocking wait.\r
+ */\r
+/* @[declare_platform_threads_semaphoretimedwait] */\r
+bool IotSemaphore_TimedWait( IotSemaphore_t * pSemaphore,\r
+                             uint32_t timeoutMs );\r
+/* @[declare_platform_threads_semaphoretimedwait] */\r
+\r
+/**\r
+ * @brief Post to (unlock) a semaphore. This function should only return when the\r
+ * semaphore post succeeds; it is not expected to fail.\r
+ *\r
+ * This function increments the count of a semaphore. Any thread may call this\r
+ * function to increment a semaphore's count.\r
+ *\r
+ * @param[in] pSemaphore The semaphore to unlock.\r
+ */\r
+/* @[declare_platform_threads_semaphorepost] */\r
+void IotSemaphore_Post( IotSemaphore_t * pSemaphore );\r
+/* @[declare_platform_threads_semaphorepost] */\r
+\r
+#endif /* ifndef IOT_THREADS_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/types/iot_platform_types.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/types/iot_platform_types.h
new file mode 100644 (file)
index 0000000..e9fc785
--- /dev/null
@@ -0,0 +1,158 @@
+/*\r
+ * Amazon FreeRTOS Platform V1.0.0\r
+ * Copyright (C) 2019 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_platform_types.h\r
+ * @brief Types of the platform layer.\r
+ */\r
+\r
+#ifndef IOT_PLATFORM_TYPES_H_\r
+#define IOT_PLATFORM_TYPES_H_\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/* Linear containers (lists and queues) include for metrics types. */\r
+#include "iot_linear_containers.h"\r
+\r
+/*------------------------- Thread management types -------------------------*/\r
+\r
+/**\r
+ * @brief A value representing the system default for new thread priority.\r
+ */\r
+#ifndef IOT_THREAD_DEFAULT_PRIORITY\r
+    #define IOT_THREAD_DEFAULT_PRIORITY      0\r
+#endif\r
+\r
+/**\r
+ * @brief A value representhing the system default for new thread stack size.\r
+ */\r
+#ifndef IOT_THREAD_DEFAULT_STACK_SIZE\r
+    #define IOT_THREAD_DEFAULT_STACK_SIZE    0\r
+#endif\r
+\r
+/**\r
+ * @ingroup platform_datatypes_handles\r
+ * @brief The type used to represent mutexes, configured with the type\r
+ * `_IotSystemMutex_t`.\r
+ *\r
+ * <span style="color:red;font-weight:bold">\r
+ * `_IotSystemMutex_t` will be automatically configured during build and generally\r
+ * does not need to be defined.\r
+ * </span>\r
+ *\r
+ * Mutexes should only be released by the threads that take them.\r
+ *\r
+ * <b>Example</b> <br>\r
+ * To change the type of #IotMutex_t to `long`:\r
+ * @code{c}\r
+ * typedef long _IotSystemMutex_t;\r
+ * #include "iot_threads.h"\r
+ * @endcode\r
+ */\r
+typedef _IotSystemMutex_t       IotMutex_t;\r
+\r
+/**\r
+ * @ingroup platform_datatypes_handles\r
+ * @brief The type used to represent semaphores, configured with the type\r
+ * `_IotSystemSemaphore_t`.\r
+ *\r
+ * <span style="color:red;font-weight:bold">\r
+ * `_IotSystemSemaphore_t` will be automatically configured during build and\r
+ * generally does not need to be defined.\r
+ * </span>\r
+ *\r
+ * Semaphores must be counting, and any thread may take (wait on) or release\r
+ * (post to) a semaphore.\r
+ *\r
+ * <b>Example</b> <br>\r
+ * To change the type of #IotSemaphore_t to `long`:\r
+ * @code{c}\r
+ * typedef long _IotSystemSemaphore_t;\r
+ * #include "iot_threads.h"\r
+ * @endcode\r
+ */\r
+typedef _IotSystemSemaphore_t   IotSemaphore_t;\r
+\r
+/**\r
+ * @brief Thread routine function.\r
+ *\r
+ * @param[in] void * The argument passed to the @ref\r
+ * platform_threads_function_createdetachedthread. For application use.\r
+ */\r
+typedef void ( * IotThreadRoutine_t )( void * );\r
+\r
+/*-------------------------- Clock and timer types --------------------------*/\r
+\r
+/**\r
+ * @ingroup platform_datatypes_handles\r
+ * @brief The type used to represent timers, configured with the type\r
+ * `_IotSystemTimer_t`.\r
+ *\r
+ * <span style="color:red;font-weight:bold">\r
+ * `_IotSystemTimer_t` will be automatically configured during build and generally\r
+ * does not need to be defined.\r
+ * </span>\r
+ *\r
+ * <b>Example</b> <br>\r
+ * To change the type of #IotTimer_t to `long`:\r
+ * @code{c}\r
+ * typedef long _IotSystemTimer_t;\r
+ * #include "iot_clock.h"\r
+ * @endcode\r
+ */\r
+typedef _IotSystemTimer_t IotTimer_t;\r
+\r
+/*------------------------------ Metrics types ------------------------------*/\r
+\r
+/**\r
+ * @brief The length of the buffer used to store IP addresses for metrics.\r
+ *\r
+ * This is the length of the longest IPv6 address plus space for the port number\r
+ * and NULL terminator.\r
+ */\r
+#define IOT_METRICS_IP_ADDRESS_LENGTH    54\r
+\r
+/**\r
+ * @brief Represents a TCP connection to a remote IPv4 server.\r
+ *\r
+ * A list of these is provided by @ref platform_metrics_function_gettcpconnections.\r
+ */\r
+typedef struct IotMetricsTcpConnection\r
+{\r
+    IotLink_t link;         /**< @brief List link member. */\r
+    void * pNetworkContext; /**< @brief Context that may be used by metrics or Defender. */\r
+    size_t addressLength;   /**< @brief The length of the address stored in #IotMetricsTcpConnection_t.pRemoteAddress. */\r
+\r
+    /**\r
+     * @brief NULL-terminated IP address and port in text format.\r
+     *\r
+     * IPv4 addresses will be in the format `xxx.xxx.xxx.xxx:port`.\r
+     * IPv6 addresses will be in the format `[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]:port`.\r
+     */\r
+    char pRemoteAddress[ IOT_METRICS_IP_ADDRESS_LENGTH ];\r
+} IotMetricsTcpConnection_t;\r
+\r
+#endif /* ifndef IOT_PLATFORM_TYPES_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/secure_sockets/freertos_plus_tcp/iot_secure_sockets.c b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/secure_sockets/freertos_plus_tcp/iot_secure_sockets.c
new file mode 100644 (file)
index 0000000..af809c2
--- /dev/null
@@ -0,0 +1,342 @@
+/*\r
+ * Amazon FreeRTOS Secure Sockets V1.1.5\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
+/* Define _SECURE_SOCKETS_WRAPPER_NOT_REDEFINE to prevent secure sockets functions\r
+ * from redefining in iot_secure_sockets_wrapper_metrics.h */\r
+#define _SECURE_SOCKETS_WRAPPER_NOT_REDEFINE\r
+\r
+/* FreeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+#include "FreeRTOSIPConfig.h"\r
+#include "list.h"\r
+#include "semphr.h"\r
+#include "FreeRTOS_IP.h"\r
+#include "FreeRTOS_Sockets.h"\r
+#include "iot_secure_sockets.h"\r
+#include "task.h"\r
+\r
+#undef _SECURE_SOCKETS_WRAPPER_NOT_REDEFINE\r
+\r
+/* Internal context structure. */\r
+typedef struct SSOCKETContext\r
+{\r
+    Socket_t xSocket;\r
+    char * pcDestination;\r
+    BaseType_t xSendFlags;\r
+    BaseType_t xRecvFlags;\r
+    BaseType_t xConnectAttempted;\r
+} SSOCKETContext_t, * SSOCKETContextPtr_t;\r
+\r
+/*\r
+ * Helper routines.\r
+ */\r
+\r
+/*\r
+ * @brief Network send callback.\r
+ */\r
+static BaseType_t prvNetworkSend( void * pvContext,\r
+                                  const unsigned char * pucData,\r
+                                  size_t xDataLength )\r
+{\r
+    SSOCKETContextPtr_t pxContext = ( SSOCKETContextPtr_t ) pvContext; /*lint !e9087 cast used for portability. */\r
+\r
+    return FreeRTOS_send( pxContext->xSocket, pucData, xDataLength, pxContext->xSendFlags );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * @brief Network receive callback.\r
+ */\r
+static BaseType_t prvNetworkRecv( void * pvContext,\r
+                                  unsigned char * pucReceiveBuffer,\r
+                                  size_t xReceiveLength )\r
+{\r
+    SSOCKETContextPtr_t pxContext = ( SSOCKETContextPtr_t ) pvContext; /*lint !e9087 cast used for portability. */\r
+\r
+    return FreeRTOS_recv( pxContext->xSocket, pucReceiveBuffer, xReceiveLength, pxContext->xRecvFlags );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Interface routines.\r
+ */\r
+\r
+int32_t SOCKETS_Close( Socket_t xSocket )\r
+{\r
+    SSOCKETContextPtr_t pxContext = ( SSOCKETContextPtr_t ) xSocket; /*lint !e9087 cast used for portability. */\r
+    int32_t lReturn;\r
+\r
+    if( ( xSocket != SOCKETS_INVALID_SOCKET ) && ( NULL != pxContext ) )\r
+    {\r
+        /* Clean-up destination string. */\r
+        if( NULL != pxContext->pcDestination )\r
+        {\r
+            vPortFree( pxContext->pcDestination );\r
+        }\r
+\r
+        /* Close the underlying socket handle. */\r
+        ( void ) FreeRTOS_closesocket( pxContext->xSocket );\r
+\r
+        /* Free the context. */\r
+        vPortFree( pxContext );\r
+        lReturn = SOCKETS_ERROR_NONE;\r
+    }\r
+    else\r
+    {\r
+        lReturn = SOCKETS_EINVAL;\r
+    }\r
+\r
+    return lReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+int32_t SOCKETS_Connect( Socket_t xSocket,\r
+                         SocketsSockaddr_t * pxAddress,\r
+                         Socklen_t xAddressLength )\r
+{\r
+    int32_t lStatus = SOCKETS_ERROR_NONE;\r
+    SSOCKETContextPtr_t pxContext = ( SSOCKETContextPtr_t ) xSocket; /*lint !e9087 cast used for portability. */\r
+    struct freertos_sockaddr xTempAddress = { 0 };\r
+\r
+    if( ( pxContext != SOCKETS_INVALID_SOCKET ) && ( pxAddress != NULL ) )\r
+    {\r
+        /* A connection was attempted. If this function fails, then the socket is invalid and the user\r
+         * must call SOCKETS_Close(), on this socket, and SOCKETS_Socket() to get a new socket. */\r
+        pxContext->xConnectAttempted = pdTRUE;\r
+\r
+        /* Connect the wrapped socket. */\r
+        xTempAddress.sin_addr = pxAddress->ulAddress;\r
+        xTempAddress.sin_family = pxAddress->ucSocketDomain;\r
+        xTempAddress.sin_len = ( uint8_t ) sizeof( xTempAddress );\r
+        xTempAddress.sin_port = pxAddress->usPort;\r
+        lStatus = FreeRTOS_connect( pxContext->xSocket, &xTempAddress, xAddressLength );\r
+    }\r
+    else\r
+    {\r
+        lStatus = SOCKETS_SOCKET_ERROR;\r
+    }\r
+\r
+    return lStatus;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+uint32_t SOCKETS_GetHostByName( const char * pcHostName )\r
+{\r
+    return FreeRTOS_gethostbyname( pcHostName );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+int32_t SOCKETS_Recv( Socket_t xSocket,\r
+                      void * pvBuffer,\r
+                      size_t xBufferLength,\r
+                      uint32_t ulFlags )\r
+{\r
+    int32_t lStatus = SOCKETS_SOCKET_ERROR;\r
+    SSOCKETContextPtr_t pxContext = ( SSOCKETContextPtr_t ) xSocket; /*lint !e9087 cast used for portability. */\r
+\r
+    if( ( xSocket != SOCKETS_INVALID_SOCKET ) &&\r
+        ( pvBuffer != NULL ) )\r
+    {\r
+        pxContext->xRecvFlags = ( BaseType_t ) ulFlags;\r
+\r
+        /* Receive unencrypted. */\r
+        lStatus = prvNetworkRecv( pxContext, pvBuffer, xBufferLength );\r
+    }\r
+    else\r
+    {\r
+        lStatus = SOCKETS_EINVAL;\r
+    }\r
+\r
+    return lStatus;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+int32_t SOCKETS_Send( Socket_t xSocket,\r
+                      const void * pvBuffer,\r
+                      size_t xDataLength,\r
+                      uint32_t ulFlags )\r
+{\r
+    int32_t lStatus = SOCKETS_SOCKET_ERROR;\r
+    SSOCKETContextPtr_t pxContext = ( SSOCKETContextPtr_t ) xSocket; /*lint !e9087 cast used for portability. */\r
+\r
+    if( ( xSocket != SOCKETS_INVALID_SOCKET ) &&\r
+        ( pvBuffer != NULL ) )\r
+    {\r
+        pxContext->xSendFlags = ( BaseType_t ) ulFlags;\r
+\r
+        /* Send unencrypted. */\r
+        lStatus = prvNetworkSend( pxContext, pvBuffer, xDataLength );\r
+    }\r
+    else\r
+    {\r
+        lStatus = SOCKETS_EINVAL;\r
+    }\r
+\r
+    return lStatus;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+int32_t SOCKETS_SetSockOpt( Socket_t xSocket,\r
+                            int32_t lLevel,\r
+                            int32_t lOptionName,\r
+                            const void * pvOptionValue,\r
+                            size_t xOptionLength )\r
+{\r
+    int32_t lStatus = SOCKETS_ERROR_NONE;\r
+    TickType_t xTimeout;\r
+    SSOCKETContextPtr_t pxContext = ( SSOCKETContextPtr_t ) xSocket; /*lint !e9087 cast used for portability. */\r
+\r
+    if( ( xSocket != SOCKETS_INVALID_SOCKET ) && ( xSocket != NULL ) )\r
+    {\r
+        switch( lOptionName )\r
+        {\r
+            case SOCKETS_SO_NONBLOCK:\r
+                xTimeout = 0;\r
+\r
+                /* Non-blocking connect is not supported.  Socket may be set to nonblocking\r
+                 * only after a connection is made. */\r
+                if( pdTRUE == pxContext->xConnectAttempted )\r
+                {\r
+                    lStatus = FreeRTOS_setsockopt( pxContext->xSocket,\r
+                                                   lLevel,\r
+                                                   SOCKETS_SO_RCVTIMEO,\r
+                                                   &xTimeout,\r
+                                                   sizeof( xTimeout ) );\r
+\r
+                    if( lStatus == SOCKETS_ERROR_NONE )\r
+                    {\r
+                        lStatus = FreeRTOS_setsockopt( pxContext->xSocket,\r
+                                                       lLevel,\r
+                                                       SOCKETS_SO_SNDTIMEO,\r
+                                                       &xTimeout,\r
+                                                       sizeof( xTimeout ) );\r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    lStatus = SOCKETS_EISCONN;\r
+                }\r
+\r
+                break;\r
+\r
+            case SOCKETS_SO_RCVTIMEO:\r
+            case SOCKETS_SO_SNDTIMEO:\r
+                /* Comply with Berkeley standard - a 0 timeout is wait forever. */\r
+                xTimeout = *( ( const TickType_t * ) pvOptionValue ); /*lint !e9087 pvOptionValue passed should be of TickType_t */\r
+\r
+                if( xTimeout == 0U )\r
+                {\r
+                    xTimeout = portMAX_DELAY;\r
+                }\r
+\r
+                lStatus = FreeRTOS_setsockopt( pxContext->xSocket,\r
+                                               lLevel,\r
+                                               lOptionName,\r
+                                               &xTimeout,\r
+                                               xOptionLength );\r
+                break;\r
+\r
+            default:\r
+                lStatus = FreeRTOS_setsockopt( pxContext->xSocket,\r
+                                               lLevel,\r
+                                               lOptionName,\r
+                                               pvOptionValue,\r
+                                               xOptionLength );\r
+                break;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        lStatus = SOCKETS_EINVAL;\r
+    }\r
+\r
+    return lStatus;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+int32_t SOCKETS_Shutdown( Socket_t xSocket,\r
+                          uint32_t ulHow )\r
+{\r
+    int32_t lReturn;\r
+    SSOCKETContextPtr_t pxContext = ( SSOCKETContextPtr_t ) xSocket; /*lint !e9087 cast used for portability. */\r
+\r
+    if( ( xSocket != SOCKETS_INVALID_SOCKET ) && ( xSocket != NULL ) )\r
+    {\r
+        lReturn = FreeRTOS_shutdown( pxContext->xSocket, ( BaseType_t ) ulHow );\r
+    }\r
+    else\r
+    {\r
+        lReturn = SOCKETS_EINVAL;\r
+    }\r
+\r
+    return lReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+Socket_t SOCKETS_Socket( int32_t lDomain,\r
+                         int32_t lType,\r
+                         int32_t lProtocol )\r
+{\r
+    SSOCKETContextPtr_t pxContext = NULL;\r
+    Socket_t xSocket;\r
+\r
+    /* Ensure that only supported values are supplied. */\r
+    configASSERT( lDomain == SOCKETS_AF_INET );\r
+    configASSERT( lType == SOCKETS_SOCK_STREAM );\r
+    configASSERT( lProtocol == SOCKETS_IPPROTO_TCP );\r
+\r
+    /* Create the wrapped socket. */\r
+    xSocket = FreeRTOS_socket( lDomain, lType, lProtocol );\r
+\r
+    if( xSocket != FREERTOS_INVALID_SOCKET )\r
+    {\r
+        /* Allocate the internal context structure. */\r
+        if( NULL == ( pxContext = pvPortMalloc( sizeof( SSOCKETContext_t ) ) ) )\r
+        {\r
+            /* Need to close socket. */\r
+            ( void ) FreeRTOS_closesocket( xSocket );\r
+            pxContext = SOCKETS_INVALID_SOCKET;\r
+        }\r
+        else\r
+        {\r
+            memset( pxContext, 0, sizeof( SSOCKETContext_t ) );\r
+            pxContext->xSocket = xSocket;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        pxContext = SOCKETS_INVALID_SOCKET;\r
+    }\r
+\r
+    return pxContext;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+BaseType_t SOCKETS_Init( void )\r
+{\r
+    /* Empty initialization for this port. */\r
+    return pdPASS;\r
+}\r
+/*-----------------------------------------------------------*/\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/secure_sockets/include/iot_secure_sockets.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/secure_sockets/include/iot_secure_sockets.h
new file mode 100644 (file)
index 0000000..d7c794a
--- /dev/null
@@ -0,0 +1,609 @@
+/*\r
+ * Amazon FreeRTOS Secure Sockets V1.1.5\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_secure_sockets.h\r
+ * @brief Secure Sockets Interface.\r
+ *\r
+ * Secure sockets is a portable layer for establishing a TCP/IP\r
+ * connection, with the option of using TLS.\r
+ *\r
+ * Secure sockets is based on the Berkeley sockets API.\r
+ * A few difference general differences between Berkeley and SOCKETS are:\r
+ * - SOCKETS has additional socket options to enable TLS, server name\r
+ * indication, and per-socket root of trust server certificates.  See\r
+ * SOCKETS_SetSockOpt() for more information.\r
+ * - SOCKETS API return an error code, rather than returning -1 and setting\r
+ * a global errno value.\r
+ *\r
+ */\r
+\r
+#ifndef _AWS_SECURE_SOCKETS_H_\r
+#define _AWS_SECURE_SOCKETS_H_\r
+\r
+/*\r
+ #ifdef __cplusplus\r
+ *  extern "C" {\r
+ #endif\r
+ */\r
+#include <stdint.h>\r
+#include <stddef.h>\r
+#include "iot_secure_sockets_config.h"\r
+#include "iot_secure_sockets_config_defaults.h"\r
+#include "iot_secure_sockets_wrapper_metrics.h"\r
+#include "iot_lib_init.h"\r
+\r
+/**\r
+ * @ingroup SecureSockets_datatypes_handles\r
+ * @brief The socket handle data type.\r
+ *\r
+ * For detail of socket, refer to [Network Sockets]\r
+ * (https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/socket.html)\r
+ *\r
+ * Data contained by the Socket_t type is port specific.\r
+ */\r
+typedef void * Socket_t;\r
+\r
+/**\r
+ * @brief The "size_t" of secure sockets.\r
+ *\r
+ * This type is used for compatibility with the expected Berkeley sockets\r
+ * naming.\r
+ */\r
+#define Socklen_t    uint32_t\r
+\r
+/**\r
+ * @anchor SocketsErrors\r
+ * @name SocketsErrors\r
+ * @brief Error codes returned by the SOCKETS API.\r
+ *\r
+ * Note that SOCKETS API may also propagate port-specific\r
+ * error codes when they are more descriptive. See your\r
+ * port's error codes for more details.\r
+ * PORT_SPECIFIC_LINK\r
+ */\r
+/**@{ */\r
+\r
+#define SOCKETS_ERROR_NONE               ( 0 )     /*!< No error. */\r
+#define SOCKETS_SOCKET_ERROR             ( -1 )    /*!< Catch-all sockets error code. */\r
+#define SOCKETS_EWOULDBLOCK              ( -11 )   /*!< A resource is temporarily unavailable. */\r
+#define SOCKETS_ENOMEM                   ( -12 )   /*!< Memory allocation failed. */\r
+#define SOCKETS_EINVAL                   ( -22 )   /*!< Invalid argument. */\r
+#define SOCKETS_ENOPROTOOPT              ( -109 )  /*!< A bad option was specified . */\r
+#define SOCKETS_ENOTCONN                 ( -126 )  /*!< The supplied socket is not connected. */\r
+#define SOCKETS_EISCONN                  ( -127 )  /*!< The supplied socket is already connected. */\r
+#define SOCKETS_ECLOSED                  ( -128 )  /*!< The supplied socket has already been closed. */\r
+#define SOCKETS_TLS_INIT_ERROR           ( -1001 ) /*!< TLS initialization failed. */\r
+#define SOCKETS_TLS_HANDSHAKE_ERROR      ( -1002 ) /*!< TLS handshake failed. */\r
+#define SOCKETS_TLS_SERVER_UNVERIFIED    ( -1003 ) /*!< A connection was made but the server could not be verified.  It is recommended that the socket be closed. */\r
+#define SOCKETS_TLS_RECV_ERROR           ( -1004 ) /*!< TLS receive operation failed. */\r
+#define SOCKETS_TLS_SEND_ERROR           ( -1005 ) /*!< TLS send operation failed. */\r
+#define SOCKETS_PERIPHERAL_RESET         ( -1006 ) /*!< Communications peripheral has been reset. */\r
+/**@} */\r
+\r
+/**\r
+ * @brief Assigned to an Socket_t variable when the socket is not valid.\r
+ */\r
+#define SOCKETS_INVALID_SOCKET    ( ( Socket_t ) ~0U )\r
+\r
+/**\r
+ * @anchor SocketDomains\r
+ * @name SocketDomains\r
+ *\r
+ * @brief Options for the lDomain parameter of SOCKETS_Socket()\r
+ * function.\r
+ *\r
+ * These select the protocol family to be used for communication.\r
+ */\r
+/**@{ */\r
+#define SOCKETS_AF_INET     ( 2 )           /*!< IPv4 Internet Protocols. */\r
+#define SOCKETS_PF_INET     SOCKETS_AF_INET /*!< IPv4 Internet Protocol. */\r
+#define SOCKETS_AF_INET6    ( 10 )          /*!< IPv6 Internet Protocols. This option is currently not supported. */\r
+/**@} */\r
+\r
+/**\r
+ * @anchor SocketTypes\r
+ * @name SocketTypes\r
+ *\r
+ * @brief Options for the lType parameter of SOCKETS_Socket()\r
+ * function.\r
+ *\r
+ * These specify the communication semantics.\r
+ */\r
+/**@{ */\r
+#define SOCKETS_SOCK_DGRAM     ( 2 )    /*!< Datagram. */\r
+#define SOCKETS_SOCK_STREAM    ( 1 )    /*!< Byte-stream. */\r
+/**@} */\r
+\r
+/**\r
+ * @anchor Protocols\r
+ * @name Protocols\r
+ *\r
+ * @brief Options for the lProtocol parameter of SOCKETS_Socket() function.\r
+ *\r
+ */\r
+/**@{ */\r
+#define SOCKETS_IPPROTO_UDP    ( 17 )   /*!< UDP. This option is currently not supported. */\r
+#define SOCKETS_IPPROTO_TCP    ( 6 )    /*!< TCP. */\r
+/**@} */\r
+\r
+/**\r
+ * @anchor SetSockOptOptions\r
+ * @name SetSockOptOptions\r
+ *\r
+ * @brief Options for lOptionName in SOCKETS_SetSockOpt().\r
+ *\r
+ */\r
+/**@{ */\r
+#define SOCKETS_SO_RCVTIMEO                      ( 0 )  /**< Set the receive timeout. */\r
+#define SOCKETS_SO_SNDTIMEO                      ( 1 )  /**< Set the send timeout. */\r
+#define SOCKETS_SO_SNDBUF                        ( 4 )  /**< Set the size of the send buffer (TCP only). */\r
+#define SOCKETS_SO_RCVBUF                        ( 5 )  /**< Set the size of the receive buffer (TCP only). */\r
+#define SOCKETS_SO_SERVER_NAME_INDICATION        ( 6 )  /**< Toggle client use of TLS SNI. */\r
+#define SOCKETS_SO_TRUSTED_SERVER_CERTIFICATE    ( 7 )  /**< Override default TLS server certificate trust. Must be PEM encoded and length must include null terminator. */\r
+#define SOCKETS_SO_REQUIRE_TLS                   ( 8 )  /**< Toggle client enforcement of TLS. */\r
+#define SOCKETS_SO_NONBLOCK                      ( 9 )  /**< Socket is nonblocking. */\r
+#define SOCKETS_SO_ALPN_PROTOCOLS                ( 10 ) /**< Application protocol list to be included in TLS ClientHello. */\r
+#define SOCKETS_SO_WAKEUP_CALLBACK               ( 17 ) /**< Set the callback to be called whenever there is data available on the socket for reading. */\r
+\r
+/**@} */\r
+\r
+/**\r
+ * @anchor ShutdownFlags <br>\r
+ * @name ShutdownFlags\r
+ *\r
+ * @brief Options for the ulHow parameter in SOCKETS_Shutdown().\r
+ */\r
+/**@{ */\r
+#define SOCKETS_SHUT_RD      ( 0 )  /**< No further receives. */\r
+#define SOCKETS_SHUT_WR      ( 1 )  /**< No further sends. */\r
+#define SOCKETS_SHUT_RDWR    ( 2 )  /**< No further send or receive. */\r
+/**@} */\r
+\r
+/**\r
+ * @brief Maximum length of an ASCII DNS name.\r
+ */\r
+#define securesocketsMAX_DNS_NAME_LENGTH    ( 253 )\r
+\r
+/**\r
+ * @ingroup SecureSockets_datatypes_paramstructs\r
+ * @brief Socket address.\r
+ *\r
+ * \sa PORT_SPECIFIC_LINK\r
+ */\r
+typedef struct SocketsSockaddr\r
+{\r
+    uint8_t ucLength;       /**< Length of SocketsSockaddr structure. */\r
+    uint8_t ucSocketDomain; /**< Only SOCKETS_AF_INET is supported. */\r
+    uint16_t usPort;        /**< Port number. Convention is to call this sin_port. */\r
+    uint32_t ulAddress;     /**< IP Address. Convention is to call this sin_addr. */\r
+} SocketsSockaddr_t;\r
+\r
+/**\r
+ * @brief Well-known port numbers.\r
+ */\r
+#define securesocketsDEFAULT_TLS_DESTINATION_PORT    443\r
+\r
+/**\r
+ * @brief Secure Sockets library initialization function.\r
+ *\r
+ * This function does general initialization and setup. It must be called once\r
+ * and only once before calling any other function.\r
+ *\r
+ * @return\r
+ * * `pdPASS` if everything succeeds\r
+ * * `pdFAIL` otherwise.\r
+ */\r
+lib_initDECLARE_LIB_INIT( SOCKETS_Init );\r
+\r
+/**\r
+ * @brief Creates a TCP socket.\r
+ *\r
+ * See the [FreeRTOS+TCP networking tutorial]\r
+ * (https://freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Networking_Tutorial.html)\r
+ * for more information on TCP sockets.\r
+ *\r
+ * See the [Berkeley Sockets API]\r
+ * (https://en.wikipedia.org/wiki/Berkeley_sockets#Socket_API_functions)\r
+ * in wikipedia\r
+ *\r
+ * @sa SOCKETS_Close()\r
+ *\r
+ * @param[in] lDomain Must be set to SOCKETS_AF_INET. See @ref SocketDomains.\r
+ * @param[in] lType Set to SOCKETS_SOCK_STREAM to create a TCP socket.\r
+ * No other value is valid.  See @ref SocketTypes.\r
+ * @param[in] lProtocol Set to SOCKETS_IPPROTO_TCP to create a TCP socket.\r
+ * No other value is valid. See @ref Protocols.\r
+ *\r
+ * @return\r
+ * * If a socket is created successfully, then the socket handle is\r
+ * returned\r
+ * * @ref SOCKETS_INVALID_SOCKET is returned if an error occurred.\r
+ */\r
+\r
+/*\r
+ * This call allocates memory and claims a socket resource.\r
+ */\r
+/* @[declare_secure_sockets_socket] */\r
+Socket_t SOCKETS_Socket( int32_t lDomain,\r
+                         int32_t lType,\r
+                         int32_t lProtocol );\r
+/* @[declare_secure_sockets_socket] */\r
+\r
+\r
+/**\r
+ * @brief Connects the socket to the specified IP address and port.\r
+ *\r
+ * The socket must first have been successfully created by a call to SOCKETS_Socket().\r
+ *\r
+ * \note To create a secure socket, SOCKETS_SetSockOpt() should be called with the\r
+ * SOCKETS_SO_REQUIRE_TLS option \a before SOCKETS_Connect() is called.\r
+ *\r
+ * If this function returns an error the socket is considered invalid.\r
+ *\r
+ * \warning SOCKETS_Connect() is not safe to be called on the same socket\r
+ * from multiple threads simultaneously with SOCKETS_Connect(),\r
+ * SOCKETS_SetSockOpt(), SOCKETS_Shutdown(), SOCKETS_Close().\r
+ *\r
+ * See the [Berkeley Sockets API]\r
+ * (https://en.wikipedia.org/wiki/Berkeley_sockets#Socket_API_functions)\r
+ * in wikipedia\r
+ *\r
+ * @param[in] xSocket The handle of the socket to be connected.\r
+ * @param[in] pxAddress A pointer to a SocketsSockaddr_t structure that contains the\r
+ * the address to connect the socket to.\r
+ * @param[in] xAddressLength Should be set to sizeof( @ref SocketsSockaddr_t ).\r
+ *\r
+ * @return\r
+ * * @ref SOCKETS_ERROR_NONE if a connection is established.\r
+ * * If an error occurred, a negative value is returned. @ref SocketsErrors\r
+ */\r
+/* @[declare_secure_sockets_connect] */\r
+int32_t SOCKETS_Connect( Socket_t xSocket,\r
+                         SocketsSockaddr_t * pxAddress,\r
+                         Socklen_t xAddressLength );\r
+/* @[declare_secure_sockets_connect] */\r
+\r
+/**\r
+ * @brief Receive data from a TCP socket.\r
+ *\r
+ * The socket must have already been created using a call to SOCKETS_Socket()\r
+ * and connected to a remote socket using SOCKETS_Connect().\r
+ *\r
+ * See the [Berkeley Sockets API]\r
+ * (https://en.wikipedia.org/wiki/Berkeley_sockets#Socket_API_functions)\r
+ * in wikipedia\r
+ *\r
+ * @param[in] xSocket The handle of the socket from which data is being received.\r
+ * @param[out] pvBuffer The buffer into which the received data will be placed.\r
+ * @param[in] xBufferLength The maximum number of bytes which can be received.\r
+ * pvBuffer must be at least xBufferLength bytes long.\r
+ * @param[in] ulFlags Not currently used. Should be set to 0.\r
+ *\r
+ * @return\r
+ * * If the receive was successful then the number of bytes received (placed in the\r
+ *   buffer pointed to by pvBuffer) is returned.\r
+ * * If a timeout occurred before data could be received then 0 is returned (timeout\r
+ *   is set using @ref SOCKETS_SO_RCVTIMEO).\r
+ * * If an error occurred, a negative value is returned. @ref SocketsErrors\r
+ */\r
+/* @[declare_secure_sockets_recv] */\r
+int32_t SOCKETS_Recv( Socket_t xSocket,\r
+                      void * pvBuffer,\r
+                      size_t xBufferLength,\r
+                      uint32_t ulFlags );\r
+/* @[declare_secure_sockets_recv] */\r
+\r
+/**\r
+ * @brief Transmit data to the remote socket.\r
+ *\r
+ * The socket must have already been created using a call to SOCKETS_Socket() and\r
+ * connected to a remote socket using SOCKETS_Connect().\r
+ *\r
+ * See the [Berkeley Sockets API]\r
+ * (https://en.wikipedia.org/wiki/Berkeley_sockets#Socket_API_functions)\r
+ * in wikipedia\r
+ *\r
+ * @param[in] xSocket The handle of the sending socket.\r
+ * @param[in] pvBuffer The buffer containing the data to be sent.\r
+ * @param[in] xDataLength The length of the data to be sent.\r
+ * @param[in] ulFlags Not currently used. Should be set to 0.\r
+ *\r
+ * @return\r
+ * * On success, the number of bytes actually sent is returned.\r
+ * * If an error occurred, a negative value is returned. @ref SocketsErrors\r
+ */\r
+/* @[declare_secure_sockets_send] */\r
+int32_t SOCKETS_Send( Socket_t xSocket,\r
+                      const void * pvBuffer,\r
+                      size_t xDataLength,\r
+                      uint32_t ulFlags );\r
+/* @[declare_secure_sockets_send] */\r
+\r
+/**\r
+ * @brief Closes all or part of a full-duplex connection on the socket.\r
+ *\r
+ * Disable reads and writes on a connected TCP socket. A connected TCP socket must be gracefully\r
+ * shut down before it can be closed.\r
+ *\r
+ * See the [Berkeley Sockets API]\r
+ * (https://en.wikipedia.org/wiki/Berkeley_sockets#Socket_API_functions)\r
+ * in wikipedia\r
+ *\r
+ * \warning SOCKETS_Shutdown() is not safe to be called on the same socket\r
+ * from multiple threads simultaneously with SOCKETS_Connect(),\r
+ * SOCKETS_SetSockOpt(), SOCKETS_Shutdown(), SOCKETS_Close().\r
+ *\r
+ * @param[in] xSocket The handle of the socket to shutdown.\r
+ * @param[in] ulHow SOCKETS_SHUT_RD, SOCKETS_SHUT_WR or SOCKETS_SHUT_RDWR.\r
+ * @ref ShutdownFlags\r
+ *\r
+ * @return\r
+ * * If the operation was successful, 0 is returned.\r
+ * * If an error occurred, a negative value is returned. @ref SocketsErrors\r
+ */\r
+/* @[declare_secure_sockets_shutdown] */\r
+int32_t SOCKETS_Shutdown( Socket_t xSocket,\r
+                          uint32_t ulHow );\r
+/* @[declare_secure_sockets_shutdown] */\r
+\r
+/**\r
+ * @brief Closes the socket and frees the related resources.\r
+ *\r
+ * A socket should be shutdown gracefully before it is closed, and cannot be used after it has been closed.\r
+ *\r
+ * See the [Berkeley Sockets API]\r
+ * (https://en.wikipedia.org/wiki/Berkeley_sockets#Socket_API_functions)\r
+ * in wikipedia\r
+ *\r
+ * \warning SOCKETS_Close() is not safe to be called on the same socket\r
+ * from multiple threads simultaneously with SOCKETS_Connect(),\r
+ * SOCKETS_SetSockOpt(), SOCKETS_Shutdown(), SOCKETS_Close().\r
+ *\r
+ * @param[in] xSocket The handle of the socket to close.\r
+ *\r
+ * @return\r
+ * * On success, 0 is returned.\r
+ * * If an error occurred, a negative value is returned. @ref SocketsErrors\r
+ */\r
+/* @[declare_secure_sockets_close] */\r
+int32_t SOCKETS_Close( Socket_t xSocket );\r
+/* @[declare_secure_sockets_close] */\r
+\r
+/**\r
+ * @brief AWS IoT ALPN protocol name for MQTT over TLS on server port 443.\r
+ */\r
+#define socketsAWS_IOT_ALPN_MQTT    "x-amzn-mqtt-ca"\r
+\r
+/**\r
+ * @brief Manipulates the options for the socket.\r
+ *\r
+ * See the [Berkeley Sockets API]\r
+ * (https://en.wikipedia.org/wiki/Berkeley_sockets#Socket_API_functions)\r
+ * in wikipedia\r
+ *\r
+ * @param[in] xSocket The handle of the socket to set the option for.\r
+ * @param[in] lLevel Not currently used. Should be set to 0.\r
+ * @param[in] lOptionName See @ref SetSockOptOptions.\r
+ * @param[in] pvOptionValue A buffer containing the value of the option to set.\r
+ * @param[in] xOptionLength The length of the buffer pointed to by pvOptionValue.\r
+ *\r
+ * \warning SOCKETS_Close() is not safe to be called on the same socket\r
+ * from multiple threads simultaneously with SOCKETS_Connect(),\r
+ * SOCKETS_SetSockOpt(), SOCKETS_Shutdown(), SOCKETS_Close().\r
+ *\r
+ * @note Socket option support and possible values vary by port. Please see\r
+ * PORT_SPECIFIC_LINK to check the valid options and limitations of your device.\r
+ *\r
+ *  - Berkeley Socket Options\r
+ *    - @ref SOCKETS_SO_RCVTIMEO\r
+ *      - Sets the receive timeout\r
+ *      - pvOptionValue (TickType_t) is the number of milliseconds that the\r
+ *      receive function should wait before timing out.\r
+ *      - Setting pvOptionValue = 0 causes receive to wait forever.\r
+ *      - See PORT_SPECIFIC_LINK for device limitations.\r
+ *    - @ref SOCKETS_SO_SNDTIMEO\r
+ *      - Sets the send timeout\r
+ *      - pvOptionValue (TickType_t) is the number of milliseconds that the\r
+ *      send function should wait before timing out.\r
+ *      - Setting pvOptionValue = 0 causes send to wait forever.\r
+ *      - See PORT_SPECIFIC_LINK for device limitations.\r
+ *  - Non-Standard Options\r
+ *    - @ref SOCKETS_SO_NONBLOCK\r
+ *      - Makes a socket non-blocking.\r
+ *      - Non-blocking connect is not supported - socket option should be\r
+ *        called after connect.\r
+ *      - pvOptionValue is ignored for this option.\r
+ *    - @ref SOCKETS_SO_WAKEUP_CALLBACK\r
+ *      - Set the callback to be called whenever there is data available on\r
+ *      the socket for reading\r
+ *      - This option provides an asynchronous way to handle received data\r
+ *      - pvOptionValue is a pointer to the callback function\r
+ *      - See PORT_SPECIFIC_LINK for device limitations.\r
+ *  - Security Sockets Options\r
+ *    - @ref SOCKETS_SO_REQUIRE_TLS\r
+ *      - Use TLS for all connect, send, and receive on this socket.\r
+ *      - This socket options MUST be set for TLS to be used, even\r
+ *        if other secure socket options are set.\r
+ *      - This socket option should be set before SOCKETS_Connect() is\r
+ *        called.\r
+ *      - pvOptionValue is ignored for this option.\r
+ *    - @ref SOCKETS_SO_TRUSTED_SERVER_CERTIFICATE\r
+ *      - Set the root of trust server certificate for the socket.\r
+ *      - This socket option only takes effect if @ref SOCKETS_SO_REQUIRE_TLS\r
+ *        is also set.  If @ref SOCKETS_SO_REQUIRE_TLS is not set,\r
+ *        this option will be ignored.\r
+ *      - pvOptionValue is a pointer to the formatted server certificate.\r
+ *        TODO: Link to description of how to format certificates with \n\r
+ *      - xOptionLength (BaseType_t) is the length of the certificate\r
+ *        in bytes.\r
+ *    - @ref SOCKETS_SO_SERVER_NAME_INDICATION\r
+ *      - Use Server Name Indication (SNI)\r
+ *      - This socket option only takes effect if @ref SOCKETS_SO_REQUIRE_TLS\r
+ *        is also set.  If @ref SOCKETS_SO_REQUIRE_TLS is not set,\r
+ *        this option will be ignored.\r
+ *      - pvOptionValue is a pointer to a string containing the hostname\r
+ *      - xOptionLength is the length of the hostname string in bytes.\r
+ *    - @ref SOCKETS_SO_ALPN_PROTOCOLS\r
+ *      - Negotiate an application protocol along with TLS.\r
+ *      - The ALPN list is expressed as an array of NULL-terminated ANSI\r
+ *        strings.\r
+ *      - xOptionLength is the number of items in the array.\r
+ *\r
+ * @return\r
+ * * On success, 0 is returned.\r
+ * * If an error occurred, a negative value is returned. @ref SocketsErrors\r
+ */\r
+/* @[declare_secure_sockets_setsockopt] */\r
+int32_t SOCKETS_SetSockOpt( Socket_t xSocket,\r
+                            int32_t lLevel,\r
+                            int32_t lOptionName,\r
+                            const void * pvOptionValue,\r
+                            size_t xOptionLength );\r
+/* @[declare_secure_sockets_setsockopt] */\r
+\r
+/**\r
+ * @brief Resolve a host name using Domain Name Service.\r
+ *\r
+ * See the [Berkeley Sockets API]\r
+ * (https://en.wikipedia.org/wiki/Berkeley_sockets#Socket_API_functions)\r
+ * in wikipedia\r
+ *\r
+ * @param[in] pcHostName The host name to resolve.\r
+ * @return\r
+ * * The IPv4 address of the specified host.\r
+ * * If an error has occurred, 0 is returned.\r
+ */\r
+/* @[declare_secure_sockets_gethostbyname] */\r
+uint32_t SOCKETS_GetHostByName( const char * pcHostName );\r
+/* @[declare_secure_sockets_gethostbyname] */\r
+\r
+\r
+\r
+/**\r
+ * @brief Convert an unsigned thirty-two-bit value from host endianness to network\r
+ * endianness.\r
+ *\r
+ * @param[in] usIn The unsigned thirty-two-bit value to convert.\r
+ */\r
+#if defined( socketsconfigBYTE_ORDER ) && ( socketsconfigBYTE_ORDER == pdLITTLE_ENDIAN )\r
+    #define SOCKETS_htonl( ulIn )    ( ( uint32_t ) ( ( ( ulIn & 0xFF ) << 24 ) | ( ( ulIn & 0xFF00 ) << 8 ) | ( ( ulIn & 0xFF0000 ) >> 8 ) | ( ( ulIn & 0xFF000000 ) >> 24 ) ) )\r
+#else\r
+    #define SOCKETS_htonl( usIn )    ( ( uint32_t ) ( usIn ) )\r
+#endif\r
+\r
+/**\r
+ * @brief Convert an unsigned thirty-two-bit value from network endianness to host\r
+ * endianness.\r
+ *\r
+ * @param[in] usIn The unsigned thirty-two-bit value to convert.\r
+ */\r
+#define SOCKETS_ntohl( usIn )    SOCKETS_htonl( usIn )\r
+\r
+\r
+/**\r
+ * @brief Convert an unsigned sixteen-bit value from host endianness to network\r
+ * endianness.\r
+ *\r
+ * @param[in] usIn The unsigned sixteen-bit value to convert.\r
+ */\r
+\r
+#if defined( socketsconfigBYTE_ORDER ) && ( socketsconfigBYTE_ORDER == pdLITTLE_ENDIAN )\r
+    #define SOCKETS_htons( usIn )    ( ( uint16_t ) ( ( ( usIn ) << 8U ) | ( ( usIn ) >> 8U ) ) )\r
+#else\r
+    #define SOCKETS_htons( usIn )    ( ( uint16_t ) ( usIn ) )\r
+#endif\r
+\r
+\r
+/**\r
+ * @brief Convert an unsigned sixteen-bit value from network endianness to host\r
+ * endianness.\r
+ *\r
+ * @param[in] usIn The unsigned sixteen-bit value to convert.\r
+ */\r
+#define SOCKETS_ntohs( usIn )    SOCKETS_htons( usIn )\r
+\r
+/**\r
+ * @brief Convert an IP address expressed as four separate numeric octets into a an IP address expressed as a 32-bit number in network byte order\r
+ * (for example 192, 168, 0, 100)\r
+ *\r
+ * @param[in] ucOctet0 0th IP Octet\r
+ * @param[in] ucOctet1 1st IP Octet\r
+ * @param[in] ucOctet2 2nd IP Octet\r
+ * @param[in] ucOctet3 3rd IP Octet\r
+ */\r
+#if defined( socketsconfigBYTE_ORDER ) && ( socketsconfigBYTE_ORDER == pdLITTLE_ENDIAN )\r
+\r
+    #define SOCKETS_inet_addr_quick( ucOctet0, ucOctet1, ucOctet2, ucOctet3 ) \\r
+    ( ( ( ( uint32_t ) ( ucOctet3 ) ) << 24UL ) |                             \\r
+      ( ( ( uint32_t ) ( ucOctet2 ) ) << 16UL ) |                             \\r
+      ( ( ( uint32_t ) ( ucOctet1 ) ) << 8UL ) |                              \\r
+      ( ( uint32_t ) ( ucOctet0 ) ) )\r
+\r
+/**\r
+ * @brief Convert an IP address expressed as a 32-bit number in network byte order to a string in decimal dot notation.\r
+ * (for example "192.168.0.100")\r
+ *\r
+ * @param[in] ulIPAddress An IP address expressed as a 32-bit value in network byte order.\r
+ * @param[in] pucBuffer A pointer to a buffer into which the IP address will be written in decimal dot notation.\r
+ */\r
+    #define SOCKETS_inet_ntoa( ulIPAddress, pucBuffer )               \\r
+    sprintf( ( char * ) ( pucBuffer ), "%u.%u.%u.%u",                 \\r
+             ( ( unsigned ) ( ( ulIPAddress ) & 0xffUL ) ),           \\r
+             ( ( unsigned ) ( ( ( ulIPAddress ) >> 8 ) & 0xffUL ) ),  \\r
+             ( ( unsigned ) ( ( ( ulIPAddress ) >> 16 ) & 0xffUL ) ), \\r
+             ( ( unsigned ) ( ( ulIPAddress ) >> 24 ) ) )\r
+\r
+#else /* socketsconfigBYTE_ORDER. */\r
+\r
+    #define SOCKETS_inet_addr_quick( ucOctet0, ucOctet1, ucOctet2, ucOctet3 ) \\r
+    ( ( ( ( uint32_t ) ( ucOctet0 ) ) << 24UL ) |                             \\r
+      ( ( ( uint32_t ) ( ucOctet1 ) ) << 16UL ) |                             \\r
+      ( ( ( uint32_t ) ( ucOctet2 ) ) << 8UL ) |                              \\r
+      ( ( uint32_t ) ( ucOctet3 ) ) )\r
+\r
+/**\r
+ * @brief Convert an IP address expressed as a 32-bit number in network byte order to a string in decimal dot notation.\r
+ * (for example "192.168.0.100")\r
+ *\r
+ * @param[in] ulIPAddress An IP address expressed as a 32-bit value in network byte order.\r
+ * @param[in] pucBuffer A pointer to a buffer into which the IP address will be written in decimal dot notation.\r
+ */\r
+    #define SOCKETS_inet_ntoa( ulIPAddress, pucBuffer )               \\r
+    sprintf( ( char * ) ( pucBuffer ), "%u.%u.%u.%u",                 \\r
+             ( ( unsigned ) ( ( ulIPAddress ) >> 24 ) ),              \\r
+             ( ( unsigned ) ( ( ( ulIPAddress ) >> 16 ) & 0xffUL ) ), \\r
+             ( ( unsigned ) ( ( ( ulIPAddress ) >> 8 ) & 0xffUL ) ),  \\r
+             ( ( unsigned ) ( ( ulIPAddress ) & 0xffUL ) ) )\r
+\r
+#endif /* socketsconfigBYTE_ORDER. */\r
+\r
+/*\r
+ #ifdef __cplusplus\r
+ *  }\r
+ #endif\r
+ */\r
+\r
+#endif /* _AWS_SECURE_SOCKETS_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/secure_sockets/include/iot_secure_sockets_config_defaults.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/secure_sockets/include/iot_secure_sockets_config_defaults.h
new file mode 100644 (file)
index 0000000..498ac5d
--- /dev/null
@@ -0,0 +1,72 @@
+/*\r
+ * Amazon FreeRTOS Secure Sockets V1.1.5\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_secure_sockets_config_defaults.h\r
+ * @brief Ensures that the required sockets configuration options are supplied\r
+ * and the optional ones are set to sane values if the user does not supply.\r
+ */\r
+\r
+#ifndef AWS_INC_SECURE_SOCKETS_CONFIG_DEFAULTS_H_\r
+#define AWS_INC_SECURE_SOCKETS_CONFIG_DEFAULTS_H_\r
+\r
+/**\r
+ * @brief Byte order of the target MCU must be defined.\r
+ *\r
+ * Valid values are pdLITTLE_ENDIAN and pdBIG_ENDIAN.\r
+ */\r
+#ifndef socketsconfigBYTE_ORDER\r
+    #error "socketsconfigBYTE_ORDER must be defined."\r
+#endif\r
+\r
+/**\r
+ * @brief Default socket send timeout.\r
+ *\r
+ * The user can change the send timeout for a socket using the SOCKETS_SetSockOpt API\r
+ * with the SOCKETS_SO_SNDTIMEO option.\r
+ */\r
+#ifndef socketsconfigDEFAULT_SEND_TIMEOUT\r
+    #define socketsconfigDEFAULT_SEND_TIMEOUT    ( 10000 )\r
+#endif\r
+\r
+/**\r
+ * @brief Default socket receive timeout.\r
+ *\r
+ * The user can change the receive timeout for a socket using the SOCKETS_SetSockOpt API\r
+ * with the SOCKETS_SO_RCVTIMEO option.\r
+ */\r
+#ifndef socketsconfigDEFAULT_RECV_TIMEOUT\r
+    #define socketsconfigDEFAULT_RECV_TIMEOUT    ( 10000 )\r
+#endif\r
+\r
+/**\r
+ * @brief By default, metrics of secure socket is disabled.\r
+ *\r
+ */\r
+#ifndef AWS_IOT_SECURE_SOCKETS_METRICS_ENABLED\r
+    #define AWS_IOT_SECURE_SOCKETS_METRICS_ENABLED    ( 0 )\r
+#endif\r
+\r
+#endif /* AWS_INC_SECURE_SOCKETS_CONFIG_DEFAULTS_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/secure_sockets/include/iot_secure_sockets_wrapper_metrics.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/secure_sockets/include/iot_secure_sockets_wrapper_metrics.h
new file mode 100644 (file)
index 0000000..a5282a2
--- /dev/null
@@ -0,0 +1,43 @@
+/*\r
+ * Amazon FreeRTOS Secure Sockets V1.1.5\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
+#ifndef _AWS_SECURE_SOCKETS_WRAPPER_METRICS_\r
+#define _AWS_SECURE_SOCKETS_WRAPPER_METRICS_\r
+\r
+/* This file redefines Secure Sockets functions to be called through a wrapper macro,\r
+ * but only if metrics is enabled explicitly. */\r
+#if AWS_IOT_SECURE_SOCKETS_METRICS_ENABLED == 1\r
+\r
+/* This macro is included in aws_secure_socket.c and aws_secure_socket_wrapper_metrics.c.\r
+ * It will prevent the redefine in those source files. */\r
+    #ifndef _SECURE_SOCKETS_WRAPPER_NOT_REDEFINE\r
+        #define SOCKETS_Init        Sockets_MetricsInit\r
+        #define SOCKETS_Connect     Sockets_MetricsConnect\r
+        #define SOCKETS_Shutdown    Sockets_MetricsShutdown\r
+    #endif\r
+\r
+#endif\r
+\r
+#endif /* ifndef _AWS_SECURE_SOCKETS_WRAPPER_METRICS_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_atomic.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_atomic.h
new file mode 100644 (file)
index 0000000..ff2a219
--- /dev/null
@@ -0,0 +1,39 @@
+/*\r
+ * Amazon FreeRTOS Common V1.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_atomic.h\r
+ * @brief Chooses the appropriate atomic operations header.\r
+ *\r
+ * On FreeRTOS, this file chooses the atomic header provided with the FreeRTOS\r
+ * kernel.\r
+ */\r
+\r
+#ifndef IOT_ATOMIC_H_\r
+#define IOT_ATOMIC_H_\r
+\r
+#include "atomic.h"\r
+\r
+#endif /* ifndef IOT_ATOMIC_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_init.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_init.h
new file mode 100644 (file)
index 0000000..5e27cf8
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+ * Amazon FreeRTOS Common V1.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_init.h\r
+ * @brief Provides function signatures for common initialization and cleanup of\r
+ * this SDK.\r
+ */\r
+\r
+#ifndef IOT_INIT_H_\r
+#define IOT_INIT_H_\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/* Standard includes. */\r
+#include <stdbool.h>\r
+\r
+/**\r
+ * @brief One-time initialization function for this SDK.\r
+ *\r
+ * This function initializes common libraries, such as static memory and task\r
+ * pool. <b>It must be called once (and only once) before calling any other\r
+ * function in this SDK.</b> Calling this function more than once without first\r
+ * calling `IotSdk_Cleanup` may result in a crash.\r
+ *\r
+ * @return `true` if initialization succeeded; `false` otherwise. Logs may be\r
+ * printed in case of failure.\r
+ *\r
+ * @warning No thread-safety guarantees are provided for this function.\r
+ */\r
+bool IotSdk_Init( void );\r
+\r
+/**\r
+ * @brief One-time deinitialization function for all common libraries.\r
+ *\r
+ * This function frees resources taken in `IotSdk_Init`. No other function\r
+ * in this SDK may be called after calling this function unless `IotSdk_Init`\r
+ * is called again.\r
+ *\r
+ * @warning No thread-safety guarantees are provided for this function.\r
+ */\r
+void IotSdk_Cleanup( void );\r
+\r
+#endif /* IOT_INIT_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_linear_containers.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_linear_containers.h
new file mode 100644 (file)
index 0000000..dc5ac25
--- /dev/null
@@ -0,0 +1,956 @@
+/*\r
+ * Amazon FreeRTOS Common V1.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_linear_containers.h\r
+ * @brief Declares and implements doubly-linked lists and queues.\r
+ */\r
+\r
+#ifndef IOT_LINEAR_CONTAINERS_H_\r
+#define IOT_LINEAR_CONTAINERS_H_\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/* Standard includes. */\r
+#include <stdbool.h>\r
+#include <stddef.h>\r
+#include <stdint.h>\r
+\r
+/**\r
+ * @defgroup linear_containers_datatypes_listqueue List and queue\r
+ * @brief Structures that represent a list or queue.\r
+ */\r
+\r
+/**\r
+ * @ingroup linear_containers_datatypes_listqueue\r
+ * @brief Link member placed in structs of a list or queue.\r
+ *\r
+ * All elements in a list or queue must contain one of these members. The macro\r
+ * #IotLink_Container can be used to calculate the starting address of the\r
+ * link's container.\r
+ */\r
+typedef struct IotLink\r
+{\r
+    struct IotLink * pPrevious; /**< @brief Pointer to the previous element. */\r
+    struct IotLink * pNext;     /**< @brief Pointer to the next element. */\r
+} IotLink_t;\r
+\r
+/**\r
+ * @ingroup linear_containers_datatypes_listqueue\r
+ * @brief Represents a doubly-linked list.\r
+ */\r
+typedef IotLink_t   IotListDouble_t;\r
+\r
+/**\r
+ * @ingroup linear_containers_datatypes_listqueue\r
+ * @brief Represents a queue.\r
+ */\r
+typedef IotLink_t   IotDeQueue_t;\r
+\r
+/**\r
+ * @constantspage{linear_containers,linear containers library}\r
+ *\r
+ * @section linear_containers_constants_initializers Linear Containers Initializers\r
+ * @brief Provides default values for initializing the linear containers data types.\r
+ *\r
+ * @snippet this define_linear_containers_initializers\r
+ *\r
+ * All user-facing data types of the linear containers library should be initialized\r
+ * using one of the following.\r
+ *\r
+ * @warning Failure to initialize a linear containers data type with the appropriate\r
+ * initializer may result in a runtime error!\r
+ * @note The initializers may change at any time in future versions, but their\r
+ * names will remain the same.\r
+ */\r
+/* @[define_linear_containers_initializers] */\r
+#define IOT_LINK_INITIALIZER           { 0 }                /**< @brief Initializer for an #IotLink_t. */\r
+#define IOT_LIST_DOUBLE_INITIALIZER    IOT_LINK_INITIALIZER /**< @brief Initializer for an #IotListDouble_t. */\r
+#define IOT_DEQUEUE_INITIALIZER        IOT_LINK_INITIALIZER /**< @brief Initializer for an #IotDeQueue_t. */\r
+/* @[define_linear_containers_initializers] */\r
+\r
+/**\r
+ * @def IotContainers_Assert( expression )\r
+ * @brief Assertion macro for the linear containers library.\r
+ *\r
+ * Set @ref IOT_CONTAINERS_ENABLE_ASSERTS to `1` to enable assertions in the linear\r
+ * containers library.\r
+ *\r
+ * @param[in] expression Expression to be evaluated.\r
+ */\r
+#if IOT_CONTAINERS_ENABLE_ASSERTS == 1\r
+    #ifndef IotContainers_Assert\r
+        #include <assert.h>\r
+        #define IotContainers_Assert( expression )    assert( expression )\r
+    #endif\r
+#else\r
+    #define IotContainers_Assert( expression )\r
+#endif\r
+\r
+/**\r
+ * @brief Calculates the starting address of a containing struct.\r
+ *\r
+ * @param[in] type Type of the containing struct.\r
+ * @param[in] pLink Pointer to a link member.\r
+ * @param[in] linkName Name of the #IotLink_t in the containing struct.\r
+ */\r
+#define IotLink_Container( type, pLink, linkName ) \\r
+    ( ( type * ) ( void * ) ( ( ( uint8_t * ) ( pLink ) ) - offsetof( type, linkName ) ) )\r
+\r
+/**\r
+ * @brief Iterates through all elements of a linear container.\r
+ *\r
+ * Container elements must not be freed or removed while iterating.\r
+ *\r
+ * @param[in] pStart The first element to iterate from.\r
+ * @param[out] pLink Pointer to a container element.\r
+ */\r
+#define IotContainers_ForEach( pStart, pLink )  \\r
+    for( ( pLink ) = ( pStart )->pNext;         \\r
+         ( pLink ) != ( pStart );               \\r
+         ( pLink ) = ( pLink )->pNext )\r
+\r
+/**\r
+ * @functionspage{linear_containers,linear containers library}\r
+ * - @functionname{linear_containers_function_link_islinked}\r
+ * - @functionname{linear_containers_function_list_double_create}\r
+ * - @functionname{linear_containers_function_list_double_count}\r
+ * - @functionname{linear_containers_function_list_double_isempty}\r
+ * - @functionname{linear_containers_function_list_double_peekhead}\r
+ * - @functionname{linear_containers_function_list_double_peektail}\r
+ * - @functionname{linear_containers_function_list_double_inserthead}\r
+ * - @functionname{linear_containers_function_list_double_inserttail}\r
+ * - @functionname{linear_containers_function_list_double_insertbefore}\r
+ * - @functionname{linear_containers_function_list_double_insertafter}\r
+ * - @functionname{linear_containers_function_list_double_insertsorted}\r
+ * - @functionname{linear_containers_function_list_double_remove}\r
+ * - @functionname{linear_containers_function_list_double_removehead}\r
+ * - @functionname{linear_containers_function_list_double_removetail}\r
+ * - @functionname{linear_containers_function_list_double_removeall}\r
+ * - @functionname{linear_containers_function_list_double_findfirstmatch}\r
+ * - @functionname{linear_containers_function_list_double_removefirstmatch}\r
+ * - @functionname{linear_containers_function_list_double_removeallmatches}\r
+ * - @functionname{linear_containers_function_queue_create}\r
+ * - @functionname{linear_containers_function_queue_count}\r
+ * - @functionname{linear_containers_function_queue_isempty}\r
+ * - @functionname{linear_containers_function_queue_peekhead}\r
+ * - @functionname{linear_containers_function_queue_peektail}\r
+ * - @functionname{linear_containers_function_queue_enqueuehead}\r
+ * - @functionname{linear_containers_function_queue_dequeuehead}\r
+ * - @functionname{linear_containers_function_queue_enqueuetail}\r
+ * - @functionname{linear_containers_function_queue_dequeuetail}\r
+ * - @functionname{linear_containers_function_queue_remove}\r
+ * - @functionname{linear_containers_function_queue_removeall}\r
+ * - @functionname{linear_containers_function_queue_removeallmatches}\r
+ */\r
+\r
+/**\r
+ * @functionpage{IotLink_IsLinked,linear_containers,link_islinked}\r
+ * @functionpage{IotListDouble_Create,linear_containers,list_double_create}\r
+ * @functionpage{IotListDouble_Count,linear_containers,list_double_count}\r
+ * @functionpage{IotListDouble_IsEmpty,linear_containers,list_double_isempty}\r
+ * @functionpage{IotListDouble_PeekHead,linear_containers,list_double_peekhead}\r
+ * @functionpage{IotListDouble_PeekTail,linear_containers,list_double_peektail}\r
+ * @functionpage{IotListDouble_InsertHead,linear_containers,list_double_inserthead}\r
+ * @functionpage{IotListDouble_InsertTail,linear_containers,list_double_inserttail}\r
+ * @functionpage{IotListDouble_InsertBefore,linear_containers,list_double_insertbefore}\r
+ * @functionpage{IotListDouble_InsertAfter,linear_containers,list_double_insertafter}\r
+ * @functionpage{IotListDouble_InsertSorted,linear_containers,list_double_insertsorted}\r
+ * @functionpage{IotListDouble_Remove,linear_containers,list_double_remove}\r
+ * @functionpage{IotListDouble_RemoveHead,linear_containers,list_double_removehead}\r
+ * @functionpage{IotListDouble_RemoveTail,linear_containers,list_double_removetail}\r
+ * @functionpage{IotListDouble_RemoveAll,linear_containers,list_double_removeall}\r
+ * @functionpage{IotListDouble_FindFirstMatch,linear_containers,list_double_findfirstmatch}\r
+ * @functionpage{IotListDouble_RemoveFirstMatch,linear_containers,list_double_removefirstmatch}\r
+ * @functionpage{IotListDouble_RemoveAllMatches,linear_containers,list_double_removeallmatches}\r
+ * @functionpage{IotDeQueue_Create,linear_containers,queue_create}\r
+ * @functionpage{IotDeQueue_Count,linear_containers,queue_count}\r
+ * @functionpage{IotDeQueue_IsEmpty,linear_containers,queue_isempty}\r
+ * @functionpage{IotDeQueue_PeekHead,linear_containers,queue_peekhead}\r
+ * @functionpage{IotDeQueue_PeekTail,linear_containers,queue_peektail}\r
+ * @functionpage{IotDeQueue_EnqueueHead,linear_containers,queue_enqueuehead}\r
+ * @functionpage{IotDeQueue_DequeueHead,linear_containers,queue_dequeuehead}\r
+ * @functionpage{IotDeQueue_EnqueueTail,linear_containers,queue_enqueuetail}\r
+ * @functionpage{IotDeQueue_DequeueTail,linear_containers,queue_dequeuetail}\r
+ * @functionpage{IotDeQueue_Remove,linear_containers,queue_remove}\r
+ * @functionpage{IotDeQueue_RemoveAll,linear_containers,queue_removeall}\r
+ * @functionpage{IotDeQueue_RemoveAllMatches,linear_containers,queue_removeallmatches}\r
+ */\r
+\r
+/**\r
+ * @brief Check if an #IotLink_t is linked in a list or queue.\r
+ *\r
+ * @param[in] pLink The link to check.\r
+ *\r
+ * @return `true` if `pCurrent` is linked in a list or queue; `false` otherwise.\r
+ */\r
+/* @[declare_linear_containers_link_islinked] */\r
+static inline bool IotLink_IsLinked( const IotLink_t * const pLink )\r
+/* @[declare_linear_containers_link_islinked] */\r
+{\r
+    bool isLinked = false;\r
+\r
+    if( pLink != NULL )\r
+    {\r
+        isLinked = ( pLink->pNext != NULL ) && ( pLink->pPrevious != NULL );\r
+    }\r
+\r
+    return isLinked;\r
+}\r
+\r
+/**\r
+ * @brief Create a new doubly-linked list.\r
+ *\r
+ * This function initializes a new doubly-linked list. It must be called on an\r
+ * uninitialized #IotListDouble_t before calling any other doubly-linked list\r
+ * function. This function must not be called on an already-initialized\r
+ * #IotListDouble_t.\r
+ *\r
+ * This function will not fail. The function @ref linear_containers_function_list_double_removeall\r
+ * may be called to destroy a list.\r
+ *\r
+ * @param[in] pList Pointer to the memory that will hold the new doubly-linked list.\r
+ */\r
+/* @[declare_linear_containers_list_double_create] */\r
+static inline void IotListDouble_Create( IotListDouble_t * const pList )\r
+/* @[declare_linear_containers_list_double_create] */\r
+{\r
+    /* This function must not be called with a NULL parameter. */\r
+    IotContainers_Assert( pList != NULL );\r
+\r
+    /* An empty list is a link pointing to itself. */\r
+    pList->pPrevious = pList;\r
+    pList->pNext = pList;\r
+}\r
+\r
+/**\r
+ * @brief Return the number of elements contained in an #IotListDouble_t.\r
+ *\r
+ * @param[in] pList The doubly-linked list with the elements to count.\r
+ *\r
+ * @return The number of elements in the doubly-linked list.\r
+ */\r
+/* @[declare_linear_containers_list_double_count] */\r
+static inline size_t IotListDouble_Count( const IotListDouble_t * const pList )\r
+/* @[declare_linear_containers_list_double_count] */\r
+{\r
+    size_t count = 0;\r
+\r
+    if( pList != NULL )\r
+    {\r
+        /* Get the list head. */\r
+        const IotLink_t * pCurrent = pList->pNext;\r
+\r
+        /* Iterate through the list to count the elements. */\r
+        while( pCurrent != pList )\r
+        {\r
+            count++;\r
+            pCurrent = pCurrent->pNext;\r
+        }\r
+    }\r
+\r
+    return count;\r
+}\r
+\r
+/**\r
+ * @brief Check if a doubly-linked list is empty.\r
+ *\r
+ * @param[in] pList The doubly-linked list to check.\r
+ *\r
+ * @return `true` if the list is empty; `false` otherwise.\r
+ */\r
+/* @[declare_linear_containers_list_double_isempty] */\r
+static inline bool IotListDouble_IsEmpty( const IotListDouble_t * const pList )\r
+/* @[declare_linear_containers_list_double_isempty] */\r
+{\r
+    /* An empty list is NULL link, or a link pointing to itself. */\r
+    return( ( pList == NULL ) || ( pList->pNext == pList ) );\r
+}\r
+\r
+/**\r
+ * @brief Return an #IotLink_t representing the first element in a doubly-linked list\r
+ * without removing it.\r
+ *\r
+ * @param[in] pList The list to peek.\r
+ *\r
+ * @return Pointer to an #IotLink_t representing the element at the head of the\r
+ * list; `NULL` if the list is empty. The macro #IotLink_Container may be used to\r
+ * determine the address of the link's container.\r
+ */\r
+/* @[declare_linear_containers_list_double_peekhead] */\r
+static inline IotLink_t * IotListDouble_PeekHead( const IotListDouble_t * const pList )\r
+/* @[declare_linear_containers_list_double_peekhead] */\r
+{\r
+    IotLink_t * pHead = NULL;\r
+\r
+    if( pList != NULL )\r
+    {\r
+        if( IotListDouble_IsEmpty( pList ) == false )\r
+        {\r
+            pHead = pList->pNext;\r
+        }\r
+    }\r
+\r
+    return pHead;\r
+}\r
+\r
+/**\r
+ * @brief Return an #IotLink_t representing the last element in a doubly-linked\r
+ * list without removing it.\r
+ *\r
+ * @param[in] pList The list to peek.\r
+ *\r
+ * @return Pointer to an #IotLink_t representing the element at the tail of the\r
+ * list; `NULL` if the list is empty. The macro #IotLink_Container may be used to\r
+ * determine the address of the link's container.\r
+ */\r
+/* @[declare_linear_containers_list_double_peektail] */\r
+static inline IotLink_t * IotListDouble_PeekTail( const IotListDouble_t * const pList )\r
+/* @[declare_linear_containers_list_double_peektail] */\r
+{\r
+    IotLink_t * pTail = NULL;\r
+\r
+    if( pList != NULL )\r
+    {\r
+        if( IotListDouble_IsEmpty( pList ) == false )\r
+        {\r
+            pTail = pList->pPrevious;\r
+        }\r
+    }\r
+\r
+    return pTail;\r
+}\r
+\r
+/**\r
+ * @brief Insert an element at the head of a doubly-linked list.\r
+ *\r
+ * @param[in] pList The doubly-linked list that will hold the new element.\r
+ * @param[in] pLink Pointer to the new element's link member.\r
+ */\r
+/* @[declare_linear_containers_list_double_inserthead] */\r
+static inline void IotListDouble_InsertHead( IotListDouble_t * const pList,\r
+                                             IotLink_t * const pLink )\r
+/* @[declare_linear_containers_list_double_inserthead] */\r
+{\r
+    /* This function must not be called with NULL parameters. */\r
+    IotContainers_Assert( pList != NULL );\r
+    IotContainers_Assert( pLink != NULL );\r
+\r
+    /* Save current list head. */\r
+    IotLink_t * pHead = pList->pNext;\r
+\r
+    /* Place new element before list head. */\r
+    pLink->pNext = pHead;\r
+    pLink->pPrevious = pList;\r
+\r
+    /* Assign new list head. */\r
+    pHead->pPrevious = pLink;\r
+    pList->pNext = pLink;\r
+}\r
+\r
+/**\r
+ * @brief Insert an element at the tail of a doubly-linked list.\r
+ *\r
+ * @param[in] pList The double-linked list that will hold the new element.\r
+ * @param[in] pLink Pointer to the new element's link member.\r
+ */\r
+/* @[declare_linear_containers_list_double_inserttail] */\r
+static inline void IotListDouble_InsertTail( IotListDouble_t * const pList,\r
+                                             IotLink_t * const pLink )\r
+/* @[declare_linear_containers_list_double_inserttail] */\r
+{\r
+    /* This function must not be called with NULL parameters. */\r
+    IotContainers_Assert( pList != NULL );\r
+    IotContainers_Assert( pLink != NULL );\r
+\r
+    /* Save current list tail. */\r
+    IotLink_t * pTail = pList->pPrevious;\r
+\r
+    pLink->pNext = pList;\r
+    pLink->pPrevious = pTail;\r
+\r
+    pList->pPrevious = pLink;\r
+    pTail->pNext = pLink;\r
+}\r
+\r
+/**\r
+ * @brief Insert an element before another element in a doubly-linked list.\r
+ *\r
+ * @param[in] pElement The new element will be placed before this element.\r
+ * @param[in] pLink Pointer to the new element's link member.\r
+ */\r
+/* @[declare_linear_containers_list_double_insertbefore] */\r
+static inline void IotListDouble_InsertBefore( IotLink_t * const pElement,\r
+                                               IotLink_t * const pLink )\r
+/* @[declare_linear_containers_list_double_insertbefore] */\r
+{\r
+    IotListDouble_InsertTail( pElement, pLink );\r
+}\r
+\r
+/**\r
+ * @brief Insert an element after another element in a doubly-linked list.\r
+ *\r
+ * @param[in] pElement The new element will be placed after this element.\r
+ * @param[in] pLink Pointer to the new element's link member.\r
+ */\r
+/* @[declare_linear_containers_list_double_insertafter] */\r
+static inline void IotListDouble_InsertAfter( IotLink_t * const pElement,\r
+                                              IotLink_t * const pLink )\r
+/* @[declare_linear_containers_list_double_insertafter] */\r
+{\r
+    IotListDouble_InsertHead( pElement, pLink );\r
+}\r
+\r
+/**\r
+ * @brief Insert an element in a sorted doubly-linked list.\r
+ *\r
+ * Places an element into a list by sorting it into order. The function\r
+ * `compare` is used to determine where to place the new element.\r
+ *\r
+ * @param[in] pList The list that will hold the new element.\r
+ * @param[in] pLink Pointer to the new element's link member.\r
+ * @param[in] compare Determines the order of the list. Returns a negative\r
+ * value if its first argument is less than its second argument; returns\r
+ * zero if its first argument is equal to its second argument; returns a\r
+ * positive value if its first argument is greater than its second argument.\r
+ * The parameters to this function are #IotLink_t, so the macro #IotLink_Container\r
+ * may be used to determine the address of the link's container.\r
+ */\r
+/* @[declare_linear_containers_list_double_insertsorted] */\r
+static inline void IotListDouble_InsertSorted( IotListDouble_t * const pList,\r
+                                               IotLink_t * const pLink,\r
+                                               int32_t ( *compare )( const IotLink_t * const, const IotLink_t * const ) )\r
+/* @[declare_linear_containers_list_double_insertsorted] */\r
+{\r
+    /* This function must not be called with NULL parameters. */\r
+    IotContainers_Assert( pList != NULL );\r
+    IotContainers_Assert( pLink != NULL );\r
+    IotContainers_Assert( compare != NULL );\r
+\r
+    /* Insert at head for empty list. */\r
+    if( IotListDouble_IsEmpty( pList ) == true )\r
+    {\r
+        IotListDouble_InsertHead( pList, pLink );\r
+    }\r
+    else\r
+    {\r
+        bool inserted = false;\r
+        IotLink_t * pCurrent = pList->pNext;\r
+\r
+        /* Iterate through the list to find the correct position. */\r
+        while( pCurrent != pList )\r
+        {\r
+            /* Comparing for '<' preserves the order of insertion. */\r
+            if( compare( pLink, pCurrent ) < 0 )\r
+            {\r
+                IotListDouble_InsertBefore( pCurrent, pLink );\r
+                inserted = true;\r
+\r
+                break;\r
+            }\r
+\r
+            pCurrent = pCurrent->pNext;\r
+        }\r
+\r
+        /* New element is greater than all elements in list. Insert at tail. */\r
+        if( inserted == false )\r
+        {\r
+            IotListDouble_InsertTail( pList, pLink );\r
+        }\r
+    }\r
+}\r
+\r
+/**\r
+ * @brief Remove a single element from a doubly-linked list.\r
+ *\r
+ * @param[in] pLink The element to remove.\r
+ */\r
+/* @[declare_linear_containers_list_double_remove] */\r
+static inline void IotListDouble_Remove( IotLink_t * const pLink )\r
+/* @[declare_linear_containers_list_double_remove] */\r
+{\r
+    /* This function must not be called with a NULL parameter. */\r
+    IotContainers_Assert( pLink != NULL );\r
+\r
+    /* This function must be called on a linked element. */\r
+    IotContainers_Assert( IotLink_IsLinked( pLink ) == true );\r
+\r
+    pLink->pPrevious->pNext = pLink->pNext;\r
+    pLink->pNext->pPrevious = pLink->pPrevious;\r
+    pLink->pPrevious = NULL;\r
+    pLink->pNext = NULL;\r
+}\r
+\r
+/**\r
+ * @brief Remove the element at the head of a doubly-linked list.\r
+ *\r
+ * @param[in] pList The doubly-linked list that holds the element to remove.\r
+ *\r
+ * @return Pointer to an #IotLink_t representing the removed list head; `NULL`\r
+ * if the list is empty. The macro #IotLink_Container may be used to determine\r
+ * the address of the link's container.\r
+ */\r
+/* @[declare_linear_containers_list_double_removehead] */\r
+static inline IotLink_t * IotListDouble_RemoveHead( IotListDouble_t * const pList )\r
+/* @[declare_linear_containers_list_double_removehead] */\r
+{\r
+    IotLink_t * pHead = NULL;\r
+\r
+    if( IotListDouble_IsEmpty( pList ) == false )\r
+    {\r
+        pHead = pList->pNext;\r
+        IotListDouble_Remove( pHead );\r
+    }\r
+\r
+    return pHead;\r
+}\r
+\r
+/**\r
+ * @brief Remove the element at the tail of a doubly-linked list.\r
+ *\r
+ * @param[in] pList The doubly-linked list that holds the element to remove.\r
+ *\r
+ * @return Pointer to an #IotLink_t representing the removed list tail; `NULL`\r
+ * if the list is empty. The macro #IotLink_Container may be used to determine\r
+ * the address of the link's container.\r
+ */\r
+/* @[declare_linear_containers_list_double_removetail] */\r
+static inline IotLink_t * IotListDouble_RemoveTail( IotListDouble_t * const pList )\r
+/* @[declare_linear_containers_list_double_removetail] */\r
+{\r
+    IotLink_t * pTail = NULL;\r
+\r
+    if( IotListDouble_IsEmpty( pList ) == false )\r
+    {\r
+        pTail = pList->pPrevious;\r
+        IotListDouble_Remove( pTail );\r
+    }\r
+\r
+    return pTail;\r
+}\r
+\r
+/**\r
+ * @brief Remove all elements in a doubly-linked list.\r
+ *\r
+ * @param[in] pList The list to empty.\r
+ * @param[in] freeElement A function to free memory used by each removed list\r
+ * element. Optional; pass `NULL` to ignore.\r
+ * @param[in] linkOffset Offset in bytes of a link member in its container, used\r
+ * to calculate the pointer to pass to `freeElement`. This value should be calculated\r
+ * with the C `offsetof` macro. This parameter is ignored if `freeElement` is `NULL`\r
+ * or its value is `0`.\r
+ */\r
+/* @[declare_linear_containers_list_double_removeall] */\r
+static inline void IotListDouble_RemoveAll( IotListDouble_t * const pList,\r
+                                            void ( *freeElement )( void * ),\r
+                                            size_t linkOffset )\r
+/* @[declare_linear_containers_list_double_removeall] */\r
+{\r
+    /* This function must not be called with a NULL pList parameter. */\r
+    IotContainers_Assert( pList != NULL );\r
+\r
+    /* Get the list head. */\r
+    IotLink_t * pCurrent = pList->pNext;\r
+\r
+    /* Iterate through the list and remove all elements. */\r
+    while( pCurrent != pList )\r
+    {\r
+        /* Save a pointer to the next list element. */\r
+        IotLink_t * pNext = pCurrent->pNext;\r
+\r
+        /* Remove and free the current list element. */\r
+        IotListDouble_Remove( pCurrent );\r
+\r
+        if( freeElement != NULL )\r
+        {\r
+            freeElement( ( ( uint8_t * ) pCurrent ) - linkOffset );\r
+        }\r
+\r
+        /* Move the iterating pointer to the next list element. */\r
+        pCurrent = pNext;\r
+    }\r
+}\r
+\r
+/**\r
+ * @brief Search a doubly-linked list for the first matching element.\r
+ *\r
+ * If a match is found, the matching element is <b>not</b> removed from the list.\r
+ * See @ref linear_containers_function_list_double_removefirstmatch for the function\r
+ * that searches and removes.\r
+ *\r
+ * @param[in] pList The doubly-linked list to search.\r
+ * @param[in] pStartPoint An element in `pList`. Only elements between this one and\r
+ * the list tail are checked. Pass `NULL` to search from the beginning of the list.\r
+ * @param[in] isMatch Function to determine if an element matches. Pass `NULL` to\r
+ * search using the address `pMatch`, i.e. `element == pMatch`.\r
+ * @param[in] pMatch If `isMatch` is `NULL`, each element in the list is compared\r
+ * to this address to find a match. Otherwise, it is passed as the second argument\r
+ * to `isMatch`.\r
+ *\r
+ * @return Pointer to an #IotLink_t representing the first matched element; `NULL`\r
+ * if no match is found. The macro #IotLink_Container may be used to determine the\r
+ * address of the link's container.\r
+ */\r
+/* @[declare_linear_containers_list_double_findfirstmatch] */\r
+static inline IotLink_t * IotListDouble_FindFirstMatch( const IotListDouble_t * const pList,\r
+                                                        const IotLink_t * const pStartPoint,\r
+                                                        bool ( *isMatch )( const IotLink_t * const, void * ),\r
+                                                        void * pMatch )\r
+/* @[declare_linear_containers_list_double_findfirstmatch] */\r
+{\r
+    /* The const must be cast away to match this function's return value. Nevertheless,\r
+     * this function will respect the const-ness of pStartPoint. */\r
+    IotLink_t * pCurrent = ( IotLink_t * ) pStartPoint;\r
+\r
+    /* This function must not be called with a NULL pList parameter. */\r
+    IotContainers_Assert( pList != NULL );\r
+\r
+    /* Search starting from list head if no start point is given. */\r
+    if( pStartPoint == NULL )\r
+    {\r
+        pCurrent = pList->pNext;\r
+    }\r
+\r
+    /* Iterate through the list to search for matches. */\r
+    while( pCurrent != pList )\r
+    {\r
+        /* Call isMatch if provided. Otherwise, compare pointers. */\r
+        if( isMatch != NULL )\r
+        {\r
+            if( isMatch( pCurrent, pMatch ) == true )\r
+            {\r
+                return pCurrent;\r
+            }\r
+        }\r
+        else\r
+        {\r
+            if( pCurrent == pMatch )\r
+            {\r
+                return pCurrent;\r
+            }\r
+        }\r
+\r
+        pCurrent = pCurrent->pNext;\r
+    }\r
+\r
+    /* No match found, return NULL. */\r
+    return NULL;\r
+}\r
+\r
+/**\r
+ * @brief Search a doubly-linked list for the first matching element and remove\r
+ * it.\r
+ *\r
+ * An #IotLink_t may be passed as `pList` to start searching after the head of a\r
+ * doubly-linked list.\r
+ *\r
+ * @param[in] pList The doubly-linked list to search.\r
+ * @param[in] pStartPoint An element in `pList`. Only elements between this one and\r
+ * the list tail are checked. Pass `NULL` to search from the beginning of the list.\r
+ * @param[in] isMatch Function to determine if an element matches. Pass `NULL` to\r
+ * search using the address `pMatch`, i.e. `element == pMatch`.\r
+ * @param[in] pMatch If `isMatch` is `NULL`, each element in the list is compared\r
+ * to this address to find a match. Otherwise, it is passed as the second argument\r
+ * to `isMatch`.\r
+ *\r
+ * @return Pointer to an #IotLink_t representing the matched and removed element;\r
+ * `NULL` if no match is found. The macro #IotLink_Container may be used to determine\r
+ * the address of the link's container.\r
+ */\r
+/* @[declare_linear_containers_list_double_removefirstmatch] */\r
+static inline IotLink_t * IotListDouble_RemoveFirstMatch( IotListDouble_t * const pList,\r
+                                                          const IotLink_t * const pStartPoint,\r
+                                                          bool ( *isMatch )( const IotLink_t *, void * ),\r
+                                                          void * pMatch )\r
+/* @[declare_linear_containers_list_double_removefirstmatch] */\r
+{\r
+    IotLink_t * pMatchedElement = IotListDouble_FindFirstMatch( pList,\r
+                                                                pStartPoint,\r
+                                                                isMatch,\r
+                                                                pMatch );\r
+\r
+    if( pMatchedElement != NULL )\r
+    {\r
+        IotListDouble_Remove( pMatchedElement );\r
+    }\r
+\r
+    return pMatchedElement;\r
+}\r
+\r
+/**\r
+ * @brief Remove all matching elements from a doubly-linked list.\r
+ *\r
+ * @param[in] pList The doubly-linked list to search.\r
+ * @param[in] isMatch Function to determine if an element matches. Pass `NULL` to\r
+ * search using the address `pMatch`, i.e. `element == pMatch`.\r
+ * @param[in] pMatch If `isMatch` is `NULL`, each element in the list is compared\r
+ * to this address to find a match. Otherwise, it is passed as the second argument\r
+ * to `isMatch`.\r
+ * @param[in] freeElement A function to free memory used by each removed list\r
+ * element. Optional; pass `NULL` to ignore.\r
+ * @param[in] linkOffset Offset in bytes of a link member in its container, used\r
+ * to calculate the pointer to pass to `freeElement`. This value should be calculated\r
+ * with the C `offsetof` macro. This parameter is ignored if `freeElement` is `NULL`\r
+ * or its value is `0`.\r
+ */\r
+/* @[declare_linear_containers_list_double_removeallmatches] */\r
+static inline void IotListDouble_RemoveAllMatches( IotListDouble_t * const pList,\r
+                                                   bool ( *isMatch )( const IotLink_t *, void * ),\r
+                                                   void * pMatch,\r
+                                                   void ( *freeElement )( void * ),\r
+                                                   size_t linkOffset )\r
+/* @[declare_linear_containers_list_double_removeallmatches] */\r
+{\r
+    IotLink_t * pMatchedElement = NULL, * pNextElement = NULL;\r
+\r
+    /* Search the list for all matching elements. */\r
+    do\r
+    {\r
+        pMatchedElement = IotListDouble_FindFirstMatch( pList,\r
+                                                        pMatchedElement,\r
+                                                        isMatch,\r
+                                                        pMatch );\r
+\r
+        if( pMatchedElement != NULL )\r
+        {\r
+            /* Save pointer to next element. */\r
+            pNextElement = pMatchedElement->pNext;\r
+\r
+            /* Match found; remove and free. */\r
+            IotListDouble_Remove( pMatchedElement );\r
+\r
+            if( freeElement != NULL )\r
+            {\r
+                freeElement( ( ( uint8_t * ) pMatchedElement ) - linkOffset );\r
+            }\r
+\r
+            /* Continue search from next element. */\r
+            pMatchedElement = pNextElement;\r
+        }\r
+    } while( pMatchedElement != NULL );\r
+}\r
+\r
+/**\r
+ * @brief Create a new queue.\r
+ *\r
+ * This function initializes a new double-ended queue. It must be called on an uninitialized\r
+ * #IotDeQueue_t before calling any other queue function. This function must not be\r
+ * called on an already-initialized #IotDeQueue_t.\r
+ *\r
+ * This function will not fail.\r
+ *\r
+ * @param[in] pQueue Pointer to the memory that will hold the new queue.\r
+ */\r
+/* @[declare_linear_containers_queue_create] */\r
+static inline void IotDeQueue_Create( IotDeQueue_t * const pQueue )\r
+/* @[declare_linear_containers_queue_create] */\r
+{\r
+    IotListDouble_Create( pQueue );\r
+}\r
+\r
+/**\r
+ * @brief Return the number of elements contained in an #IotDeQueue_t.\r
+ *\r
+ * @param[in] pQueue The queue with the elements to count.\r
+ *\r
+ * @return The number of items elements in the queue.\r
+ */\r
+/* @[declare_linear_containers_queue_count] */\r
+static inline size_t IotDeQueue_Count( const IotDeQueue_t * const pQueue )\r
+/* @[declare_linear_containers_queue_count] */\r
+{\r
+    return IotListDouble_Count( pQueue );\r
+}\r
+\r
+/**\r
+ * @brief Check if a queue is empty.\r
+ *\r
+ * @param[in] pQueue The queue to check.\r
+ *\r
+ * @return `true` if the queue is empty; `false` otherwise.\r
+ *\r
+ */\r
+/* @[declare_linear_containers_queue_isempty] */\r
+static inline bool IotDeQueue_IsEmpty( const IotDeQueue_t * const pQueue )\r
+/* @[declare_linear_containers_queue_isempty] */\r
+{\r
+    return IotListDouble_IsEmpty( pQueue );\r
+}\r
+\r
+/**\r
+ * @brief Return an #IotLink_t representing the element at the front of the queue\r
+ * without removing it.\r
+ *\r
+ * @param[in] pQueue The queue to peek.\r
+ *\r
+ * @return Pointer to an #IotLink_t representing the element at the head of the\r
+ * queue; `NULL` if the queue is empty. The macro #IotLink_Container may be used\r
+ * to determine the address of the link's container.\r
+ */\r
+/* @[declare_linear_containers_queue_peekhead] */\r
+static inline IotLink_t * IotDeQueue_PeekHead( const IotDeQueue_t * const pQueue )\r
+/* @[declare_linear_containers_queue_peekhead] */\r
+{\r
+    return IotListDouble_PeekHead( pQueue );\r
+}\r
+\r
+/**\r
+ * @brief Return an #IotLink_t representing the element at the back of the queue\r
+ * without removing it.\r
+ *\r
+ * @param[in] pQueue The queue to peek.\r
+ *\r
+ * @return Pointer to an #IotLink_t representing the element at the head of the\r
+ * queue; `NULL` if the queue is empty. The macro #IotLink_Container may be used\r
+ * to determine the address of the link's container.\r
+ */\r
+/* @[declare_linear_containers_queue_peektail] */\r
+static inline IotLink_t * IotDeQueue_PeekTail( const IotDeQueue_t * const pQueue )\r
+/* @[declare_linear_containers_queue_peektail] */\r
+{\r
+    return IotListDouble_PeekTail( pQueue );\r
+}\r
+\r
+/**\r
+ * @brief Add an element at the head of the queue.\r
+ *\r
+ * @param[in] pQueue The queue that will hold the new element.\r
+ * @param[in] pLink Pointer to the new element's link member.\r
+ */\r
+/* @[declare_linear_containers_queue_enqueuehead] */\r
+static inline void IotDeQueue_EnqueueHead( IotDeQueue_t * const pQueue,\r
+                                     IotLink_t * const pLink )\r
+/* @[declare_linear_containers_queue_enqueuehead] */\r
+{\r
+    IotListDouble_InsertHead( pQueue, pLink );\r
+}\r
+\r
+/**\r
+ * @brief Remove an element at the head of the queue.\r
+ *\r
+ * @param[in] pQueue The queue that holds the element to remove.\r
+ *\r
+ * @return Pointer to an #IotLink_t representing the removed queue element; `NULL`\r
+ * if the queue is empty. The macro #IotLink_Container may be used to determine\r
+ * the address of the link's container.\r
+ */\r
+/* @[declare_linear_containers_queue_dequeuehead] */\r
+static inline IotLink_t * IotDeQueue_DequeueHead( IotDeQueue_t * const pQueue )\r
+/* @[declare_linear_containers_queue_dequeuehead] */\r
+{\r
+    return IotListDouble_RemoveHead( pQueue );\r
+}\r
+\r
+/**\r
+ * @brief Add an element at the tail of the queue.\r
+ *\r
+ * @param[in] pQueue The queue that will hold the new element.\r
+ * @param[in] pLink Pointer to the new element's link member.\r
+ */\r
+/* @[declare_linear_containers_queue_enqueuetail] */\r
+static inline void IotDeQueue_EnqueueTail( IotDeQueue_t * const pQueue,\r
+                                     IotLink_t * const pLink )\r
+/* @[declare_linear_containers_queue_enqueuetail] */\r
+{\r
+    IotListDouble_InsertTail( pQueue, pLink );\r
+}\r
+\r
+/**\r
+ * @brief Remove an element at the tail of the queue.\r
+ *\r
+ * @param[in] pQueue The queue that holds the element to remove.\r
+ *\r
+ * @return Pointer to an #IotLink_t representing the removed queue element; `NULL`\r
+ * if the queue is empty. The macro #IotLink_Container may be used to determine\r
+ * the address of the link's container.\r
+ */\r
+/* @[declare_linear_containers_queue_dequeuetail] */\r
+static inline IotLink_t * IotDeQueue_DequeueTail( IotDeQueue_t * const pQueue )\r
+/* @[declare_linear_containers_queue_dequeuetail] */\r
+{\r
+    return IotListDouble_RemoveTail( pQueue );\r
+}\r
+\r
+/**\r
+ * @brief Remove a single element from a queue.\r
+ *\r
+ * @param[in] pLink The element to remove.\r
+ */\r
+/* @[declare_linear_containers_queue_remove] */\r
+static inline void IotDeQueue_Remove( IotLink_t * const pLink )\r
+/* @[declare_linear_containers_queue_remove] */\r
+{\r
+    IotListDouble_Remove( pLink );\r
+}\r
+\r
+/**\r
+ * @brief Remove all elements in a queue.\r
+ *\r
+ * @param[in] pQueue The queue to empty.\r
+ * @param[in] freeElement A function to free memory used by each removed queue\r
+ * element. Optional; pass `NULL` to ignore.\r
+ * @param[in] linkOffset Offset in bytes of a link member in its container, used\r
+ * to calculate the pointer to pass to `freeElement`. This value should be calculated\r
+ * with the C `offsetof` macro. This parameter is ignored if `freeElement` is `NULL`\r
+ * or its value is `0`.\r
+ */\r
+/* @[declare_linear_containers_queue_removeall] */\r
+static inline void IotDeQueue_RemoveAll( IotDeQueue_t * const pQueue,\r
+                                       void ( * freeElement )( void * ),\r
+                                       size_t linkOffset )\r
+/* @[declare_linear_containers_queue_removeall] */\r
+{\r
+    IotListDouble_RemoveAll( pQueue, freeElement, linkOffset );\r
+}\r
+\r
+/**\r
+ * @brief Remove all matching elements from a queue.\r
+ *\r
+ * @param[in] pQueue The queue to search.\r
+ * @param[in] isMatch Function to determine if an element matches. Pass `NULL` to\r
+ * search using the address `pMatch`, i.e. `element == pMatch`.\r
+ * @param[in] pMatch If `isMatch` is `NULL`, each element in the queue is compared\r
+ * to this address to find a match. Otherwise, it is passed as the second argument\r
+ * to `isMatch`.\r
+ * @param[in] freeElement A function to free memory used by each removed queue\r
+ * element. Optional; pass `NULL` to ignore.\r
+ * @param[in] linkOffset Offset in bytes of a link member in its container, used\r
+ * to calculate the pointer to pass to `freeElement`. This value should be calculated\r
+ * with the C `offsetof` macro. This parameter is ignored if `freeElement` is `NULL`\r
+ * or its value is `0`.\r
+ */\r
+/* @[declare_linear_containers_queue_removeallmatches] */\r
+static inline void IotDeQueue_RemoveAllMatches( IotDeQueue_t * const pQueue,\r
+                                              bool ( * isMatch )( const IotLink_t *, void * ),\r
+                                              void * pMatch,\r
+                                              void ( * freeElement )( void * ),\r
+                                              size_t linkOffset )\r
+/* @[declare_linear_containers_queue_removeallmatches] */\r
+{\r
+    IotListDouble_RemoveAllMatches( pQueue, isMatch, pMatch, freeElement, linkOffset );\r
+}\r
+\r
+#endif /* IOT_LINEAR_CONTAINERS_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_logging_setup.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_logging_setup.h
new file mode 100644 (file)
index 0000000..ec3d6d1
--- /dev/null
@@ -0,0 +1,223 @@
+/*\r
+ * Amazon FreeRTOS Common V1.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_logging_setup.h\r
+ * @brief Defines the logging macro #IotLog.\r
+ */\r
+\r
+#ifndef IOT_LOGGING_SETUP_H_\r
+#define IOT_LOGGING_SETUP_H_\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/* Logging include. Because it's included here, iot_logging.h never needs\r
+ * to be included in source. */\r
+#include "private/iot_logging.h"\r
+\r
+/**\r
+ * @functionpage{IotLog,logging,log}\r
+ * @functionpage{IotLog_PrintBuffer,logging,printbuffer}\r
+ */\r
+\r
+/**\r
+ * @def IotLog( messageLevel, pLogConfig, ... )\r
+ * @brief Logging function for a specific library. In most cases, this is the\r
+ * logging function to call.\r
+ *\r
+ * This function prints a single log message. It is available when @ref\r
+ * LIBRARY_LOG_LEVEL is not #IOT_LOG_NONE. Log messages automatically\r
+ * include the [log level](@ref logging_constants_levels), [library name]\r
+ * (@ref LIBRARY_LOG_NAME), and time. An optional @ref IotLogConfig_t may\r
+ * be passed to this function to hide information for a single log message.\r
+ *\r
+ * The logging library must be set up before this function may be called. See\r
+ * @ref logging_setup_use for more information.\r
+ *\r
+ * This logging function also has the following abbreviated forms that can be used\r
+ * when an #IotLogConfig_t isn't needed.\r
+ *\r
+ * Name         | Equivalent to\r
+ * ----         | -------------\r
+ * #IotLogError | @code{c} IotLog( IOT_LOG_ERROR, NULL, ... ) @endcode\r
+ * #IotLogWarn  | @code{c} IotLog( IOT_LOG_WARN, NULL, ... ) @endcode\r
+ * #IotLogInfo  | @code{c} IotLog( IOT_LOG_INFO, NULL, ... ) @endcode\r
+ * #IotLogDebug | @code{c} IotLog( IOT_LOG_DEBUG, NULL, ... ) @endcode\r
+ *\r
+ * @param[in] messageLevel Log level of this message. Must be one of the\r
+ * @ref logging_constants_levels.\r
+ * @param[in] pLogConfig Pointer to an #IotLogConfig_t. Optional; pass `NULL`\r
+ * to ignore.\r
+ * @param[in] ... Message and format specification.\r
+ *\r
+ * @return No return value. On errors, it prints nothing.\r
+ *\r
+ * @note This function may be implemented as a macro.\r
+ * @see @ref logging_function_generic for the generic (not library-specific)\r
+ * logging function.\r
+ */\r
+\r
+/**\r
+ * @def IotLog_PrintBuffer( pHeader, pBuffer, bufferSize )\r
+ * @brief Log the contents of buffer as bytes. Only available when @ref\r
+ * LIBRARY_LOG_LEVEL is #IOT_LOG_DEBUG.\r
+ *\r
+ * This function prints the bytes located at a given memory address. It is\r
+ * intended for debugging only, and is therefore only available when @ref\r
+ * LIBRARY_LOG_LEVEL is #IOT_LOG_DEBUG.\r
+ *\r
+ * Log messages printed by this function <b>always</b> include the [log level]\r
+ * (@ref logging_constants_levels), [library name](@ref LIBRARY_LOG_NAME),\r
+ * and time.  In addition, this function may print an optional header `pHeader`\r
+ * before it prints the contents of the buffer. This function does not have an\r
+ * #IotLogConfig_t parameter.\r
+ *\r
+ * The logging library must be set up before this function may be called. See\r
+ * @ref logging_setup_use for more information.\r
+ *\r
+ * @param[in] pHeader A message to log before the buffer. Optional; pass `NULL`\r
+ * to ignore.\r
+ * @param[in] pBuffer Pointer to start of buffer.\r
+ * @param[in] bufferSize Size of `pBuffer`.\r
+ *\r
+ * @return No return value. On errors, it prints nothing.\r
+ *\r
+ * @note This function may be implemented as a macro.\r
+ * @note To conserve memory, @ref logging_function_genericprintbuffer (the underlying\r
+ * implementation) only allocates enough memory for a single line of output. Therefore,\r
+ * in multithreaded systems, its output may appear "fragmented" if other threads are\r
+ * logging simultaneously.\r
+ * @see @ref logging_function_genericprintbuffer for the generic (not library-specific)\r
+ * buffer logging function.\r
+ *\r
+ * <b>Example</b>\r
+ * @code{c}\r
+ * const uint8_t pBuffer[] = { 0x00, 0x01, 0x02, 0x03 };\r
+ *\r
+ * IotLog_PrintBuffer( "This buffer contains:",\r
+ *                     pBuffer,\r
+ *                     4 );\r
+ * @endcode\r
+ * The code above prints something like the following:\r
+ * @code{c}\r
+ * [DEBUG][LIB_NAME][2018-01-01 12:00:00] This buffer contains:\r
+ * 00 01 02 03\r
+ * @endcode\r
+ */\r
+\r
+/**\r
+ * @def IotLogError( ...  )\r
+ * @brief Abbreviated logging macro for level #IOT_LOG_ERROR.\r
+ *\r
+ * Equivalent to:\r
+ * @code{c}\r
+ * IotLog( IOT_LOG_ERROR, NULL, ... )\r
+ * @endcode\r
+ */\r
+\r
+/**\r
+ * @def IotLogWarn( ...  )\r
+ * @brief Abbreviated logging macro for level #IOT_LOG_WARN.\r
+ *\r
+ * Equivalent to:\r
+ * @code{c}\r
+ * IotLog( IOT_LOG_WARN, NULL, ... )\r
+ * @endcode\r
+ */\r
+\r
+/**\r
+ * @def IotLogInfo( ...  )\r
+ * @brief Abbreviated logging macro for level #IOT_LOG_INFO.\r
+ *\r
+ * Equivalent to:\r
+ * @code{c}\r
+ * IotLog( IOT_LOG_INFO, NULL, ... )\r
+ * @endcode\r
+ */\r
+\r
+/**\r
+ * @def IotLogDebug( ...  )\r
+ * @brief Abbreviated logging macro for level #IOT_LOG_DEBUG.\r
+ *\r
+ * Equivalent to:\r
+ * @code{c}\r
+ * IotLog( IOT_LOG_DEBUG, NULL, ... )\r
+ * @endcode\r
+ */\r
+\r
+/* Check that LIBRARY_LOG_LEVEL is defined and has a valid value. */\r
+#if !defined( LIBRARY_LOG_LEVEL ) ||            \\r
+    ( LIBRARY_LOG_LEVEL != IOT_LOG_NONE &&  \\r
+      LIBRARY_LOG_LEVEL != IOT_LOG_ERROR && \\r
+      LIBRARY_LOG_LEVEL != IOT_LOG_WARN &&  \\r
+      LIBRARY_LOG_LEVEL != IOT_LOG_INFO &&  \\r
+      LIBRARY_LOG_LEVEL != IOT_LOG_DEBUG )\r
+    #error "Please define LIBRARY_LOG_LEVEL as either IOT_LOG_NONE, IOT_LOG_ERROR, IOT_LOG_WARN, IOT_LOG_INFO, or IOT_LOG_DEBUG."\r
+/* Check that LIBRARY_LOG_NAME is defined and has a valid value. */\r
+#elif !defined( LIBRARY_LOG_NAME )\r
+    #error "Please define LIBRARY_LOG_NAME."\r
+#else\r
+    /* Define IotLog if the log level is greater than "none". */\r
+    #if LIBRARY_LOG_LEVEL > IOT_LOG_NONE\r
+        #define IotLog( messageLevel, pLogConfig, ... )   \\r
+                IotLog_Generic( LIBRARY_LOG_LEVEL,        \\r
+                                LIBRARY_LOG_NAME,        \\r
+                                messageLevel,             \\r
+                                pLogConfig,               \\r
+                                __VA_ARGS__ )\r
+\r
+        /* Define the abbreviated logging macros. */\r
+        #define IotLogError( ...  )    IotLog( IOT_LOG_ERROR, NULL, __VA_ARGS__ )\r
+        #define IotLogWarn( ... )      IotLog( IOT_LOG_WARN, NULL, __VA_ARGS__ )\r
+        #define IotLogInfo( ... )      IotLog( IOT_LOG_INFO, NULL, __VA_ARGS__ )\r
+        #define IotLogDebug( ... )     IotLog( IOT_LOG_DEBUG, NULL, __VA_ARGS__ )\r
+\r
+        /* If log level is DEBUG, enable the function to print buffers. */\r
+        #if LIBRARY_LOG_LEVEL >= IOT_LOG_DEBUG\r
+        #define IotLog_PrintBuffer( pHeader, pBuffer, bufferSize )    \\r
+                IotLog_GenericPrintBuffer( LIBRARY_LOG_NAME,         \\r
+                                           pHeader,                   \\r
+                                           pBuffer,                   \\r
+                                           bufferSize )\r
+        #else\r
+        #define IotLog_PrintBuffer( pHeader, pBuffer, bufferSize )\r
+        #endif\r
+    /* Remove references to IotLog from the source code if logging is disabled. */\r
+    #else\r
+        /* @[declare_logging_log] */\r
+        #define IotLog( messageLevel, pLogConfig, ... )\r
+        /* @[declare_logging_log] */\r
+        /* @[declare_logging_printbuffer] */\r
+        #define IotLog_PrintBuffer( pHeader, pBuffer, bufferSize )\r
+        /* @[declare_logging_printbuffer] */\r
+        #define IotLogError( ...  )\r
+        #define IotLogWarn( ... )\r
+        #define IotLogInfo( ... )\r
+        #define IotLogDebug( ... )\r
+    #endif\r
+#endif\r
+\r
+#endif /* ifndef IOT_LOGGING_SETUP_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_taskpool.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_taskpool.h
new file mode 100644 (file)
index 0000000..a91ccf1
--- /dev/null
@@ -0,0 +1,558 @@
+/*\r
+ * Amazon FreeRTOS Common V1.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_taskpool.h\r
+ * @brief User-facing functions of the task pool library.\r
+ */\r
+\r
+#ifndef IOT_TASKPOOL_H_\r
+#define IOT_TASKPOOL_H_\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/* Standard includes. */\r
+#include <stdbool.h>\r
+#include <stdint.h>\r
+#include <stddef.h>\r
+\r
+/* Task pool types. */\r
+#include "types/iot_taskpool_types.h"\r
+\r
+/*------------------------- Task Pool library functions --------------------------*/\r
+\r
+/**\r
+ * @functionspage{taskpool,task pool library}\r
+ * - @functionname{taskpool_function_createsystemtaskpool}\r
+ * - @functionname{taskpool_function_getsystemtaskpool}\r
+ * - @functionname{taskpool_function_create}\r
+ * - @functionname{taskpool_function_destroy}\r
+ * - @functionname{taskpool_function_setmaxthreads}\r
+ * - @functionname{taskpool_function_createjob}\r
+ * - @functionname{taskpool_function_createrecyclablejob}\r
+ * - @functionname{taskpool_function_destroyrecyclablejob}\r
+ * - @functionname{taskpool_function_recyclejob}\r
+ * - @functionname{taskpool_function_schedule}\r
+ * - @functionname{taskpool_function_scheduledeferred}\r
+ * - @functionname{taskpool_function_getstatus}\r
+ * - @functionname{taskpool_function_trycancel}\r
+ * - @functionname{taskpool_function_getjobstoragefromhandle}\r
+ * - @functionname{taskpool_function_strerror}\r
+ */\r
+\r
+/**\r
+ * @functionpage{IotTaskPool_CreateSystemTaskPool,taskpool,createsystemtaskpool}\r
+ * @functionpage{IotTaskPool_GetSystemTaskPool,taskpool,getsystemtaskpool}\r
+ * @functionpage{IotTaskPool_Create,taskpool,create}\r
+ * @functionpage{IotTaskPool_Destroy,taskpool,destroy}\r
+ * @functionpage{IotTaskPool_SetMaxThreads,taskpool,setmaxthreads}\r
+ * @functionpage{IotTaskPool_CreateJob,taskpool,createjob}\r
+ * @functionpage{IotTaskPool_CreateRecyclableJob,taskpool,createrecyclablejob}\r
+ * @functionpage{IotTaskPool_DestroyRecyclableJob,taskpool,destroyrecyclablejob}\r
+ * @functionpage{IotTaskPool_RecycleJob,taskpool,recyclejob}\r
+ * @functionpage{IotTaskPool_Schedule,taskpool,schedule}\r
+ * @functionpage{IotTaskPool_ScheduleDeferred,taskpool,scheduledeferred}\r
+ * @functionpage{IotTaskPool_GetStatus,taskpool,getstatus}\r
+ * @functionpage{IotTaskPool_TryCancel,taskpool,trycancel}\r
+ * @functionpage{IotTaskPool_GetJobStorageFromHandle,taskpool,getjobstoragefromhandle}\r
+ * @functionpage{IotTaskPool_strerror,taskpool,strerror}\r
+ */\r
+\r
+/**\r
+ * @brief Creates the one single instance of the system task pool.\r
+ *\r
+ * This function should be called once by the application to initialize the one single instance of the system task pool.\r
+ * An application should initialize the system task pool early in the boot sequence, before initializing any other library\r
+ * and before posting any jobs. Early initialization it typically easy to accomplish by creating the system task pool\r
+ * before starting the scheduler.\r
+ *\r
+ * This function does not allocate memory to hold the task pool data structures and state, but it\r
+ * may allocate memory to hold the dependent entities and data structures, e.g. the threads of the task\r
+ * pool. The system task pool handle is recoverable for later use by calling @ref IotTaskPool_GetSystemTaskPool or\r
+ * the shortcut @ref IOT_SYSTEM_TASKPOOL.\r
+ *\r
+ * @param[in] pInfo A pointer to the task pool initialization data.\r
+ *\r
+ * @return One of the following:\r
+ * - #IOT_TASKPOOL_SUCCESS\r
+ * - #IOT_TASKPOOL_BAD_PARAMETER\r
+ * - #IOT_TASKPOOL_NO_MEMORY\r
+ *\r
+ * @warning This function should be called only once. Calling this function more that once will result in\r
+ * undefined behavior.\r
+ *\r
+ */\r
+/* @[declare_taskpool_createsystemtaskpool] */\r
+IotTaskPoolError_t IotTaskPool_CreateSystemTaskPool( const IotTaskPoolInfo_t * const pInfo );\r
+/* @[declare_taskpool_createsystemtaskpool] */\r
+\r
+/**\r
+ * @brief Retrieves the one and only instance of a system task pool\r
+ *\r
+ * This function retrieves the system task pool created with @ref IotTaskPool_CreateSystemTaskPool, and it is functionally\r
+ * equivalent to using the shortcut @ref IOT_SYSTEM_TASKPOOL.\r
+ *\r
+ * @return The system task pool handle.\r
+ *\r
+ * @warning This function should be called after creating the system task pool with @ref IotTaskPool_CreateSystemTaskPool.\r
+ * Calling this function before creating the system task pool may return a pointer to an uninitialized task pool, NULL, or otherwise\r
+ * fail with undefined behaviour.\r
+ *\r
+ */\r
+/* @[declare_taskpool_getsystemtaskpool] */\r
+IotTaskPool_t IotTaskPool_GetSystemTaskPool( void );\r
+/* @[declare_taskpool_getsystemtaskpool] */\r
+\r
+/**\r
+ * @brief Creates one instance of a task pool.\r
+ *\r
+ * This function should be called by the user to initialize one instance of a task\r
+ * pool. The task pool instance will be created around the storage pointed to by the `pTaskPool`\r
+ * parameter. This function will create the minimum number of threads requested by the user\r
+ * through an instance of the #IotTaskPoolInfo_t type specified with the `pInfo` parameter.\r
+ * This function does not allocate memory to hold the task pool data structures and state, but it\r
+ * may allocates memory to hold the dependent data structures, e.g. the threads of the task\r
+ * pool.\r
+ *\r
+ * @param[in] pInfo A pointer to the task pool initialization data.\r
+ * @param[out] pTaskPool A pointer to the task pool handle to be used after initialization.\r
+ * The pointer `pTaskPool` will hold a valid handle only if (@ref IotTaskPool_Create)\r
+ * completes successfully.\r
+ *\r
+ * @return One of the following:\r
+ * - #IOT_TASKPOOL_SUCCESS\r
+ * - #IOT_TASKPOOL_BAD_PARAMETER\r
+ * - #IOT_TASKPOOL_NO_MEMORY\r
+ *\r
+ */\r
+/* @[declare_taskpool_create] */\r
+IotTaskPoolError_t IotTaskPool_Create( const IotTaskPoolInfo_t * const pInfo,\r
+                                       IotTaskPool_t * const pTaskPool );\r
+/* @[declare_taskpool_create] */\r
+\r
+/**\r
+ * @brief Destroys a task pool instance and collects all memory associated with a task pool and its\r
+ * satellite data structures.\r
+ *\r
+ * This function should be called to destroy one instance of a task pool previously created with a call\r
+ * to @ref IotTaskPool_Create or @ref IotTaskPool_CreateSystemTaskPool.\r
+ * Calling this fuction release all underlying resources. After calling this function, any job scheduled but not yet executed\r
+ * will be canceled and destroyed.\r
+ * The `taskPool` instance will no longer be valid after this function returns.\r
+ *\r
+ * @param[in] taskPool A handle to the task pool, e.g. as returned by a call to @ref IotTaskPool_Create or\r
+ * @ref IotTaskPool_CreateSystemTaskPool. The `taskPool` instance will no longer be valid after this function returns.\r
+ *\r
+ * @return One of the following:\r
+ * - #IOT_TASKPOOL_SUCCESS\r
+ * - #IOT_TASKPOOL_BAD_PARAMETER\r
+ *\r
+ */\r
+/* @[declare_taskpool_destroy] */\r
+IotTaskPoolError_t IotTaskPool_Destroy( IotTaskPool_t taskPool );\r
+/* @[declare_taskpool_destroy] */\r
+\r
+/**\r
+ * @brief Sets the maximum number of threads for one instance of a task pool.\r
+ *\r
+ * This function sets the maximum number of threads for the task pool\r
+ * pointed to by `taskPool`.\r
+ *\r
+ * If the number of currently active threads in the task pool is greater than `maxThreads`, this\r
+ * function causes the task pool to shrink the number of active threads.\r
+ *\r
+ * @param[in] taskPool A handle to the task pool that must have been previously initialized with\r
+ * a call to @ref IotTaskPool_Create or @ref IotTaskPool_CreateSystemTaskPool.\r
+ * @param[in] maxThreads The maximum number of threads for the task pool.\r
+ *\r
+ * @return One of the following:\r
+ * - #IOT_TASKPOOL_SUCCESS\r
+ * - #IOT_TASKPOOL_BAD_PARAMETER\r
+ * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS\r
+ *\r
+ */\r
+/* @[declare_taskpool_setmaxthreads] */\r
+IotTaskPoolError_t IotTaskPool_SetMaxThreads( IotTaskPool_t taskPool,\r
+                                              uint32_t maxThreads );\r
+/* @[declare_taskpool_setmaxthreads] */\r
+\r
+/**\r
+ * @brief Creates a job for the task pool around a user-provided storage.\r
+ *\r
+ * This function may allocate memory to hold the state for a job.\r
+ *\r
+ * @param[in] userCallback A user-specified callback for the job.\r
+ * @param[in] pUserContext A user-specified context for the callback.\r
+ * @param[in] pJobStorage The storage for the job data structure.\r
+ * @param[out] pJob A pointer to an instance of @ref IotTaskPoolJob_t that will be initialized when this\r
+ * function returns successfully. This handle can be used to inspect the job status with\r
+ * @ref IotTaskPool_GetStatus or cancel the job with @ref IotTaskPool_TryCancel, etc....\r
+ *\r
+ * @return One of the following:\r
+ * - #IOT_TASKPOOL_SUCCESS\r
+ * - #IOT_TASKPOOL_BAD_PARAMETER\r
+ *\r
+ *\r
+ */\r
+/* @[declare_taskpool_createjob] */\r
+IotTaskPoolError_t IotTaskPool_CreateJob( IotTaskPoolRoutine_t userCallback,\r
+                                          void * pUserContext,\r
+                                          IotTaskPoolJobStorage_t * const pJobStorage,\r
+                                          IotTaskPoolJob_t * const pJob );\r
+/* @[declare_taskpool_createjob] */\r
+\r
+/**\r
+ * brief Creates a job for the task pool by allocating the job dynamically.\r
+ *\r
+ * A recyclable job does not need to be allocated twice, but it can rather be reused through\r
+ * subsequent calls to @ref IotTaskPool_CreateRecyclableJob.\r
+ *\r
+ * @param[in] taskPool A handle to the task pool for which to create a recyclable job.\r
+ * @param[in] userCallback A user-specified callback for the job.\r
+ * @param[in] pUserContext A user-specified context for the callback.\r
+ * @param[out] pJob A pointer to an instance of @ref IotTaskPoolJob_t that will be initialized when this\r
+ * function returns successfully. This handle can be used to inspect the job status with\r
+ * @ref IotTaskPool_GetStatus or cancel the job with @ref IotTaskPool_TryCancel, etc....\r
+ *\r
+ * @return One of the following:\r
+ * - #IOT_TASKPOOL_SUCCESS\r
+ * - #IOT_TASKPOOL_BAD_PARAMETER\r
+ * - #IOT_TASKPOOL_NO_MEMORY\r
+ * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS\r
+ *\r
+ * @note This function will not allocate memory. //_RB_ Incorrect comment.\r
+ *\r
+ * @warning A recyclable job should be recycled with a call to @ref IotTaskPool_RecycleJob rather than destroyed.\r
+ *\r
+ */\r
+/* @[declare_taskpool_createrecyclablejob] */\r
+IotTaskPoolError_t IotTaskPool_CreateRecyclableJob( IotTaskPool_t taskPool,\r
+                                                    IotTaskPoolRoutine_t userCallback,\r
+                                                    void * pUserContext,\r
+                                                    IotTaskPoolJob_t * const pJob );\r
+/* @[declare_taskpool_createrecyclablejob] */\r
+\r
+/**\r
+ * @brief This function un-initializes a job.\r
+ *\r
+ * This function will destroy a job created with @ref IotTaskPool_CreateRecyclableJob.\r
+ * A job should not be destroyed twice. A job that was previously scheduled but has not completed yet should not be destroyed,\r
+ * but rather the application should attempt to cancel it first by calling @ref IotTaskPool_TryCancel.\r
+ * An attempt to destroy a job that was scheduled but not yet executed or canceled, may result in a\r
+ * @ref IOT_TASKPOOL_ILLEGAL_OPERATION error.\r
+ *\r
+ * @param[in] taskPool A handle to the task pool, e.g. as returned by a call to @ref IotTaskPool_Create or @ref IotTaskPool_CreateSystemTaskPool.\r
+ * @param[in] job A handle to a job that was create with a call to @ref IotTaskPool_CreateJob.\r
+ *\r
+ * @return One of the following:\r
+ * - #IOT_TASKPOOL_SUCCESS\r
+ * - #IOT_TASKPOOL_BAD_PARAMETER\r
+ * - #IOT_TASKPOOL_ILLEGAL_OPERATION\r
+ * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS\r
+ *\r
+ * @warning The task pool will try and prevent destroying jobs that are currently queued for execution, but does\r
+ * not enforce strict ordering of operations. It is up to the user to make sure @ref IotTaskPool_DestroyRecyclableJob is not called\r
+ * our of order.\r
+ *\r
+ * @warning Calling this function on job that was not previously created with @ref IotTaskPool_CreateRecyclableJob\r
+ * will result in a @ref IOT_TASKPOOL_ILLEGAL_OPERATION error.\r
+ *\r
+ */\r
+/* @[declare_taskpool_destroyrecyclablejob] */\r
+IotTaskPoolError_t IotTaskPool_DestroyRecyclableJob( IotTaskPool_t taskPool,\r
+                                                     IotTaskPoolJob_t job );\r
+/* @[declare_taskpool_destroyrecyclablejob] */\r
+\r
+/**\r
+ * @brief Recycles a job into the task pool job cache.\r
+ *\r
+ * This function will try and recycle the job into the task pool cache. If the cache is full,\r
+ * the job memory is destroyed as if the user called @ref IotTaskPool_DestroyRecyclableJob. The job should be recycled into\r
+ * the task pool instance from where it was allocated.\r
+ * Failure to do so will yield undefined results. A job should not be recycled twice. A job\r
+ * that was previously scheduled but not completed or canceled cannot be safely recycled. An attempt to do so will result\r
+ * in an @ref IOT_TASKPOOL_ILLEGAL_OPERATION error.\r
+ *\r
+ * @param[in] taskPool A handle to the task pool, e.g. as returned by a call to @ref IotTaskPool_Create.\r
+ * @param[out] job A pointer to a job that was create with a call to @ref IotTaskPool_CreateJob.\r
+ *\r
+ * @return One of the following:\r
+ * - #IOT_TASKPOOL_SUCCESS\r
+ * - #IOT_TASKPOOL_BAD_PARAMETER\r
+ * - #IOT_TASKPOOL_ILLEGAL_OPERATION\r
+ * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS\r
+ *\r
+ * @warning The `taskPool` used in this function should be the same\r
+ * used to create the job pointed to by `job`, or the results will be undefined.\r
+ *\r
+ * @warning Attempting to call this function on a statically allocated job will result in @ref IOT_TASKPOOL_ILLEGAL_OPERATION\r
+ * error.\r
+ *\r
+ * @warning This function should be used to recycle a job in the task pool cache when after the job executed.\r
+ * Failing to call either this function or @ref IotTaskPool_DestroyRecyclableJob will result is a memory leak. Statically\r
+ * allocated jobs do not need to be recycled or destroyed.\r
+ *\r
+ */\r
+/* @[declare_taskpool_recyclejob] */\r
+IotTaskPoolError_t IotTaskPool_RecycleJob( IotTaskPool_t taskPool,\r
+                                           IotTaskPoolJob_t job );\r
+/* @[declare_taskpool_recyclejob] */\r
+\r
+/**\r
+ * @brief This function schedules a job created with @ref IotTaskPool_CreateJob or @ref IotTaskPool_CreateRecyclableJob\r
+ * against the task pool pointed to by `taskPool`.\r
+ *\r
+ * See @ref taskpool_design for a description of the jobs lifetime and interaction with the threads used in the task pool\r
+ * library.\r
+ *\r
+ * @param[in] taskPool A handle to the task pool that must have been previously initialized with.\r
+ * a call to @ref IotTaskPool_Create.\r
+ * @param[in] job A job to schedule for execution. This must be first initialized with a call to @ref IotTaskPool_CreateJob.\r
+ * @param[in] flags Flags to be passed by the user, e.g. to identify the job as high priority by specifying #IOT_TASKPOOL_JOB_HIGH_PRIORITY.\r
+ *\r
+ * @return One of the following:\r
+ * - #IOT_TASKPOOL_SUCCESS\r
+ * - #IOT_TASKPOOL_BAD_PARAMETER\r
+ * - #IOT_TASKPOOL_ILLEGAL_OPERATION\r
+ * - #IOT_TASKPOOL_NO_MEMORY\r
+ * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS\r
+ *\r
+ *\r
+ * @note This function will not allocate memory, so it is guaranteed to succeed if the paramters are correct and the task pool\r
+ * was correctly initialized, and not yet destroyed.\r
+ *\r
+ * @warning The `taskPool` used in this function should be the same used to create the job pointed to by `job`, or the\r
+ * results will be undefined.\r
+ *\r
+ * <b>Example</b>\r
+ * @code{c}\r
+ * // An example of a user context to pass to a callback through a task pool thread.\r
+ * typedef struct JobUserContext\r
+ * {\r
+ *     uint32_t counter;\r
+ * } JobUserContext_t;\r
+ *\r
+ * // An example of a user callback to invoke through a task pool thread.\r
+ * static void ExecutionCb( IotTaskPool_t taskPool, IotTaskPoolJob_t job, void * context )\r
+ * {\r
+ *     ( void )taskPool;\r
+ *     ( void )job;\r
+ *\r
+ *     JobUserContext_t * pUserContext = ( JobUserContext_t * )context;\r
+ *\r
+ *     pUserContext->counter++;\r
+ * }\r
+ *\r
+ * void TaskPoolExample( )\r
+ * {\r
+ *     JobUserContext_t userContext = { 0 };\r
+ *     IotTaskPoolJob_t job;\r
+ *     IotTaskPool_t taskPool;\r
+ *\r
+ *     // Configure the task pool to hold at least two threads and three at the maximum.\r
+ *     // Provide proper stack size and priority per the application needs.\r
+ *\r
+ *     const IotTaskPoolInfo_t tpInfo = { .minThreads = 2, .maxThreads = 3, .stackSize = 512, .priority = 0 };\r
+ *\r
+ *     // Create a task pool.\r
+ *     IotTaskPool_Create( &tpInfo, &taskPool );\r
+ *\r
+ *     // Statically allocate one job, schedule it.\r
+ *     IotTaskPool_CreateJob( &ExecutionCb, &userContext, &job );\r
+ *\r
+ *     IotTaskPoolError_t errorSchedule = IotTaskPool_Schedule( taskPool, &job, 0 );\r
+ *\r
+ *     switch ( errorSchedule )\r
+ *     {\r
+ *     case IOT_TASKPOOL_SUCCESS:\r
+ *         break;\r
+ *     case IOT_TASKPOOL_BAD_PARAMETER:          // Invalid parameters, such as a NULL handle, can trigger this error.\r
+ *     case IOT_TASKPOOL_ILLEGAL_OPERATION:      // Scheduling a job that was previously scheduled or destroyed could trigger this error.\r
+ *     case IOT_TASKPOOL_NO_MEMORY:              // Scheduling a with flag #IOT_TASKPOOL_JOB_HIGH_PRIORITY could trigger this error.\r
+ *     case IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS:   // Scheduling a job after trying to destroy the task pool could trigger this error.\r
+ *         // ASSERT\r
+ *         break;\r
+ *     default:\r
+ *         // ASSERT\r
+ *     }\r
+ *\r
+ *     //\r
+ *     // ... Perform other operations ...\r
+ *     //\r
+ *\r
+ *     IotTaskPool_Destroy( taskPool );\r
+ * }\r
+ * @endcode\r
+ */\r
+/* @[declare_taskpool_schedule] */\r
+IotTaskPoolError_t IotTaskPool_Schedule( IotTaskPool_t taskPool,\r
+                                         IotTaskPoolJob_t job,\r
+                                         uint32_t flags );\r
+/* @[declare_taskpool_schedule] */\r
+\r
+/**\r
+ * @brief This function schedules a job created with @ref IotTaskPool_CreateJob against the task pool\r
+ * pointed to by `taskPool` to be executed after a user-defined time interval.\r
+ *\r
+ * See @ref taskpool_design for a description of the jobs lifetime and interaction with the threads used in the task pool\r
+ * library.\r
+ *\r
+ * @param[in] taskPool A handle to the task pool that must have been previously initialized with.\r
+ * a call to @ref IotTaskPool_Create.\r
+ * @param[in] job A job to schedule for execution. This must be first initialized with a call to @ref IotTaskPool_CreateJob.\r
+ * @param[in] timeMs The time in milliseconds to wait before scheduling the job.\r
+ *\r
+ * @return One of the following:\r
+ * - #IOT_TASKPOOL_SUCCESS\r
+ * - #IOT_TASKPOOL_BAD_PARAMETER\r
+ * - #IOT_TASKPOOL_ILLEGAL_OPERATION\r
+ * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS\r
+ *\r
+ *\r
+ * @note This function will not allocate memory.\r
+ *\r
+ * @warning The `taskPool` used in this function should be the same\r
+ * used to create the job pointed to by `job`, or the results will be undefined.\r
+ *\r
+ */\r
+/* @[declare_taskpool_scheduledeferred] */\r
+IotTaskPoolError_t IotTaskPool_ScheduleDeferred( IotTaskPool_t taskPool,\r
+                                                 IotTaskPoolJob_t job,\r
+                                                 uint32_t timeMs );\r
+/* @[declare_taskpool_scheduledeferred] */\r
+\r
+/**\r
+ * @brief This function retrieves the current status of a job.\r
+ *\r
+ * @param[in] taskPool A handle to the task pool that must have been previously initialized with\r
+ * a call to @ref IotTaskPool_Create or @ref IotTaskPool_CreateSystemTaskPool.\r
+ * @param[in] job The job to cancel.\r
+ * @param[out] pStatus The status of the job at the time of cancellation.\r
+ *\r
+ * @return One of the following:\r
+ * - #IOT_TASKPOOL_SUCCESS\r
+ * - #IOT_TASKPOOL_BAD_PARAMETER\r
+ * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS\r
+ *\r
+ * @warning This function is not thread safe and the job status returned in `pStatus` may be invalid by the time\r
+ * the calling thread has a chance to inspect it.\r
+ */\r
+/* @[declare_taskpool_getstatus] */\r
+IotTaskPoolError_t IotTaskPool_GetStatus( IotTaskPool_t taskPool,\r
+                                          IotTaskPoolJob_t job,\r
+                                          IotTaskPoolJobStatus_t * const pStatus );\r
+/* @[declare_taskpool_getstatus] */\r
+\r
+/**\r
+ * @brief This function tries to cancel a job that was previously scheduled with @ref IotTaskPool_Schedule.\r
+ *\r
+ * A job can be canceled only if it is not yet executing, i.e. if its status is\r
+ * @ref IOT_TASKPOOL_STATUS_READY or @ref IOT_TASKPOOL_STATUS_SCHEDULED. Calling\r
+ * @ref IotTaskPool_TryCancel on a job whose status is @ref IOT_TASKPOOL_STATUS_COMPLETED,\r
+ * or #IOT_TASKPOOL_STATUS_CANCELED will yield a #IOT_TASKPOOL_CANCEL_FAILED return result.\r
+ *\r
+ * @param[in] taskPool A handle to the task pool that must have been previously initialized with\r
+ * a call to @ref IotTaskPool_Create.\r
+ * @param[in] job The job to cancel.\r
+ * @param[out] pStatus The status of the job at the time of cancellation.\r
+ *\r
+ * @return One of the following:\r
+ * - #IOT_TASKPOOL_SUCCESS\r
+ * - #IOT_TASKPOOL_BAD_PARAMETER\r
+ * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS\r
+ * - #IOT_TASKPOOL_CANCEL_FAILED\r
+ *\r
+ * @warning The `taskPool` used in this function should be the same\r
+ * used to create the job pointed to by `job`, or the results will be undefined.\r
+ *\r
+ */\r
+/* @[declare_taskpool_trycancel] */\r
+IotTaskPoolError_t IotTaskPool_TryCancel( IotTaskPool_t taskPool,\r
+                                          IotTaskPoolJob_t job,\r
+                                          IotTaskPoolJobStatus_t * const pStatus );\r
+/* @[declare_taskpool_trycancel] */\r
+\r
+/**\r
+ * @brief Returns a pointer to the job storage from an instance of a job handle\r
+ * of type @ref IotTaskPoolJob_t. This function is guaranteed to succeed for a\r
+ * valid job handle.\r
+ *\r
+ * @param[in] job The job handle.\r
+ *\r
+ * @return A pointer to the storage associated with the job handle `job`.\r
+ *\r
+ * @warning If the `job` handle used is invalid, the results will be undefined.\r
+ */\r
+/* @[declare_taskpool_getjobstoragefromhandle] */\r
+IotTaskPoolJobStorage_t * IotTaskPool_GetJobStorageFromHandle( IotTaskPoolJob_t job );\r
+/* @[declare_taskpool_getjobstoragefromhandle] */\r
+\r
+/**\r
+ * @brief Returns a string that describes an @ref IotTaskPoolError_t.\r
+ *\r
+ * Like the POSIX's `strerror`, this function returns a string describing a\r
+ * return code. In this case, the return code is a task pool library error code,\r
+ * `status`.\r
+ *\r
+ * The string returned by this function <b>MUST</b> be treated as read-only: any\r
+ * attempt to modify its contents may result in a crash. Therefore, this function\r
+ * is limited to usage in logging.\r
+ *\r
+ * @param[in] status The status to describe.\r
+ *\r
+ * @return A read-only string that describes `status`.\r
+ *\r
+ * @warning The string returned by this function must never be modified.\r
+ */\r
+/* @[declare_taskpool_strerror] */\r
+const char * IotTaskPool_strerror( IotTaskPoolError_t status );\r
+/* @[declare_taskpool_strerror] */\r
+\r
+/**\r
+ * @brief The maximum number of task pools to be created when using\r
+ * a memory pool.\r
+ */\r
+#ifndef IOT_TASKPOOLS\r
+#define IOT_TASKPOOLS                          ( 4 )\r
+#endif\r
+\r
+/**\r
+ * @brief The maximum number of jobs to cache.\r
+ */\r
+#ifndef IOT_TASKPOOL_JOBS_RECYCLE_LIMIT\r
+    #define IOT_TASKPOOL_JOBS_RECYCLE_LIMIT    ( 8UL )\r
+#endif\r
+\r
+/**\r
+ * @brief The maximum timeout in milliseconds to wait for a job to be scheduled before waking up a worker thread.\r
+ * A worker thread that wakes up as a result of a timeout may exit to allow the task pool to fold back to its\r
+ * minimum number of threads.\r
+ */\r
+#ifndef IOT_TASKPOOL_JOB_WAIT_TIMEOUT_MS\r
+    #define IOT_TASKPOOL_JOB_WAIT_TIMEOUT_MS    ( 60 * 1000UL )\r
+#endif\r
+\r
+#endif /* ifndef IOT_TASKPOOL_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/private/iot_error.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/private/iot_error.h
new file mode 100644 (file)
index 0000000..8050390
--- /dev/null
@@ -0,0 +1,117 @@
+/*\r
+ * Amazon FreeRTOS Common V1.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_error.h\r
+ * @brief Provides macros for error checking and function cleanup.\r
+ *\r
+ * The macros in this file are generic. They may be customized by each library\r
+ * by setting the library prefix.\r
+ */\r
+\r
+#ifndef IOT_ERROR_H_\r
+#define IOT_ERROR_H_\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/**\r
+ * @brief Declare the status variable and an initial value.\r
+ *\r
+ * This macro should be at the beginning of any functions that use cleanup sections.\r
+ *\r
+ * @param[in] statusType The type of the status variable for this function.\r
+ * @param[in] initialValue The initial value to assign to the status variable.\r
+ */\r
+#define IOT_FUNCTION_ENTRY( statusType, initialValue )    statusType status = initialValue\r
+\r
+/**\r
+ * @brief Declares the label that begins a cleanup section.\r
+ *\r
+ * This macro should be placed at the end of a function and followed by\r
+ * #IOT_FUNCTION_CLEANUP_END.\r
+ */\r
+#define IOT_FUNCTION_CLEANUP_BEGIN()                      iotCleanup:\r
+\r
+/**\r
+ * @brief Declares the end of a cleanup section.\r
+ *\r
+ * This macro should be placed at the end of a function and preceded by\r
+ * #IOT_FUNCTION_CLEANUP_BEGIN.\r
+ */\r
+#define IOT_FUNCTION_CLEANUP_END()                        return status\r
+\r
+/**\r
+ * @brief Declares an empty cleanup section.\r
+ *\r
+ * This macro should be placed at the end of a function to exit on error if no\r
+ * cleanup is required.\r
+ */\r
+#define IOT_FUNCTION_EXIT_NO_CLEANUP()                    IOT_FUNCTION_CLEANUP_BEGIN(); IOT_FUNCTION_CLEANUP_END()\r
+\r
+/**\r
+ * @brief Jump to the cleanup section.\r
+ */\r
+#define IOT_GOTO_CLEANUP()                                goto iotCleanup\r
+\r
+/**\r
+ * @brief Assign a value to the status variable and jump to the cleanup section.\r
+ *\r
+ * @param[in] statusValue The value to assign to the status variable.\r
+ */\r
+#define IOT_SET_AND_GOTO_CLEANUP( statusValue )           { status = ( statusValue ); IOT_GOTO_CLEANUP(); }\r
+\r
+/**\r
+ * @brief Jump to the cleanup section if a condition is `false`.\r
+ *\r
+ * This macro may be used in place of `assert` to exit a function is a condition\r
+ * is `false`.\r
+ *\r
+ * @param[in] condition The condition to check.\r
+ */\r
+#define IOT_GOTO_CLEANUP_IF_FALSE( condition )            { if( ( condition ) == false ) { IOT_GOTO_CLEANUP(); } }\r
+\r
+/**\r
+ * @brief Assign a value to the status variable and jump to the cleanup section\r
+ * if a condition is `false`.\r
+ *\r
+ * @param[in] statusValue The value to assign to the status variable.\r
+ * @param[in] condition The condition to check.\r
+ */\r
+#define IOT_SET_AND_GOTO_CLEANUP_IF_FALSE( statusValue, condition ) \\r
+    if( ( condition ) == false )                                    \\r
+        IOT_SET_AND_GOTO_CLEANUP( statusValue )\r
+\r
+/**\r
+ * @brief Check a condition; if `false`, assign the "Bad parameter" status value\r
+ * and jump to the cleanup section.\r
+ *\r
+ * @param[in] libraryPrefix The library prefix of the status variable.\r
+ * @param[in] condition The condition to check.\r
+ */\r
+#define IOT_VALIDATE_PARAMETER( libraryPrefix, condition ) \\r
+    IOT_SET_AND_GOTO_CLEANUP_IF_FALSE( libraryPrefix ## _BAD_PARAMETER, condition )\r
+\r
+#endif /* ifndef IOT_ERROR_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/private/iot_lib_init.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/private/iot_lib_init.h
new file mode 100644 (file)
index 0000000..2930d74
--- /dev/null
@@ -0,0 +1,33 @@
+/*\r
+ * Amazon FreeRTOS Common V1.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
+#ifndef _AWS_LIB_INIT_H_\r
+#define _AWS_LIB_INIT_H_\r
+\r
+#include "FreeRTOS.h"\r
+\r
+#define lib_initDECLARE_LIB_INIT( f )    extern BaseType_t f( void )\r
+\r
+#endif /* _AWS_LIB_INIT_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/private/iot_logging.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/private/iot_logging.h
new file mode 100644 (file)
index 0000000..377dd69
--- /dev/null
@@ -0,0 +1,229 @@
+/*\r
+ * Amazon FreeRTOS Common V1.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_logging.h\r
+ * @brief Generic logging function header file.\r
+ *\r
+ * Declares the generic logging function and the log levels. This file never\r
+ * needs to be included in source code. The header iot_logging_setup.h should\r
+ * be included instead.\r
+ *\r
+ * @see iot_logging_setup.h\r
+ */\r
+\r
+#ifndef IOT_LOGGING_H_\r
+#define IOT_LOGGING_H_\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/* Standard includes. */\r
+#include <stdbool.h>\r
+#include <stddef.h>\r
+#include <stdint.h>\r
+\r
+/**\r
+ * @constantspage{logging,logging library}\r
+ *\r
+ * @section logging_constants_levels Log levels\r
+ * @brief Log levels for the libraries in this SDK.\r
+ *\r
+ * Each library should specify a log level by setting @ref LIBRARY_LOG_LEVEL.\r
+ * All log messages with a level at or below the specified level will be printed\r
+ * for that library.\r
+ *\r
+ * Currently, there are 4 log levels. In the order of lowest to highest, they are:\r
+ * - #IOT_LOG_NONE <br>\r
+ *   @copybrief IOT_LOG_NONE\r
+ * - #IOT_LOG_ERROR <br>\r
+ *   @copybrief IOT_LOG_ERROR\r
+ * - #IOT_LOG_WARN <br>\r
+ *   @copybrief IOT_LOG_WARN\r
+ * - #IOT_LOG_INFO <br>\r
+ *   @copybrief IOT_LOG_INFO\r
+ * - #IOT_LOG_DEBUG <br>\r
+ *   @copybrief IOT_LOG_DEBUG\r
+ */\r
+\r
+/**\r
+ * @brief No log messages.\r
+ *\r
+ * Log messages with this level will be silently discarded. When @ref\r
+ * LIBRARY_LOG_LEVEL is #IOT_LOG_NONE, logging is disabled and no [logging functions]\r
+ * (@ref logging_functions) can be called.\r
+ */\r
+#define IOT_LOG_NONE     0\r
+\r
+/**\r
+ * @brief Only critical, unrecoverable errors.\r
+ *\r
+ * Log messages with this level will be printed when a library encounters an\r
+ * error from which it cannot easily recover.\r
+ */\r
+#define IOT_LOG_ERROR    1\r
+\r
+/**\r
+ * @brief Message about an abnormal but recoverable event.\r
+ *\r
+ * Log messages with this level will be printed when a library encounters an\r
+ * abnormal event that may be indicative of an error. Libraries should continue\r
+ * execution after logging a warning.\r
+ */\r
+#define IOT_LOG_WARN     2\r
+\r
+/**\r
+ * @brief A helpful, informational message.\r
+ *\r
+ * Log messages with this level may indicate the normal status of a library\r
+ * function. They should be used to track how far a program has executed.\r
+ */\r
+#define IOT_LOG_INFO     3\r
+\r
+/**\r
+ * @brief Detailed and excessive debug information.\r
+ *\r
+ * Log messages with this level are intended for developers. They may contain\r
+ * excessive information such as internal variables, buffers, or other specific\r
+ * information.\r
+ */\r
+#define IOT_LOG_DEBUG    4\r
+\r
+/**\r
+ * @paramstructs{logging,logging}\r
+ */\r
+\r
+/**\r
+ * @ingroup logging_datatypes_paramstructs\r
+ * @brief Log message configuration struct.\r
+ *\r
+ * @paramfor @ref logging_function_log, @ref logging_function_generic\r
+ *\r
+ * By default, log messages print the library name, log level, and a timestring.\r
+ * This struct can be passed to @ref logging_function_generic to disable one of\r
+ * the above components in the log message.\r
+ *\r
+ * <b>Example:</b>\r
+ *\r
+ * @code{c}\r
+ * IotLog_Generic( IOT_LOG_DEBUG, "SAMPLE", IOT_LOG_DEBUG, NULL, "Hello world!" );\r
+ * @endcode\r
+ * The code above prints the following message:\r
+ * @code\r
+ * [DEBUG][SAMPLE][2018-01-01 12:00:00] Hello world!\r
+ * @endcode\r
+ *\r
+ * The timestring can be disabled as follows:\r
+ * @code\r
+ * IotLogConfig_t logConfig = { .hideLogLevel = false, .hideLibraryName = false, .hideTimestring = true};\r
+ * IotLog_Generic( IOT_LOG_DEBUG, "SAMPLE", IOT_LOG_DEBUG, &logConfig, "Hello world!" );\r
+ * @endcode\r
+ * The resulting log message will be:\r
+ * @code\r
+ * [DEBUG][SAMPLE] Hello world!\r
+ * @endcode\r
+ */\r
+typedef struct IotLogConfig\r
+{\r
+    bool hideLogLevel;    /**< @brief Don't print the log level string for this message. */\r
+    bool hideLibraryName; /**< @brief Don't print the library name for this message. */\r
+    bool hideTimestring;  /**< @brief Don't print the timestring for this message. */\r
+} IotLogConfig_t;\r
+\r
+/**\r
+ * @functionspage{logging,logging library}\r
+ *\r
+ * - @functionname{logging_function_log}\r
+ * - @functionname{logging_function_printbuffer}\r
+ * - @functionname{logging_function_generic}\r
+ * - @functionname{logging_function_genericprintbuffer}\r
+ */\r
+\r
+/**\r
+ * @functionpage{IotLog_Generic,logging,generic}\r
+ * @functionpage{IotLog_PrintBuffer,logging,genericprintbuffer}\r
+ */\r
+\r
+/**\r
+ * @brief Generic logging function that prints a single message.\r
+ *\r
+ * This function is the generic logging function shared across all libraries.\r
+ * The library-specific logging function @ref logging_function_log is implemented\r
+ * using this function. Like @ref logging_function_log, this function is only\r
+ * available when @ref LIBRARY_LOG_LEVEL is #IOT_LOG_NONE.\r
+ *\r
+ * In most cases, the library-specific logging function @ref logging_function_log\r
+ * should be called instead of this function.\r
+ *\r
+ * @param[in] libraryLogSetting The log level setting of the library, used to\r
+ * determine if the log message should be printed. Must be one of the @ref\r
+ * logging_constants_levels.\r
+ * @param[in] pLibraryName The library name to print. See @ref LIBRARY_LOG_NAME.\r
+ * @param[in] messageLevel The log level of the this message. See @ref LIBRARY_LOG_LEVEL.\r
+ * @param[in] pLogConfig Pointer to a #IotLogConfig_t. Optional; pass `NULL` to ignore.\r
+ * @param[in] pFormat Format string for the log message.\r
+ * @param[in] ... Arguments for format specification.\r
+ *\r
+ * @return No return value. On errors, it prints nothing.\r
+ */\r
+/* @[declare_logging_generic] */\r
+void IotLog_Generic( int libraryLogSetting,\r
+                     const char * const pLibraryName,\r
+                     int messageLevel,\r
+                     const IotLogConfig_t * const pLogConfig,\r
+                     const char * const pFormat,\r
+                     ... );\r
+/* @[declare_logging_generic] */\r
+\r
+/**\r
+ * @brief Generic function to log the contents of a buffer as bytes.\r
+ *\r
+ * This function is the generic buffer logging function shared across all libraries.\r
+ * The library-specific buffer logging function @ref logging_function_printbuffer is\r
+ * implemented using this function. Like @ref logging_function_printbuffer, this\r
+ * function is only available when @ref LIBRARY_LOG_LEVEL is #IOT_LOG_DEBUG.\r
+ *\r
+ * In most cases, the library-specific buffer logging function @ref\r
+ * logging_function_printbuffer should be called instead of this function.\r
+ *\r
+ * @param[in] pLibraryName The library name to print with the log. See @ref LIBRARY_LOG_NAME.\r
+ * @param[in] pHeader A message to print before printing the buffer.\r
+ * @param[in] pBuffer The buffer to print.\r
+ * @param[in] bufferSize The number of bytes in `pBuffer` to print.\r
+ *\r
+ * @return No return value. On errors, it prints nothing.\r
+ *\r
+ * @note To conserve memory, this function only allocates enough memory for a\r
+ * single line of output. Therefore, in multithreaded systems, its output may\r
+ * appear "fragmented" if other threads are logging simultaneously.\r
+ */\r
+/* @[declare_logging_genericprintbuffer] */\r
+void IotLog_GenericPrintBuffer( const char * const pLibraryName,\r
+                                const char * const pHeader,\r
+                                const uint8_t * const pBuffer,\r
+                                size_t bufferSize );\r
+/* @[declare_logging_genericprintbuffer] */\r
+\r
+#endif /* ifndef IOT_LOGGING_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/private/iot_static_memory.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/private/iot_static_memory.h
new file mode 100644 (file)
index 0000000..76fe2b3
--- /dev/null
@@ -0,0 +1,250 @@
+/*\r
+ * Amazon FreeRTOS Common V1.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_static_memory.h\r
+ * @brief Common functions for managing static buffers. Only used when\r
+ * @ref IOT_STATIC_MEMORY_ONLY is `1`.\r
+ */\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/* The functions in this file should only exist in static memory only mode, hence\r
+ * the check for IOT_STATIC_MEMORY_ONLY in the double inclusion guard. */\r
+#if !defined( IOT_STATIC_MEMORY_H_ ) && ( IOT_STATIC_MEMORY_ONLY == 1 )\r
+#define IOT_STATIC_MEMORY_H_\r
+\r
+/* Standard includes. */\r
+#include <stdbool.h>\r
+#include <stddef.h>\r
+#include <stdint.h>\r
+\r
+/**\r
+ * @functionspage{static_memory,static memory component}\r
+ * - @functionname{static_memory_function_init}\r
+ * - @functionname{static_memory_function_cleanup}\r
+ * - @functionname{static_memory_function_findfree}\r
+ * - @functionname{static_memory_function_returninuse}\r
+ * - @functionname{static_memory_function_messagebuffersize}\r
+ * - @functionname{static_memory_function_mallocmessagebuffer}\r
+ * - @functionname{static_memory_function_freemessagebuffer}\r
+ */\r
+\r
+/*----------------------- Initialization and cleanup ------------------------*/\r
+\r
+/**\r
+ * @functionpage{IotStaticMemory_Init,static_memory,init}\r
+ * @functionpage{IotStaticMemory_Cleanup,static_memory,cleanup}\r
+ */\r
+\r
+/**\r
+ * @brief One-time initialization function for static memory.\r
+ *\r
+ * This function performs internal setup of static memory. <b>It must be called\r
+ * once (and only once) before calling any other static memory function.</b>\r
+ * Calling this function more than once without first calling\r
+ * @ref static_memory_function_cleanup may result in a crash.\r
+ *\r
+ * @return `true` if initialization succeeded; `false` otherwise.\r
+ *\r
+ * @attention This function is called by `IotSdk_Init` and does not need to be\r
+ * called by itself.\r
+ *\r
+ * @warning No thread-safety guarantees are provided for this function.\r
+ *\r
+ * @see static_memory_function_cleanup\r
+ */\r
+/* @[declare_static_memory_init] */\r
+bool IotStaticMemory_Init( void );\r
+/* @[declare_static_memory_init] */\r
+\r
+/**\r
+ * @brief One-time deinitialization function for static memory.\r
+ *\r
+ * This function frees resources taken in @ref static_memory_function_init.\r
+ * It should be called after to clean up static memory. After this function\r
+ * returns, @ref static_memory_function_init must be called again before\r
+ * calling any other static memory function.\r
+ *\r
+ * @attention This function is called by `IotSdk_Cleanup` and does not need\r
+ * to be called by itself.\r
+ *\r
+ * @warning No thread-safety guarantees are provided for this function.\r
+ *\r
+ * @see static_memory_function_init\r
+ */\r
+/* @[declare_static_memory_cleanup] */\r
+void IotStaticMemory_Cleanup( void );\r
+/* @[declare_static_memory_cleanup] */\r
+\r
+/*------------------------- Buffer allocation and free ----------------------*/\r
+\r
+/**\r
+ * @functionpage{IotStaticMemory_FindFree,static_memory,findfree}\r
+ * @functionpage{IotStaticMemory_ReturnInUse,static_memory,returninuse}\r
+ */\r
+\r
+/**\r
+ * @brief Find a free buffer using the "in-use" flags.\r
+ *\r
+ * If a free buffer is found, this function marks the buffer in-use. This function\r
+ * is common to the static memory implementation.\r
+ *\r
+ * @param[in] pInUse The "in-use" flags to search.\r
+ * @param[in] limit How many flags to check, i.e. the size of `pInUse`.\r
+ *\r
+ * @return The index of a free buffer; `-1` if no free buffers are available.\r
+ *\r
+ * <b>Example</b>:\r
+ * @code{c}\r
+ * // To use this function, first declare two arrays. One provides the statically-allocated\r
+ * // objects, the other provides flags to determine which objects are in-use.\r
+ * #define NUMBER_OF_OBJECTS    ...\r
+ * #define OBJECT_SIZE          ...\r
+ * static bool _pInUseObjects[ NUMBER_OF_OBJECTS ] = { 0 };\r
+ * static uint8_t _pObjects[ NUMBER_OF_OBJECTS ][ OBJECT_SIZE ] = { { 0 } }; // Placeholder for objects.\r
+ *\r
+ * // The function to statically allocate objects. Must have the same signature\r
+ * // as malloc().\r
+ * void * Iot_MallocObject( size_t size )\r
+ * {\r
+ *     int32_t freeIndex = -1;\r
+ *     void * pNewObject = NULL;\r
+ *\r
+ *     // Check that sizes match. \r
+ *     if( size != OBJECT_SIZE )\r
+ *     {\r
+ *         // Get the index of a free object.\r
+ *         freeIndex = IotStaticMemory_FindFree( _pInUseMessageBuffers,\r
+ *                                               IOT_MESSAGE_BUFFERS );\r
+ *\r
+ *         if( freeIndex != -1 )\r
+ *         {\r
+ *             pNewBuffer = &( _pMessageBuffers[ freeIndex ][ 0 ] );\r
+ *         }\r
+ *     }\r
+ *\r
+ *     return pNewBuffer;\r
+ * }\r
+ * @endcode\r
+ */\r
+/* @[declare_static_memory_findfree] */\r
+int32_t IotStaticMemory_FindFree( bool * pInUse,\r
+                                  size_t limit );\r
+/* @[declare_static_memory_findfree] */\r
+\r
+/**\r
+ * @brief Return an "in-use" buffer.\r
+ *\r
+ * This function is common to the static memory implementation.\r
+ *\r
+ * @param[in] ptr Pointer to the buffer to return.\r
+ * @param[in] pPool The pool of buffers that the in-use buffer was allocated from.\r
+ * @param[in] pInUse The "in-use" flags for pPool.\r
+ * @param[in] limit How many buffers (and flags) to check while searching for ptr.\r
+ * @param[in] elementSize The size of a single element in pPool.\r
+ *\r
+ * <b>Example</b>:\r
+ * @code{c}\r
+ * // To use this function, first declare two arrays. One provides the statically-allocated\r
+ * // objects, the other provides flags to determine which objects are in-use.\r
+ * #define NUMBER_OF_OBJECTS    ...\r
+ * #define OBJECT_SIZE          ...\r
+ * static bool _pInUseObjects[ NUMBER_OF_OBJECTS ] = { 0 };\r
+ * static uint8_t _pObjects[ NUMBER_OF_OBJECTS ][ OBJECT_SIZE ] = { { 0 } }; // Placeholder for objects.\r
+ *\r
+ * // The function to free statically-allocated objects. Must have the same signature\r
+ * // as free().\r
+ * void Iot_FreeObject( void * ptr )\r
+ * {\r
+ *     IotStaticMemory_ReturnInUse( ptr,\r
+ *                                 _pObjects,\r
+ *                                 _pInUseObjects,\r
+ *                                 NUMBER_OF_OBJECTS,\r
+ *                                 OBJECT_SIZE );\r
+ * }\r
+ * @endcode\r
+ */\r
+/* @[declare_static_memory_returninuse] */\r
+void IotStaticMemory_ReturnInUse( void * ptr,\r
+                                  void * pPool,\r
+                                  bool * pInUse,\r
+                                  size_t limit,\r
+                                  size_t elementSize );\r
+/* @[declare_static_memory_returninuse] */\r
+\r
+/*------------------------ Message buffer management ------------------------*/\r
+\r
+/**\r
+ * @functionpage{Iot_MessageBufferSize,static_memory,messagebuffersize}\r
+ * @functionpage{Iot_MallocMessageBuffer,static_memory,mallocmessagebuffer}\r
+ * @functionpage{Iot_FreeMessageBuffer,static_memory,freemessagebuffer}\r
+ */\r
+\r
+/**\r
+ * @brief Get the fixed size of a message buffer.\r
+ *\r
+ * The size of the message buffers are known at compile time, but it is a [constant]\r
+ * (@ref IOT_MESSAGE_BUFFER_SIZE) that may not be visible to all source files.\r
+ * This function allows other source files to know the size of a message buffer.\r
+ *\r
+ * @return The size, in bytes, of a single message buffer.\r
+ */\r
+/* @[declare_static_memory_messagebuffersize] */\r
+size_t Iot_MessageBufferSize( void );\r
+/* @[declare_static_memory_messagebuffersize] */\r
+\r
+/**\r
+ * @brief Get an empty message buffer.\r
+ *\r
+ * This function is the analog of [malloc]\r
+ * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html)\r
+ * for message buffers.\r
+ *\r
+ * @param[in] size Requested size for a message buffer.\r
+ *\r
+ * @return Pointer to the start of a message buffer. If the `size` argument is larger\r
+ * than the [fixed size of a message buffer](@ref IOT_MESSAGE_BUFFER_SIZE)\r
+ * or no message buffers are available, `NULL` is returned.\r
+ */\r
+/* @[declare_static_memory_mallocmessagebuffer] */\r
+void * Iot_MallocMessageBuffer( size_t size );\r
+/* @[declare_static_memory_mallocmessagebuffer] */\r
+\r
+/**\r
+ * @brief Free an in-use message buffer.\r
+ *\r
+ * This function is the analog of [free]\r
+ * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html)\r
+ * for message buffers.\r
+ *\r
+ * @param[in] ptr Pointer to the message buffer to free.\r
+ */\r
+/* @[declare_static_memory_freemessagebuffer] */\r
+void Iot_FreeMessageBuffer( void * ptr );\r
+/* @[declare_static_memory_freemessagebuffer] */\r
\r
+#endif /* if !defined( IOT_STATIC_MEMORY_H_ ) && ( IOT_STATIC_MEMORY_ONLY == 1 ) */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/private/iot_taskpool_internal.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/private/iot_taskpool_internal.h
new file mode 100644 (file)
index 0000000..3779ff9
--- /dev/null
@@ -0,0 +1,293 @@
+/*\r
+ * Amazon FreeRTOS Common V1.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_taskpool_internal.h\r
+ * @brief Internal header of task pool library. This header should not be included in\r
+ * typical application code.\r
+ */\r
+\r
+#ifndef IOT_TASKPOOL_INTERNAL_H_\r
+#define IOT_TASKPOOL_INTERNAL_H_\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/* Task pool include. */\r
+#include "private/iot_error.h"\r
+#include "iot_taskpool.h"\r
+\r
+/* FreeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+#include "semphr.h"\r
+#include "timers.h"\r
+\r
+/* Establish a few convenience macros to handle errors in a standard way. */\r
+\r
+/**\r
+ * @brief Every public API return an enumeration value with an undelying value of 0 in case of success.\r
+ */\r
+#define TASKPOOL_SUCCEEDED( x )               ( ( x ) == IOT_TASKPOOL_SUCCESS )\r
+\r
+/**\r
+ * @brief Every public API returns an enumeration value with an undelying value different than 0 in case of success.\r
+ */\r
+#define TASKPOOL_FAILED( x )                  ( ( x ) != IOT_TASKPOOL_SUCCESS )\r
+\r
+/**\r
+ * @brief Jump to the cleanup area.\r
+ */\r
+#define TASKPOOL_GOTO_CLEANUP()               IOT_GOTO_CLEANUP()\r
+\r
+/**\r
+ * @brief Declare the storage for the error status variable.\r
+ */\r
+#define  TASKPOOL_FUNCTION_ENTRY( result )    IOT_FUNCTION_ENTRY( IotTaskPoolError_t, result )\r
+\r
+/**\r
+ * @brief Check error and leave in case of failure.\r
+ */\r
+#define TASKPOOL_ON_ERROR_GOTO_CLEANUP( expr )                           \\r
+    { if( TASKPOOL_FAILED( status = ( expr ) ) ) { IOT_GOTO_CLEANUP(); } \\r
+    }\r
+\r
+/**\r
+ * @brief Exit if an argument is NULL.\r
+ */\r
+#define TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( ptr )      IOT_VALIDATE_PARAMETER( IOT_TASKPOOL, ( ptr != NULL ) )\r
+\r
+/**\r
+ * @brief Exit if an argument is NULL.\r
+ */\r
+#define TASKPOOL_ON_ARG_ERROR_GOTO_CLEANUP( expr )    IOT_VALIDATE_PARAMETER( IOT_TASKPOOL, ( ( expr ) == false ) )\r
+\r
+/**\r
+ * @brief Set error and leave.\r
+ */\r
+#define TASKPOOL_SET_AND_GOTO_CLEANUP( expr )         IOT_SET_AND_GOTO_CLEANUP( expr )\r
+\r
+/**\r
+ * @brief Initialize error and declare start of cleanup area.\r
+ */\r
+#define TASKPOOL_FUNCTION_CLEANUP()                   IOT_FUNCTION_CLEANUP_BEGIN()\r
+\r
+/**\r
+ * @brief Initialize error and declare end of cleanup area.\r
+ */\r
+#define TASKPOOL_FUNCTION_CLEANUP_END()               IOT_FUNCTION_CLEANUP_END()\r
+\r
+/**\r
+ * @brief Create an empty cleanup area.\r
+ */\r
+#define TASKPOOL_NO_FUNCTION_CLEANUP()                IOT_FUNCTION_EXIT_NO_CLEANUP()\r
+\r
+/**\r
+ * @brief Does not create a cleanup area.\r
+ */\r
+#define TASKPOOL_NO_FUNCTION_CLEANUP_NOLABEL()        return status\r
+\r
+/**\r
+ * @def IotTaskPool_Assert( expression )\r
+ * @brief Assertion macro for the Task pool library.\r
+ *\r
+ * Set @ref IOT_TASKPOOL_ENABLE_ASSERTS to `1` to enable assertions in the Task pool\r
+ * library.\r
+ *\r
+ * @param[in] expression Expression to be evaluated.\r
+ */\r
+#if IOT_TASKPOOL_ENABLE_ASSERTS == 1\r
+    #ifndef IotTaskPool_Assert\r
+        #include <assert.h>\r
+        #define IotTaskPool_Assert( expression )    assert( expression )\r
+    #endif\r
+#else\r
+    #define IotTaskPool_Assert( expression )\r
+#endif\r
+\r
+/* Configure logs for TASKPOOL functions. */\r
+#ifdef IOT_LOG_LEVEL_TASKPOOL\r
+    #define LIBRARY_LOG_LEVEL        IOT_LOG_LEVEL_TASKPOOL\r
+#else\r
+    #ifdef IOT_LOG_LEVEL_GLOBAL\r
+        #define LIBRARY_LOG_LEVEL    IOT_LOG_LEVEL_GLOBAL\r
+    #else\r
+        #define LIBRARY_LOG_LEVEL    IOT_LOG_NONE\r
+    #endif\r
+#endif\r
+\r
+#define LIBRARY_LOG_NAME    ( "TASKPOOL" )\r
+#include "iot_logging_setup.h"\r
+\r
+/*\r
+ * Provide default values for undefined memory allocation functions based on\r
+ * the usage of dynamic memory allocation.\r
+ */\r
+#if IOT_STATIC_MEMORY_ONLY == 1\r
+    #include "private/iot_static_memory.h"\r
+\r
+/**\r
+ * @brief Allocate an #_taskPool_t. This function should have the\r
+ * same signature as [malloc].\r
+ */\r
+    void * IotTaskPool_MallocTaskPool( size_t size );\r
+\r
+/**\r
+ * @brief Free an #_taskPool_t. This function should have the\r
+ * same signature as [malloc].\r
+ */\r
+    void IotTaskPool_FreeTaskPool( void * ptr );\r
+\r
+/**\r
+ * @brief Allocate an #IotTaskPoolJob_t. This function should have the\r
+ * same signature as [malloc].\r
+ */\r
+    void * IotTaskPool_MallocJob( size_t size );\r
+\r
+/**\r
+ * @brief Free an #IotTaskPoolJob_t. This function should have the same\r
+ * same signature as [malloc].\r
+ * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html).\r
+ */\r
+    void IotTaskPool_FreeJob( void * ptr );\r
+\r
+/**\r
+ * @brief Allocate an #_taskPoolTimerEvent_t. This function should have the\r
+ * same signature as [malloc].\r
+ */\r
+    void * IotTaskPool_MallocTimerEvent( size_t size );\r
+\r
+/**\r
+ * @brief Free an #_taskPoolTimerEvent_t. This function should have the\r
+ * same signature as[ free ].\r
+ */\r
+    void IotTaskPool_FreeTimerEvent( void * ptr );\r
+\r
+#else /* if IOT_STATIC_MEMORY_ONLY == 1 */\r
+    #include <stdlib.h>\r
+\r
+    #ifndef IotTaskPool_MallocTaskPool\r
+        #define IotTaskPool_MallocTaskPool    malloc\r
+    #endif\r
+\r
+    #ifndef IotTaskPool_FreeTaskPool\r
+        #define IotTaskPool_FreeTaskPool    free\r
+    #endif\r
+\r
+    #ifndef IotTaskPool_MallocJob\r
+        #define IotTaskPool_MallocJob    malloc\r
+    #endif\r
+\r
+    #ifndef IotTaskPool_FreeJob\r
+        #define IotTaskPool_FreeJob    free\r
+    #endif\r
+\r
+    #ifndef IotTaskPool_MallocTimerEvent\r
+        #define IotTaskPool_MallocTimerEvent    malloc\r
+    #endif\r
+\r
+    #ifndef IotTaskPool_FreeTimerEvent\r
+        #define IotTaskPool_FreeTimerEvent    free\r
+    #endif\r
+\r
+#endif /* if IOT_STATIC_MEMORY_ONLY == 1 */\r
+\r
+/* ---------------------------------------------------------------------------------------------- */\r
+\r
+/**\r
+ * @cond DOXYGEN_IGNORE\r
+ * Doxygen should ignore this section.\r
+ *\r
+ * A macros to manage task pool memory allocation.\r
+ */\r
+#define IOT_TASK_POOL_INTERNAL_STATIC    ( ( uint32_t ) 0x00000001 )      /* Flag to mark a job as user-allocated. */\r
+/** @endcond */\r
+\r
+/**\r
+ * @brief Task pool jobs cache.\r
+ *\r
+ * @warning This is a system-level data type that should not be modified or used directly in any application.\r
+ * @warning This is a system-level data type that can and will change across different versions of the platform, with no regards for backward compatibility.\r
+ *\r
+ */\r
+typedef struct _taskPoolCache\r
+{\r
+    IotListDouble_t freeList; /**< @brief A list ot hold cached jobs. */\r
+\r
+    uint32_t freeCount;       /**< @brief A counter to track the number of jobs in the cache. */\r
+} _taskPoolCache_t;\r
+\r
+/**\r
+ * @brief The task pool data structure keeps track of the internal state and the signals for the dispatcher threads.\r
+ * The task pool is a thread safe data structure.\r
+ *\r
+ * @warning This is a system-level data type that should not be modified or used directly in any application.\r
+ * @warning This is a system-level data type that can and will change across different versions of the platform, with no regards for backward compatibility.\r
+ *\r
+ */\r
+typedef struct _taskPool\r
+{\r
+    IotDeQueue_t dispatchQueue;              /**< @brief The queue for the jobs waiting to be executed. */\r
+    IotListDouble_t timerEventsList;         /**< @brief The timeouts queue for all deferred jobs waiting to be executed. */\r
+    _taskPoolCache_t jobsCache;              /**< @brief A cache to re-use jobs in order to limit memory allocations. */\r
+    uint32_t activeThreads;                  /**< @brief The number of threads in the task pool at any given time. */\r
+    int32_t priority;                        /**< @brief The priority for all task pool threads. */\r
+    SemaphoreHandle_t dispatchSignal;        /**< @brief The synchronization object on which threads are waiting for incoming jobs. */\r
+    StaticSemaphore_t dispatchSignalBuffer;  /**< @brief The semaphore buffer. */\r
+    StaticSemaphore_t startStopSignalBuffer; /**< @brief The semaphore buffer. */\r
+    TimerHandle_t timer;                     /**< @brief The timer for deferred jobs. */\r
+    StaticTimer_t timerBuffer;               /**< @brief The timer buffer. */\r
+    bool running;                            /**< @brief A flag to track whether the task pool is operational or should shut down. */\r
+} _taskPool_t;\r
+\r
+/**\r
+ * @brief The job data structure keeps track of the user callback and context, as well as the status of the job.\r
+ *\r
+ * @warning This is a system-level data type that should not be modified or used directly in any application.\r
+ * @warning This is a system-level data type that can and will change across different versions of the platform, with no regards for backward compatibility.\r
+ *\r
+ */\r
+typedef struct _taskPoolJob\r
+{\r
+    IotLink_t link;                    /**< @brief The link to insert the job in the dispatch queue. */\r
+    IotTaskPoolRoutine_t userCallback; /**< @brief The user provided callback. */\r
+    void * pUserContext;               /**< @brief The user provided context. */\r
+    uint32_t flags;                    /**< @brief Internal flags. */\r
+    IotTaskPoolJobStatus_t status;     /**< @brief The status for the job. */\r
+} _taskPoolJob_t;\r
+\r
+/**\r
+ * @brief Represents an operation that is subject to a timer.\r
+ *\r
+ * These events are queued per MQTT connection. They are sorted by their\r
+ * expiration time.\r
+ */\r
+typedef struct _taskPoolTimerEvent\r
+{\r
+    IotLink_t link;            /**< @brief List link member. */\r
+    TickType_t expirationTime; /**< @brief When this event should be processed. */\r
+    IotTaskPoolJob_t job;      /**< @brief The task pool job associated with this event. */\r
+} _taskPoolTimerEvent_t;\r
+\r
+#endif /* ifndef IOT_TASKPOOL_INTERNAL_H_ */
\ No newline at end of file
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/types/iot_taskpool_types.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/types/iot_taskpool_types.h
new file mode 100644 (file)
index 0000000..ce80167
--- /dev/null
@@ -0,0 +1,362 @@
+/*\r
+ * Amazon FreeRTOS Common V1.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_taskpool_types.h\r
+ * @brief Types of the task pool.\r
+ */\r
+\r
+#ifndef IOT_TASKPOOL_TYPES_H_\r
+#define IOT_TASKPOOL_TYPES_H_\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/* Standard includes. */\r
+#include <stdbool.h>\r
+#include <stdint.h>\r
+\r
+/* Platform types includes. */\r
+#include "types/iot_platform_types.h"\r
+\r
+/* Linear containers (lists and queues) include. */\r
+#include "iot_linear_containers.h"\r
+\r
+/*-------------------------- Task pool enumerated types --------------------------*/\r
+\r
+/**\r
+ * @ingroup taskpool_datatypes_enums\r
+ * @brief Return codes of [task pool functions](@ref taskpool_functions).\r
+ */\r
+typedef enum IotTaskPoolError\r
+{\r
+    /**\r
+     * @brief Task pool operation completed successfully.\r
+     *\r
+     * Functions that may return this value:\r
+     * - @ref taskpool_function_createsystemtaskpool\r
+     * - @ref taskpool_function_create\r
+     * - @ref taskpool_function_destroy\r
+     * - @ref taskpool_function_setmaxthreads\r
+     * - @ref taskpool_function_createjob\r
+     * - @ref taskpool_function_createrecyclablejob\r
+     * - @ref taskpool_function_destroyrecyclablejob\r
+     * - @ref taskpool_function_recyclejob\r
+     * - @ref taskpool_function_schedule\r
+     * - @ref taskpool_function_scheduledeferred\r
+     * - @ref taskpool_function_getstatus\r
+     * - @ref taskpool_function_trycancel\r
+     *\r
+     */\r
+    IOT_TASKPOOL_SUCCESS = 0,\r
+\r
+    /**\r
+     * @brief Task pool operation failed because at least one parameter is invalid.\r
+     *\r
+     * Functions that may return this value:\r
+     * - @ref taskpool_function_createsystemtaskpool\r
+     * - @ref taskpool_function_create\r
+     * - @ref taskpool_function_destroy\r
+     * - @ref taskpool_function_setmaxthreads\r
+     * - @ref taskpool_function_createjob\r
+     * - @ref taskpool_function_createrecyclablejob\r
+     * - @ref taskpool_function_destroyrecyclablejob\r
+     * - @ref taskpool_function_recyclejob\r
+     * - @ref taskpool_function_schedule\r
+     * - @ref taskpool_function_scheduledeferred\r
+     * - @ref taskpool_function_getstatus\r
+     * - @ref taskpool_function_trycancel\r
+     *\r
+     */\r
+    IOT_TASKPOOL_BAD_PARAMETER,\r
+\r
+    /**\r
+     * @brief Task pool operation failed because it is illegal.\r
+     *\r
+     * Functions that may return this value:\r
+     * - @ref taskpool_function_createjob\r
+     * - @ref taskpool_function_createrecyclablejob\r
+     * - @ref taskpool_function_destroyrecyclablejob\r
+     * - @ref taskpool_function_recyclejob\r
+     * - @ref taskpool_function_schedule\r
+     * - @ref taskpool_function_scheduledeferred\r
+     * - @ref taskpool_function_trycancel\r
+     *\r
+     */\r
+    IOT_TASKPOOL_ILLEGAL_OPERATION,\r
+\r
+    /**\r
+     * @brief Task pool operation failed because allocating memory failed.\r
+     *\r
+     * Functions that may return this value:\r
+     * - @ref taskpool_function_createsystemtaskpool\r
+     * - @ref taskpool_function_create\r
+     * - @ref taskpool_function_setmaxthreads\r
+     * - @ref taskpool_function_createrecyclablejob\r
+     * - @ref taskpool_function_scheduledeferred\r
+     * - @ref taskpool_function_getstatus\r
+     *\r
+     */\r
+    IOT_TASKPOOL_NO_MEMORY,\r
+\r
+    /**\r
+     * @brief Task pool operation failed because of an invalid parameter.\r
+     *\r
+     * Functions that may return this value:\r
+     * - @ref taskpool_function_setmaxthreads\r
+     * - @ref taskpool_function_createrecyclablejob\r
+     * - @ref taskpool_function_destroyrecyclablejob\r
+     * - @ref taskpool_function_recyclejob\r
+     * - @ref taskpool_function_schedule\r
+     * - @ref taskpool_function_scheduledeferred\r
+     * - @ref taskpool_function_getstatus\r
+     * - @ref taskpool_function_trycancel\r
+     *\r
+     */\r
+    IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS,\r
+\r
+    /**\r
+     * @brief Task pool cancellation failed.\r
+     *\r
+     * Functions that may return this value:\r
+     * - @ref taskpool_function_trycancel\r
+     *\r
+     */\r
+    IOT_TASKPOOL_CANCEL_FAILED,\r
+} IotTaskPoolError_t;\r
+\r
+/**\r
+ * @enums{taskpool,Task pool library}\r
+ */\r
+\r
+/**\r
+ * @ingroup taskpool_datatypes_enums\r
+ * @brief Status codes of [task pool Job](@ref IotTaskPoolJob_t).\r
+ *\r
+ */\r
+typedef enum IotTaskPoolJobStatus\r
+{\r
+    /**\r
+     * @brief Job is ready to be scheduled.\r
+     *\r
+     */\r
+    IOT_TASKPOOL_STATUS_READY = 0,\r
+\r
+    /**\r
+     * @brief Job has been queued for execution.\r
+     *\r
+     */\r
+    IOT_TASKPOOL_STATUS_SCHEDULED,\r
+\r
+    /**\r
+     * @brief Job has been scheduled for deferred execution.\r
+     *\r
+     */\r
+    IOT_TASKPOOL_STATUS_DEFERRED,\r
+\r
+    /**\r
+     * @brief Job is executing.\r
+     *\r
+     */\r
+    IOT_TASKPOOL_STATUS_COMPLETED,\r
+\r
+    /**\r
+     * @brief Job has been canceled before executing.\r
+     *\r
+     */\r
+    IOT_TASKPOOL_STATUS_CANCELED,\r
+\r
+    /**\r
+     * @brief Job status is undefined.\r
+     *\r
+     */\r
+    IOT_TASKPOOL_STATUS_UNDEFINED,\r
+} IotTaskPoolJobStatus_t;\r
+\r
+/*------------------------- Task pool types and handles --------------------------*/\r
+\r
+/**\r
+ * @ingroup taskpool_datatypes_handles\r
+ * @brief Opaque handle of a Task Pool instance.\r
+ *\r
+ * This type identifies a Task Pool instance, which is valid after a successful call\r
+ * to @ref taskpool_function_createsystemtaskpool or @ref taskpool_function_create. A\r
+ *  variable of this type is passed as the first\r
+ * argument to [Task Pool library functions](@ref taskpool_functions) to identify which\r
+ * task pool that function acts on.\r
+ *\r
+ * A call to @ref taskpool_function_destroy makes a task pool handle invalid. Once\r
+ * @ref taskpool_function_destroy returns, the task handle should no longer\r
+ * be used.\r
+ *\r
+ * @initializer{IotTaskPool_t,IOT_TASKPOOL_INITIALIZER}\r
+ */\r
+typedef struct _taskPool * IotTaskPool_t;\r
+\r
+/**\r
+ * @ingroup taskpool_datatypes_structs\r
+ * @brief The job storage data structure provides the storage for a statically allocated Task Pool Job instance.\r
+ *\r
+ * @warning This is a system-level data type that should not be modified or used directly in any application.\r
+ * @warning This is a system-level data type that can and will change across different versions of the platform, with no regards for backward compatibility.\r
+ *\r
+ */\r
+typedef struct IotTaskPoolJobStorage\r
+{\r
+    IotLink_t link;                 /**< @brief Placeholder. */\r
+    void * dummy2;                  /**< @brief Placeholder. */\r
+    void * dummy3;                  /**< @brief Placeholder. */\r
+    uint32_t dummy4;                /**< @brief Placeholder. */\r
+    IotTaskPoolJobStatus_t status;  /**< @brief Placeholder. */\r
+} IotTaskPoolJobStorage_t;\r
+\r
+/**\r
+ * @ingroup taskpool_datatypes_handles\r
+ * @brief Opaque handle of a Task Pool Job.\r
+ *\r
+ * This type identifies a Task Pool Job instance, which is valid after a successful call\r
+ * to @ref taskpool_function_createjob or @ref taskpool_function_createrecyclablejob.\r
+ *\r
+ * A call to @ref taskpool_function_recyclejob or @ref taskpool_function_destroyrecyclablejob makes a\r
+ * task pool job handle invalid. Once @ref taskpool_function_recyclejob or\r
+ * @ref taskpool_function_destroyrecyclablejob returns, the task job handle should no longer be used.\r
+ *\r
+ * @initializer{IotTaskPoolJob_t,IOT_TASKPOOL_JOB_INITIALIZER}\r
+ *\r
+ */\r
+typedef struct _taskPoolJob * IotTaskPoolJob_t;\r
+\r
+/*------------------------- Task pool parameter structs --------------------------*/\r
+\r
+/**\r
+ * @ingroup taskpool_datatypes_functionpointers\r
+ * @brief Callback type for a user callback.\r
+ *\r
+ * This type identifies the user callback signature to execute a task pool job. This callback will be invoked\r
+ * by the task pool threads with the `pUserContext` parameter, as specified by the user when\r
+ * calling @ref IotTaskPool_Schedule.\r
+ *\r
+ */\r
+typedef void ( * IotTaskPoolRoutine_t )( IotTaskPool_t pTaskPool,\r
+                                         IotTaskPoolJob_t pJob,\r
+                                         void * pUserContext );\r
+\r
+/**\r
+ * @ingroup taskpool_datatypes_paramstructs\r
+ * @brief Initialization information to create one task pool instance.\r
+ *\r
+ * @paramfor  @ref taskpool_function_createsystemtaskpool @ref taskpool_function_create.\r
+ *\r
+ * Passed as an argument to @ref taskpool_function_create.\r
+ *\r
+ * @initializer{IotTaskPoolInfo_t,IOT_TASKPOOL_INFO_INITIALIZER}\r
+ */\r
+typedef struct IotTaskPoolInfo\r
+{\r
+    /**\r
+     * @brief Specifies the operating parameters for a task pool.\r
+     *\r
+     * @attention #IotTaskPoolInfo_t.minThreads <b>MUST</b> be at least 1.\r
+     * #IotTaskPoolInfo_t.maxThreads <b>MUST</b> be greater or equal to #IotTaskPoolInfo_t.minThreads.\r
+     * If the minimum number of threads is same as the maximum, then the task pool will not try and grow the\r
+     * number of worker threads at run time.\r
+     */\r
+\r
+    uint32_t minThreads; /**< @brief Minimum number of threads in a task pool. These threads will be created when the task pool is first created with @ref taskpool_function_create. */\r
+    uint32_t maxThreads; /**< @brief Maximum number of threads in a task pool. A task pool may try and grow the number of active threads up to #IotTaskPoolInfo_t.maxThreads. */\r
+    uint32_t stackSize;  /**< @brief Stack size for every task pool thread. The stack size for each thread is fixed after the task pool is created and cannot be changed. */\r
+    int32_t priority;    /**< @brief priority for every task pool thread. The priority for each thread is fixed after the task pool is created and cannot be changed. */\r
+} IotTaskPoolInfo_t;\r
+\r
+/*------------------------- TASKPOOL defined constants --------------------------*/\r
+\r
+/**\r
+ * @constantspage{taskpool,task pool library}\r
+ *\r
+ * @section taskpool_constants_initializers Task pool Initializers\r
+ * @brief Provides default values for initializing the data types of the task pool library.\r
+ *\r
+ * @snippet this define_taskpool_initializers\r
+ *\r
+ * All user-facing data types of the task pool library can be initialized using\r
+ * one of the following.\r
+ *\r
+ * @warning Failure to initialize a task pool data type with the appropriate initializer\r
+ * may result in a runtime error!\r
+ * @note The initializers may change at any time in future versions, but their\r
+ * names will remain the same.\r
+ *\r
+ * <b>Example</b>\r
+ * @code{c}\r
+ *\r
+ * IotTaskPool_t * pTaskPool;\r
+ *\r
+ * const IotTaskPoolInfo_t tpInfo = IOT_TASKPOOL_INFO_INITIALIZER_LARGE;\r
+ *\r
+ * IotTaskPoolError_t error = IotTaskPool_Create( &tpInfo, &pTaskPool );\r
+ *\r
+ * // Use the task pool\r
+ * // ...\r
+ *\r
+ * @endcode\r
+ *\r
+ */\r
+/* @[define_taskpool_initializers] */\r
+/** @brief Initializer for a small #IotTaskPoolInfo_t. */\r
+#define IOT_TASKPOOL_INFO_INITIALIZER_SMALL     { .minThreads = 1, .maxThreads = 1, .stackSize = IOT_THREAD_DEFAULT_STACK_SIZE, .priority = IOT_THREAD_DEFAULT_PRIORITY }\r
+/** @brief Initializer for a medium #IotTaskPoolInfo_t. */\r
+#define IOT_TASKPOOL_INFO_INITIALIZER_MEDIUM    { .minThreads = 1, .maxThreads = 2, .stackSize = IOT_THREAD_DEFAULT_STACK_SIZE, .priority = IOT_THREAD_DEFAULT_PRIORITY }\r
+/** @brief Initializer for a large #IotTaskPoolInfo_t. */\r
+#define IOT_TASKPOOL_INFO_INITIALIZER_LARGE     { .minThreads = 2, .maxThreads = 3, .stackSize = IOT_THREAD_DEFAULT_STACK_SIZE, .priority = IOT_THREAD_DEFAULT_PRIORITY }\r
+/** @brief Initializer for a very large #IotTaskPoolInfo_t. */\r
+#define IOT_TASKPOOL_INFO_INITIALIZER_XLARGE    { .minThreads = 2, .maxThreads = 4, .stackSize = IOT_THREAD_DEFAULT_STACK_SIZE, .priority = IOT_THREAD_DEFAULT_PRIORITY }\r
+/** @brief Initializer for a typical #IotTaskPoolInfo_t. */\r
+#define IOT_TASKPOOL_INFO_INITIALIZER           IOT_TASKPOOL_INFO_INITIALIZER_MEDIUM\r
+/** @brief Initializer for a #IotTaskPool_t. */\r
+#define IOT_TASKPOOL_INITIALIZER                NULL\r
+/** @brief Initializer for a #IotTaskPoolJobStorage_t. */\r
+#define IOT_TASKPOOL_JOB_STORAGE_INITIALIZER    { { NULL, NULL }, NULL, NULL, 0, IOT_TASKPOOL_STATUS_UNDEFINED }\r
+/** @brief Initializer for a #IotTaskPoolJob_t. */\r
+#define IOT_TASKPOOL_JOB_INITIALIZER            NULL\r
+/* @[define_taskpool_initializers] */\r
+\r
+/**\r
+ * @brief Flag for scheduling a job to execute immediately, even if the maximum number of threads in the\r
+ * task pool was reached already.\r
+ *\r
+ * @warning This flag may cause the task pool to create a worker to serve the job immediately, and\r
+ * therefore using this flag may incur in additional memory usage and potentially fail scheduling the job.\r
+ */\r
+#define IOT_TASKPOOL_JOB_HIGH_PRIORITY    ( ( uint32_t ) 0x00000001 )\r
+\r
+/**\r
+ * @brief Allows the use of the handle to the system task pool.\r
+ *\r
+ * @warning The task pool handle is not valid unless @ref IotTaskPool_CreateSystemTaskPool is\r
+ * called before the handle is used.\r
+ */\r
+#define IOT_SYSTEM_TASKPOOL               ( IotTaskPool_GetSystemTaskPool() )\r
+\r
+#endif /* ifndef IOT_TASKPOOL_TYPES_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/logging/iot_logging.c b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/logging/iot_logging.c
new file mode 100644 (file)
index 0000000..aac8d31
--- /dev/null
@@ -0,0 +1,454 @@
+/*\r
+ * Amazon FreeRTOS Common V1.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_logging.c\r
+ * @brief Implementation of logging functions from iot_logging.h\r
+ */\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/* Standard includes. */\r
+#include <stdarg.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+/* Platform clock include. */\r
+#include "platform/iot_clock.h"\r
+\r
+/* Logging includes. */\r
+#include "private/iot_logging.h"\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* This implementation assumes the following values for the log level constants.\r
+ * Ensure that the values have not been modified. */\r
+#if IOT_LOG_NONE != 0\r
+    #error "IOT_LOG_NONE must be 0."\r
+#endif\r
+#if IOT_LOG_ERROR != 1\r
+    #error "IOT_LOG_ERROR must be 1."\r
+#endif\r
+#if IOT_LOG_WARN != 2\r
+    #error "IOT_LOG_WARN must be 2."\r
+#endif\r
+#if IOT_LOG_INFO != 3\r
+    #error "IOT_LOG_INFO must be 3."\r
+#endif\r
+#if IOT_LOG_DEBUG != 4\r
+    #error "IOT_LOG_DEBUG must be 4."\r
+#endif\r
+\r
+/**\r
+ * @def IotLogging_Puts( message )\r
+ * @brief Function the logging library uses to print a line.\r
+ *\r
+ * This function can be set by using a define. By default, the standard library\r
+ * [puts](http://pubs.opengroup.org/onlinepubs/9699919799/functions/puts.html)\r
+ * function is used.\r
+ */\r
+#ifndef IotLogging_Puts\r
+    #define IotLogging_Puts    puts\r
+#endif\r
+\r
+/*\r
+ * Provide default values for undefined memory allocation functions based on\r
+ * the usage of dynamic memory allocation.\r
+ */\r
+#if IOT_STATIC_MEMORY_ONLY == 1\r
+    /* Static memory allocation header. */\r
+    #include "private/iot_static_memory.h"\r
+\r
+/**\r
+ * @brief Allocate a new logging buffer. This function must have the same\r
+ * signature as [malloc](http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html).\r
+ */\r
+    #ifndef IotLogging_Malloc\r
+        #define IotLogging_Malloc    Iot_MallocMessageBuffer\r
+    #endif\r
+\r
+/**\r
+ * @brief Free a logging buffer. This function must have the same signature\r
+ * as [free](http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
+ */\r
+    #ifndef IotLogging_Free\r
+        #define IotLogging_Free    Iot_FreeMessageBuffer\r
+    #endif\r
+\r
+/**\r
+ * @brief Get the size of a logging buffer. Statically-allocated buffers\r
+ * should all have the same size.\r
+ */\r
+    #ifndef IotLogging_StaticBufferSize\r
+        #define IotLogging_StaticBufferSize    Iot_MessageBufferSize\r
+    #endif\r
+#else /* if IOT_STATIC_MEMORY_ONLY == 1 */\r
+    #ifndef IotLogging_Malloc\r
+        #include <stdlib.h>\r
+        #define IotLogging_Malloc    malloc\r
+    #endif\r
+\r
+    #ifndef IotLogging_Free\r
+        #include <stdlib.h>\r
+        #define IotLogging_Free    free\r
+    #endif\r
+#endif /* if IOT_STATIC_MEMORY_ONLY == 1 */\r
+\r
+/**\r
+ * @brief A guess of the maximum length of a timestring.\r
+ *\r
+ * There's no way for this logging library to know the length of a timestring\r
+ * before it's generated. Therefore, the logging library will assume a maximum\r
+ * length of any timestring it may get. This value should be generous enough\r
+ * to accommodate the vast majority of timestrings.\r
+ *\r
+ * @see @ref platform_clock_function_gettimestring\r
+ */\r
+#define MAX_TIMESTRING_LENGTH    ( 64 )\r
+\r
+/**\r
+ * @brief The longest string in #_pLogLevelStrings (below), plus 3 to accommodate\r
+ * `[]` and a null-terminator.\r
+ */\r
+#define MAX_LOG_LEVEL_LENGTH     ( 8 )\r
+\r
+/**\r
+ * @brief How many bytes @ref logging_function_genericprintbuffer should output on\r
+ * each line.\r
+ */\r
+#define BYTES_PER_LINE           ( 16 )\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/**\r
+ * @brief Lookup table for log levels.\r
+ *\r
+ * Converts one of the @ref logging_constants_levels to a string.\r
+ */\r
+static const char * const _pLogLevelStrings[ 5 ] =\r
+{\r
+    "",      /* IOT_LOG_NONE */\r
+    "ERROR", /* IOT_LOG_ERROR */\r
+    "WARN ", /* IOT_LOG_WARN */\r
+    "INFO ", /* IOT_LOG_INFO */\r
+    "DEBUG"  /* IOT_LOG_DEBUG */\r
+};\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+#if !defined( IOT_STATIC_MEMORY_ONLY ) || ( IOT_STATIC_MEMORY_ONLY == 0 )\r
+    static bool _reallocLoggingBuffer( void ** pOldBuffer,\r
+                                       size_t newSize,\r
+                                       size_t oldSize )\r
+    {\r
+        bool status = false;\r
+\r
+        /* Allocate a new, larger buffer. */\r
+        void * pNewBuffer = IotLogging_Malloc( newSize );\r
+\r
+        /* Ensure that memory allocation succeeded. */\r
+        if( pNewBuffer != NULL )\r
+        {\r
+            /* Copy the data from the old buffer to the new buffer. */\r
+            ( void ) memcpy( pNewBuffer, *pOldBuffer, oldSize );\r
+\r
+            /* Free the old buffer and update the pointer. */\r
+            IotLogging_Free( *pOldBuffer );\r
+            *pOldBuffer = pNewBuffer;\r
+\r
+            status = true;\r
+        }\r
+\r
+        return status;\r
+    }\r
+#endif /* if !defined( IOT_STATIC_MEMORY_ONLY ) || ( IOT_STATIC_MEMORY_ONLY == 0 ) */\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void IotLog_Generic( int libraryLogSetting,\r
+                     const char * const pLibraryName,\r
+                     int messageLevel,\r
+                     const IotLogConfig_t * const pLogConfig,\r
+                     const char * const pFormat,\r
+                     ... )\r
+{\r
+    int requiredMessageSize = 0;\r
+    size_t bufferSize = 0,\r
+           bufferPosition = 0, timestringLength = 0;\r
+    char * pLoggingBuffer = NULL;\r
+    va_list args;\r
+\r
+    /* If the library's log level setting is lower than the message level,\r
+     * return without doing anything. */\r
+    if( ( messageLevel == 0 ) || ( messageLevel > libraryLogSetting ) )\r
+    {\r
+        return;\r
+    }\r
+\r
+    if( ( pLogConfig == NULL ) || ( pLogConfig->hideLogLevel == false ) )\r
+    {\r
+        /* Add length of log level if requested. */\r
+        bufferSize += MAX_LOG_LEVEL_LENGTH;\r
+    }\r
+\r
+    /* Estimate the amount of buffer needed for this log message. */\r
+    if( ( pLogConfig == NULL ) || ( pLogConfig->hideLibraryName == false ) )\r
+    {\r
+        /* Add size of library name if requested. Add 2 to accommodate "[]". */\r
+        bufferSize += strlen( pLibraryName ) + 2;\r
+    }\r
+\r
+    if( ( pLogConfig == NULL ) || ( pLogConfig->hideTimestring == false ) )\r
+    {\r
+        /* Add length of timestring if requested. */\r
+        bufferSize += MAX_TIMESTRING_LENGTH;\r
+    }\r
+\r
+    /* Add 64 as an initial (arbitrary) guess for the length of the message. */\r
+    bufferSize += 64;\r
+\r
+    /* In static memory mode, check that the log message will fit in the a\r
+     * static buffer. */\r
+    #if IOT_STATIC_MEMORY_ONLY == 1\r
+        if( bufferSize >= IotLogging_StaticBufferSize() )\r
+        {\r
+            /* If the static buffers are likely too small to fit the log message,\r
+             * return. */\r
+            return;\r
+        }\r
+\r
+        /* Otherwise, update the buffer size to the size of a static buffer. */\r
+        bufferSize = IotLogging_StaticBufferSize();\r
+    #endif\r
+\r
+    /* Allocate memory for the logging buffer. */\r
+    pLoggingBuffer = ( char * ) IotLogging_Malloc( bufferSize );\r
+\r
+    if( pLoggingBuffer == NULL )\r
+    {\r
+        return;\r
+    }\r
+\r
+    /* Print the message log level if requested. */\r
+    if( ( pLogConfig == NULL ) || ( pLogConfig->hideLogLevel == false ) )\r
+    {\r
+        /* Ensure that message level is valid. */\r
+        if( ( messageLevel >= IOT_LOG_NONE ) && ( messageLevel <= IOT_LOG_DEBUG ) )\r
+        {\r
+            /* Add the log level string to the logging buffer. */\r
+            requiredMessageSize = snprintf( pLoggingBuffer + bufferPosition,\r
+                                            bufferSize - bufferPosition,\r
+                                            "[%s]",\r
+                                            _pLogLevelStrings[ messageLevel ] );\r
+\r
+            /* Check for encoding errors. */\r
+            if( requiredMessageSize <= 0 )\r
+            {\r
+                IotLogging_Free( pLoggingBuffer );\r
+\r
+                return;\r
+            }\r
+\r
+            /* Update the buffer position. */\r
+            bufferPosition += ( size_t ) requiredMessageSize;\r
+        }\r
+    }\r
+\r
+    /* Print the library name if requested. */\r
+    if( ( pLogConfig == NULL ) || ( pLogConfig->hideLibraryName == false ) )\r
+    {\r
+        /* Add the library name to the logging buffer. */\r
+        requiredMessageSize = snprintf( pLoggingBuffer + bufferPosition,\r
+                                        bufferSize - bufferPosition,\r
+                                        "[%s]",\r
+                                        pLibraryName );\r
+\r
+        /* Check for encoding errors. */\r
+        if( requiredMessageSize <= 0 )\r
+        {\r
+            IotLogging_Free( pLoggingBuffer );\r
+\r
+            return;\r
+        }\r
+\r
+        /* Update the buffer position. */\r
+        bufferPosition += ( size_t ) requiredMessageSize;\r
+    }\r
+\r
+    /* Print the timestring if requested. */\r
+    if( ( pLogConfig == NULL ) || ( pLogConfig->hideTimestring == false ) )\r
+    {\r
+        /* Add the opening '[' enclosing the timestring. */\r
+        pLoggingBuffer[ bufferPosition ] = '[';\r
+        bufferPosition++;\r
+\r
+        /* Generate the timestring and add it to the buffer. */\r
+        if( IotClock_GetTimestring( pLoggingBuffer + bufferPosition,\r
+                                    bufferSize - bufferPosition,\r
+                                    &timestringLength ) == true )\r
+        {\r
+            /* If the timestring was successfully generated, add the closing "]". */\r
+            bufferPosition += timestringLength;\r
+            pLoggingBuffer[ bufferPosition ] = ']';\r
+            bufferPosition++;\r
+        }\r
+        else\r
+        {\r
+            /* Sufficient memory for a timestring should have been allocated. A timestring\r
+             * probably failed to generate due to a clock read error; remove the opening '['\r
+             * from the logging buffer. */\r
+            bufferPosition--;\r
+            pLoggingBuffer[ bufferPosition ] = '\0';\r
+        }\r
+    }\r
+\r
+    /* Add a padding space between the last closing ']' and the message, unless\r
+     * the logging buffer is empty. */\r
+    if( bufferPosition > 0 )\r
+    {\r
+        pLoggingBuffer[ bufferPosition ] = ' ';\r
+        bufferPosition++;\r
+    }\r
+\r
+    va_start( args, pFormat );\r
+\r
+    /* Add the log message to the logging buffer. */\r
+    requiredMessageSize = vsnprintf( pLoggingBuffer + bufferPosition,\r
+                                     bufferSize - bufferPosition,\r
+                                     pFormat,\r
+                                     args );\r
+\r
+    va_end( args );\r
+\r
+    /* If the logging buffer was too small to fit the log message, reallocate\r
+     * a larger logging buffer. */\r
+    if( ( size_t ) requiredMessageSize >= bufferSize - bufferPosition )\r
+    {\r
+        #if IOT_STATIC_MEMORY_ONLY == 1\r
+\r
+            /* There's no point trying to allocate a larger static buffer. Return\r
+             * immediately. */\r
+            IotLogging_Free( pLoggingBuffer );\r
+\r
+            return;\r
+        #else\r
+            if( _reallocLoggingBuffer( ( void ** ) &pLoggingBuffer,\r
+                                       ( size_t ) requiredMessageSize + bufferPosition + 1,\r
+                                       bufferSize ) == false )\r
+            {\r
+                /* If buffer reallocation failed, return. */\r
+                IotLogging_Free( pLoggingBuffer );\r
+\r
+                return;\r
+            }\r
+\r
+            /* Reallocation successful, update buffer size. */\r
+            bufferSize = ( size_t ) requiredMessageSize + bufferPosition + 1;\r
+\r
+            /* Add the log message to the buffer. Now that the buffer has been\r
+             * reallocated, this should succeed. */\r
+            va_start( args, pFormat );\r
+            requiredMessageSize = vsnprintf( pLoggingBuffer + bufferPosition,\r
+                                             bufferSize - bufferPosition,\r
+                                             pFormat,\r
+                                             args );\r
+            va_end( args );\r
+        #endif /* if IOT_STATIC_MEMORY_ONLY == 1 */\r
+    }\r
+\r
+    /* Check for encoding errors. */\r
+    if( requiredMessageSize <= 0 )\r
+    {\r
+        IotLogging_Free( pLoggingBuffer );\r
+\r
+        return;\r
+    }\r
+\r
+    /* Print the logging buffer to stdout. */\r
+    IotLogging_Puts( pLoggingBuffer );\r
+\r
+    /* Free the logging buffer. */\r
+    IotLogging_Free( pLoggingBuffer );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void IotLog_GenericPrintBuffer( const char * const pLibraryName,\r
+                                const char * const pHeader,\r
+                                const uint8_t * const pBuffer,\r
+                                size_t bufferSize )\r
+{\r
+    size_t i = 0, offset = 0;\r
+\r
+    /* Allocate memory to hold each line of the log message. Since each byte\r
+     * of pBuffer is printed in 4 characters (2 digits, a space, and a null-\r
+     * terminator), the size of each line is 4 * BYTES_PER_LINE. */\r
+    char * pMessageBuffer = IotLogging_Malloc( 4 * BYTES_PER_LINE );\r
+\r
+    /* Exit if no memory is available. */\r
+    if( pMessageBuffer == NULL )\r
+    {\r
+        return;\r
+    }\r
+\r
+    /* Print pHeader before printing pBuffer. */\r
+    if( pHeader != NULL )\r
+    {\r
+        IotLog_Generic( IOT_LOG_DEBUG,\r
+                        pLibraryName,\r
+                        IOT_LOG_DEBUG,\r
+                        NULL,\r
+                        pHeader );\r
+    }\r
+\r
+    /* Print each byte in pBuffer. */\r
+    for( i = 0; i < bufferSize; i++ )\r
+    {\r
+        /* Print a line if BYTES_PER_LINE is reached. But don't print a line\r
+         * at the beginning (when i=0). */\r
+        if( ( i % BYTES_PER_LINE == 0 ) && ( i != 0 ) )\r
+        {\r
+            IotLogging_Puts( pMessageBuffer );\r
+\r
+            /* Reset offset so that pMessageBuffer is filled from the beginning. */\r
+            offset = 0;\r
+        }\r
+\r
+        /* Print a single byte into pMessageBuffer. */\r
+        ( void ) snprintf( pMessageBuffer + offset, 4, "%02x ", pBuffer[ i ] );\r
+\r
+        /* Move the offset where the next character is printed. */\r
+        offset += 3;\r
+    }\r
+\r
+    /* Print the final line of bytes. This line isn't printed by the for-loop above. */\r
+    IotLogging_Puts( pMessageBuffer );\r
+\r
+    /* Free memory used by this function. */\r
+    IotLogging_Free( pMessageBuffer );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/logging/iot_logging_task_dynamic_buffers.c b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/logging/iot_logging_task_dynamic_buffers.c
new file mode 100644 (file)
index 0000000..ac08e22
--- /dev/null
@@ -0,0 +1,250 @@
+/*\r
+ * Amazon FreeRTOS Common V1.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
+/* FreeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "queue.h"\r
+\r
+/* Logging includes. */\r
+#include "iot_logging_task.h"\r
+\r
+/* Standard includes. */\r
+#include <stdio.h>\r
+#include <stdarg.h>\r
+#include <string.h>\r
+\r
+/* Sanity check all the definitions required by this file are set. */\r
+#ifndef configPRINT_STRING\r
+    #error configPRINT_STRING( x ) must be defined in FreeRTOSConfig.h to use this logging file.  Set configPRINT_STRING( x ) to a function that outputs a string, where X is the string.  For example, #define configPRINT_STRING( x ) MyUARTWriteString( X )\r
+#endif\r
+\r
+#ifndef configLOGGING_MAX_MESSAGE_LENGTH\r
+    #error configLOGGING_MAX_MESSAGE_LENGTH must be defined in FreeRTOSConfig.h to use this logging file.  configLOGGING_MAX_MESSAGE_LENGTH sets the size of the buffer into which formatted text is written, so also sets the maximum log message length.\r
+#endif\r
+\r
+#ifndef configLOGGING_INCLUDE_TIME_AND_TASK_NAME\r
+    #error configLOGGING_INCLUDE_TIME_AND_TASK_NAME must be defined in FreeRTOSConfig.h to use this logging file.  Set configLOGGING_INCLUDE_TIME_AND_TASK_NAME to 1 to prepend a time stamp, message number and the name of the calling task to each logged message.  Otherwise set to 0.\r
+#endif\r
+\r
+/* A block time of 0 just means don't block. */\r
+#define loggingDONT_BLOCK    0\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * The task that actually performs the print output.  Using a separate task\r
+ * enables the use of slow output, such as as a UART, without the task that is\r
+ * outputting the log message having to wait for the message to be completely\r
+ * written.  Using a separate task also serializes access to the output port.\r
+ *\r
+ * The structure of this task is very simple; it blocks on a queue to wait for\r
+ * a pointer to a string, sending any received strings to a macro that performs\r
+ * the actual output.  The macro is port specific, so implemented outside of\r
+ * this file.  This version uses dynamic memory, so the buffer that contained\r
+ * the log message is freed after it has been output.\r
+ */\r
+static void prvLoggingTask( void * pvParameters );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * The queue used to pass pointers to log messages from the task that created\r
+ * the message to the task that will performs the output.\r
+ */\r
+static QueueHandle_t xQueue = NULL;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+BaseType_t xLoggingTaskInitialize( uint16_t usStackSize,\r
+                                   UBaseType_t uxPriority,\r
+                                   UBaseType_t uxQueueLength )\r
+{\r
+    BaseType_t xReturn = pdFAIL;\r
+\r
+    /* Ensure the logging task has not been created already. */\r
+    if( xQueue == NULL )\r
+    {\r
+        /* Create the queue used to pass pointers to strings to the logging task. */\r
+        xQueue = xQueueCreate( uxQueueLength, sizeof( char ** ) );\r
+\r
+        if( xQueue != NULL )\r
+        {\r
+            if( xTaskCreate( prvLoggingTask, "Logging", usStackSize, NULL, uxPriority, NULL ) == pdPASS )\r
+            {\r
+                xReturn = pdPASS;\r
+            }\r
+            else\r
+            {\r
+                /* Could not create the task, so delete the queue again. */\r
+                vQueueDelete( xQueue );\r
+            }\r
+        }\r
+    }\r
+\r
+    return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvLoggingTask( void * pvParameters )\r
+{\r
+    char * pcReceivedString = NULL;\r
+\r
+    for( ; ; )\r
+    {\r
+        /* Block to wait for the next string to print. */\r
+        if( xQueueReceive( xQueue, &pcReceivedString, portMAX_DELAY ) == pdPASS )\r
+        {\r
+            configPRINT_STRING( pcReceivedString );\r
+            vPortFree( ( void * ) pcReceivedString );\r
+        }\r
+    }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/*!\r
+ * \brief Formats a string to be printed and sends it\r
+ * to the print queue.\r
+ *\r
+ * Appends the message number, time (in ticks), and task\r
+ * that called vLoggingPrintf to the beginning of each\r
+ * print statement.\r
+ *\r
+ */\r
+void vLoggingPrintf( const char * pcFormat,\r
+                     ... )\r
+{\r
+    size_t xLength = 0;\r
+    int32_t xLength2 = 0;\r
+    va_list args;\r
+    char * pcPrintString = NULL;\r
+\r
+    /* The queue is created by xLoggingTaskInitialize().  Check\r
+     * xLoggingTaskInitialize() has been called. */\r
+    configASSERT( xQueue );\r
+\r
+    /* Allocate a buffer to hold the log message. */\r
+    pcPrintString = pvPortMalloc( configLOGGING_MAX_MESSAGE_LENGTH );\r
+\r
+    if( pcPrintString != NULL )\r
+    {\r
+        /* There are a variable number of parameters. */\r
+        va_start( args, pcFormat );\r
+\r
+        if( strcmp( pcFormat, "\n" ) != 0 )\r
+        {\r
+            #if ( configLOGGING_INCLUDE_TIME_AND_TASK_NAME == 1 )\r
+                {\r
+                    const char * pcTaskName;\r
+                    const char * pcNoTask = "None";\r
+                    static BaseType_t xMessageNumber = 0;\r
+\r
+                    /* Add a time stamp and the name of the calling task to the\r
+                     * start of the log. */\r
+                    if( xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED )\r
+                    {\r
+                        pcTaskName = pcTaskGetName( NULL );\r
+                    }\r
+                    else\r
+                    {\r
+                        pcTaskName = pcNoTask;\r
+                    }\r
+\r
+                    xLength = snprintf( pcPrintString, configLOGGING_MAX_MESSAGE_LENGTH, "%lu %lu [%s] ",\r
+                                        ( unsigned long ) xMessageNumber++,\r
+                                        ( unsigned long ) xTaskGetTickCount(),\r
+                                        pcTaskName );\r
+                }\r
+            #else /* if ( configLOGGING_INCLUDE_TIME_AND_TASK_NAME == 1 ) */\r
+                {\r
+                    xLength = 0;\r
+                }\r
+            #endif /* if ( configLOGGING_INCLUDE_TIME_AND_TASK_NAME == 1 ) */\r
+        }\r
+\r
+        xLength2 = vsnprintf( pcPrintString + xLength, configLOGGING_MAX_MESSAGE_LENGTH - xLength, pcFormat, args );\r
+\r
+        if( xLength2 < 0 )\r
+        {\r
+            /* vsnprintf() failed. Restore the terminating NULL\r
+             * character of the first part. Note that the first\r
+             * part of the buffer may be empty if the value of\r
+             * configLOGGING_INCLUDE_TIME_AND_TASK_NAME is not\r
+             * 1 and as a result, the whole buffer may be empty.\r
+             * That's the reason we have a check for xLength > 0\r
+             * before sending the buffer to the logging task.\r
+             */\r
+            xLength2 = 0;\r
+            pcPrintString[ xLength ] = '\0';\r
+        }\r
+\r
+        xLength += ( size_t ) xLength2;\r
+        va_end( args );\r
+\r
+        /* Only send the buffer to the logging task if it is\r
+         * not empty. */\r
+        if( xLength > 0 )\r
+        {\r
+            /* Send the string to the logging task for IO. */\r
+            if( xQueueSend( xQueue, &pcPrintString, loggingDONT_BLOCK ) != pdPASS )\r
+            {\r
+                /* The buffer was not sent so must be freed again. */\r
+                vPortFree( ( void * ) pcPrintString );\r
+            }\r
+        }\r
+        else\r
+        {\r
+            /* The buffer was not sent, so it must be\r
+             * freed. */\r
+            vPortFree( ( void * ) pcPrintString );\r
+        }\r
+    }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vLoggingPrint( const char * pcMessage )\r
+{\r
+    char * pcPrintString = NULL;\r
+    size_t xLength = 0;\r
+\r
+    /* The queue is created by xLoggingTaskInitialize().  Check\r
+     * xLoggingTaskInitialize() has been called. */\r
+    configASSERT( xQueue );\r
+\r
+    xLength = strlen( pcMessage ) + 1;\r
+    pcPrintString = pvPortMalloc( xLength );\r
+\r
+    if( pcPrintString != NULL )\r
+    {\r
+        strncpy( pcPrintString, pcMessage, xLength );\r
+\r
+        /* Send the string to the logging task for IO. */\r
+        if( xQueueSend( xQueue, &pcPrintString, loggingDONT_BLOCK ) != pdPASS )\r
+        {\r
+            /* The buffer was not sent so must be freed again. */\r
+            vPortFree( ( void * ) pcPrintString );\r
+        }\r
+    }\r
+}\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/taskpool/iot_taskpool.c b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/taskpool/iot_taskpool.c
new file mode 100644 (file)
index 0000000..6f90c19
--- /dev/null
@@ -0,0 +1,1185 @@
+/*\r
+ * Amazon FreeRTOS Common V1.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
+ * @file iot_taskpool.c\r
+ * @brief Implements the task pool functions in iot_taskpool.h\r
+ */\r
+\r
+/* Kernel includes. */\r
+#include "FreeRTOS.h"\r
+#include "semphr.h"\r
+\r
+/* IoT libraries includes. */\r
+#include "iot_config.h"\r
+\r
+/* Standard includes. */\r
+#include <stdbool.h>\r
+#include <stdio.h>\r
+#include <stddef.h>\r
+#include <stdint.h>\r
+#include <string.h>\r
+\r
+#if !defined( configSUPPORT_STATIC_ALLOCATION ) || ( configSUPPORT_STATIC_ALLOCATION != 1 )\r
+    #error configSUPPORT_STATIC_ALLOCATION must be set to 1 in FreeRTOSConfig.h to build this file.\r
+#endif\r
+\r
+/* Task pool internal include. */\r
+#include "private/iot_taskpool_internal.h"\r
+\r
+/**\r
+ * @brief Maximum semaphore value for wait operations.\r
+ */\r
+#define TASKPOOL_MAX_SEM_VALUE              0xFFFF\r
+\r
+/**\r
+ * @brief Reschedule delay in milliseconds for deferred jobs.\r
+ */\r
+#define TASKPOOL_JOB_RESCHEDULE_DELAY_MS    ( 10ULL )\r
+\r
+/* ---------------------------------------------------------------------------------- */\r
+\r
+/**\r
+ * Doxygen should ignore this section.\r
+ *\r
+ * @brief The system task pool handle for all libraries to use.\r
+ * User application can use the system task pool as well knowing that the usage will be shared with\r
+ * the system libraries as well. The system task pool needs to be initialized before any library is used or\r
+ * before any code that posts jobs to the task pool runs.\r
+ */\r
+static _taskPool_t _IotSystemTaskPool = { .dispatchQueue = IOT_DEQUEUE_INITIALIZER };\r
+\r
+/* -------------- Convenience functions to create/recycle/destroy jobs -------------- */\r
+\r
+/**\r
+ * @brief Initializes one instance of a Task pool cache.\r
+ *\r
+ * @param[in] pCache The pre-allocated instance of the cache to initialize.\r
+ */\r
+static void _initJobsCache( _taskPoolCache_t * const pCache );\r
+\r
+/**\r
+ * @brief Initialize a job.\r
+ *\r
+ * @param[in] pJob The job to initialize.\r
+ * @param[in] userCallback The user callback for the job.\r
+ * @param[in] pUserContext The context tp be passed to the callback.\r
+ * @param[in] isStatic A flag to indicate whether the job is statically or synamically allocated.\r
+ */\r
+static void _initializeJob( _taskPoolJob_t * const pJob,\r
+                            IotTaskPoolRoutine_t userCallback,\r
+                            void * pUserContext,\r
+                            bool isStatic );\r
+\r
+/**\r
+ * @brief Extracts and initializes one instance of a job from the cache or, if there is none available, it allocates and initialized a new one.\r
+ *\r
+ * @param[in] pCache The instance of the cache to extract the job from.\r
+ */\r
+static _taskPoolJob_t * _fetchOrAllocateJob( _taskPoolCache_t * const pCache );\r
+\r
+/**\r
+ * Recycles one instance of a job into the cache or, if the cache is full, it destroys it.\r
+ *\r
+ * @param[in] pCache The instance of the cache to recycle the job into.\r
+ * @param[in] pJob The job to recycle.\r
+ *\r
+ */\r
+static void _recycleJob( _taskPoolCache_t * const pCache,\r
+                         _taskPoolJob_t * const pJob );\r
+\r
+/**\r
+ * Destroys one instance of a job.\r
+ *\r
+ * @param[in] pJob The job to destroy.\r
+ *\r
+ */\r
+static void _destroyJob( _taskPoolJob_t * const pJob );\r
+\r
+/* -------------- The worker thread procedure for a task pool thread -------------- */\r
+\r
+/**\r
+ * The procedure for a task pool worker thread.\r
+ *\r
+ * @param[in] pUserContext The user context.\r
+ *\r
+ */\r
+static void _taskPoolWorker( void * pUserContext );\r
+\r
+/* -------------- Convenience functions to handle timer events  -------------- */\r
+\r
+/**\r
+ * Comparer for the time list.\r
+ *\r
+ * param[in] pTimerEventLink1 The link to the first timer event.\r
+ * param[in] pTimerEventLink1 The link to the first timer event.\r
+ */\r
+static int32_t _timerEventCompare( const IotLink_t * const pTimerEventLink1,\r
+                                   const IotLink_t * const pTimerEventLink2 );\r
+\r
+/**\r
+ * Reschedules the timer for handling deferred jobs to the next timeout.\r
+ *\r
+ * param[in] timer The timer to reschedule.\r
+ * param[in] pFirstTimerEvent The timer event that carries the timeout and job inforamtion.\r
+ */\r
+static void _rescheduleDeferredJobsTimer( TimerHandle_t const timer,\r
+                                          _taskPoolTimerEvent_t * const pFirstTimerEvent );\r
+\r
+/**\r
+ * The task pool timer procedure for scheduling deferred jobs.\r
+ *\r
+ * param[in] timer The timer to handle.\r
+ */\r
+static void _timerCallback( TimerHandle_t xTimer );\r
+\r
+/* -------------- Convenience functions to create/initialize/destroy the task pool -------------- */\r
+\r
+/**\r
+ * Parameter validation for a task pool initialization.\r
+ *\r
+ * @param[in] pInfo The initialization information for the task pool.\r
+ *\r
+ */\r
+static IotTaskPoolError_t _performTaskPoolParameterValidation( const IotTaskPoolInfo_t * const pInfo );\r
+\r
+/**\r
+ * Initializes a pre-allocated instance of a task pool.\r
+ *\r
+ * @param[in] pTaskPool The pre-allocated instance of the task pool to initialize.\r
+ *\r
+ */\r
+static void _initTaskPoolControlStructures( _taskPool_t * const pTaskPool );\r
+\r
+/**\r
+ * Initializes a pre-allocated instance of a task pool.\r
+ *\r
+ * @param[in] pInfo The initialization information for the task pool.\r
+ * @param[out] pTaskPool A pointer to the task pool data structure to initialize.\r
+ *\r
+ */\r
+static IotTaskPoolError_t _createTaskPool( const IotTaskPoolInfo_t * const pInfo,\r
+                                           _taskPool_t * const pTaskPool );\r
+\r
+/**\r
+ * Destroys one instance of a task pool.\r
+ *\r
+ * @param[in] pTaskPool The task pool to destroy.\r
+ *\r
+ */\r
+static void _destroyTaskPool( _taskPool_t * const pTaskPool );\r
+\r
+/**\r
+ * Places a job in the dispatch queue.\r
+ *\r
+ * @param[in] pTaskPool The task pool to scheduel the job with.\r
+ * @param[in] pJob The job to schedule.\r
+ * @param[in] flags The job flags.\r
+ *\r
+ */\r
+static IotTaskPoolError_t _scheduleInternal( _taskPool_t * const pTaskPool,\r
+                                             _taskPoolJob_t * const pJob );\r
+/**\r
+ * Matches a deferred job in the timer queue with its timer event wrapper.\r
+ *\r
+ * @param[in] pLink A pointer to the timer event link in the timer queue.\r
+ * @param[in] pMatch A pointer to the job to match.\r
+ *\r
+ */\r
+static bool _matchJobByPointer( const IotLink_t * const pLink,\r
+                                void * pMatch );\r
+\r
+/**\r
+ * Tries to cancel a job.\r
+ *\r
+ * @param[in] pTaskPool The task pool to cancel an operation against.\r
+ * @param[in] pJob The job to cancel.\r
+ * @param[out] pStatus The status of the job at the time of cancellation.\r
+ *\r
+ */\r
+static IotTaskPoolError_t _tryCancelInternal( _taskPool_t * const pTaskPool,\r
+                                              _taskPoolJob_t * const pJob,\r
+                                              IotTaskPoolJobStatus_t * const pStatus );\r
+\r
+/* ---------------------------------------------------------------------------------------------- */\r
+\r
+/*\r
+ * The full IoT Task Pool Library has many use cases, including Linux\r
+ * development. Â Typical FreeRTOS use cases do not require the full\r
+ * functionality so optimised version is provided specifically for use with\r
+ * FreeRTOS.  Unlike the full version, this optimised version:\r
+ *   + Only supports a single task pool (system task pool) at a time.\r
+ *   + Does not auto-scale by dynamically adding more tasks if the number of\r
+ *   + tasks in the pool becomes exhausted. Â The number of tasks in the pool\r
+ *     are fixed at compile time.  See the task pool configuration options for\r
+ *     more information.\r
+ *   + Cannot be shut down - it exists for the lifetime of the application.\r
+ *\r
+ * As such this file does not implement the following API functions:\r
+ *   + IotTaskPool_GetSystemTaskPool()\r
+ *   + IotTaskPool_Create()\r
+ *   + IotTaskPool_Destroy()\r
+ *   + IotTaskPool_SetMaxThreads()\r
+ *\r
+ * Users who are interested in the functionality of the full IoT Task Pool\r
+ * library can us it in place of this optimised version.\r
+ */\r
+\r
+IotTaskPoolError_t IotTaskPool_CreateSystemTaskPool( const IotTaskPoolInfo_t * const pInfo )\r
+{\r
+    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
+\r
+    /* At this time the task pool cannot be created before the scheduler has\r
+    started because the function attempts to block on synchronization\r
+    primitives (although I'm not sure why). */\r
+    configASSERT( xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED );\r
+\r
+    /* Guard against multiple attempts to create the system task pool in case\r
+    this function is called by more than one library initialization routine. */\r
+    if( _IotSystemTaskPool.running == false )\r
+    {\r
+        /* Parameter checking. */\r
+        TASKPOOL_ON_ERROR_GOTO_CLEANUP( _performTaskPoolParameterValidation( pInfo ) );\r
+\r
+        /* Create the system task pool pool. */\r
+        TASKPOOL_SET_AND_GOTO_CLEANUP( _createTaskPool( pInfo, &_IotSystemTaskPool ) );\r
+    }\r
+\r
+    TASKPOOL_NO_FUNCTION_CLEANUP();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+IotTaskPoolError_t IotTaskPool_CreateJob( IotTaskPoolRoutine_t userCallback,\r
+                                          void * pUserContext,\r
+                                          IotTaskPoolJobStorage_t * const pJobStorage,\r
+                                          IotTaskPoolJob_t * const ppJob )\r
+{\r
+    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
+\r
+    /* Parameter checking. */\r
+    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( userCallback );\r
+    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pJobStorage );\r
+    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( ppJob );\r
+\r
+    /* Build a job around the user-provided storage. */\r
+    _initializeJob( ( _taskPoolJob_t * ) pJobStorage, userCallback, pUserContext, true );\r
+\r
+    *ppJob = ( IotTaskPoolJob_t ) pJobStorage;\r
+\r
+    TASKPOOL_NO_FUNCTION_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotTaskPoolError_t IotTaskPool_CreateRecyclableJob( IotTaskPool_t taskPoolHandle,\r
+                                                    IotTaskPoolRoutine_t userCallback,\r
+                                                    void * pUserContext,\r
+                                                    IotTaskPoolJob_t * const ppJob )\r
+{\r
+    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
+\r
+    _taskPool_t * const pTaskPool = &_IotSystemTaskPool;\r
+    _taskPoolJob_t * pTempJob = NULL;\r
+\r
+    /* This lean version of the task pool only supports the task pool created\r
+    by this library (the system task pool).  NULL means use the system task\r
+    pool - no other values are allowed.  Use the full implementation of this\r
+    library if you want multiple task pools (there is more than one task in\r
+    each pool. */\r
+    configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) );\r
+\r
+    /* Avoid compiler warnings about unused parameters if configASSERT() is not\r
+    defined. */\r
+    ( void ) taskPoolHandle;\r
+\r
+    /* Parameter checking. */\r
+    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( userCallback );\r
+    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( ppJob );\r
+\r
+    taskENTER_CRITICAL();\r
+    {\r
+        /* Bail out early if this task pool is shutting down. */\r
+        pTempJob = _fetchOrAllocateJob( &pTaskPool->jobsCache );\r
+    }\r
+    taskEXIT_CRITICAL();\r
+\r
+    if( pTempJob == NULL )\r
+    {\r
+        IotLogInfo( "Failed to allocate a job." );\r
+\r
+        TASKPOOL_SET_AND_GOTO_CLEANUP( IOT_TASKPOOL_NO_MEMORY );\r
+    }\r
+\r
+    _initializeJob( pTempJob, userCallback, pUserContext, false );\r
+\r
+    *ppJob = pTempJob;\r
+\r
+    TASKPOOL_NO_FUNCTION_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotTaskPoolError_t IotTaskPool_DestroyRecyclableJob( IotTaskPool_t taskPoolHandle,\r
+                                                     IotTaskPoolJob_t pJobHandle )\r
+{\r
+    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
+\r
+    _taskPoolJob_t * pJob = ( _taskPoolJob_t * ) pJobHandle;\r
+\r
+    /* This lean version of the task pool only supports the task pool created\r
+    by this library (the system task pool).  NULL means use the system task\r
+    pool - no other values are allowed.  Use the full implementation of this\r
+    library if you want multiple task pools (there is more than one task in\r
+    each pool. */\r
+    configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) );\r
+\r
+    /* Avoid compiler warnings about unused parameters if configASSERT() is not\r
+    defined. */\r
+    ( void ) taskPoolHandle;\r
+\r
+    /* Parameter checking. */\r
+    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pJobHandle );\r
+\r
+    IotTaskPool_Assert( IotLink_IsLinked( &pJob->link ) == false );\r
+\r
+    _destroyJob( pJob );\r
+\r
+    TASKPOOL_NO_FUNCTION_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotTaskPoolError_t IotTaskPool_RecycleJob( IotTaskPool_t taskPoolHandle,\r
+                                           IotTaskPoolJob_t pJob )\r
+{\r
+    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
+\r
+    _taskPool_t * pTaskPool = ( _taskPool_t * ) &_IotSystemTaskPool;\r
+\r
+    /* This lean version of the task pool only supports the task pool created\r
+    by this library (the system task pool).  NULL means use the system task\r
+    pool - no other values are allowed.  Use the full implementation of this\r
+    library if you want multiple task pools (there is more than one task in\r
+    each pool. */\r
+    configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) );\r
+\r
+    /* Ensure unused parameters do not cause compiler warnings in case\r
+    configASSERT() is not defined. */\r
+    ( void ) taskPoolHandle;\r
+\r
+    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pJob );\r
+\r
+    taskENTER_CRITICAL();\r
+    {\r
+        IotTaskPool_Assert( IotLink_IsLinked( &pJob->link ) == false );\r
+\r
+        _recycleJob( &pTaskPool->jobsCache, pJob );\r
+    }\r
+    taskEXIT_CRITICAL();\r
+\r
+    TASKPOOL_NO_FUNCTION_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotTaskPoolError_t IotTaskPool_Schedule( IotTaskPool_t taskPoolHandle,\r
+                                         IotTaskPoolJob_t pJob,\r
+                                         uint32_t flags )\r
+{\r
+    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
+\r
+    _taskPool_t * const pTaskPool = &_IotSystemTaskPool;\r
+\r
+    /* Task pool must have been created. */\r
+    configASSERT( pTaskPool->running != false );\r
+\r
+    /* This lean version of the task pool only supports the task pool created\r
+    by this library (the system task pool).  NULL means use the system task\r
+    pool - no other values are allowed.  Use the full implementation of this\r
+    library if you want multiple task pools (there is more than one task in\r
+    each pool. */\r
+    configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) );\r
+\r
+    /* Avoid compiler warnings about unused parameters if configASSERT() is not\r
+    defined. */\r
+    ( void ) taskPoolHandle;\r
+\r
+    /* Parameter checking. */\r
+    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pJob );\r
+    TASKPOOL_ON_ARG_ERROR_GOTO_CLEANUP( ( flags != 0UL ) && ( flags != IOT_TASKPOOL_JOB_HIGH_PRIORITY ) );\r
+\r
+    taskENTER_CRITICAL(); //_RB_ Critical section is too long - does the whole thing need to be protected?\r
+    {\r
+        _scheduleInternal( pTaskPool, pJob );\r
+    }\r
+    taskEXIT_CRITICAL();\r
+\r
+    TASKPOOL_NO_FUNCTION_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotTaskPoolError_t IotTaskPool_ScheduleDeferred( IotTaskPool_t taskPoolHandle,\r
+                                                 IotTaskPoolJob_t job,\r
+                                                 uint32_t timeMs )\r
+{\r
+    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
+\r
+    _taskPool_t * pTaskPool = &_IotSystemTaskPool;\r
+\r
+    /* This lean version of the task pool only supports the task pool created\r
+    by this library (the system task pool).  NULL means use the system task\r
+    pool - no other values are allowed.  Use the full implementation of this\r
+    library if you want multiple task pools (there is more than one task in\r
+    each pool. */\r
+    configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) );\r
+\r
+    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( job );\r
+\r
+    if( timeMs == 0UL )\r
+    {\r
+        TASKPOOL_SET_AND_GOTO_CLEANUP( IotTaskPool_Schedule( pTaskPool, job, 0 ) );\r
+    }\r
+\r
+    taskENTER_CRITICAL();\r
+    {\r
+        _taskPoolTimerEvent_t * pTimerEvent = IotTaskPool_MallocTimerEvent( sizeof( _taskPoolTimerEvent_t ) );\r
+\r
+        if( pTimerEvent == NULL )\r
+        {\r
+            taskEXIT_CRITICAL();\r
+\r
+            TASKPOOL_SET_AND_GOTO_CLEANUP( IOT_TASKPOOL_NO_MEMORY );\r
+        }\r
+\r
+        IotLink_t * pTimerEventLink;\r
+\r
+        TickType_t now = xTaskGetTickCount();\r
+\r
+        pTimerEvent->link.pNext = NULL;\r
+        pTimerEvent->link.pPrevious = NULL;\r
+        pTimerEvent->expirationTime = now + pdMS_TO_TICKS( timeMs );\r
+        pTimerEvent->job = job; //_RB_ Think up to here can be outside the critical section.\r
+\r
+        /* Append the timer event to the timer list. */\r
+        IotListDouble_InsertSorted( &pTaskPool->timerEventsList, &pTimerEvent->link, _timerEventCompare );\r
+\r
+        /* Update the job status to 'scheduled'. */\r
+        job->status = IOT_TASKPOOL_STATUS_DEFERRED;\r
+\r
+        /* Peek the first event in the timer event list. There must be at least one,\r
+         * since we just inserted it. */\r
+        pTimerEventLink = IotListDouble_PeekHead( &pTaskPool->timerEventsList );\r
+        IotTaskPool_Assert( pTimerEventLink != NULL );\r
+\r
+        /* If the event we inserted is at the front of the queue, then\r
+         * we need to reschedule the underlying timer. */\r
+        if( pTimerEventLink == &pTimerEvent->link )\r
+        {\r
+            pTimerEvent = IotLink_Container( _taskPoolTimerEvent_t, pTimerEventLink, link );\r
+\r
+            _rescheduleDeferredJobsTimer( pTaskPool->timer, pTimerEvent );\r
+        }\r
+    }\r
+    taskEXIT_CRITICAL();\r
+\r
+    TASKPOOL_NO_FUNCTION_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotTaskPoolError_t IotTaskPool_GetStatus( IotTaskPool_t taskPoolHandle,\r
+                                          IotTaskPoolJob_t job,\r
+                                          IotTaskPoolJobStatus_t * const pStatus )\r
+{\r
+    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
+\r
+    /* This lean version of the task pool only supports the task pool created\r
+    by this library (the system task pool).  NULL means use the system task\r
+    pool - no other values are allowed.  Use the full implementation of this\r
+    library if you want multiple task pools (there is more than one task in\r
+    each pool. */\r
+    configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) );\r
+    ( void ) taskPoolHandle;\r
+\r
+    /* Parameter checking. */\r
+    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( job );\r
+    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pStatus );\r
+    *pStatus = IOT_TASKPOOL_STATUS_UNDEFINED;\r
+\r
+    taskENTER_CRITICAL();\r
+    {\r
+        *pStatus = job->status;\r
+    }\r
+    taskEXIT_CRITICAL();\r
+\r
+    TASKPOOL_NO_FUNCTION_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotTaskPoolError_t IotTaskPool_TryCancel( IotTaskPool_t taskPoolHandle,\r
+                                          IotTaskPoolJob_t job,\r
+                                          IotTaskPoolJobStatus_t * const pStatus )\r
+{\r
+    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
+\r
+    _taskPool_t * const pTaskPool = &_IotSystemTaskPool;\r
+\r
+    /* This lean version of the task pool only supports the task pool created\r
+    by this library (the system task pool).  NULL means use the system task\r
+    pool - no other values are allowed.  Use the full implementation of this\r
+    library if you want multiple task pools (there is more than one task in\r
+    each pool. */\r
+    configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) );\r
+    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( job );\r
+\r
+    if( pStatus != NULL )\r
+    {\r
+        *pStatus = IOT_TASKPOOL_STATUS_UNDEFINED;\r
+    }\r
+\r
+    taskENTER_CRITICAL();\r
+    {\r
+        status = _tryCancelInternal( pTaskPool, job, pStatus );\r
+    }\r
+    taskEXIT_CRITICAL();\r
+\r
+    TASKPOOL_NO_FUNCTION_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotTaskPoolJobStorage_t * IotTaskPool_GetJobStorageFromHandle( IotTaskPoolJob_t pJob )\r
+{\r
+    return ( IotTaskPoolJobStorage_t * ) pJob;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+const char * IotTaskPool_strerror( IotTaskPoolError_t status )\r
+{\r
+    const char * pMessage = NULL;\r
+\r
+    switch( status )\r
+    {\r
+        case IOT_TASKPOOL_SUCCESS:\r
+            pMessage = "SUCCESS";\r
+            break;\r
+\r
+        case IOT_TASKPOOL_BAD_PARAMETER:\r
+            pMessage = "BAD PARAMETER";\r
+            break;\r
+\r
+        case IOT_TASKPOOL_ILLEGAL_OPERATION:\r
+            pMessage = "ILLEGAL OPERATION";\r
+            break;\r
+\r
+        case IOT_TASKPOOL_NO_MEMORY:\r
+            pMessage = "NO MEMORY";\r
+            break;\r
+\r
+        case IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS:\r
+            pMessage = "SHUTDOWN IN PROGRESS";\r
+            break;\r
+\r
+        case IOT_TASKPOOL_CANCEL_FAILED:\r
+            pMessage = "CANCEL FAILED";\r
+            break;\r
+\r
+        default:\r
+            pMessage = "INVALID STATUS";\r
+            break;\r
+    }\r
+\r
+    return pMessage;\r
+}\r
+\r
+/* ---------------------------------------------------------------------------------------------- */\r
+/* ---------------------------------------------------------------------------------------------- */\r
+/* ---------------------------------------------------------------------------------------------- */\r
+\r
+static IotTaskPoolError_t _performTaskPoolParameterValidation( const IotTaskPoolInfo_t * const pInfo )\r
+{\r
+    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
+\r
+    /* Check input values for consistency. */\r
+    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pInfo );\r
+    TASKPOOL_ON_ARG_ERROR_GOTO_CLEANUP( pInfo->minThreads > pInfo->maxThreads );\r
+    TASKPOOL_ON_ARG_ERROR_GOTO_CLEANUP( pInfo->minThreads < 1UL );\r
+    TASKPOOL_ON_ARG_ERROR_GOTO_CLEANUP( pInfo->maxThreads < 1UL );\r
+\r
+    TASKPOOL_NO_FUNCTION_CLEANUP();\r
+}\r
+\r
+static void _initTaskPoolControlStructures( _taskPool_t * const pTaskPool )\r
+{\r
+    /* Initialize a job data structures that require no de-initialization.\r
+     * All other data structures carry a value of 'NULL' before initailization.\r
+     */\r
+    IotDeQueue_Create( &pTaskPool->dispatchQueue );\r
+    IotListDouble_Create( &pTaskPool->timerEventsList );\r
+\r
+    _initJobsCache( &pTaskPool->jobsCache );\r
+\r
+    /* Initialize the semaphore for waiting for incoming work.  Cannot fail as\r
+    statically allocated. */\r
+    pTaskPool->dispatchSignal = xSemaphoreCreateCountingStatic( TASKPOOL_MAX_SEM_VALUE, 0, &pTaskPool->dispatchSignalBuffer );\r
+}\r
+\r
+static IotTaskPoolError_t _createTaskPool( const IotTaskPoolInfo_t * const pInfo,\r
+                                           _taskPool_t * const pTaskPool )\r
+{\r
+    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
+\r
+    /* Static TCB structures and arrays to be used by statically allocated\r
+    worker tasks. */\r
+    static StaticTask_t workerTaskTCBs[ IOT_TASKPOOL_NUMBER_OF_WORKERS ];\r
+    static StackType_t workerTaskStacks[ IOT_TASKPOOL_NUMBER_OF_WORKERS ][ IOT_TASKPOOL_WORKER_STACK_SIZE_BYTES / sizeof( portSTACK_TYPE ) ];\r
+\r
+       /* Static structure to hold te software timer. */\r
+       static StaticTimer_t staticTimer;\r
+\r
+    uint32_t threadsCreated = 0; /* Although initialised before use removing the initialiser here results in compiler warnings. */\r
+    char taskName[ 10 ];\r
+\r
+    /* Check input values for consistency. */\r
+    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pTaskPool );\r
+\r
+    /* Zero out all data structures. */\r
+    memset( ( void * ) pTaskPool, 0x00, sizeof( _taskPool_t ) );\r
+\r
+    /* Initialize all internal data structure prior to creating all threads. */\r
+    _initTaskPoolControlStructures( pTaskPool );\r
+\r
+    /* Create the timer for a new connection. */\r
+    pTaskPool->timer = xTimerCreateStatic( NULL, /* Text name for the timer, only used for debugging. */\r
+                                                  portMAX_DELAY, /* Timer period in ticks. */\r
+                                                  pdFALSE, /* pdFALSE means its a one-shot timer. */\r
+                                                 ( void * ) pTaskPool, /* Parameter passed into callback. */\r
+                                                 _timerCallback, /* Callback that executes when the timer expires. */\r
+                                                 &staticTimer ); /* Static storage for the timer's data structure. */\r
+\r
+    /* The task pool will initialize the minimum number of threads requested by the user upon start.\r
+    Note this tailored version of the task pool does not autoscale, but fixes the number of tasks\r
+    in the pool to the originally specified minimum, and the specified maximum value is ignored. */\r
+    /* Create the minimum number of threads specified by the user, and if one fails shutdown and return error. */\r
+    for( threadsCreated = 0; threadsCreated < pInfo->minThreads; )\r
+    {\r
+        /* Generate a unique name for the task. */\r
+        snprintf( taskName, sizeof( taskName ), "pool%d", ( int ) threadsCreated );\r
+\r
+        xTaskCreateStatic( _taskPoolWorker, /* Function that implements the task. */\r
+                           taskName,       /* Text name for the task, used for debugging only. */\r
+                                      IOT_TASKPOOL_WORKER_STACK_SIZE_BYTES / sizeof( portSTACK_TYPE ), /* xTaskCreate() expects the stack size to be specified in words. */\r
+                           pTaskPool,       /* Parameter passed into the task. */\r
+                           pInfo->priority, /* Priority at which the task starts running. */\r
+                           &( workerTaskStacks[ threadsCreated ][ 0 ] ), /* Pointer to static storage for the task's stack. */\r
+                                                  &( workerTaskTCBs[ threadsCreated ] ) ); /* Pointer to static storage for te task's TCB. */\r
+\r
+               /* Upon successful thread creation, increase the number of active threads. */\r
+        pTaskPool->activeThreads++;\r
+        ++threadsCreated;\r
+    }\r
+       pTaskPool->running = true;\r
+\r
+    TASKPOOL_FUNCTION_CLEANUP();\r
+\r
+    TASKPOOL_FUNCTION_CLEANUP_END();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static void _destroyTaskPool( _taskPool_t * const pTaskPool )\r
+{\r
+    if( pTaskPool->timer != NULL )\r
+    {\r
+        xTimerDelete( pTaskPool->timer, 0 );\r
+    }\r
+}\r
+\r
+/* ---------------------------------------------------------------------------------------------- */\r
+\r
+static void _taskPoolWorker( void * pUserContext )\r
+{\r
+    IotTaskPool_Assert( pUserContext != NULL );\r
+\r
+    IotTaskPoolRoutine_t userCallback = NULL;\r
+\r
+    /* Extract pTaskPool pointer from context. */\r
+    _taskPool_t * pTaskPool = ( _taskPool_t * ) pUserContext;\r
+\r
+    /* OUTER LOOP: it controls the lifetime of the worker thread. */\r
+    for( ;; )\r
+    {\r
+        IotLink_t * pFirst = NULL;\r
+        _taskPoolJob_t * pJob = NULL;\r
+\r
+        /* Wait on incoming notifications... */\r
+        configASSERT( pTaskPool->dispatchSignal );\r
+        xSemaphoreTake( pTaskPool->dispatchSignal, portMAX_DELAY );\r
+\r
+        /* Acquire the lock to check for incoming notifications. */\r
+        taskENTER_CRITICAL();\r
+        {\r
+            /* Dequeue the first job in FIFO order. */\r
+            pFirst = IotDeQueue_DequeueHead( &pTaskPool->dispatchQueue );\r
+\r
+            /* If there is indeed a job, then update status under lock, and release the lock before processing the job. */\r
+            if( pFirst != NULL )\r
+            {\r
+                /* Extract the job from its link. */\r
+                pJob = IotLink_Container( _taskPoolJob_t, pFirst, link );\r
+\r
+                /* Update status to 'executing'. */\r
+                pJob->status = IOT_TASKPOOL_STATUS_COMPLETED; /*_RB_ Should this be 'executing'? */\r
+                userCallback = pJob->userCallback;\r
+            }\r
+        }\r
+        taskEXIT_CRITICAL();\r
+\r
+        /* INNER LOOP: it controls the execution of jobs: the exit condition is the lack of a job to execute. */\r
+        while( pJob != NULL )\r
+        {\r
+            /* Process the job by invoking the associated callback with the user context.\r
+             * This task pool thread will not be available until the user callback returns.\r
+             */\r
+            {\r
+                IotTaskPool_Assert( IotLink_IsLinked( &pJob->link ) == false );\r
+                IotTaskPool_Assert( userCallback != NULL );\r
+\r
+                userCallback( pTaskPool, pJob, pJob->pUserContext );\r
+\r
+                /* This job is finished, clear its pointer. */\r
+                pJob = NULL;\r
+                userCallback = NULL;\r
+            }\r
+\r
+            /* Acquire the lock before updating the job status. */\r
+            taskENTER_CRITICAL();\r
+            {\r
+                /* Try and dequeue the next job in the dispatch queue. */\r
+                IotLink_t * pItem = NULL;\r
+\r
+                /* Dequeue the next job from the dispatch queue. */\r
+                pItem = IotDeQueue_DequeueHead( &pTaskPool->dispatchQueue );\r
+\r
+                /* If there is no job left in the dispatch queue, update the worker status and leave. */\r
+                if( pItem == NULL )\r
+                {\r
+                    taskEXIT_CRITICAL();\r
+\r
+                    /* Abandon the INNER LOOP. Execution will transfer back to the OUTER LOOP condition. */\r
+                    break;\r
+                }\r
+                else\r
+                {\r
+                    pJob = IotLink_Container( _taskPoolJob_t, pItem, link );\r
+\r
+                    userCallback = pJob->userCallback;\r
+                }\r
+\r
+                pJob->status = IOT_TASKPOOL_STATUS_COMPLETED;\r
+            }\r
+            taskEXIT_CRITICAL();\r
+        }\r
+    }\r
+}\r
+\r
+/* ---------------------------------------------------------------------------------------------- */\r
+\r
+static void _initJobsCache( _taskPoolCache_t * const pCache )\r
+{\r
+    IotDeQueue_Create( &pCache->freeList );\r
+\r
+    pCache->freeCount = 0;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static void _initializeJob( _taskPoolJob_t * const pJob,\r
+                            IotTaskPoolRoutine_t userCallback,\r
+                            void * pUserContext,\r
+                            bool isStatic )\r
+{\r
+    pJob->link.pNext = NULL;\r
+    pJob->link.pPrevious = NULL;\r
+    pJob->userCallback = userCallback;\r
+    pJob->pUserContext = pUserContext;\r
+\r
+    if( isStatic )\r
+    {\r
+        pJob->flags = IOT_TASK_POOL_INTERNAL_STATIC;\r
+        pJob->status = IOT_TASKPOOL_STATUS_READY;\r
+    }\r
+    else\r
+    {\r
+        pJob->status = IOT_TASKPOOL_STATUS_READY;\r
+    }\r
+}\r
+\r
+static _taskPoolJob_t * _fetchOrAllocateJob( _taskPoolCache_t * const pCache )\r
+{\r
+    _taskPoolJob_t * pJob = NULL;\r
+    IotLink_t * pLink = IotListDouble_RemoveHead( &( pCache->freeList ) );\r
+\r
+    if( pLink != NULL )\r
+    {\r
+        pJob = IotLink_Container( _taskPoolJob_t, pLink, link );\r
+    }\r
+\r
+    /* If there is no available job in the cache, then allocate one. */\r
+    if( pJob == NULL )\r
+    {\r
+        pJob = ( _taskPoolJob_t * ) IotTaskPool_MallocJob( sizeof( _taskPoolJob_t ) );\r
+\r
+        if( pJob != NULL )\r
+        {\r
+            memset( pJob, 0x00, sizeof( _taskPoolJob_t ) );\r
+        }\r
+        else\r
+        {\r
+            /* Log allocation failure for troubleshooting purposes. */\r
+            IotLogInfo( "Failed to allocate job." );\r
+        }\r
+    }\r
+    /* If there was a job in the cache, then make sure we keep the counters up-to-date. */\r
+    else\r
+    {\r
+        IotTaskPool_Assert( pCache->freeCount > 0 );\r
+\r
+        pCache->freeCount--;\r
+    }\r
+\r
+    return pJob;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static void _recycleJob( _taskPoolCache_t * const pCache,\r
+                         _taskPoolJob_t * const pJob )\r
+{\r
+    /* We should never try and recycling a job that is linked into some queue. */\r
+    IotTaskPool_Assert( IotLink_IsLinked( &pJob->link ) == false );//_RB_ Seems to be duplicate of test before this is called.\r
+\r
+    /* We will recycle the job if there is space in the cache. */\r
+    if( pCache->freeCount < IOT_TASKPOOL_JOBS_RECYCLE_LIMIT )\r
+    {\r
+        /* Destroy user data, for added safety&security. */\r
+        pJob->userCallback = NULL;\r
+        pJob->pUserContext = NULL;\r
+\r
+        /* Reset the status for added debuggability. */\r
+        pJob->status = IOT_TASKPOOL_STATUS_UNDEFINED;\r
+\r
+        IotListDouble_InsertTail( &pCache->freeList, &pJob->link );\r
+\r
+        pCache->freeCount++;\r
+\r
+        IotTaskPool_Assert( pCache->freeCount >= 1 );\r
+    }\r
+    else\r
+    {\r
+        _destroyJob( pJob );\r
+    }\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static void _destroyJob( _taskPoolJob_t * const pJob )\r
+{\r
+    /* Destroy user data, for added safety & security. */\r
+    pJob->userCallback = NULL;\r
+    pJob->pUserContext = NULL;\r
+\r
+    /* Reset the status for added debuggability. */\r
+    pJob->status = IOT_TASKPOOL_STATUS_UNDEFINED;\r
+\r
+    /* Only dispose of dynamically allocated jobs. */\r
+    if( ( pJob->flags & IOT_TASK_POOL_INTERNAL_STATIC ) == 0UL )\r
+    {\r
+        IotTaskPool_FreeJob( pJob );\r
+    }\r
+}\r
+\r
+/* ---------------------------------------------------------------------------------------------- */\r
+\r
+static IotTaskPoolError_t _scheduleInternal( _taskPool_t * const pTaskPool,\r
+                                             _taskPoolJob_t * const pJob )\r
+{\r
+    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
+\r
+    /* Update the job status to 'scheduled'. */\r
+    pJob->status = IOT_TASKPOOL_STATUS_SCHEDULED;\r
+\r
+    /* Append the job to the dispatch queue. */\r
+    IotDeQueue_EnqueueTail( &pTaskPool->dispatchQueue, &pJob->link );\r
+\r
+    /* Signal a worker to pick up the job. */\r
+    xSemaphoreGive( pTaskPool->dispatchSignal );\r
+\r
+    TASKPOOL_NO_FUNCTION_CLEANUP_NOLABEL();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static bool _matchJobByPointer( const IotLink_t * const pLink,\r
+                                void * pMatch )\r
+{\r
+    const _taskPoolJob_t * const pJob = ( _taskPoolJob_t * ) pMatch;\r
+\r
+    const _taskPoolTimerEvent_t * const pTimerEvent = IotLink_Container( _taskPoolTimerEvent_t, pLink, link );\r
+\r
+    if( pJob == pTimerEvent->job )\r
+    {\r
+        return true;\r
+    }\r
+\r
+    return false;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static IotTaskPoolError_t _tryCancelInternal( _taskPool_t * const pTaskPool,\r
+                                              _taskPoolJob_t * const pJob,\r
+                                              IotTaskPoolJobStatus_t * const pStatus )\r
+{\r
+    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
+\r
+    bool cancelable = false;\r
+\r
+    /* We can only cancel jobs that are either 'ready' (waiting to be scheduled). 'deferred', or 'scheduled'. */\r
+\r
+    IotTaskPoolJobStatus_t currentStatus = pJob->status;\r
+\r
+    switch( currentStatus )\r
+    {\r
+        case IOT_TASKPOOL_STATUS_READY:\r
+        case IOT_TASKPOOL_STATUS_DEFERRED:\r
+        case IOT_TASKPOOL_STATUS_SCHEDULED:\r
+        case IOT_TASKPOOL_STATUS_CANCELED:\r
+            cancelable = true;\r
+            break;\r
+\r
+        case IOT_TASKPOOL_STATUS_COMPLETED:\r
+            /* Log message for debug purposes. */\r
+            IotLogWarn( "Attempt to cancel a job that is already executing, or canceled." );\r
+            break;\r
+\r
+        default:\r
+            /* Log message for debug purposes purposes. */\r
+            IotLogError( "Attempt to cancel a job with an undefined state." );\r
+            break;\r
+    }\r
+\r
+    /* Update the returned status to the current status of the job. */\r
+    if( pStatus != NULL )\r
+    {\r
+        *pStatus = currentStatus;\r
+    }\r
+\r
+    if( cancelable == false )\r
+    {\r
+        TASKPOOL_SET_AND_GOTO_CLEANUP( IOT_TASKPOOL_CANCEL_FAILED );\r
+    }\r
+    else\r
+    {\r
+        /* Update the status of the job. */\r
+        pJob->status = IOT_TASKPOOL_STATUS_CANCELED;\r
+\r
+        /* If the job is cancelable and its current status is 'scheduled' then unlink it from the dispatch\r
+         * queue and signal any waiting threads. */\r
+        if( currentStatus == IOT_TASKPOOL_STATUS_SCHEDULED )\r
+        {\r
+            /* A scheduled work items must be in the dispatch queue. */\r
+            IotTaskPool_Assert( IotLink_IsLinked( &pJob->link ) );\r
+\r
+            IotDeQueue_Remove( &pJob->link );\r
+        }\r
+\r
+        /* If the job current status is 'deferred' then the job has to be pending\r
+         * in the timeouts queue. */\r
+        else if( currentStatus == IOT_TASKPOOL_STATUS_DEFERRED )\r
+        {\r
+            /* Find the timer event associated with the current job. There MUST be one, hence assert if not. */\r
+            IotLink_t * pTimerEventLink = IotListDouble_FindFirstMatch( &pTaskPool->timerEventsList, NULL, _matchJobByPointer, pJob );\r
+            IotTaskPool_Assert( pTimerEventLink != NULL );\r
+\r
+            if( pTimerEventLink != NULL )\r
+            {\r
+                bool shouldReschedule = false;\r
+\r
+                /* If the job being canceled was at the head of the timeouts queue, then we need to reschedule the timer\r
+                 * with the next job timeout */\r
+                IotLink_t * pHeadLink = IotListDouble_PeekHead( &pTaskPool->timerEventsList );\r
+\r
+                if( pHeadLink == pTimerEventLink )\r
+                {\r
+                    shouldReschedule = true;\r
+                }\r
+\r
+                /* Remove the timer event associated with the canceled job and free the associated memory. */\r
+                IotListDouble_Remove( pTimerEventLink );\r
+                IotTaskPool_FreeTimerEvent( IotLink_Container( _taskPoolTimerEvent_t, pTimerEventLink, link ) );\r
+\r
+                if( shouldReschedule )\r
+                {\r
+                    IotLink_t * pNextTimerEventLink = IotListDouble_PeekHead( &pTaskPool->timerEventsList );\r
+\r
+                    if( pNextTimerEventLink != NULL )\r
+                    {\r
+                        _rescheduleDeferredJobsTimer( pTaskPool->timer, IotLink_Container( _taskPoolTimerEvent_t, pNextTimerEventLink, link ) );\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        else\r
+        {\r
+            /* A cancelable job status should be either 'scheduled' or 'deferrred'. */\r
+            IotTaskPool_Assert( ( currentStatus == IOT_TASKPOOL_STATUS_READY ) || ( currentStatus == IOT_TASKPOOL_STATUS_CANCELED ) );\r
+        }\r
+    }\r
+\r
+    TASKPOOL_NO_FUNCTION_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static int32_t _timerEventCompare( const IotLink_t * const pTimerEventLink1,\r
+                                   const IotLink_t * const pTimerEventLink2 )\r
+{\r
+    const _taskPoolTimerEvent_t * const pTimerEvent1 = IotLink_Container( _taskPoolTimerEvent_t,\r
+                                                                          pTimerEventLink1,\r
+                                                                          link );\r
+    const _taskPoolTimerEvent_t * const pTimerEvent2 = IotLink_Container( _taskPoolTimerEvent_t,\r
+                                                                          pTimerEventLink2,\r
+                                                                          link );\r
+\r
+    if( pTimerEvent1->expirationTime < pTimerEvent2->expirationTime )\r
+    {\r
+        return -1;\r
+    }\r
+\r
+    if( pTimerEvent1->expirationTime > pTimerEvent2->expirationTime )\r
+    {\r
+        return 1;\r
+    }\r
+\r
+    return 0;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static void _rescheduleDeferredJobsTimer( TimerHandle_t const timer,\r
+                                          _taskPoolTimerEvent_t * const pFirstTimerEvent )\r
+{\r
+    uint64_t delta = 0;\r
+    TickType_t now = xTaskGetTickCount();\r
+\r
+    if( pFirstTimerEvent->expirationTime > now )\r
+    {\r
+        delta = pFirstTimerEvent->expirationTime - now;\r
+    }\r
+\r
+    if( delta < TASKPOOL_JOB_RESCHEDULE_DELAY_MS )\r
+    {\r
+        delta = TASKPOOL_JOB_RESCHEDULE_DELAY_MS; /* The job will be late... */\r
+    }\r
+\r
+    IotTaskPool_Assert( delta > 0 );\r
+\r
+    if( xTimerChangePeriod( timer, ( uint32_t ) delta, portMAX_DELAY ) == pdFAIL )\r
+    {\r
+        IotLogWarn( "Failed to re-arm timer for task pool" );\r
+    }\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static void _timerCallback( TimerHandle_t xTimer )\r
+{\r
+    _taskPool_t * pTaskPool = pvTimerGetTimerID( xTimer );\r
+\r
+    IotTaskPool_Assert( pTaskPool );\r
+\r
+    _taskPoolTimerEvent_t * pTimerEvent = NULL;\r
+\r
+    IotLogDebug( "Timer thread started for task pool %p.", pTaskPool );\r
+\r
+    /* Attempt to lock the timer mutex. Return immediately if the mutex cannot be locked.\r
+     * If this mutex cannot be locked it means that another thread is manipulating the\r
+     * timeouts list, and will reset the timer to fire again, although it will be late.\r
+     */\r
+    taskENTER_CRITICAL(); //_RB_ Critical section is too long.\r
+    {\r
+        /* Dispatch all deferred job whose timer expired, then reset the timer for the next\r
+         * job down the line. */\r
+        for( ; ; )\r
+        {\r
+            /* Peek the first event in the timer event list. */\r
+            IotLink_t * pLink = IotListDouble_PeekHead( &pTaskPool->timerEventsList );\r
+\r
+            /* Check if the timer misfired for any reason.  */\r
+            if( pLink != NULL )\r
+            {\r
+                /* Record the current time. */\r
+                TickType_t now = xTaskGetTickCount();\r
+\r
+                /* Extract the job from its envelope. */\r
+                pTimerEvent = IotLink_Container( _taskPoolTimerEvent_t, pLink, link );\r
+\r
+                /* Check if the first event should be processed now. */\r
+                if( pTimerEvent->expirationTime <= now )\r
+                {\r
+                    /*  Remove the timer event for immediate processing. */\r
+                    IotListDouble_Remove( &( pTimerEvent->link ) );\r
+                }\r
+                else\r
+                {\r
+                    /* The first element in the timer queue shouldn't be processed yet.\r
+                     * Arm the timer for when it should be processed and leave altogether. */\r
+                    _rescheduleDeferredJobsTimer( pTaskPool->timer, pTimerEvent );\r
+\r
+                    break;\r
+                }\r
+            }\r
+            /* If there are no timer events to process, terminate this thread. */\r
+            else\r
+            {\r
+                IotLogDebug( "No further timer events to process. Exiting timer thread." );\r
+\r
+                break;\r
+            }\r
+\r
+            IotLogDebug( "Scheduling job from timer event." );\r
+\r
+            /* Queue the job associated with the received timer event. */\r
+            ( void ) _scheduleInternal( pTaskPool, pTimerEvent->job );\r
+\r
+            /* Free the timer event. */\r
+            IotTaskPool_FreeTimerEvent( pTimerEvent );\r
+        }\r
+    }\r
+    taskEXIT_CRITICAL();\r
+}\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/taskpool/iot_taskpool_static_memory.c b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/taskpool/iot_taskpool_static_memory.c
new file mode 100644 (file)
index 0000000..8de4f6e
--- /dev/null
@@ -0,0 +1,175 @@
+/*\r
+ * Amazon FreeRTOS Common V1.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_taskpool_static_memory.c\r
+ * @brief Implementation of task pool static memory functions.\r
+ */\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/* This file should only be compiled if dynamic memory allocation is forbidden. */\r
+#if IOT_STATIC_MEMORY_ONLY == 1\r
+\r
+/* Standard includes. */\r
+#include <stdbool.h>\r
+#include <stddef.h>\r
+#include <string.h>\r
+\r
+/* Static memory include. */\r
+#include "private/iot_static_memory.h"\r
+\r
+/* Task pool internal include. */\r
+#include "private/iot_taskpool_internal.h"\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Validate static memory configuration settings. */\r
+#if IOT_TASKPOOL_JOBS_RECYCLE_LIMIT <= 0\r
+    #error "IOT_TASKPOOL_JOBS_RECYCLE_LIMIT cannot be 0 or negative."\r
+#endif\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Static memory buffers and flags, allocated and zeroed at compile-time.\r
+ */\r
+static bool _pInUseTaskPools[ IOT_TASKPOOLS ] = { 0 };                                                /**< @brief Task pools in-use flags. */\r
+static _taskPool_t _pTaskPools[ IOT_TASKPOOLS ] = { { .dispatchQueue = IOT_DEQUEUE_INITIALIZER } };   /**< @brief Task pools. */\r
+\r
+static bool _pInUseTaskPoolJobs[ IOT_TASKPOOL_JOBS_RECYCLE_LIMIT ] = { 0 };                                     /**< @brief Task pool jobs in-use flags. */\r
+static _taskPoolJob_t _pTaskPoolJobs[ IOT_TASKPOOL_JOBS_RECYCLE_LIMIT ] = { { .link = IOT_LINK_INITIALIZER } }; /**< @brief Task pool jobs. */\r
+\r
+static bool _pInUseTaskPoolTimerEvents[ IOT_TASKPOOL_JOBS_RECYCLE_LIMIT ] = { 0 };                              /**< @brief Task pool timer event in-use flags. */\r
+static _taskPoolTimerEvent_t _pTaskPoolTimerEvents[ IOT_TASKPOOL_JOBS_RECYCLE_LIMIT ] = { { .link = { 0 } } };  /**< @brief Task pool timer events. */\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void * IotTaskPool_MallocTaskPool( size_t size )\r
+{\r
+    int freeIndex = -1;\r
+    void * pNewTaskPool = NULL;\r
+\r
+    /* Check size argument. */\r
+    if( size == sizeof( _taskPool_t ) )\r
+    {\r
+        /* Find a free task pool job. */\r
+        freeIndex = IotStaticMemory_FindFree( _pInUseTaskPools, IOT_TASKPOOLS );\r
+\r
+        if( freeIndex != -1 )\r
+        {\r
+            pNewTaskPool = &( _pTaskPools[ freeIndex ] );\r
+        }\r
+    }\r
+\r
+    return pNewTaskPool;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void IotTaskPool_FreeTaskPool( void * ptr )\r
+{\r
+    /* Return the in-use task pool job. */\r
+    IotStaticMemory_ReturnInUse( ptr,\r
+                                 _pTaskPools,\r
+                                 _pInUseTaskPools,\r
+                                 IOT_TASKPOOLS,\r
+                                 sizeof( _taskPool_t ) );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void * IotTaskPool_MallocJob( size_t size )\r
+{\r
+    int32_t freeIndex = -1;\r
+    void * pNewJob = NULL;\r
+\r
+    /* Check size argument. */\r
+    if( size == sizeof( _taskPoolJob_t ) )\r
+    {\r
+        /* Find a free task pool job. */\r
+        freeIndex = IotStaticMemory_FindFree( _pInUseTaskPoolJobs,\r
+                                              IOT_TASKPOOL_JOBS_RECYCLE_LIMIT );\r
+\r
+        if( freeIndex != -1 )\r
+        {\r
+            pNewJob = &( _pTaskPoolJobs[ freeIndex ] );\r
+        }\r
+    }\r
+\r
+    return pNewJob;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void IotTaskPool_FreeJob( void * ptr )\r
+{\r
+    /* Return the in-use task pool job. */\r
+    IotStaticMemory_ReturnInUse( ptr,\r
+                                 _pTaskPoolJobs,\r
+                                 _pInUseTaskPoolJobs,\r
+                                 IOT_TASKPOOL_JOBS_RECYCLE_LIMIT,\r
+                                 sizeof( _taskPoolJob_t ) );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void * IotTaskPool_MallocTimerEvent( size_t size )\r
+{\r
+    int32_t freeIndex = -1;\r
+    void * pNewTimerEvent = NULL;\r
+\r
+    /* Check size argument. */\r
+    if( size == sizeof( _taskPoolTimerEvent_t ) )\r
+    {\r
+        /* Find a free task pool timer event. */\r
+        freeIndex = IotStaticMemory_FindFree( _pInUseTaskPoolTimerEvents,\r
+                                              IOT_TASKPOOL_JOBS_RECYCLE_LIMIT );\r
+\r
+        if( freeIndex != -1 )\r
+        {\r
+            pNewTimerEvent = &( _pTaskPoolTimerEvents[ freeIndex ] );\r
+        }\r
+    }\r
+\r
+    return pNewTimerEvent;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void IotTaskPool_FreeTimerEvent( void * ptr )\r
+{\r
+    /* Return the in-use task pool timer event. */\r
+    IotStaticMemory_ReturnInUse( ptr,\r
+                                 _pTaskPoolTimerEvents,\r
+                                 _pInUseTaskPoolTimerEvents,\r
+                                 IOT_TASKPOOL_JOBS_RECYCLE_LIMIT,\r
+                                 sizeof( _taskPoolTimerEvent_t ) );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+#endif\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt.h
new file mode 100644 (file)
index 0000000..327784a
--- /dev/null
@@ -0,0 +1,823 @@
+/*\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.h\r
+ * @brief User-facing functions of the MQTT 3.1.1 library.\r
+ */\r
+\r
+#ifndef IOT_MQTT_H_\r
+#define IOT_MQTT_H_\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/* MQTT types include. */\r
+#include "types/iot_mqtt_types.h"\r
+\r
+/*------------------------- MQTT library functions --------------------------*/\r
+\r
+/**\r
+ * @functionspage{mqtt,MQTT library}\r
+ * - @functionname{mqtt_function_init}\r
+ * - @functionname{mqtt_function_cleanup}\r
+ * - @functionname{mqtt_function_receivecallback}\r
+ * - @functionname{mqtt_function_connect}\r
+ * - @functionname{mqtt_function_disconnect}\r
+ * - @functionname{mqtt_function_subscribe}\r
+ * - @functionname{mqtt_function_timedsubscribe}\r
+ * - @functionname{mqtt_function_unsubscribe}\r
+ * - @functionname{mqtt_function_timedunsubscribe}\r
+ * - @functionname{mqtt_function_publish}\r
+ * - @functionname{mqtt_function_timedpublish}\r
+ * - @functionname{mqtt_function_wait}\r
+ * - @functionname{mqtt_function_strerror}\r
+ * - @functionname{mqtt_function_operationtype}\r
+ * - @functionname{mqtt_function_issubscribed}\r
+ */\r
+\r
+/**\r
+ * @functionpage{IotMqtt_Init,mqtt,init}\r
+ * @functionpage{IotMqtt_Cleanup,mqtt,cleanup}\r
+ * @functionpage{IotMqtt_ReceiveCallback,mqtt,receivecallback}\r
+ * @functionpage{IotMqtt_Connect,mqtt,connect}\r
+ * @functionpage{IotMqtt_Disconnect,mqtt,disconnect}\r
+ * @functionpage{IotMqtt_Subscribe,mqtt,subscribe}\r
+ * @functionpage{IotMqtt_TimedSubscribe,mqtt,timedsubscribe}\r
+ * @functionpage{IotMqtt_Unsubscribe,mqtt,unsubscribe}\r
+ * @functionpage{IotMqtt_TimedUnsubscribe,mqtt,timedunsubscribe}\r
+ * @functionpage{IotMqtt_Publish,mqtt,publish}\r
+ * @functionpage{IotMqtt_TimedPublish,mqtt,timedpublish}\r
+ * @functionpage{IotMqtt_Wait,mqtt,wait}\r
+ * @functionpage{IotMqtt_strerror,mqtt,strerror}\r
+ * @functionpage{IotMqtt_OperationType,mqtt,operationtype}\r
+ * @functionpage{IotMqtt_IsSubscribed,mqtt,issubscribed}\r
+ */\r
+\r
+/**\r
+ * @brief One-time initialization function for the MQTT library.\r
+ *\r
+ * This function performs setup of the MQTT library. <b>It must be called\r
+ * once (and only once) before calling any other MQTT function.</b> Calling this\r
+ * function more than once without first calling @ref mqtt_function_cleanup\r
+ * may result in a crash.\r
+ *\r
+ * @return One of the following:\r
+ * - #IOT_MQTT_SUCCESS\r
+ * - #IOT_MQTT_INIT_FAILED\r
+ *\r
+ * @warning No thread-safety guarantees are provided for this function.\r
+ *\r
+ * @see @ref mqtt_function_cleanup\r
+ */\r
+/* @[declare_mqtt_init] */\r
+IotMqttError_t IotMqtt_Init( void );\r
+/* @[declare_mqtt_init] */\r
+\r
+/**\r
+ * @brief One-time deinitialization function for the MQTT library.\r
+ *\r
+ * This function frees resources taken in @ref mqtt_function_init. It should be\r
+ * called after [closing all MQTT connections](@ref mqtt_function_disconnect) to\r
+ * clean up the MQTT library. After this function returns, @ref mqtt_function_init\r
+ * must be called again before calling any other MQTT function.\r
+ *\r
+ * @warning No thread-safety guarantees are provided for this function. Do not\r
+ * call this function if any MQTT connections are open!\r
+ *\r
+ * @see @ref mqtt_function_init\r
+ */\r
+/* @[declare_mqtt_cleanup] */\r
+void IotMqtt_Cleanup( void );\r
+/* @[declare_mqtt_cleanup] */\r
+\r
+/**\r
+ * @brief Network receive callback for the MQTT library.\r
+ *\r
+ * This function should be called by the system whenever data is available for\r
+ * the MQTT library.\r
+ *\r
+ * @param[in] pNetworkConnection The network connection associated with the MQTT\r
+ * connection, passed by the network stack.\r
+ * @param[in] pReceiveContext A pointer to the MQTT connection handle for which\r
+ * the packet was received.\r
+ */\r
+/* @[declare_mqtt_receivecallback] */\r
+void IotMqtt_ReceiveCallback( void * pNetworkConnection,\r
+                              void * pReceiveContext );\r
+/* @[declare_mqtt_receivecallback] */\r
+\r
+/**\r
+ * @brief Establish a new MQTT connection.\r
+ *\r
+ * This function opens a connection between a new MQTT client and an MQTT server\r
+ * (also called a <i>broker</i>). MQTT connections are established on top of transport\r
+ * layer protocols (such as TCP/IP), and optionally, application layer security\r
+ * protocols (such as TLS). The MQTT packet that establishes a connection is called\r
+ * the MQTT CONNECT packet. After @ref mqtt_function_init, this function must be\r
+ * called before any other MQTT library function.\r
+ *\r
+ * If [pConnectInfo->cleanSession](@ref IotMqttConnectInfo_t.cleanSession) is `true`,\r
+ * this function establishes a clean MQTT session. Subscriptions and unacknowledged\r
+ * PUBLISH messages will be discarded when the connection is closed.\r
+ *\r
+ * If [pConnectInfo->cleanSession](@ref IotMqttConnectInfo_t.cleanSession) is `false`,\r
+ * this function establishes (or re-establishes) a persistent MQTT session. The parameters\r
+ * [pConnectInfo->pPreviousSubscriptions](@ref IotMqttConnectInfo_t.pPreviousSubscriptions)\r
+ * and [pConnectInfo->previousSubscriptionCount](@ref IotMqttConnectInfo_t.previousSubscriptionCount)\r
+ * may be used to restore subscriptions present in a re-established persistent session.\r
+ * Any restored subscriptions <b>MUST</b> have been present in the persistent session;\r
+ * <b>this function does not send an MQTT SUBSCRIBE packet!</b>\r
+ *\r
+ * This MQTT library is network agnostic, meaning it has no knowledge of the\r
+ * underlying network protocol carrying the MQTT packets. It interacts with the\r
+ * network through a network abstraction layer, allowing it to be used with many\r
+ * different network stacks. The network abstraction layer is established\r
+ * per-connection, allowing every #IotMqttConnection_t to use a different network\r
+ * stack. The parameter `pNetworkInterface` sets up the network abstraction layer\r
+ * for an MQTT connection; see the documentation on #IotMqttNetworkInfo_t for details\r
+ * on its members.\r
+ *\r
+ * The `pConnectInfo` parameter provides the contents of the MQTT CONNECT packet.\r
+ * Most members [are defined by the MQTT spec.](@ref IotMqttConnectInfo_t). The\r
+ * [pConnectInfo->pWillInfo](@ref IotMqttConnectInfo_t.pWillInfo) member provides\r
+ * information on a Last Will and Testament (LWT) message to be published if the\r
+ * MQTT connection is closed without [sending a DISCONNECT packet]\r
+ * (@ref mqtt_function_disconnect). Unlike other PUBLISH\r
+ * messages, a LWT message payload is limited to 65535 bytes in length. Additionally,\r
+ * the retry [interval](@ref IotMqttPublishInfo_t.retryMs) and [limit]\r
+ * (@ref IotMqttPublishInfo_t.retryLimit) members of #IotMqttPublishInfo_t\r
+ * are ignored for LWT messages. The LWT message is optional; `pWillInfo` may be NULL.\r
+ *\r
+ * Unlike @ref mqtt_function_publish, @ref mqtt_function_subscribe, and\r
+ * @ref mqtt_function_unsubscribe, this function is always blocking. Additionally,\r
+ * because the MQTT connection acknowledgement packet (CONNACK packet) does not\r
+ * contain any information on <i>which</i> CONNECT packet it acknowledges, only one\r
+ * CONNECT operation may be in progress at any time. This means that parallel\r
+ * threads making calls to @ref mqtt_function_connect will be serialized to send\r
+ * their CONNECT packets one-by-one.\r
+ *\r
+ * @param[in] pNetworkInfo Information on the transport-layer network connection\r
+ * to use with the MQTT connection.\r
+ * @param[in] pConnectInfo MQTT connection setup parameters.\r
+ * @param[in] timeoutMs If the MQTT server does not accept the connection within\r
+ * this timeout, this function returns #IOT_MQTT_TIMEOUT.\r
+ * @param[out] pMqttConnection Set to a newly-initialized MQTT connection handle\r
+ * if this function succeeds.\r
+ *\r
+ * @return One of the following:\r
+ * - #IOT_MQTT_SUCCESS\r
+ * - #IOT_MQTT_BAD_PARAMETER\r
+ * - #IOT_MQTT_NO_MEMORY\r
+ * - #IOT_MQTT_NETWORK_ERROR\r
+ * - #IOT_MQTT_SCHEDULING_ERROR\r
+ * - #IOT_MQTT_BAD_RESPONSE\r
+ * - #IOT_MQTT_TIMEOUT\r
+ * - #IOT_MQTT_SERVER_REFUSED\r
+ *\r
+ * <b>Example</b>\r
+ * @code{c}\r
+ * // An initialized and connected network connection.\r
+ * IotNetworkConnection_t pNetworkConnection;\r
+ *\r
+ * // Parameters to MQTT connect.\r
+ * IotMqttConnection_t mqttConnection = IOT_MQTT_CONNECTION_INITIALIZER;\r
+ * IotMqttNetworkInfo_t networkInfo = IOT_MQTT_NETWORK_INFO_INITIALIZER;\r
+ * IotMqttConnectInfo_t connectInfo = IOT_MQTT_CONNECT_INFO_INITIALIZER;\r
+ * IotMqttPublishInfo_t willInfo = IOT_MQTT_PUBLISH_INFO_INITIALIZER;\r
+ *\r
+ * // Example network abstraction types.\r
+ * IotNetworkServerInfo_t serverInfo = { ... };\r
+ * IotNetworkCredentialInfo_t credentialInfo = { ... };\r
+ * IotNetworkInterface_t networkInterface = { ... };\r
+ *\r
+ * // Example using a generic network implementation.\r
+ * networkInfo.createNetworkConnection = true;\r
+ * networkInfo.pNetworkServerInfo = &serverInfo;\r
+ * networkInfo.pNetworkCredentialInfo = &credentialInfo;\r
+ * networkInfo.pNetworkInterface = &networkInterface;\r
+ *\r
+ * // Set the members of the connection info (password and username not used).\r
+ * connectInfo.cleanSession = true;\r
+ * connectInfo.keepAliveSeconds = 30;\r
+ * connectInfo.pClientIdentifier = "uniqueclientidentifier";\r
+ * connectInfo.clientIdentifierLength = 22;\r
+ *\r
+ * // Set the members of the will info (retain and retry not used).\r
+ * willInfo.qos = IOT_MQTT_QOS_1;\r
+ * willInfo.pTopicName = "will/topic/name";\r
+ * willInfo.topicNameLength = 15;\r
+ * willInfo.pPayload = "MQTT client unexpectedly disconnected.";\r
+ * willInfo.payloadLength = 38;\r
+ *\r
+ * // Set the pointer to the will info.\r
+ * connectInfo.pWillInfo = &willInfo;\r
+ *\r
+ * // Call CONNECT with a 5 second block time. Should return\r
+ * // IOT_MQTT_SUCCESS when successful.\r
+ * IotMqttError_t result = IotMqtt_Connect( &networkInfo,\r
+ *                                          &connectInfo,\r
+ *                                          5000,\r
+ *                                          &mqttConnection );\r
+ *\r
+ * if( result == IOT_MQTT_SUCCESS )\r
+ * {\r
+ *     // Do something with the MQTT connection...\r
+ *\r
+ *     // Clean up and close the MQTT connection once it's no longer needed.\r
+ *     IotMqtt_Disconnect( mqttConnection, 0 );\r
+ * }\r
+ * @endcode\r
+ */\r
+/* @[declare_mqtt_connect] */\r
+IotMqttError_t IotMqtt_Connect( const IotMqttNetworkInfo_t * pNetworkInfo,\r
+                                const IotMqttConnectInfo_t * pConnectInfo,\r
+                                uint32_t timeoutMs,\r
+                                IotMqttConnection_t * const pMqttConnection );\r
+/* @[declare_mqtt_connect] */\r
+\r
+/**\r
+ * @brief Closes an MQTT connection and frees resources.\r
+ *\r
+ * This function closes an MQTT connection and should only be called once\r
+ * the MQTT connection is no longer needed. Its exact behavior depends on the\r
+ * `flags` parameter.\r
+ *\r
+ * Normally, `flags` should be `0`. This gracefully shuts down an MQTT\r
+ * connection by sending an MQTT DISCONNECT packet. Any [network close function]\r
+ * (@ref IotNetworkInterface_t::close) provided [when the connection was established]\r
+ * (@ref mqtt_function_connect) will also be called. Note that because the MQTT server\r
+ * will not acknowledge a DISCONNECT packet, the client has no way of knowing if\r
+ * the server received the DISCONNECT packet. In the case where the DISCONNECT\r
+ * packet is lost in transport, any Last Will and Testament (LWT) message established\r
+ * with the connection may be published. However, if the DISCONNECT reaches the\r
+ * MQTT server, the LWT message will be discarded and not published.\r
+ *\r
+ * Should the underlying network connection become unusable, this function should\r
+ * be called with `flags` set to #IOT_MQTT_FLAG_CLEANUP_ONLY. In this case, no\r
+ * DISCONNECT packet will be sent, though the [network close function](@ref IotNetworkInterface_t::close)\r
+ * will still be called. This function will only free the resources used by the MQTT\r
+ * connection; it still must be called even if the network is offline to avoid leaking\r
+ * resources.\r
+ *\r
+ * Once this function is called, its parameter `mqttConnection` should no longer\r
+ * be used.\r
+ *\r
+ * @param[in] mqttConnection The MQTT connection to close and clean up.\r
+ * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
+ */\r
+/* @[declare_mqtt_disconnect] */\r
+void IotMqtt_Disconnect( IotMqttConnection_t mqttConnection,\r
+                         uint32_t flags );\r
+/* @[declare_mqtt_disconnect] */\r
+\r
+/**\r
+ * @brief Subscribes to the given array of topic filters and receive an asynchronous\r
+ * notification when the subscribe completes.\r
+ *\r
+ * This function transmits an MQTT SUBSCRIBE packet to the server. A SUBSCRIBE\r
+ * packet notifies the server to send any matching PUBLISH messages to this client.\r
+ * A single SUBSCRIBE packet may carry more than one topic filter, hence the\r
+ * parameters to this function include an array of [subscriptions]\r
+ * (@ref IotMqttSubscription_t).\r
+ *\r
+ * An MQTT subscription has two pieces:\r
+ * 1. The subscription topic filter registered with the MQTT server. The MQTT\r
+ * SUBSCRIBE packet sent from this client to server notifies the server to send\r
+ * messages matching the given topic filters to this client.\r
+ * 2. The [callback function](@ref IotMqttCallbackInfo_t.function) that this\r
+ * client will invoke when an incoming message is received. The callback function\r
+ * notifies applications of an incoming PUBLISH message.\r
+ *\r
+ * The helper function @ref mqtt_function_issubscribed can be used to check if a\r
+ * [callback function](@ref IotMqttCallbackInfo_t.function) is registered for\r
+ * a particular topic filter.\r
+ *\r
+ * To modify an already-registered subscription callback, call this function with\r
+ * a new `pSubscriptionList`. Any topic filters in `pSubscriptionList` that already\r
+ * have a registered callback will be replaced with the new values in `pSubscriptionList`.\r
+ *\r
+ * @attention QoS 2 subscriptions are currently unsupported. Only 0 or 1 are valid\r
+ * for subscription QoS.\r
+ *\r
+ * @param[in] mqttConnection The MQTT connection to use for the subscription.\r
+ * @param[in] pSubscriptionList Pointer to the first element in the array of\r
+ * subscriptions.\r
+ * @param[in] subscriptionCount The number of elements in pSubscriptionList.\r
+ * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
+ * @param[in] pCallbackInfo Asynchronous notification of this function's completion.\r
+ * @param[out] pSubscribeOperation Set to a handle by which this operation may be\r
+ * referenced after this function returns. This reference is invalidated once\r
+ * the subscription operation completes.\r
+ *\r
+ * @return This function will return #IOT_MQTT_STATUS_PENDING upon success.\r
+ * @return Upon completion of the subscription (either through an\r
+ * #IotMqttCallbackInfo_t or @ref mqtt_function_wait), the status will be one of:\r
+ * - #IOT_MQTT_SUCCESS\r
+ * - #IOT_MQTT_NETWORK_ERROR\r
+ * - #IOT_MQTT_SCHEDULING_ERROR\r
+ * - #IOT_MQTT_BAD_RESPONSE\r
+ * - #IOT_MQTT_SERVER_REFUSED\r
+ * @return If this function fails before queuing a subscribe operation, it will return\r
+ * one of:\r
+ * - #IOT_MQTT_BAD_PARAMETER\r
+ * - #IOT_MQTT_NO_MEMORY\r
+ *\r
+ * @see @ref mqtt_function_timedsubscribe for a blocking variant of this function.\r
+ * @see @ref mqtt_function_unsubscribe for the function that removes subscriptions.\r
+ *\r
+ * <b>Example</b>\r
+ * @code{c}\r
+ * #define NUMBER_OF_SUBSCRIPTIONS ...\r
+ *\r
+ * // Subscription callback function.\r
+ * void subscriptionCallback( void * pArgument, IotMqttCallbackParam_t * pPublish );\r
+ *\r
+ * // An initialized and connected MQTT connection.\r
+ * IotMqttConnection_t mqttConnection;\r
+ *\r
+ * // Subscription information.\r
+ * pSubscriptions[ NUMBER_OF_SUBSCRIPTIONS ] = { IOT_MQTT_SUBSCRIPTION_INITIALIZER };\r
+ * IotMqttOperation_t lastOperation = IOT_MQTT_OPERATION_INITIALIZER;\r
+ *\r
+ * // Set the subscription information.\r
+ * for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )\r
+ * {\r
+ *     pSubscriptions[ i ].qos = IOT_MQTT_QOS_1;\r
+ *     pSubscriptions[ i ].pTopicFilter = "some/topic/filter";\r
+ *     pSubscriptions[ i ].topicLength = ( uint16_t ) strlen( pSubscriptions[ i ].pTopicFilter );\r
+ *     pSubscriptions[ i ].callback.function = subscriptionCallback;\r
+ * }\r
+ *\r
+ * IotMqttError_t result = IotMqtt_Subscribe( mqttConnection,\r
+ *                                            pSubscriptions,\r
+ *                                            NUMBER_OF_SUBSCRIPTIONS,\r
+ *                                            IOT_MQTT_FLAG_WAITABLE,\r
+ *                                            NULL,\r
+ *                                            &lastOperation );\r
+ *\r
+ * // Subscribe returns IOT_MQTT_STATUS_PENDING when successful. Wait up to\r
+ * // 5 seconds for the operation to complete.\r
+ * if( result == IOT_MQTT_STATUS_PENDING )\r
+ * {\r
+ *     result = IotMqtt_Wait( subscriptionRef, 5000 );\r
+ * }\r
+ *\r
+ * // Check that the subscriptions were successful.\r
+ * if( result == IOT_MQTT_SUCCESS )\r
+ * {\r
+ *     // Wait for messages on the subscription topic filters...\r
+ *\r
+ *     // Unsubscribe once the subscriptions are no longer needed.\r
+ *     result = IotMqtt_Unsubscribe( mqttConnection,\r
+ *                                   pSubscriptions,\r
+ *                                   NUMBER_OF_SUBSCRIPTIONS,\r
+ *                                   IOT_MQTT_FLAG_WAITABLE,\r
+ *                                   NULL,\r
+ *                                   &lastOperation );\r
+ *\r
+ *     // UNSUBSCRIBE returns IOT_MQTT_STATUS_PENDING when successful.\r
+ *     // Wait up to 5 seconds for the operation to complete.\r
+ *     if( result == IOT_MQTT_STATUS_PENDING )\r
+ *     {\r
+ *         result = IotMqtt_Wait( lastOperation, 5000 );\r
+ *     }\r
+ * }\r
+ * // Check which subscriptions were rejected by the server.\r
+ * else if( result == IOT_MQTT_SERVER_REFUSED )\r
+ * {\r
+ *     for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )\r
+ *     {\r
+ *         if( IotMqtt_IsSubscribed( mqttConnection,\r
+ *                                   pSubscriptions[ i ].pTopicFilter,\r
+ *                                   pSubscriptions[ i ].topicFilterLength,\r
+ *                                   NULL ) == false )\r
+ *         {\r
+ *             // This subscription was rejected.\r
+ *         }\r
+ *     }\r
+ * }\r
+ * @endcode\r
+ */\r
+/* @[declare_mqtt_subscribe] */\r
+IotMqttError_t IotMqtt_Subscribe( IotMqttConnection_t mqttConnection,\r
+                                  const IotMqttSubscription_t * pSubscriptionList,\r
+                                  size_t subscriptionCount,\r
+                                  uint32_t flags,\r
+                                  const IotMqttCallbackInfo_t * pCallbackInfo,\r
+                                  IotMqttOperation_t * pSubscribeOperation );\r
+/* @[declare_mqtt_subscribe] */\r
+\r
+/**\r
+ * @brief Subscribes to the given array of topic filters with a timeout.\r
+ *\r
+ * This function transmits an MQTT SUBSCRIBE packet to the server, then waits for\r
+ * a server response to the packet. Internally, this function is a call to @ref\r
+ * mqtt_function_subscribe followed by @ref mqtt_function_wait. See @ref\r
+ * mqtt_function_subscribe for more information about the MQTT SUBSCRIBE operation.\r
+ *\r
+ * @attention QoS 2 subscriptions are currently unsupported. Only 0 or 1 are valid\r
+ * for subscription QoS.\r
+ *\r
+ * @param[in] mqttConnection The MQTT connection to use for the subscription.\r
+ * @param[in] pSubscriptionList Pointer to the first element in the array of\r
+ * subscriptions.\r
+ * @param[in] subscriptionCount The number of elements in pSubscriptionList.\r
+ * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
+ * Currently, flags are ignored by this function; this parameter is for\r
+ * future-compatibility.\r
+ * @param[in] timeoutMs If the MQTT server does not acknowledge the subscriptions within\r
+ * this timeout, this function returns #IOT_MQTT_TIMEOUT.\r
+ *\r
+ * @return One of the following:\r
+ * - #IOT_MQTT_SUCCESS\r
+ * - #IOT_MQTT_BAD_PARAMETER\r
+ * - #IOT_MQTT_NO_MEMORY\r
+ * - #IOT_MQTT_NETWORK_ERROR\r
+ * - #IOT_MQTT_SCHEDULING_ERROR\r
+ * - #IOT_MQTT_BAD_RESPONSE\r
+ * - #IOT_MQTT_TIMEOUT\r
+ * - #IOT_MQTT_SERVER_REFUSED\r
+ */\r
+/* @[declare_mqtt_timedsubscribe] */\r
+IotMqttError_t IotMqtt_TimedSubscribe( IotMqttConnection_t mqttConnection,\r
+                                       const IotMqttSubscription_t * pSubscriptionList,\r
+                                       size_t subscriptionCount,\r
+                                       uint32_t flags,\r
+                                       uint32_t timeoutMs );\r
+/* @[declare_mqtt_timedsubscribe] */\r
+\r
+/**\r
+ * @brief Unsubscribes from the given array of topic filters and receive an asynchronous\r
+ * notification when the unsubscribe completes.\r
+ *\r
+ * This function transmits an MQTT UNSUBSCRIBE packet to the server. An UNSUBSCRIBE\r
+ * packet removes registered topic filters from the server. After unsubscribing,\r
+ * the server will no longer send messages on these topic filters to the client.\r
+ *\r
+ * Corresponding [subscription callback functions](@ref IotMqttCallbackInfo_t.function)\r
+ * are also removed from the MQTT connection. These subscription callback functions\r
+ * will be removed even if the MQTT UNSUBSCRIBE packet fails to send.\r
+ *\r
+ * @param[in] mqttConnection The MQTT connection used for the subscription.\r
+ * @param[in] pSubscriptionList Pointer to the first element in the array of\r
+ * subscriptions.\r
+ * @param[in] subscriptionCount The number of elements in pSubscriptionList.\r
+ * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
+ * @param[in] pCallbackInfo Asynchronous notification of this function's completion.\r
+ * @param[out] pUnsubscribeOperation Set to a handle by which this operation may be\r
+ * referenced after this function returns. This reference is invalidated once\r
+ * the unsubscribe operation completes.\r
+ *\r
+ * @return This function will return #IOT_MQTT_STATUS_PENDING upon success.\r
+ * @return Upon completion of the unsubscribe (either through an\r
+ * #IotMqttCallbackInfo_t or @ref mqtt_function_wait), the status will be one of:\r
+ * - #IOT_MQTT_SUCCESS\r
+ * - #IOT_MQTT_NETWORK_ERROR\r
+ * - #IOT_MQTT_SCHEDULING_ERROR\r
+ * - #IOT_MQTT_BAD_RESPONSE\r
+ * @return If this function fails before queuing an unsubscribe operation, it will return\r
+ * one of:\r
+ * - #IOT_MQTT_BAD_PARAMETER\r
+ * - #IOT_MQTT_NO_MEMORY\r
+ *\r
+ * @see @ref mqtt_function_timedsubscribe for a blocking variant of this function.\r
+ * @see @ref mqtt_function_subscribe for the function that adds subscriptions.\r
+ */\r
+/* @[declare_mqtt_unsubscribe] */\r
+IotMqttError_t IotMqtt_Unsubscribe( IotMqttConnection_t mqttConnection,\r
+                                    const IotMqttSubscription_t * pSubscriptionList,\r
+                                    size_t subscriptionCount,\r
+                                    uint32_t flags,\r
+                                    const IotMqttCallbackInfo_t * pCallbackInfo,\r
+                                    IotMqttOperation_t * pUnsubscribeOperation );\r
+/* @[declare_mqtt_unsubscribe] */\r
+\r
+/**\r
+ * @brief Unsubscribes from a given array of topic filters with a timeout.\r
+ *\r
+ * This function transmits an MQTT UNSUBSCRIBE packet to the server, then waits\r
+ * for a server response to the packet. Internally, this function is a call to\r
+ * @ref mqtt_function_unsubscribe followed by @ref mqtt_function_wait. See @ref\r
+ * mqtt_function_unsubscribe for more information about the MQTT UNSUBSCRIBE\r
+ * operation.\r
+ *\r
+ * @param[in] mqttConnection The MQTT connection used for the subscription.\r
+ * @param[in] pSubscriptionList Pointer to the first element in the array of\r
+ * subscriptions.\r
+ * @param[in] subscriptionCount The number of elements in pSubscriptionList.\r
+ * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
+ * Currently, flags are ignored by this function; this parameter is for\r
+ * future-compatibility.\r
+ * @param[in] timeoutMs If the MQTT server does not acknowledge the UNSUBSCRIBE within\r
+ * this timeout, this function returns #IOT_MQTT_TIMEOUT.\r
+ *\r
+ * @return One of the following:\r
+ * - #IOT_MQTT_SUCCESS\r
+ * - #IOT_MQTT_BAD_PARAMETER\r
+ * - #IOT_MQTT_NO_MEMORY\r
+ * - #IOT_MQTT_NETWORK_ERROR\r
+ * - #IOT_MQTT_SCHEDULING_ERROR\r
+ * - #IOT_MQTT_BAD_RESPONSE\r
+ */\r
+/* @[declare_mqtt_timedunsubscribe] */\r
+IotMqttError_t IotMqtt_TimedUnsubscribe( IotMqttConnection_t mqttConnection,\r
+                                         const IotMqttSubscription_t * pSubscriptionList,\r
+                                         size_t subscriptionCount,\r
+                                         uint32_t flags,\r
+                                         uint32_t timeoutMs );\r
+/* @[declare_mqtt_timedunsubscribe] */\r
+\r
+/**\r
+ * @brief Publishes a message to the given topic name and receive an asynchronous\r
+ * notification when the publish completes.\r
+ *\r
+ * This function transmits an MQTT PUBLISH packet to the server. A PUBLISH packet\r
+ * contains a payload and a topic name. Any clients with a subscription on a\r
+ * topic filter matching the PUBLISH topic name will receive a copy of the\r
+ * PUBLISH packet from the server.\r
+ *\r
+ * If a PUBLISH packet fails to reach the server and it is not a QoS 0 message,\r
+ * it will be retransmitted. See #IotMqttPublishInfo_t for a description\r
+ * of the retransmission strategy.\r
+ *\r
+ * @attention QoS 2 messages are currently unsupported. Only 0 or 1 are valid\r
+ * for message QoS.\r
+ *\r
+ * @param[in] mqttConnection The MQTT connection to use for the publish.\r
+ * @param[in] pPublishInfo MQTT publish parameters.\r
+ * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
+ * @param[in] pCallbackInfo Asynchronous notification of this function's completion.\r
+ * @param[out] pPublishOperation Set to a handle by which this operation may be\r
+ * referenced after this function returns. This reference is invalidated once\r
+ * the publish operation completes.\r
+ *\r
+ * @return This function will return #IOT_MQTT_STATUS_PENDING upon success for\r
+ * QoS 1 publishes. For a QoS 0 publish it returns #IOT_MQTT_SUCCESS upon\r
+ * success.\r
+ * @return Upon completion of a QoS 1 publish (either through an\r
+ * #IotMqttCallbackInfo_t or @ref mqtt_function_wait), the status will be one of:\r
+ * - #IOT_MQTT_SUCCESS\r
+ * - #IOT_MQTT_NETWORK_ERROR\r
+ * - #IOT_MQTT_SCHEDULING_ERROR\r
+ * - #IOT_MQTT_BAD_RESPONSE\r
+ * - #IOT_MQTT_RETRY_NO_RESPONSE (if [pPublishInfo->retryMs](@ref IotMqttPublishInfo_t.retryMs)\r
+ * and [pPublishInfo->retryLimit](@ref IotMqttPublishInfo_t.retryLimit) were set).\r
+ * @return If this function fails before queuing an publish operation (regardless\r
+ * of QoS), it will return one of:\r
+ * - #IOT_MQTT_BAD_PARAMETER\r
+ * - #IOT_MQTT_NO_MEMORY\r
+ *\r
+ * @note The parameters `pCallbackInfo` and `pPublishOperation` should only be used for QoS\r
+ * 1 publishes. For QoS 0, they should both be `NULL`.\r
+ *\r
+ * @see @ref mqtt_function_timedpublish for a blocking variant of this function.\r
+ *\r
+ * <b>Example</b>\r
+ * @code{c}\r
+ * // An initialized and connected MQTT connection.\r
+ * IotMqttConnection_t mqttConnection;\r
+ *\r
+ * // Publish information.\r
+ * IotMqttPublishInfo_t publishInfo = IOT_MQTT_PUBLISH_INFO_INITIALIZER;\r
+ *\r
+ * // Set the publish information. QoS 0 example (retain not used):\r
+ * publishInfo.qos = IOT_MQTT_QOS_0;\r
+ * publishInfo.pTopicName = "some/topic/name";\r
+ * publishInfo.topicNameLength = 15;\r
+ * publishInfo.pPayload = "payload";\r
+ * publishInfo.payloadLength = 8;\r
+ *\r
+ * // QoS 0 publish should return IOT_MQTT_SUCCESS upon success.\r
+ * IotMqttError_t qos0Result = IotMqtt_Publish( mqttConnection,\r
+ *                                              &publishInfo,\r
+ *                                              0,\r
+ *                                              NULL,\r
+ *                                              NULL );\r
+ *\r
+ * // QoS 1 with retry example (using same topic name and payload as QoS 0 example):\r
+ * IotMqttOperation_t qos1Operation = IOT_MQTT_OPERATION_INITIALIZER;\r
+ * publishInfo.qos = IOT_MQTT_QOS_1;\r
+ * publishInfo.retryMs = 1000; // Retry if no response is received in 1 second.\r
+ * publishInfo.retryLimit = 5; // Retry up to 5 times.\r
+ *\r
+ * // QoS 1 publish should return IOT_MQTT_STATUS_PENDING upon success.\r
+ * IotMqttError_t qos1Result = IotMqtt_Publish( mqttConnection,\r
+ *                                              &publishInfo,\r
+ *                                              IOT_MQTT_FLAG_WAITABLE,\r
+ *                                              NULL,\r
+ *                                              &qos1Operation );\r
+ *\r
+ * // Wait up to 5 seconds for the publish to complete.\r
+ * if( qos1Result == IOT_MQTT_STATUS_PENDING )\r
+ * {\r
+ *     qos1Result = IotMqtt_Wait( qos1Operation, 5000 );\r
+ * }\r
+ * @endcode\r
+ */\r
+/* @[declare_mqtt_publish] */\r
+IotMqttError_t IotMqtt_Publish( IotMqttConnection_t mqttConnection,\r
+                                const IotMqttPublishInfo_t * pPublishInfo,\r
+                                uint32_t flags,\r
+                                const IotMqttCallbackInfo_t * pCallbackInfo,\r
+                                IotMqttOperation_t * pPublishOperation );\r
+/* @[declare_mqtt_publish] */\r
+\r
+/**\r
+ * @brief Publish a message to the given topic name with a timeout.\r
+ *\r
+ * This function transmits an MQTT PUBLISH packet to the server, then waits for\r
+ * a server response to the packet. Internally, this function is a call to @ref\r
+ * mqtt_function_publish followed by @ref mqtt_function_wait. See @ref\r
+ * mqtt_function_publish for more information about the MQTT PUBLISH operation.\r
+ *\r
+ * @attention QoS 2 messages are currently unsupported. Only 0 or 1 are valid\r
+ * for message QoS.\r
+ *\r
+ * @param[in] mqttConnection The MQTT connection to use for the publish.\r
+ * @param[in] pPublishInfo MQTT publish parameters.\r
+ * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
+ * Currently, flags are ignored by this function; this parameter is for\r
+ * future-compatibility.\r
+ * @param[in] timeoutMs If the MQTT server does not acknowledge a QoS 1 PUBLISH\r
+ * within this timeout, this function returns #IOT_MQTT_TIMEOUT. This parameter\r
+ * is ignored for QoS 0 PUBLISH messages.\r
+ *\r
+ * @return One of the following:\r
+ * - #IOT_MQTT_SUCCESS\r
+ * - #IOT_MQTT_BAD_PARAMETER\r
+ * - #IOT_MQTT_NO_MEMORY\r
+ * - #IOT_MQTT_NETWORK_ERROR\r
+ * - #IOT_MQTT_SCHEDULING_ERROR\r
+ * - #IOT_MQTT_BAD_RESPONSE\r
+ * - #IOT_MQTT_RETRY_NO_RESPONSE (if [pPublishInfo->retryMs](@ref IotMqttPublishInfo_t.retryMs)\r
+ * and [pPublishInfo->retryLimit](@ref IotMqttPublishInfo_t.retryLimit) were set).\r
+ */\r
+/* @[declare_mqtt_timedpublish] */\r
+IotMqttError_t IotMqtt_TimedPublish( IotMqttConnection_t mqttConnection,\r
+                                     const IotMqttPublishInfo_t * pPublishInfo,\r
+                                     uint32_t flags,\r
+                                     uint32_t timeoutMs );\r
+/* @[declare_mqtt_timedpublish] */\r
+\r
+/**\r
+ * @brief Waits for an operation to complete.\r
+ *\r
+ * This function blocks to wait for a [subscribe](@ref mqtt_function_subscribe),\r
+ * [unsubscribe](@ref mqtt_function_unsubscribe), or [publish]\r
+ * (@ref mqtt_function_publish) to complete. These operations are by default\r
+ * asynchronous; the function calls queue an operation for processing, and a\r
+ * callback is invoked once the operation is complete.\r
+ *\r
+ * To use this function, the flag #IOT_MQTT_FLAG_WAITABLE must have been\r
+ * set in the operation's function call. Additionally, this function must always\r
+ * be called with any waitable operation to clean up resources.\r
+ *\r
+ * Regardless of its return value, this function always clean up resources used\r
+ * by the waitable operation. This means `reference` is invalidated as soon as\r
+ * this function returns, even if it returns #IOT_MQTT_TIMEOUT or another error.\r
+ *\r
+ * @param[in] operation Reference to the operation to wait for. The flag\r
+ * #IOT_MQTT_FLAG_WAITABLE must have been set for this operation.\r
+ * @param[in] timeoutMs How long to wait before returning #IOT_MQTT_TIMEOUT.\r
+ *\r
+ * @return The return value of this function depends on the MQTT operation associated\r
+ * with `reference`. See #IotMqttError_t for possible return values.\r
+ *\r
+ * <b>Example</b>\r
+ * @code{c}\r
+ * // Operation reference and timeout.\r
+ * IotMqttOperation_t publishOperation = IOT_MQTT_OPERATION_INITIALIZER;\r
+ * uint32_t timeoutMs = 5000; // 5 seconds\r
+ *\r
+ * // MQTT operation to wait for.\r
+ * IotMqttError_t result = IotMqtt_Publish( mqttConnection,\r
+ *                                          &publishInfo,\r
+ *                                          IOT_MQTT_FLAG_WAITABLE,\r
+ *                                          NULL,\r
+ *                                          &publishOperation );\r
+ *\r
+ * // Publish should have returned IOT_MQTT_STATUS_PENDING. The call to wait\r
+ * // returns once the result of the publish is available or the timeout expires.\r
+ * if( result == IOT_MQTT_STATUS_PENDING )\r
+ * {\r
+ *     result = IotMqtt_Wait( publishOperation, timeoutMs );\r
+ *\r
+ *     // After the call to wait, the result of the publish is known\r
+ *     // (not IOT_MQTT_STATUS_PENDING).\r
+ *     assert( result != IOT_MQTT_STATUS_PENDING );\r
+ * }\r
+ * @endcode\r
+ */\r
+/* @[declare_mqtt_wait] */\r
+IotMqttError_t IotMqtt_Wait( IotMqttOperation_t operation,\r
+                             uint32_t timeoutMs );\r
+/* @[declare_mqtt_wait] */\r
+\r
+/*-------------------------- MQTT helper functions --------------------------*/\r
+\r
+/**\r
+ * @brief Returns a string that describes an #IotMqttError_t.\r
+ *\r
+ * Like the POSIX's `strerror`, this function returns a string describing a\r
+ * return code. In this case, the return code is an MQTT library error code,\r
+ * `status`.\r
+ *\r
+ * The string returned by this function <b>MUST</b> be treated as read-only: any\r
+ * attempt to modify its contents may result in a crash. Therefore, this function\r
+ * is limited to usage in logging.\r
+ *\r
+ * @param[in] status The status to describe.\r
+ *\r
+ * @return A read-only string that describes `status`.\r
+ *\r
+ * @warning The string returned by this function must never be modified.\r
+ */\r
+/* @[declare_mqtt_strerror] */\r
+const char * IotMqtt_strerror( IotMqttError_t status );\r
+/* @[declare_mqtt_strerror] */\r
+\r
+/**\r
+ * @brief Returns a string that describes an #IotMqttOperationType_t.\r
+ *\r
+ * This function returns a string describing an MQTT operation type, `operation`.\r
+ *\r
+ * The string returned by this function <b>MUST</b> be treated as read-only: any\r
+ * attempt to modify its contents may result in a crash. Therefore, this function\r
+ * is limited to usage in logging.\r
+ *\r
+ * @param[in] operation The operation to describe.\r
+ *\r
+ * @return A read-only string that describes `operation`.\r
+ *\r
+ * @warning The string returned by this function must never be modified.\r
+ */\r
+/* @[declare_mqtt_operationtype] */\r
+const char * IotMqtt_OperationType( IotMqttOperationType_t operation );\r
+/* @[declare_mqtt_operationtype] */\r
+\r
+/**\r
+ * @brief Check if an MQTT connection has a subscription for a topic filter.\r
+ *\r
+ * This function checks whether an MQTT connection `mqttConnection` has a\r
+ * subscription callback registered for a topic filter `pTopicFilter`. If a\r
+ * subscription callback is found, its details are copied into the output parameter\r
+ * `pCurrentSubscription`. This subscription callback will be invoked for incoming\r
+ * PUBLISH messages on `pTopicFilter`.\r
+ *\r
+ * <b>The check for a matching subscription is only performed client-side</b>;\r
+ * therefore, this function should not be relied upon for perfect accuracy. For\r
+ * example, this function may return an incorrect result if the MQTT server\r
+ * crashes and drops subscriptions without informing the client.\r
+ *\r
+ * Note that an MQTT connection's subscriptions might change between the time this\r
+ * function checks the subscription list and its caller tests the return value.\r
+ * This function certainly should not be used concurrently with any pending SUBSCRIBE\r
+ * or UNSUBSCRIBE operations.\r
+ *\r
+ * One suitable use of this function is to check <i>which</i> subscriptions were rejected\r
+ * if @ref mqtt_function_subscribe returns #IOT_MQTT_SERVER_REFUSED; that return\r
+ * code only means that <i>at least one</i> subscription was rejected.\r
+ *\r
+ * @param[in] mqttConnection The MQTT connection to check.\r
+ * @param[in] pTopicFilter The topic filter to check.\r
+ * @param[in] topicFilterLength Length of `pTopicFilter`.\r
+ * @param[out] pCurrentSubscription If a subscription is found, its details are\r
+ * copied here. This output parameter is only valid if this function returns `true`.\r
+ * Pass `NULL` to ignore.\r
+ *\r
+ * @return `true` if a subscription was found; `false` otherwise.\r
+ *\r
+ * @note The subscription QoS is not stored by the MQTT library; therefore,\r
+ * `pCurrentSubscription->qos` will always be set to #IOT_MQTT_QOS_0.\r
+ */\r
+/* @[declare_mqtt_issubscribed] */\r
+bool IotMqtt_IsSubscribed( IotMqttConnection_t mqttConnection,\r
+                           const char * pTopicFilter,\r
+                           uint16_t topicFilterLength,\r
+                           IotMqttSubscription_t * pCurrentSubscription );\r
+/* @[declare_mqtt_issubscribed] */\r
+\r
+#endif /* ifndef IOT_MQTT_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt_agent.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt_agent.h
new file mode 100644 (file)
index 0000000..fbaaeb7
--- /dev/null
@@ -0,0 +1,358 @@
+/*\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_agent.h\r
+ * @brief MQTT Agent Interface.\r
+ */\r
+\r
+#ifndef _AWS_MQTT_AGENT_H_\r
+#define _AWS_MQTT_AGENT_H_\r
+\r
+/* FreeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+\r
+/* MQTT lib includes. */\r
+#include "iot_mqtt_lib.h"\r
+\r
+/* Library initialization definition include */\r
+#include "iot_lib_init.h"\r
+\r
+/**\r
+ * @brief Opaque handle to represent an MQTT client.\r
+ *\r
+ * The MQTT library is capable of creating multiple MQTT clients, maximum number of which\r
+ * is controlled by mqttconfigMAX_BROKERS macro. Each client is identified by an opaque\r
+ * handle which is returned by the MQTT_AGENT_Create API call and later used in all\r
+ * the subsequent API calls.\r
+ */\r
+typedef void * MQTTAgentHandle_t;\r
+\r
+/**\r
+ * @brief Return codes.\r
+ *\r
+ * Each API returns a value of this type.\r
+ */\r
+typedef enum\r
+{\r
+    eMQTTAgentSuccess,              /**< The operation was successful. */\r
+    eMQTTAgentFailure,              /**< The operation failed. */\r
+    eMQTTAgentTimeout,              /**< The operation timed out. */\r
+    eMQTTAgentAPICalledFromCallback /**< The MQTT agent APIs must not be called from MQTT callbacks as callbacks run\r
+                                     *   in the context of MQTT agent task and therefore can result in deadlock. This\r
+                                     *   error code is returned if any MQTT agent API is invoked from any callback. */\r
+} MQTTAgentReturnCode_t;\r
+\r
+/**\r
+ * @brief Various events reported by the library in the callback.\r
+ *\r
+ * The user can register an optional callback with the MQTT library to\r
+ * get notified of various events including Publish messages received\r
+ * from the broker. This enum identifies the event received in the\r
+ * callback.\r
+ */\r
+typedef enum\r
+{\r
+    eMQTTAgentPublish,   /**< A Publish message was received from the broker. */\r
+    eMQTTAgentDisconnect /**< The connection to the broker got disconnected. */\r
+} MQTTAgentEvent_t;\r
+\r
+/**\r
+ * @brief Passed by the library in the callback to inform the user of various events.\r
+ *\r
+ * If the user has registered a callback to get notified of various events, a pointer\r
+ * to this structure is passed in the callback function.\r
+ * @see MQTTAgentEvent_t.\r
+ */\r
+typedef struct MQTTAgentCallbackParams\r
+{\r
+    MQTTAgentEvent_t xMQTTEvent; /**< Type of the event received. */\r
+    /* This union is here for future support. */\r
+    union\r
+    {\r
+        MQTTPublishData_t xPublishData; /**< Publish data. Meaningful only in case of eMQTTAgentPublish event. */\r
+    } u;\r
+} MQTTAgentCallbackParams_t;\r
+\r
+/**\r
+ * @brief Signature of the callback registered by the user to get notified of various events.\r
+ *\r
+ * The user can register an optional callback to get notified of various events.\r
+ *\r
+ * @param[in] pvUserData The user data as provided in the connect parameters while connecting.\r
+ * @param[in] pxCallbackParams The event and related data.\r
+ *\r
+ * @return The return value is ignored in all other cases except publish (i.e. eMQTTAgentPublish\r
+ * event):\r
+ * 1. If pdTRUE is returned - The ownership of the buffer passed in the callback (xBuffer\r
+ * in MQTTPublishData_t) lies with the user.\r
+ * 2. If pdFALSE is returned - The ownership of the buffer passed in the callback (xBuffer\r
+ * in MQTTPublishData_t) remains with the library and it is recycled as soon as\r
+ * the callback returns.<br>\r
+ * The user should take the ownership of the buffer containing the received message from the\r
+ * broker by returning pdTRUE from the callback if the user wants to use the buffer after\r
+ * the callback is over. The user should return the buffer whenever done by calling the\r
+ * MQTT_AGENT_ReturnBuffer API.\r
+ *\r
+ * @see MQTTAgentCallbackParams_t.\r
+ */\r
+typedef BaseType_t ( * MQTTAgentCallback_t )( void * pvUserData,\r
+                                              const MQTTAgentCallbackParams_t * const pxCallbackParams );\r
+\r
+/**\r
+ * @brief Flags for the MQTT agent connect params.\r
+ */\r
+#define mqttagentURL_IS_IP_ADDRESS       0x00000001    /**< Set this bit in xFlags if the provided URL is an IP address. */\r
+#define mqttagentREQUIRE_TLS             0x00000002    /**< Set this bit in xFlags to use TLS. */\r
+#define mqttagentUSE_AWS_IOT_ALPN_443    0x00000004    /**< Set this bit in xFlags to use AWS IoT support for MQTT over TLS port 443. */\r
+\r
+/**\r
+ * @brief Parameters passed to the MQTT_AGENT_Connect API.\r
+ */\r
+typedef struct MQTTAgentConnectParams\r
+{\r
+    const char * pcURL;             /**< The URL of the MQTT broker to connect to. */\r
+    BaseType_t xFlags;              /**< Flags to control the behavior of MQTT connect. */\r
+    BaseType_t xURLIsIPAddress;     /**< Deprecated. Set the mqttagentURL_IS_IP_ADDRESS bit in xFlags instead. */\r
+    uint16_t usPort;                /**< Port number at which MQTT broker is listening. This field is ignored if the mqttagentUSE_AWS_IOT_ALPN_443 flag is set. */\r
+    const uint8_t * pucClientId;    /**< Client Identifier of the MQTT client. It should be unique per broker. */\r
+    uint16_t usClientIdLength;      /**< The length of the client Id. */\r
+    BaseType_t xSecuredConnection;  /**< Deprecated. Set the mqttagentREQUIRE_TLS bit in xFlags instead. */\r
+    void * pvUserData;              /**< User data supplied back as it is in the callback. Can be NULL. */\r
+    MQTTAgentCallback_t pxCallback; /**< Callback used to report various events. In addition to other events, this callback is invoked for the publish\r
+                                     *   messages received on the topics for which the user has not registered any subscription callback. Can be NULL. */\r
+    char * pcCertificate;           /**< Certificate used for secure connection. Can be NULL. If it is NULL, the one specified in the aws_credential_keys.h is used. */\r
+    uint32_t ulCertificateSize;     /**< Size of certificate used for secure connection. */\r
+} MQTTAgentConnectParams_t;\r
+\r
+/**\r
+ * @brief Parameters passed to the MQTT_AGENT_Subscribe API.\r
+ */\r
+typedef struct MQTTAgentSubscribeParams\r
+{\r
+    const uint8_t * pucTopic;                    /**< The topic to subscribe to. This can be a topic filter containing wild cards as permitted by the MQTT protocol. */\r
+    uint16_t usTopicLength;                      /**< The length of the topic. */\r
+    MQTTQoS_t xQoS;                              /**< Requested Quality of Service. */\r
+    #if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 )\r
+        void * pvPublishCallbackContext;         /**< Passed as it is in the publish callback. Can be NULL. */\r
+        MQTTPublishCallback_t pxPublishCallback; /**< Callback function to be called whenever a publish message is received on this topic or on a topic which matches this\r
+                                                  *   topic filter. If a publish message is received on a topic which matches more than one topic filters, the order in which\r
+                                                  *   the callbacks are invoked is undefined. This can be NULL if the user does not want to register a topic specific callback,\r
+                                                  *   in which case the generic callback ( if registered during connect ) is invoked. */\r
+    #endif /* mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT */\r
+} MQTTAgentSubscribeParams_t;\r
+\r
+/**\r
+ * @brief Parameters passed to the MQTT_AGENT_Unsubscribe API.\r
+ */\r
+typedef struct MQTTAgentUnsubscribeParams\r
+{\r
+    const uint8_t * pucTopic; /**< The topic to unsubscribe from. */\r
+    uint16_t usTopicLength;   /**< The length of the topic. */\r
+} MQTTAgentUnsubscribeParams_t;\r
+\r
+/**\r
+ * @brief Parameters passed to the MQTT_AGENT_Publish API.\r
+ */\r
+typedef struct MQTTAgentPublishParams\r
+{\r
+    const uint8_t * pucTopic; /**< The topic string on which the message should be published. */\r
+    uint16_t usTopicLength;   /**< The length of the topic. */\r
+    MQTTQoS_t xQoS;           /**< Quality of Service (qos). */\r
+    const void * pvData;      /**< The data to publish. This data is copied into the MQTT buffers and therefore the user can free the buffer after the MQTT_AGENT_Publish call returns. */\r
+    uint32_t ulDataLength;    /**< Length of the data. */\r
+} MQTTAgentPublishParams_t;\r
+\r
+/**\r
+ * @brief MQTT library Init function.\r
+ *\r
+ * This function does general initialization and setup. It must be called once\r
+ * and only once before calling any other function.\r
+ *\r
+ * @return pdPASS if everything succeeds, pdFAIL otherwise.\r
+ */\r
+lib_initDECLARE_LIB_INIT( MQTT_AGENT_Init );\r
+\r
+/**\r
+ * @brief Creates a new MQTT client.\r
+ *\r
+ * The MQTT library is capable of creating multiple MQTT clients, maximum number of which\r
+ * is controlled by mqttconfigMAX_BROKERS macro. If mqttconfigMAX_BROKERS clients are already\r
+ * in use, this function will fail immediately. Otherwise a new client is setup and the handle\r
+ * to the created client is returned in the pxMQTTHandle parameter which should be used in all\r
+ * the subsequent API calls. Note that the returned handled is only valid if the return value\r
+ * of the API is eMQTTAgentSuccess.\r
+ *\r
+ * @param[out] pxMQTTHandle Output parameter to return the opaque client handle.\r
+ *\r
+ * @return eMQTTAgentSuccess if a new client is successfully created, otherwise an error code\r
+ * explaining the reason of the failure is returned.\r
+ */\r
+MQTTAgentReturnCode_t MQTT_AGENT_Create( MQTTAgentHandle_t * const pxMQTTHandle );\r
+\r
+/**\r
+ * @brief Deletes the already created MQTT client.\r
+ *\r
+ * This function just frees up the internal resources and does not disconnect. The user must\r
+ * call MQTT_AGENT_Disconnect API to make sure that the client is disconnected before\r
+ * deleting it.\r
+ *\r
+ * @param[in] xMQTTHandle The opaque handle as returned from MQTT_AGENT_Create.\r
+ *\r
+ * @return eMQTTAgentSuccess if the client is successfully deleted, otherwise an\r
+ * error code explaining the reason of the failure is returned.\r
+ */\r
+MQTTAgentReturnCode_t MQTT_AGENT_Delete( MQTTAgentHandle_t xMQTTHandle );\r
+\r
+/**\r
+ * @brief Establishes a connection with the MQTT broker.\r
+ *\r
+ * @note This function alters the calling task's notification state and value. If xTimeoutTicks\r
+ * is short the calling task's notification state and value may be updated after MQTT_AGENT_Connect()\r
+ * has returned.\r
+ *\r
+ * @param[in] xMQTTHandle The opaque handle as returned from MQTT_AGENT_Create.\r
+ * @param[in] pxConnectParams Connect parameters.\r
+ * @param[in] xTimeoutTicks Maximum time in ticks after which the operation should fail. Use pdMS_TO_TICKS\r
+ * macro to convert milliseconds to ticks.\r
+ *\r
+ * @return eMQTTAgentSuccess if the connect operation succeeds, otherwise an error code explaining the\r
+ * reason of the failure is returned.\r
+ */\r
+MQTTAgentReturnCode_t MQTT_AGENT_Connect( MQTTAgentHandle_t xMQTTHandle,\r
+                                          const MQTTAgentConnectParams_t * const pxConnectParams,\r
+                                          TickType_t xTimeoutTicks );\r
+\r
+/**\r
+ * @brief Disconnects the connection with the MQTT broker.\r
+ *\r
+ * @note This function alters the calling task's notification state and value. If xTimeoutTicks\r
+ * is short the calling task's notification state and value may be updated after MQTT_AGENT_Disconnect()\r
+ * has returned.\r
+ *\r
+ * @param[in] xMQTTHandle The opaque handle as returned from MQTT_AGENT_Create.\r
+ * @param[in] xTimeoutTicks Maximum time in ticks after which the operation should fail. Use pdMS_TO_TICKS\r
+ * macro to convert milliseconds to ticks.\r
+ *\r
+ * @return eMQTTAgentSuccess if the disconnect operation succeeds, otherwise an error code explaining\r
+ * the reason of the failure is returned.\r
+ */\r
+MQTTAgentReturnCode_t MQTT_AGENT_Disconnect( MQTTAgentHandle_t xMQTTHandle,\r
+                                             TickType_t xTimeoutTicks );\r
+\r
+/**\r
+ * @brief Subscribes to a given topic.\r
+ *\r
+ * @note This function alters the calling task's notification state and value. If xTimeoutTicks\r
+ * is short the calling task's notification state and value may be updated after MQTT_AGENT_Subscribe()\r
+ * has returned.\r
+ *\r
+ * Whenever a publish message is received on a topic, the registered callbacks are invoked\r
+ * in the following order:\r
+ * * If we have an exact matching entry in the subscription manager, the corresponding\r
+ *   callback is invoked.\r
+ * * Then the wild card topic filters are checked for match and the corresponding callbacks\r
+ *   are invoked for the ones which match the topic.\r
+ *\r
+ * @note If a publish message is received on a topic which matches more than one topic\r
+ * filters, the order in which the registered callbacks are invoked is undefined.\r
+ *\r
+ * @warning If the user takes the ownership of the MQTT buffer by returning eMQTTTrue from the\r
+ * callback, no further callbacks are invoked. The user should make sure not to take the ownership\r
+ * of the MQTT buffer if they want all the callbacks to get invoked. For example:\r
+ * * Subscriptions: a/b/c, a/b/#, a/b/+\r
+ * * Publish message received on topic: a/b/c --> First the callback corresponding to a/b/c\r
+ *   subscription is invoked. Then the callbacks for topic filters a/b/# and a/b/+ are invoked\r
+ *   in no particular order. If the user decides to take the ownership of the MQTT buffer in\r
+ *   any of the callback by returning eMQTTTrue, no further callbacks are invoked.\r
+ *\r
+ * @param[in] xMQTTHandle The opaque handle as returned from MQTT_AGENT_Create.\r
+ * @param[in] pxSubscribeParams Subscribe parameters.\r
+ * @param[in] xTimeoutTicks Maximum time in ticks after which the operation should fail. Use pdMS_TO_TICKS\r
+ * macro to convert milliseconds to ticks.\r
+ *\r
+ * @return eMQTTAgentSuccess if the subscribe operation succeeds, otherwise an error code explaining\r
+ * the reason of the failure is returned.\r
+ */\r
+MQTTAgentReturnCode_t MQTT_AGENT_Subscribe( MQTTAgentHandle_t xMQTTHandle,\r
+                                            const MQTTAgentSubscribeParams_t * const pxSubscribeParams,\r
+                                            TickType_t xTimeoutTicks );\r
+\r
+/**\r
+ * @brief Unsubscribes from a given topic.\r
+ *\r
+ * @note This function alters the calling task's notification state and value. If xTimeoutTicks\r
+ * is short the calling task's notification state and value may be updated after MQTT_AGENT_Unsubscribe()\r
+ * has returned.\r
+ *\r
+ * @param[in] xMQTTHandle The opaque handle as returned from MQTT_AGENT_Create.\r
+ * @param[in] pxUnsubscribeParams Unsubscribe parameters.\r
+ * @param[in] xTimeoutTicks Maximum time in ticks after which the operation should fail. Use pdMS_TO_TICKS\r
+ * macro to convert milliseconds to ticks.\r
+ *\r
+ * @return eMQTTAgentSuccess if the unsubscribe operation succeeds, otherwise an error code explaining\r
+ * the reason of the failure is returned.\r
+ */\r
+MQTTAgentReturnCode_t MQTT_AGENT_Unsubscribe( MQTTAgentHandle_t xMQTTHandle,\r
+                                              const MQTTAgentUnsubscribeParams_t * const pxUnsubscribeParams,\r
+                                              TickType_t xTimeoutTicks );\r
+\r
+/**\r
+ * @brief Publishes a message to a given topic.\r
+ *\r
+ * @note This function alters the calling task's notification state and value. If xTimeoutTicks\r
+ * is short the calling task's notification state and value may be updated after MQTT_AGENT_Publish()\r
+ * has returned.\r
+ *\r
+ * @param[in] xMQTTHandle The opaque handle as returned from MQTT_AGENT_Create.\r
+ * @param[in] pxPublishParams Publish parameters.\r
+ * @param[in] xTimeoutTicks Maximum time in ticks after which the operation should fail. Use pdMS_TO_TICKS\r
+ * macro to convert milliseconds to ticks.\r
+ *\r
+ * @return eMQTTAgentSuccess if the publish operation succeeds, otherwise an error code explaining\r
+ * the reason of the failure is returned.\r
+ */\r
+MQTTAgentReturnCode_t MQTT_AGENT_Publish( MQTTAgentHandle_t xMQTTHandle,\r
+                                          const MQTTAgentPublishParams_t * const pxPublishParams,\r
+                                          TickType_t xTimeoutTicks );\r
+\r
+/**\r
+ * @brief Returns the buffer provided in the publish callback.\r
+ *\r
+ * When a publish message is received from the broker, the buffer containing the message\r
+ * is returned in the user supplied callback (xBuffer in MQTTPublishData_t) and the user\r
+ * can take the ownership by returning pdTRUE from the callback. The user should later\r
+ * return the buffer whenever done by calling the MQTT_AGENT_ReturnBuffer API.\r
+ *\r
+ * @param[in] xMQTTHandle The opaque handle as returned from MQTT_AGENT_Create.\r
+ * @param[in] xBufferHandle The buffer to return.\r
+ *\r
+ * @return eMQTTAgentSuccess if the return buffer operation succeeds, otherwise an error\r
+ * code explaining the reason of the failure is returned.\r
+ */\r
+MQTTAgentReturnCode_t MQTT_AGENT_ReturnBuffer( MQTTAgentHandle_t xMQTTHandle,\r
+                                               MQTTBufferHandle_t xBufferHandle );\r
+\r
+#endif /* _AWS_MQTT_AGENT_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt_agent_config_defaults.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt_agent_config_defaults.h
new file mode 100644 (file)
index 0000000..1ac7780
--- /dev/null
@@ -0,0 +1,180 @@
+/*\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_agent_config_defaults.h\r
+ * @brief MQTT agent default config options.\r
+ *\r
+ * Ensures that the config options for MQTT agent are set to sensible\r
+ * default values if the user does not provide one.\r
+ */\r
+\r
+#ifndef _AWS_MQTT_AGENT_CONFIG_DEFAULTS_H_\r
+#define _AWS_MQTT_AGENT_CONFIG_DEFAULTS_H_\r
+\r
+/* FreeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/**\r
+ * @brief Controls whether or not to report usage metrics to the\r
+ * AWS IoT broker.\r
+ *\r
+ * If mqttconfigENABLE_METRICS is set to 1, a string containing\r
+ * metric information will be included in the "username" field of\r
+ * the MQTT connect messages.\r
+ */\r
+#ifndef mqttconfigENABLE_METRICS\r
+    #define mqttconfigENABLE_METRICS    ( 1 )\r
+#endif\r
+\r
+/**\r
+ * @brief The maximum time interval in seconds allowed to elapse between 2 consecutive\r
+ * control packets.\r
+ */\r
+#ifndef mqttconfigKEEP_ALIVE_INTERVAL_SECONDS\r
+    #define mqttconfigKEEP_ALIVE_INTERVAL_SECONDS    ( 1200 )\r
+#endif\r
+\r
+/**\r
+ * @brief Defines the frequency at which the client should send Keep Alive messages.\r
+ *\r
+ * Even though the maximum time allowed between 2 consecutive control packets\r
+ * is defined by the mqttconfigKEEP_ALIVE_INTERVAL_SECONDS macro, the user\r
+ * can and should send Keep Alive messages at a slightly faster rate to ensure\r
+ * that the connection is not closed by the server because of network delays.\r
+ * This macro defines the interval of inactivity after which a keep alive messages\r
+ * is sent.\r
+ */\r
+#ifndef mqttconfigKEEP_ALIVE_ACTUAL_INTERVAL_TICKS\r
+    #define mqttconfigKEEP_ALIVE_ACTUAL_INTERVAL_TICKS    ( 5000 )\r
+#endif\r
+\r
+/**\r
+ * @brief The maximum interval in ticks to wait for PINGRESP.\r
+ *\r
+ * If PINGRESP is not received within this much time after sending PINGREQ,\r
+ * the client assumes that the PINGREQ timed out.\r
+ */\r
+#ifndef mqttconfigKEEP_ALIVE_TIMEOUT_TICKS\r
+    #define mqttconfigKEEP_ALIVE_TIMEOUT_TICKS    ( 1000 )\r
+#endif\r
+\r
+/**\r
+ * @brief The maximum time in ticks for which the MQTT task is permitted to block.\r
+ *\r
+ * The MQTT task blocks until the user initiates any action or until it receives\r
+ * any data from the broker. This macro controls the maximum time the MQTT task can\r
+ * block. It should be set to a small number for the platforms which do not have any\r
+ * mechanism to wake up the MQTT task whenever data is received on a connected socket.\r
+ * This ensures that the MQTT task keeps waking up frequently and processes the publish\r
+ * messages received from the broker, if any.\r
+ *\r
+ * If the platform's secure_sockets layer supports SOCKETS_SO_WAKEUP_CALLBACK i.e.\r
+ * the MQTT task can wake up whenever data is received on a connected socket, this\r
+ * value should be set to maximum value:\r
+ * #define  #define mqttconfigMQTT_TASK_MAX_BLOCK_TICKS    ( ~( ( uint32_t ) 0 ) )\r
+ *\r
+ * If the platform's secure_sockets layer does not support SOCKETS_SO_WAKEUP_CALLBACK\r
+ * i.e. the MQTT task cannot wake up whenever data is received on a connected socket,\r
+ * this value should be set to a small number:\r
+ * #define mqttconfigMQTT_TASK_MAX_BLOCK_TICKS             ( 100 )\r
+ */\r
+#ifndef mqttconfigMQTT_TASK_MAX_BLOCK_TICKS\r
+    #error "mqttconfigMQTT_TASK_MAX_BLOCK_TICKS must be defined in iot_mqtt_agent_config.h."\r
+#endif\r
+\r
+/**\r
+ * @defgroup MQTTTask MQTT task configuration parameters.\r
+ */\r
+/** @{ */\r
+#ifndef mqttconfigMQTT_TASK_STACK_DEPTH\r
+    #define mqttconfigMQTT_TASK_STACK_DEPTH    ( configMINIMAL_STACK_SIZE * 4 )\r
+#endif\r
+\r
+#ifndef mqttconfigMQTT_TASK_PRIORITY\r
+    #define mqttconfigMQTT_TASK_PRIORITY    ( tskIDLE_PRIORITY )\r
+#endif\r
+/** @} */\r
+\r
+/**\r
+ * @brief Maximum number of MQTT clients that can exist simultaneously.\r
+ */\r
+#ifndef mqttconfigMAX_BROKERS\r
+    #define mqttconfigMAX_BROKERS    ( 1 )\r
+#endif\r
+\r
+/**\r
+ * @brief Maximum number of parallel operations per client.\r
+ */\r
+#ifndef mqttconfigMAX_PARALLEL_OPS\r
+    #define mqttconfigMAX_PARALLEL_OPS    ( 5 )\r
+#endif\r
+\r
+/**\r
+ * @brief Time in milliseconds after which the TCP send operation should timeout.\r
+ */\r
+#ifndef mqttconfigTCP_SEND_TIMEOUT_MS\r
+    #define mqttconfigTCP_SEND_TIMEOUT_MS    ( 2000 )\r
+#endif\r
+\r
+/**\r
+ * @brief Length of the buffer used to receive data.\r
+ */\r
+#ifndef mqttconfigRX_BUFFER_SIZE\r
+    #define mqttconfigRX_BUFFER_SIZE    ( 1024 )\r
+#endif\r
+\r
+/**\r
+ * @defgroup BufferPoolInterface The functions used by the MQTT client to get and return buffers.\r
+ *\r
+ * The MQTT client needs buffers for both transmitting and receiving messages.\r
+ * Whenever it needs a buffer, it invokes mqttconfigGET_FREE_BUFFER_FXN function to get\r
+ * a buffer and after it is done it invokes mqttconfigRETURN_BUFFER_FXN to return the\r
+ * buffer. By default, BUFFERPOOL_GetFreeBuffer and BUFFERPOOL_ReturnBuffer functions are\r
+ * used to get and return buffers from the central buffer pool. The user can change the\r
+ * buffer management functions for MQTT client by defining mqttconfigGET_FREE_BUFFER_FXN\r
+ * and mqttconfigRETURN_BUFFER_FXN macros. The user should implement the two functions\r
+ * having signatures same as BUFFERPOOL_GetFreeBuffer and BUFFERPOOL_ReturnBuffer and then\r
+ * define the macros in BufferPoolConfig.h:\r
+ * @code\r
+ * uint8_t* UserDefined_GetFreeBuffer( uint32_t *pulBufferLength );\r
+ * void UserDefined_ReturnBuffer( uint8_t * const pucBuffer );\r
+ *\r
+ * #define mqttconfigGET_FREE_BUFFER_FXN       UserDefined_GetFreeBuffer\r
+ * #define mqttconfigRETURN_BUFFER_FXN         UserDefined_ReturnBuffer\r
+ * @endcode\r
+ */\r
+/** @{ */\r
+#ifndef mqttconfigGET_FREE_BUFFER_FXN\r
+    #define mqttconfigGET_FREE_BUFFER_FXN    BUFFERPOOL_GetFreeBuffer\r
+#endif\r
+\r
+#ifndef mqttconfigRETURN_BUFFER_FXN\r
+    #define mqttconfigRETURN_BUFFER_FXN    BUFFERPOOL_ReturnBuffer\r
+#endif\r
+/** @} */\r
+\r
+#endif /* _AWS_MQTT_AGENT_CONFIG_DEFAULTS_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt_config_defaults.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt_config_defaults.h
new file mode 100644 (file)
index 0000000..08bcd41
--- /dev/null
@@ -0,0 +1,115 @@
+/*\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_config_defaults.h\r
+ * @brief MQTT default config options.\r
+ *\r
+ * Ensures that the config options for MQTT are set to sensible default\r
+ * values if the user does not provide one.\r
+ */\r
+\r
+#ifndef _AWS_MQTT_CONFIG_DEFAULTS_H_\r
+#define _AWS_MQTT_CONFIG_DEFAULTS_H_\r
+\r
+/**\r
+ * @brief Enable subscription management.\r
+ *\r
+ * Subscription management allows the user to register per subscription\r
+ * callback.\r
+ */\r
+#ifndef mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT\r
+    #define mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT    ( 1 )\r
+#endif\r
+\r
+/**\r
+ * @brief Maximum length of the topic which can be stored in subscription\r
+ * manager.\r
+ *\r
+ * If the user has enabled subscription management (by defining the macro\r
+ * mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT to 1), then this macro must be defined\r
+ * to accommodate the maximum length topic which the user is going to subscribe.\r
+ * The subscribe operation will fail if the user tries to subscribe to a topic\r
+ * of length more than the maximum specified here.\r
+ */\r
+#ifndef mqttconfigSUBSCRIPTION_MANAGER_MAX_TOPIC_LENGTH\r
+    #define mqttconfigSUBSCRIPTION_MANAGER_MAX_TOPIC_LENGTH    ( 128 )\r
+#endif\r
+\r
+/**\r
+ * @brief Maximum number of subscriptions which can be stored in subscription\r
+ * manager.\r
+ *\r
+ * If the user has enabled subscription management (by defining the macro\r
+ * mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT to 1), then this macro must be defined\r
+ * to the maximum number of topics which the user is going to subscribe\r
+ * simultaneously. The subscribe operation will fail is the user tries to\r
+ * subscribe to more topics than the maximum specified here.\r
+ */\r
+#ifndef mqttconfigSUBSCRIPTION_MANAGER_MAX_SUBSCRIPTIONS\r
+    #define mqttconfigSUBSCRIPTION_MANAGER_MAX_SUBSCRIPTIONS    ( 8 )\r
+#endif\r
+\r
+/**\r
+ * @brief Define mqttconfigASSERT to enable asserts.\r
+ *\r
+ * mqttconfigASSERT should be defined to match the semantics of standard\r
+ * C assert() macro i.e. an assertion should trigger if the parameter\r
+ * passed is zero. If the standard C assert is available, the user might\r
+ * do the following:\r
+ * @code\r
+ * #define mqttconfigASSERT( x ) assert( x )\r
+ * @endcode\r
+ *\r
+ * Otherwise, a user can choose to implement a function which should be\r
+ * called when an assertion triggers and then define the mqttconfigASSERT\r
+ * to that function:\r
+ * @code\r
+ * extern void vAssertCalled( const char *pcFile, uint32_t ulLine );\r
+ * #define mqttconfigASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )\r
+ * @endcode\r
+ */\r
+#ifndef mqttconfigASSERT\r
+    #define mqttconfigASSERT( x )\r
+#endif\r
+\r
+/**\r
+ * @brief Define mqttconfigENABLE_DEBUG_LOGS macro to 1 for enabling debug logs.\r
+ *\r
+ * If you choose to enable debug logs, the following function must be implemented\r
+ * which is called to print logs:\r
+ * @code\r
+ * void vLoggingPrintf( const char *pcFormatString, ... );\r
+ * @endcode\r
+ */\r
+#if ( mqttconfigENABLE_DEBUG_LOGS == 1 )\r
+    extern void vLoggingPrintf( const char * pcFormatString,\r
+                                ... );\r
+    #define mqttconfigDEBUG_LOG( x )    vLoggingPrintf x\r
+#else\r
+    #define mqttconfigDEBUG_LOG( x )\r
+#endif\r
+\r
+#endif /* _AWS_MQTT_CONFIG_DEFAULTS_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt_lib.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt_lib.h
new file mode 100644 (file)
index 0000000..ae3e263
--- /dev/null
@@ -0,0 +1,113 @@
+/*\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_lib.h\r
+ * @brief MQTT Core Library interface.\r
+ */\r
+\r
+#ifndef _AWS_MQTT_LIB_H_\r
+#define _AWS_MQTT_LIB_H_\r
+\r
+/* This ifndef enables the core MQTT library to be used without\r
+ * providing MQTTConfig.h. All the config values in this case are\r
+ * taken from MQTTConfigDefaults.h. */\r
+#ifndef mqttDO_NOT_USE_CUSTOM_CONFIG\r
+    #include "aws_mqtt_config.h"\r
+#endif\r
+#include "iot_mqtt_config_defaults.h"\r
+\r
+#include "iot_doubly_linked_list.h"\r
+\r
+ /**\r
+  * @brief Opaque handle to represent an MQTT buffer.\r
+  */\r
+typedef void * MQTTBufferHandle_t;\r
+\r
+/**\r
+ * @brief Boolean type.\r
+ */\r
+typedef enum\r
+{\r
+    eMQTTFalse = 0, /**< Boolean False. */\r
+    eMQTTTrue = 1   /**< Boolean True. */\r
+} MQTTBool_t;\r
+\r
+/**\r
+ * @brief Quality of Service (qos).\r
+ */\r
+typedef enum\r
+{\r
+    eMQTTQoS0 = 0, /**< Quality of Service 0 - Fire and Forget. No ACK. */\r
+    eMQTTQoS1 = 1, /**< Quality of Service 1 - Wait till ACK or Timeout. */\r
+    eMQTTQoS2 = 2  /**< Quality of Service 2 - Not supported. */\r
+} MQTTQoS_t;\r
+\r
+/**\r
+ * @brief The data sent by the MQTT library in the user supplied callback\r
+ * when a publish message from the broker is received.\r
+ */\r
+typedef struct MQTTPublishData\r
+{\r
+    MQTTQoS_t xQos;             /**< Quality of Service (qos). */\r
+    const uint8_t * pucTopic;   /**< The topic on which the message is received. */\r
+    uint16_t usTopicLength;     /**< Length of the topic. */\r
+    const void * pvData;        /**< The received message. */\r
+    uint32_t ulDataLength;      /**< Length of the message. */\r
+    MQTTBufferHandle_t xBuffer; /**< The buffer containing the whole MQTT message. Both pcTopic and pvData are pointers to the locations in this buffer. */\r
+} MQTTPublishData_t;\r
+\r
+/**\r
+ * @brief Signature of the user supplied topic specific publish callback which gets called\r
+ * whenever a publish message is received on the topic this callback is registered for.\r
+ *\r
+ * The user can choose to register this optional topic specific callback while subscribing to\r
+ * a topic. Whenever a publish message is received on the topic, this callback is invoked. If\r
+ * the user chooses not to enable subscription management or chooses not to register a topic\r
+ * specific callback, the generic callback supplied during Init is invoked.\r
+ *\r
+ * @param[in] pvPublishCallbackContext The callback context as supplied by the user in the\r
+ * subscribe parameters.\r
+ * @param[in] pxPublishData The publish data.\r
+ *\r
+ * @return The return value is interpreted as follows:\r
+ * 1. If eMQTTTrue is returned - the ownership of the buffer passed in the callback (xBuffer\r
+ * in MQTTPublishData_t) lies with the user.\r
+ * 2. If eMQTTFalse is returned - the ownership of the buffer passed in the callback (xBuffer\r
+ * in MQTTPublishData_t) remains with the library and it is recycled as soon as the callback\r
+ * returns.<br>\r
+ * The user should take the ownership of the buffer containing the received message from the\r
+ * broker by returning eMQTTTrue from the callback if the user wants to use the buffer after\r
+ * the callback is over. The user should return the buffer whenever done by calling the\r
+ * MQTT_ReturnBuffer API.\r
+ */\r
+#if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 )\r
+\r
+    typedef MQTTBool_t ( * MQTTPublishCallback_t )( void * pvPublishCallbackContext,\r
+                                                    const MQTTPublishData_t * const pxPublishData );\r
+\r
+#endif /* mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT */\r
+\r
+#endif /* _AWS_MQTT_LIB_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/types/iot_mqtt_types.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/types/iot_mqtt_types.h
new file mode 100644 (file)
index 0000000..c4bea31
--- /dev/null
@@ -0,0 +1,1087 @@
+/*\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_types.h\r
+ * @brief Types of the MQTT library.\r
+ */\r
+\r
+#ifndef IOT_MQTT_TYPES_H_\r
+#define IOT_MQTT_TYPES_H_\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/* Standard includes. */\r
+#include <stdbool.h>\r
+#include <stdint.h>\r
+#include <stddef.h>\r
+\r
+/* Type includes. */\r
+#include "types/iot_platform_types.h"\r
+#include "types/iot_taskpool_types.h"\r
+\r
+/* Platform network include. */\r
+#include "platform/iot_network.h"\r
+\r
+/*---------------------------- MQTT handle types ----------------------------*/\r
+\r
+/**\r
+ * @handles{mqtt,MQTT library}\r
+ */\r
+\r
+/**\r
+ * @ingroup mqtt_datatypes_handles\r
+ * @brief Opaque handle of an MQTT connection.\r
+ *\r
+ * This type identifies an MQTT connection, which is valid after a successful call\r
+ * to @ref mqtt_function_connect. A variable of this type is passed as the first\r
+ * argument to [MQTT library functions](@ref mqtt_functions) to identify which\r
+ * connection that function acts on.\r
+ *\r
+ * A call to @ref mqtt_function_disconnect makes a connection handle invalid. Once\r
+ * @ref mqtt_function_disconnect returns, the connection handle should no longer\r
+ * be used.\r
+ *\r
+ * @initializer{IotMqttConnection_t,IOT_MQTT_CONNECTION_INITIALIZER}\r
+ */\r
+typedef struct _mqttConnection   * IotMqttConnection_t;\r
+\r
+/**\r
+ * @ingroup mqtt_datatypes_handles\r
+ * @brief Opaque handle that references an in-progress MQTT operation.\r
+ *\r
+ * Set as an output parameter of @ref mqtt_function_publish, @ref mqtt_function_subscribe,\r
+ * and @ref mqtt_function_unsubscribe. These functions queue an MQTT operation; the result\r
+ * of the operation is unknown until a response from the MQTT server is received. Therefore,\r
+ * this handle serves as a reference to MQTT operations awaiting MQTT server response.\r
+ *\r
+ * This reference will be valid from the successful return of @ref mqtt_function_publish,\r
+ * @ref mqtt_function_subscribe, or @ref mqtt_function_unsubscribe. The reference becomes\r
+ * invalid once the [completion callback](@ref IotMqttCallbackInfo_t) is invoked, or\r
+ * @ref mqtt_function_wait returns.\r
+ *\r
+ * @initializer{IotMqttOperation_t,IOT_MQTT_OPERATION_INITIALIZER}\r
+ *\r
+ * @see @ref mqtt_function_wait and #IOT_MQTT_FLAG_WAITABLE for waiting on a reference.\r
+ * #IotMqttCallbackInfo_t and #IotMqttCallbackParam_t for an asynchronous notification\r
+ * of completion.\r
+ */\r
+typedef struct _mqttOperation    * IotMqttOperation_t;\r
+\r
+/*-------------------------- MQTT enumerated types --------------------------*/\r
+\r
+/**\r
+ * @enums{mqtt,MQTT library}\r
+ */\r
+\r
+/**\r
+ * @ingroup mqtt_datatypes_enums\r
+ * @brief Return codes of [MQTT functions](@ref mqtt_functions).\r
+ *\r
+ * The function @ref mqtt_function_strerror can be used to get a return code's\r
+ * description.\r
+ */\r
+typedef enum IotMqttError\r
+{\r
+    /**\r
+     * @brief MQTT operation completed successfully.\r
+     *\r
+     * Functions that may return this value:\r
+     * - @ref mqtt_function_connect\r
+     * - @ref mqtt_function_publish with QoS 0 parameter\r
+     * - @ref mqtt_function_wait\r
+     * - @ref mqtt_function_timedsubscribe\r
+     * - @ref mqtt_function_timedunsubscribe\r
+     * - @ref mqtt_function_timedpublish\r
+     *\r
+     * Will also be the value of an operation completion callback's\r
+     * #IotMqttCallbackParam_t.result when successful.\r
+     */\r
+    IOT_MQTT_SUCCESS = 0,\r
+\r
+    /**\r
+     * @brief MQTT operation queued, awaiting result.\r
+     *\r
+     * Functions that may return this value:\r
+     * - @ref mqtt_function_subscribe\r
+     * - @ref mqtt_function_unsubscribe\r
+     * - @ref mqtt_function_publish with QoS 1 parameter\r
+     */\r
+    IOT_MQTT_STATUS_PENDING,\r
+\r
+    /**\r
+     * @brief Initialization failed.\r
+     *\r
+     * Functions that may return this value:\r
+     * - @ref mqtt_function_init\r
+     */\r
+    IOT_MQTT_INIT_FAILED,\r
+\r
+    /**\r
+     * @brief At least one parameter is invalid.\r
+     *\r
+     * Functions that may return this value:\r
+     * - @ref mqtt_function_connect\r
+     * - @ref mqtt_function_subscribe and @ref mqtt_function_timedsubscribe\r
+     * - @ref mqtt_function_unsubscribe and @ref mqtt_function_timedunsubscribe\r
+     * - @ref mqtt_function_publish and @ref mqtt_function_timedpublish\r
+     * - @ref mqtt_function_wait\r
+     */\r
+    IOT_MQTT_BAD_PARAMETER,\r
+\r
+    /**\r
+     * @brief MQTT operation failed because of memory allocation failure.\r
+     *\r
+     * Functions that may return this value:\r
+     * - @ref mqtt_function_connect\r
+     * - @ref mqtt_function_subscribe and @ref mqtt_function_timedsubscribe\r
+     * - @ref mqtt_function_unsubscribe and @ref mqtt_function_timedunsubscribe\r
+     * - @ref mqtt_function_publish and @ref mqtt_function_timedpublish\r
+     */\r
+    IOT_MQTT_NO_MEMORY,\r
+\r
+    /**\r
+     * @brief MQTT operation failed because the network was unusable.\r
+     *\r
+     * This return value may indicate that the network is disconnected.\r
+     *\r
+     * Functions that may return this value:\r
+     * - @ref mqtt_function_connect\r
+     * - @ref mqtt_function_wait\r
+     * - @ref mqtt_function_timedsubscribe\r
+     * - @ref mqtt_function_timedunsubscribe\r
+     * - @ref mqtt_function_timedpublish\r
+     *\r
+     * May also be the value of an operation completion callback's\r
+     * #IotMqttCallbackParam_t.result.\r
+     */\r
+    IOT_MQTT_NETWORK_ERROR,\r
+\r
+    /**\r
+     * @brief MQTT operation could not be scheduled, i.e. enqueued for sending.\r
+     *\r
+     * Functions that may return this value:\r
+     * - @ref mqtt_function_connect\r
+     * - @ref mqtt_function_subscribe and @ref mqtt_function_timedsubscribe\r
+     * - @ref mqtt_function_unsubscribe and @ref mqtt_function_timedunsubscribe\r
+     * - @ref mqtt_function_publish and @ref mqtt_function_timedpublish\r
+     */\r
+    IOT_MQTT_SCHEDULING_ERROR,\r
+\r
+    /**\r
+     * @brief MQTT response packet received from the network is malformed.\r
+     *\r
+     * Functions that may return this value:\r
+     * - @ref mqtt_function_connect\r
+     * - @ref mqtt_function_wait\r
+     * - @ref mqtt_function_timedsubscribe\r
+     * - @ref mqtt_function_timedunsubscribe\r
+     * - @ref mqtt_function_timedpublish\r
+     *\r
+     * May also be the value of an operation completion callback's\r
+     * #IotMqttCallbackParam_t.result.\r
+     *\r
+     * @note If this value is received, the network connection has been closed.\r
+     */\r
+    IOT_MQTT_BAD_RESPONSE,\r
+\r
+    /**\r
+     * @brief A blocking MQTT operation timed out.\r
+     *\r
+     * Functions that may return this value:\r
+     * - @ref mqtt_function_connect\r
+     * - @ref mqtt_function_wait\r
+     * - @ref mqtt_function_timedsubscribe\r
+     * - @ref mqtt_function_timedunsubscribe\r
+     * - @ref mqtt_function_timedpublish\r
+     */\r
+    IOT_MQTT_TIMEOUT,\r
+\r
+    /**\r
+     * @brief A CONNECT or at least one subscription was refused by the server.\r
+     *\r
+     * Functions that may return this value:\r
+     * - @ref mqtt_function_connect\r
+     * - @ref mqtt_function_wait, but only when its #IotMqttOperation_t parameter\r
+     * is associated with a SUBSCRIBE operation.\r
+     * - @ref mqtt_function_timedsubscribe\r
+     *\r
+     * May also be the value of an operation completion callback's\r
+     * #IotMqttCallbackParam_t.result for a SUBSCRIBE.\r
+     *\r
+     * @note If this value is returned and multiple subscriptions were passed to\r
+     * @ref mqtt_function_subscribe (or @ref mqtt_function_timedsubscribe), it's\r
+     * still possible that some of the subscriptions succeeded. This value only\r
+     * signifies that AT LEAST ONE subscription was rejected. The function @ref\r
+     * mqtt_function_issubscribed can be used to determine which subscriptions\r
+     * were accepted or rejected.\r
+     */\r
+    IOT_MQTT_SERVER_REFUSED,\r
+\r
+    /**\r
+     * @brief A QoS 1 PUBLISH received no response and [the retry limit]\r
+     * (#IotMqttPublishInfo_t.retryLimit) was reached.\r
+     *\r
+     * Functions that may return this value:\r
+     * - @ref mqtt_function_wait, but only when its #IotMqttOperation_t parameter\r
+     * is associated with a QoS 1 PUBLISH operation\r
+     * - @ref mqtt_function_timedpublish\r
+     *\r
+     * May also be the value of an operation completion callback's\r
+     * #IotMqttCallbackParam_t.result for a QoS 1 PUBLISH.\r
+     */\r
+    IOT_MQTT_RETRY_NO_RESPONSE\r
+} IotMqttError_t;\r
+\r
+/**\r
+ * @ingroup mqtt_datatypes_enums\r
+ * @brief Types of MQTT operations.\r
+ *\r
+ * The function @ref mqtt_function_operationtype can be used to get an operation\r
+ * type's description.\r
+ */\r
+typedef enum IotMqttOperationType\r
+{\r
+    IOT_MQTT_CONNECT,           /**< Client-to-server CONNECT. */\r
+    IOT_MQTT_PUBLISH_TO_SERVER, /**< Client-to-server PUBLISH. */\r
+    IOT_MQTT_PUBACK,            /**< Client-to-server PUBACK. */\r
+    IOT_MQTT_SUBSCRIBE,         /**< Client-to-server SUBSCRIBE. */\r
+    IOT_MQTT_UNSUBSCRIBE,       /**< Client-to-server UNSUBSCRIBE. */\r
+    IOT_MQTT_PINGREQ,           /**< Client-to-server PINGREQ. */\r
+    IOT_MQTT_DISCONNECT         /**< Client-to-server DISCONNECT. */\r
+} IotMqttOperationType_t;\r
+\r
+/**\r
+ * @ingroup mqtt_datatypes_enums\r
+ * @brief Quality of service levels for MQTT PUBLISH messages.\r
+ *\r
+ * All MQTT PUBLISH messages, including Last Will and Testament and messages\r
+ * received on subscription filters, have an associated <i>Quality of Service</i>,\r
+ * which defines any delivery guarantees for that message.\r
+ * - QoS 0 messages will be delivered at most once. This is a "best effort"\r
+ * transmission with no retransmissions.\r
+ * - QoS 1 messages will be delivered at least once. See #IotMqttPublishInfo_t\r
+ * for the retransmission strategy this library uses to redeliver messages\r
+ * assumed to be lost.\r
+ *\r
+ * @attention QoS 2 is not supported by this library and should not be used.\r
+ */\r
+typedef enum IotMqttQos\r
+{\r
+    IOT_MQTT_QOS_0 = 0, /**< Delivery at most once. */\r
+    IOT_MQTT_QOS_1 = 1, /**< Delivery at least once. See #IotMqttPublishInfo_t for client-side retry strategy. */\r
+    IOT_MQTT_QOS_2 = 2  /**< Delivery exactly once. Unsupported, but enumerated for completeness. */\r
+} IotMqttQos_t;\r
+\r
+/**\r
+ * @ingroup mqtt_datatypes_enums\r
+ * @brief The reason that an MQTT connection (and its associated network connection)\r
+ * was disconnected.\r
+ *\r
+ * When an MQTT connection is closed, its associated [disconnect callback]\r
+ * (@ref IotMqttNetworkInfo_t::disconnectCallback) will be invoked. This type\r
+ * is passed inside of an #IotMqttCallbackParam_t to provide a reason for the\r
+ * disconnect.\r
+ */\r
+typedef enum IotMqttDisconnectReason\r
+{\r
+    IOT_MQTT_DISCONNECT_CALLED,   /**< @ref mqtt_function_disconnect was invoked. */\r
+    IOT_MQTT_BAD_PACKET_RECEIVED, /**< An invalid packet was received from the network. */\r
+    IOT_MQTT_KEEP_ALIVE_TIMEOUT   /**< Keep-alive response was not received within @ref IOT_MQTT_RESPONSE_WAIT_MS. */\r
+} IotMqttDisconnectReason_t;\r
+\r
+/*------------------------- MQTT parameter structs --------------------------*/\r
+\r
+/**\r
+ * @paramstructs{mqtt,MQTT}\r
+ */\r
+\r
+/**\r
+ * @ingroup mqtt_datatypes_paramstructs\r
+ * @brief Information on a PUBLISH message.\r
+ *\r
+ * @paramfor @ref mqtt_function_connect, @ref mqtt_function_publish\r
+ *\r
+ * Passed to @ref mqtt_function_publish as the message to publish and @ref\r
+ * mqtt_function_connect as the Last Will and Testament (LWT) message.\r
+ *\r
+ * @initializer{IotMqttPublishInfo_t,IOT_MQTT_PUBLISH_INFO_INITIALIZER}\r
+ *\r
+ * #IotMqttPublishInfo_t.retryMs and #IotMqttPublishInfo_t.retryLimit are only\r
+ * relevant to QoS 1 PUBLISH messages. They are ignored for QoS 0 PUBLISH\r
+ * messages and LWT messages. These members control retransmissions of QoS 1\r
+ * messages under the following rules:\r
+ * - Retransmission is disabled when #IotMqttPublishInfo_t.retryLimit is 0.\r
+ * After sending the PUBLISH, the library will wait indefinitely for a PUBACK.\r
+ * - If #IotMqttPublishInfo_t.retryLimit is greater than 0, then QoS 1 publishes\r
+ * that do not receive a PUBACK within #IotMqttPublishInfo_t.retryMs will be\r
+ * retransmitted, up to #IotMqttPublishInfo_t.retryLimit times.\r
+ *\r
+ * Retransmission follows a truncated exponential backoff strategy. The constant\r
+ * @ref IOT_MQTT_RETRY_MS_CEILING controls the maximum time between retransmissions.\r
+ *\r
+ * After #IotMqttPublishInfo_t.retryLimit retransmissions are sent, the MQTT\r
+ * library will wait @ref IOT_MQTT_RESPONSE_WAIT_MS before a final check\r
+ * for a PUBACK. If no PUBACK was received within this time, the QoS 1 PUBLISH\r
+ * fails with the code #IOT_MQTT_RETRY_NO_RESPONSE.\r
+ *\r
+ * @note The lengths of the strings in this struct should not include the NULL\r
+ * terminator. Strings in this struct do not need to be NULL-terminated.\r
+ *\r
+ * @note The AWS IoT MQTT server does not support the DUP bit. When\r
+ * [using this library with the AWS IoT MQTT server](@ref IotMqttConnectInfo_t.awsIotMqttMode),\r
+ * retransmissions will instead be sent with a new packet identifier in the PUBLISH\r
+ * packet. This is a nonstandard workaround. Note that this workaround has some\r
+ * flaws, including the following:\r
+ * - The previous packet identifier is forgotten, so if a PUBACK arrives for that\r
+ * packet identifier, it will be ignored. On an exceptionally busy network, this\r
+ * may cause excessive retransmissions when too many PUBACKS arrive after the\r
+ * PUBLISH packet identifier is changed. However, the exponential backoff\r
+ * retransmission strategy should mitigate this problem.\r
+ * - Log messages will be printed using the new packet identifier; the old packet\r
+ * identifier is not saved.\r
+ *\r
+ * <b>Example</b>\r
+ *\r
+ * Consider a situation where\r
+ * - @ref IOT_MQTT_RETRY_MS_CEILING is 60000\r
+ * - #IotMqttPublishInfo_t.retryMs is 2000\r
+ * - #IotMqttPublishInfo_t.retryLimit is 20\r
+ *\r
+ * A PUBLISH message will be retransmitted at the following times after the initial\r
+ * transmission if no PUBACK is received:\r
+ * - 2000 ms (2000 ms after previous transmission)\r
+ * - 6000 ms (4000 ms after previous transmission)\r
+ * - 14000 ms (8000 ms after previous transmission)\r
+ * - 30000 ms (16000 ms after previous transmission)\r
+ * - 62000 ms (32000 ms after previous transmission)\r
+ * - 122000 ms, 182000 ms, 242000 ms... (every 60000 ms until 20 transmissions have been sent)\r
+ *\r
+ * After the 20th retransmission, the MQTT library will wait\r
+ * @ref IOT_MQTT_RESPONSE_WAIT_MS before checking a final time for a PUBACK.\r
+ */\r
+typedef struct IotMqttPublishInfo\r
+{\r
+    IotMqttQos_t qos;         /**< @brief QoS of message. Must be 0 or 1. */\r
+    bool retain;              /**< @brief MQTT message retain flag. */\r
+\r
+    const char * pTopicName;  /**< @brief Topic name of PUBLISH. */\r
+    uint16_t topicNameLength; /**< @brief Length of #IotMqttPublishInfo_t.pTopicName. */\r
+\r
+    const void * pPayload;    /**< @brief Payload of PUBLISH. */\r
+    size_t payloadLength;     /**< @brief Length of #IotMqttPublishInfo_t.pPayload. For LWT messages, this is limited to 65535. */\r
+\r
+    uint32_t retryMs;         /**< @brief If no response is received within this time, the message is retransmitted. */\r
+    uint32_t retryLimit;      /**< @brief How many times to attempt retransmission. */\r
+} IotMqttPublishInfo_t;\r
+\r
+/**\r
+ * @ingroup mqtt_datatypes_paramstructs\r
+ * @brief Parameter to an MQTT callback function.\r
+ *\r
+ * @paramfor MQTT callback functions\r
+ *\r
+ * The MQTT library passes this struct to registered callback whenever an\r
+ * operation completes, a message is received on a topic filter, or an MQTT\r
+ * connection is disconnected.\r
+ *\r
+ * The members of this struct are different based on the callback trigger. If the\r
+ * callback function was triggered for completed operation, the `operation`\r
+ * member is valid. Otherwise, if the callback was triggered because of a\r
+ * server-to-client PUBLISH, the `message` member is valid. Finally, if the callback\r
+ * was triggered because of a disconnect, the `disconnectReason` member is valid.\r
+ *\r
+ * For an incoming PUBLISH, the `message.pTopicFilter` parameter provides the\r
+ * subscription topic filter that matched the topic name in the PUBLISH. Because\r
+ * topic filters may use MQTT wildcards, the topic filter may be different from the\r
+ * topic name. This pointer must be treated as read-only; the topic filter must not\r
+ * be modified. Additionally, the topic filter may go out of scope as soon as the\r
+ * callback function returns, so it must be copied if it is needed at a later time.\r
+ *\r
+ * @attention Any pointers in this callback parameter may be freed as soon as\r
+ * the [callback function](@ref IotMqttCallbackInfo_t.function) returns.\r
+ * Therefore, data must be copied if it is needed after the callback function\r
+ * returns.\r
+ * @attention The MQTT library may set strings that are not NULL-terminated.\r
+ *\r
+ * @see #IotMqttCallbackInfo_t for the signature of a callback function.\r
+ */\r
+typedef struct IotMqttCallbackParam\r
+{\r
+    /**\r
+     * @brief The MQTT connection associated with this completed operation,\r
+     * incoming PUBLISH, or disconnect.\r
+     *\r
+     * [MQTT API functions](@ref mqtt_functions) are safe to call from a callback\r
+     * for completed operations or incoming PUBLISH messages. However, blocking\r
+     * function calls (including @ref mqtt_function_wait) are not recommended\r
+     * (though still safe). Do not call any API functions from a disconnect\r
+     * callback.\r
+     */\r
+    IotMqttConnection_t mqttConnection;\r
+\r
+    union\r
+    {\r
+        /* Valid for completed operations. */\r
+        struct\r
+        {\r
+            IotMqttOperationType_t type;  /**< @brief Type of operation that completed. */\r
+            IotMqttOperation_t reference; /**< @brief Reference to the operation that completed. */\r
+            IotMqttError_t result;        /**< @brief Result of operation, e.g. succeeded or failed. */\r
+        } operation;\r
+\r
+        /* Valid for incoming PUBLISH messages. */\r
+        struct\r
+        {\r
+            const char * pTopicFilter;  /**< @brief Topic filter that matched the message. */\r
+            uint16_t topicFilterLength; /**< @brief Length of `pTopicFilter`. */\r
+            IotMqttPublishInfo_t info;  /**< @brief PUBLISH message received from the server. */\r
+        } message;\r
+\r
+        /* Valid when a connection is disconnected. */\r
+        IotMqttDisconnectReason_t disconnectReason; /**< @brief Why the MQTT connection was disconnected. */\r
+    } u; /**< @brief Valid member depends on callback type. */\r
+} IotMqttCallbackParam_t;\r
+\r
+/**\r
+ * @ingroup mqtt_datatypes_paramstructs\r
+ * @brief Information on a user-provided MQTT callback function.\r
+ *\r
+ * @paramfor @ref mqtt_function_subscribe, @ref mqtt_function_unsubscribe,\r
+ * and @ref mqtt_function_publish. Cannot be used with #IOT_MQTT_FLAG_WAITABLE.\r
+ *\r
+ * Provides a function to be invoked when an operation completes or when a\r
+ * server-to-client PUBLISH is received.\r
+ *\r
+ * @initializer{IotMqttCallbackInfo_t,IOT_MQTT_CALLBACK_INFO_INITIALIZER}\r
+ *\r
+ * Below is an example for receiving an asynchronous notification on operation\r
+ * completion. See @ref mqtt_function_subscribe for an example of using this struct\r
+ * with for incoming PUBLISH messages.\r
+ *\r
+ * @code{c}\r
+ * // Operation completion callback.\r
+ * void operationComplete( void * pArgument, IotMqttCallbackParam_t * pOperation );\r
+ *\r
+ * // Callback information.\r
+ * IotMqttCallbackInfo_t callbackInfo = IOT_MQTT_CALLBACK_INFO_INITIALIZER;\r
+ * callbackInfo.function = operationComplete;\r
+ *\r
+ * // Operation to wait for.\r
+ * IotMqttError_t result = IotMqtt_Publish( &mqttConnection,\r
+ *                                          &publishInfo,\r
+ *                                          0,\r
+ *                                          &callbackInfo,\r
+ *                                          &reference );\r
+ *\r
+ * // Publish should have returned IOT_MQTT_STATUS_PENDING. Once a response\r
+ * // is received, operationComplete is executed with the actual status passed\r
+ * // in pOperation.\r
+ * @endcode\r
+ */\r
+typedef struct IotMqttCallbackInfo\r
+{\r
+    void * pCallbackContext; /**< @brief The first parameter to pass to the callback function to provide context. */\r
+\r
+    /**\r
+     * @brief User-provided callback function signature.\r
+     *\r
+     * @param[in] void * #IotMqttCallbackInfo_t.pCallbackContext\r
+     * @param[in] IotMqttCallbackParam_t * Details on the outcome of the MQTT operation\r
+     * or an incoming MQTT PUBLISH.\r
+     *\r
+     * @see #IotMqttCallbackParam_t for more information on the second parameter.\r
+     */\r
+    void ( * function )( void *,\r
+                         IotMqttCallbackParam_t * );\r
+} IotMqttCallbackInfo_t;\r
+\r
+/**\r
+ * @ingroup mqtt_datatypes_paramstructs\r
+ * @brief Information on an MQTT subscription.\r
+ *\r
+ * @paramfor @ref mqtt_function_subscribe, @ref mqtt_function_unsubscribe\r
+ *\r
+ * An array of these is passed to @ref mqtt_function_subscribe and @ref\r
+ * mqtt_function_unsubscribe. However, #IotMqttSubscription_t.callback and\r
+ * and #IotMqttSubscription_t.qos are ignored by @ref mqtt_function_unsubscribe.\r
+ *\r
+ * @initializer{IotMqttSubscription_t,IOT_MQTT_SUBSCRIPTION_INITIALIZER}\r
+ *\r
+ * @note The lengths of the strings in this struct should not include the NULL\r
+ * terminator. Strings in this struct do not need to be NULL-terminated.\r
+ * @see #IotMqttCallbackInfo_t for details on setting a callback function.\r
+ */\r
+typedef struct IotMqttSubscription\r
+{\r
+    /**\r
+     * @brief QoS of messages delivered on subscription.\r
+     *\r
+     * Must be `0` or `1`. Ignored by @ref mqtt_function_unsubscribe.\r
+     */\r
+    IotMqttQos_t qos;\r
+\r
+    const char * pTopicFilter;  /**< @brief Topic filter of subscription. */\r
+    uint16_t topicFilterLength; /**< @brief Length of #IotMqttSubscription_t.pTopicFilter. */\r
+\r
+    /**\r
+     * @brief Callback to invoke when a message is received.\r
+     *\r
+     * See #IotMqttCallbackInfo_t. Ignored by @ref mqtt_function_unsubscribe.\r
+     */\r
+    IotMqttCallbackInfo_t callback;\r
+} IotMqttSubscription_t;\r
+\r
+/**\r
+ * @ingroup mqtt_datatypes_paramstructs\r
+ * @brief Information on a new MQTT connection.\r
+ *\r
+ * @paramfor @ref mqtt_function_connect\r
+ *\r
+ * Passed as an argument to @ref mqtt_function_connect. Most members of this struct\r
+ * correspond to the content of an [MQTT CONNECT packet.]\r
+ * (http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/csprd02/mqtt-v3.1.1-csprd02.html#_Toc385349764)\r
+ *\r
+ * @initializer{IotMqttConnectInfo_t,IOT_MQTT_CONNECT_INFO_INITIALIZER}\r
+ *\r
+ * @note The lengths of the strings in this struct should not include the NULL\r
+ * terminator. Strings in this struct do not need to be NULL-terminated.\r
+ */\r
+typedef struct IotMqttConnectInfo\r
+{\r
+    /**\r
+     * @brief Specifies if this MQTT connection is to an AWS IoT MQTT server.\r
+     *\r
+     * The AWS IoT MQTT broker [differs somewhat from the MQTT specification.]\r
+     * (https://docs.aws.amazon.com/iot/latest/developerguide/mqtt.html)\r
+     * When this member is `true`, the MQTT library will accommodate these\r
+     * differences. This setting should be `false` when communicating with a\r
+     * fully-compliant MQTT broker.\r
+     *\r
+     * @attention This setting <b>MUST</b> be `true` when using the AWS IoT MQTT\r
+     * server; it <b>MUST</b> be `false` otherwise.\r
+     * @note Currently, @ref IOT_MQTT_CONNECT_INFO_INITIALIZER sets this\r
+     * this member to `true`.\r
+     */\r
+    bool awsIotMqttMode;\r
+\r
+    /**\r
+     * @brief Whether this connection is a clean session.\r
+     *\r
+     * MQTT servers can maintain and topic filter subscriptions and unacknowledged\r
+     * PUBLISH messages. These form part of an <i>MQTT session</i>, which is identified by\r
+     * the [client identifier](@ref IotMqttConnectInfo_t.pClientIdentifier).\r
+     *\r
+     * Setting this value to `true` establishes a <i>clean session</i>, which causes\r
+     * the MQTT server to discard any previous session data for a client identifier.\r
+     * When the client disconnects, the server discards all session data. If this\r
+     * value is `true`, #IotMqttConnectInfo_t.pPreviousSubscriptions and\r
+     * #IotMqttConnectInfo_t.previousSubscriptionCount are ignored.\r
+     *\r
+     * Setting this value to `false` does one of the following:\r
+     * - If no previous session exists, the MQTT server will create a new\r
+     * <i>persistent session</i>. The server may maintain subscriptions and\r
+     * unacknowledged PUBLISH messages after a client disconnects, to be restored\r
+     * once the same client identifier reconnects.\r
+     * - If a previous session exists, the MQTT server restores all of the session's\r
+     * subscriptions for the client identifier and may immediately transmit any\r
+     * unacknowledged PUBLISH packets to the client.\r
+     *\r
+     * When a client with a persistent session disconnects, the MQTT server\r
+     * continues to maintain all subscriptions and unacknowledged PUBLISH messages.\r
+     * The client must also remember the session subscriptions to restore them\r
+     * upon reconnecting. #IotMqttConnectInfo_t.pPreviousSubscriptions and\r
+     * #IotMqttConnectInfo_t.previousSubscriptionCount are used to restore a\r
+     * previous session's subscriptions client-side.\r
+     */\r
+    bool cleanSession;\r
+\r
+    /**\r
+     * @brief An array of MQTT subscriptions present in a previous session, if any.\r
+     *\r
+     * Pointer to the start of an array of subscriptions present a previous session,\r
+     * if any. These subscriptions will be immediately restored upon reconnecting.\r
+     *\r
+     * This member is ignored if it is `NULL` or #IotMqttConnectInfo_t.cleanSession\r
+     * is `true`. If this member is not `NULL`, #IotMqttConnectInfo_t.previousSubscriptionCount\r
+     * must be nonzero.\r
+     */\r
+    const IotMqttSubscription_t * pPreviousSubscriptions;\r
+\r
+    /**\r
+     * @brief The number of MQTT subscriptions present in a previous session, if any.\r
+     *\r
+     * Number of subscriptions contained in the array\r
+     * #IotMqttConnectInfo_t.pPreviousSubscriptions.\r
+     *\r
+     * This value is ignored if #IotMqttConnectInfo_t.pPreviousSubscriptions\r
+     * is `NULL` or #IotMqttConnectInfo_t.cleanSession is `true`. If\r
+     * #IotMqttConnectInfo_t.pPreviousSubscriptions is not `NULL`, this value\r
+     * must be nonzero.\r
+     */\r
+    size_t previousSubscriptionCount;\r
+\r
+    /**\r
+     * @brief A message to publish if the new MQTT connection is unexpectedly closed.\r
+     *\r
+     * A Last Will and Testament (LWT) message may be published if this connection is\r
+     * closed without sending an MQTT DISCONNECT packet. This pointer should be set to\r
+     * an #IotMqttPublishInfo_t representing any LWT message to publish. If an LWT\r
+     * is not needed, this member must be set to `NULL`.\r
+     *\r
+     * Unlike other PUBLISH messages, an LWT message is limited to 65535 bytes in\r
+     * length. Additionally, [pWillInfo->retryMs](@ref IotMqttPublishInfo_t.retryMs)\r
+     * and [pWillInfo->retryLimit](@ref IotMqttPublishInfo_t.retryLimit) will\r
+     * be ignored.\r
+     */\r
+    const IotMqttPublishInfo_t * pWillInfo;\r
+\r
+    uint16_t keepAliveSeconds;       /**< @brief Period of keep-alive messages. Set to 0 to disable keep-alive. */\r
+\r
+    const char * pClientIdentifier;  /**< @brief MQTT client identifier. */\r
+    uint16_t clientIdentifierLength; /**< @brief Length of #IotMqttConnectInfo_t.pClientIdentifier. */\r
+\r
+    /* These credentials are not used by AWS IoT and may be ignored if\r
+     * awsIotMqttMode is true. */\r
+    const char * pUserName;  /**< @brief Username for MQTT connection. */\r
+    uint16_t userNameLength; /**< @brief Length of #IotMqttConnectInfo_t.pUserName. */\r
+    const char * pPassword;  /**< @brief Password for MQTT connection. */\r
+    uint16_t passwordLength; /**< @brief Length of #IotMqttConnectInfo_t.pPassword. */\r
+} IotMqttConnectInfo_t;\r
+\r
+#if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
+\r
+/**\r
+ * @cond DOXYGEN_IGNORE\r
+ * Doxygen should ignore this section.\r
+ *\r
+ * Forward declaration of the internal MQTT packet structure.\r
+ */\r
+    struct _mqttPacket;\r
+/** @endcond */\r
+\r
+/**\r
+ * @ingroup mqtt_datatypes_paramstructs\r
+ * @brief Function pointers for MQTT packet serializer overrides.\r
+ *\r
+ * These function pointers allow the MQTT serialization and deserialization functions\r
+ * to be overridden for an MQTT connection. The compile-time setting\r
+ * @ref IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES must be `1` to enable this functionality.\r
+ * See the #IotMqttSerializer_t::serialize and #IotMqttSerializer_t::deserialize\r
+ * members for a list of functions that can be overridden. In addition, the functions\r
+ * for freeing packets and determining the packet type can also be overridden. If\r
+ * @ref IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES is `1`, the serializer initialization and\r
+ * cleanup functions may be extended. See documentation of\r
+ * @ref IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES for more information.\r
+ *\r
+ * If any function pointers that are `NULL`, then the default implementation of that\r
+ * function will be used.\r
+ */\r
+    typedef struct IotMqttSerializer\r
+    {\r
+        /**\r
+         * @brief Get the MQTT packet type from a stream of bytes off the network.\r
+         *\r
+         * @param[in] pNetworkConnection Reference to the network connection.\r
+         * @param[in] pNetworkInterface Function pointers used to interact with the\r
+         * network.\r
+         *\r
+         * <b>Default implementation:</b> #_IotMqtt_GetPacketType\r
+         */\r
+        uint8_t ( * getPacketType )( void * /* pNetworkConnection */,\r
+                                     const IotNetworkInterface_t * /* pNetworkInterface */ );\r
+\r
+        /**\r
+         * @brief Get the remaining length from a stream of bytes off the network.\r
+         *\r
+         * @param[in] pNetworkConnection Reference to the network connection.\r
+         * @param[in] pNetworkInterface Function pointers used to interact with the\r
+         * network.\r
+         *\r
+         * <b>Default implementation:</b> #_IotMqtt_GetRemainingLength\r
+         */\r
+        size_t ( * getRemainingLength )( void * pNetworkConnection,\r
+                                         const IotNetworkInterface_t * pNetworkInterface );\r
+\r
+        /**\r
+         * @brief Free a packet generated by the serializer.\r
+         *\r
+         * This function pointer must be set if any other serializer override is set.\r
+         * @param[in] uint8_t* The packet to free.\r
+         *\r
+         * <b>Default implementation:</b> #_IotMqtt_FreePacket\r
+         */\r
+        void ( * freePacket )( uint8_t * /* pPacket */ );\r
+\r
+        struct\r
+        {\r
+            /**\r
+             * @brief CONNECT packet serializer function.\r
+             * @param[in] IotMqttConnectInfo_t* User-provided CONNECT information.\r
+             * @param[out] uint8_t** Where the CONNECT packet is written.\r
+             * @param[out] size_t* Size of the CONNECT packet.\r
+             *\r
+             * <b>Default implementation:</b> #_IotMqtt_SerializeConnect\r
+             */\r
+            IotMqttError_t ( * connect )( const IotMqttConnectInfo_t * /* pConnectInfo */,\r
+                                          uint8_t ** /* pConnectPacket */,\r
+                                          size_t * /* pPacketSize */ );\r
+\r
+            /**\r
+             * @brief PUBLISH packet serializer function.\r
+             * @param[in] IotMqttPublishInfo_t* User-provided PUBLISH information.\r
+             * @param[out] uint8_t** Where the PUBLISH packet is written.\r
+             * @param[out] size_t* Size of the PUBLISH packet.\r
+             * @param[out] uint16_t* The packet identifier generated for this PUBLISH.\r
+             * @param[out] uint8_t** Where the high byte of the packet identifier\r
+             * is written.\r
+             *\r
+             * <b>Default implementation:</b> #_IotMqtt_SerializePublish\r
+             */\r
+            IotMqttError_t ( * publish )( const IotMqttPublishInfo_t * /* pPublishInfo */,\r
+                                          uint8_t ** /* pPublishPacket */,\r
+                                          size_t * /* pPacketSize */,\r
+                                          uint16_t * /* pPacketIdentifier */,\r
+                                          uint8_t ** /* pPacketIdentifierHigh */ );\r
+\r
+            /**\r
+             * @brief Set the `DUP` bit in a QoS `1` PUBLISH packet.\r
+             * @param[in] uint8_t* Pointer to the PUBLISH packet to modify.\r
+             * @param[in] uint8_t* The high byte of any packet identifier to modify.\r
+             * @param[out] uint16_t* New packet identifier (AWS IoT MQTT mode only).\r
+             *\r
+             * <b>Default implementation:</b> #_IotMqtt_PublishSetDup\r
+             */\r
+            void ( *publishSetDup )( uint8_t * /* pPublishPacket */,\r
+                                     uint8_t * /* pPacketIdentifierHigh */,\r
+                                     uint16_t * /* pNewPacketIdentifier */ );\r
+\r
+            /**\r
+             * @brief PUBACK packet serializer function.\r
+             * @param[in] uint16_t The packet identifier to place in PUBACK.\r
+             * @param[out] uint8_t** Where the PUBACK packet is written.\r
+             * @param[out] size_t* Size of the PUBACK packet.\r
+             *\r
+             * <b>Default implementation:</b> #_IotMqtt_SerializePuback\r
+             */\r
+            IotMqttError_t ( * puback )( uint16_t /* packetIdentifier */,\r
+                                         uint8_t ** /* pPubackPacket */,\r
+                                         size_t * /* pPacketSize */ );\r
+\r
+            /**\r
+             * @brief SUBSCRIBE packet serializer function.\r
+             * @param[in] IotMqttSubscription_t* User-provided array of subscriptions.\r
+             * @param[in] size_t Number of elements in the subscription array.\r
+             * @param[out] uint8_t** Where the SUBSCRIBE packet is written.\r
+             * @param[out] size_t* Size of the SUBSCRIBE packet.\r
+             * @param[out] uint16_t* The packet identifier generated for this SUBSCRIBE.\r
+             *\r
+             * <b>Default implementation:</b> #_IotMqtt_SerializeSubscribe\r
+             */\r
+            IotMqttError_t ( * subscribe )( const IotMqttSubscription_t * /* pSubscriptionList */,\r
+                                            size_t /* subscriptionCount */,\r
+                                            uint8_t ** /* pSubscribePacket */,\r
+                                            size_t * /* pPacketSize */,\r
+                                            uint16_t * /* pPacketIdentifier */ );\r
+\r
+            /**\r
+             * @brief UNSUBSCRIBE packet serializer function.\r
+             * @param[in] IotMqttSubscription_t* User-provided array of subscriptions to remove.\r
+             * @param[in] size_t Number of elements in the subscription array.\r
+             * @param[out] uint8_t** Where the UNSUBSCRIBE packet is written.\r
+             * @param[out] size_t* Size of the UNSUBSCRIBE packet.\r
+             * @param[out] uint16_t* The packet identifier generated for this UNSUBSCRIBE.\r
+             *\r
+             * <b>Default implementation:</b> #_IotMqtt_SerializeUnsubscribe\r
+             */\r
+            IotMqttError_t ( * unsubscribe )( const IotMqttSubscription_t * /* pSubscriptionList */,\r
+                                              size_t /* subscriptionCount */,\r
+                                              uint8_t ** /* pUnsubscribePacket */,\r
+                                              size_t * /* pPacketSize */,\r
+                                              uint16_t * /* pPacketIdentifier */ );\r
+\r
+            /**\r
+             * @brief PINGREQ packet serializer function.\r
+             * @param[out] uint8_t** Where the PINGREQ packet is written.\r
+             * @param[out] size_t* Size of the PINGREQ packet.\r
+             *\r
+             * <b>Default implementation:</b> #_IotMqtt_SerializePingreq\r
+             */\r
+            IotMqttError_t ( * pingreq )( uint8_t ** /* pPingreqPacket */,\r
+                                          size_t * /* pPacketSize */ );\r
+\r
+            /**\r
+             * @brief DISCONNECT packet serializer function.\r
+             * @param[out] uint8_t** Where the DISCONNECT packet is written.\r
+             * @param[out] size_t* Size of the DISCONNECT packet.\r
+             *\r
+             * <b>Default implementation:</b> #_IotMqtt_SerializeDisconnect\r
+             */\r
+            IotMqttError_t ( * disconnect )( uint8_t ** /* pDisconnectPacket */,\r
+                                             size_t * /* pPacketSize */ );\r
+        } serialize; /**< @brief Overrides the packet serialization functions for a single connection. */\r
+\r
+        struct\r
+        {\r
+            /**\r
+             * @brief CONNACK packet deserializer function.\r
+             * @param[in,out] _mqttPacket* Pointer to an MQTT packet struct representing a CONNACK.\r
+             *\r
+             * <b>Default implementation:</b> #_IotMqtt_DeserializeConnack\r
+             */\r
+            IotMqttError_t ( * connack )( struct _mqttPacket * /* pConnack */ );\r
+\r
+            /**\r
+             * @brief PUBLISH packet deserializer function.\r
+             * @param[in,out] _mqttPacket* Pointer to an MQTT packet struct representing a PUBLISH.\r
+             *\r
+             * <b>Default implementation:</b> #_IotMqtt_DeserializePublish\r
+             */\r
+            IotMqttError_t ( * publish )( struct _mqttPacket * /* pPublish */ );\r
+\r
+            /**\r
+             * @brief PUBACK packet deserializer function.\r
+             * @param[in,out] _mqttPacket* Pointer to an MQTT packet struct representing a PUBACK.\r
+             *\r
+             * <b>Default implementation:</b> #_IotMqtt_DeserializePuback\r
+             */\r
+            IotMqttError_t ( * puback )( struct _mqttPacket * pPuback );\r
+\r
+            /**\r
+             * @brief SUBACK packet deserializer function.\r
+             * @param[in,out] _mqttPacket* Pointer to an MQTT packet struct representing a SUBACK.\r
+             *\r
+             * <b>Default implementation:</b> #_IotMqtt_DeserializeSuback\r
+             */\r
+            IotMqttError_t ( * suback )( struct _mqttPacket * /* pSuback */ );\r
+\r
+            /**\r
+             * @brief UNSUBACK packet deserializer function.\r
+             * @param[in,out] _mqttPacket* Pointer to an MQTT packet struct representing an UNSUBACK.\r
+             *\r
+             * <b>Default implementation:</b> #_IotMqtt_DeserializeUnsuback\r
+             */\r
+            IotMqttError_t ( * unsuback )( struct _mqttPacket * /* pUnsuback */ );\r
+\r
+            /**\r
+             * @brief PINGRESP packet deserializer function.\r
+             * @param[in,out] _mqttPacket* Pointer to an MQTT packet struct representing a PINGRESP.\r
+             *\r
+             * <b>Default implementation:</b> #_IotMqtt_DeserializePingresp\r
+             */\r
+            IotMqttError_t ( * pingresp )( struct _mqttPacket * /* pPingresp */ );\r
+        } deserialize; /**< @brief Overrides the packet deserialization functions for a single connection. */\r
+    } IotMqttSerializer_t;\r
+#else /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */\r
+\r
+/* When MQTT packet serializer overrides are disabled, this struct is an\r
+ * incomplete type. */\r
+    typedef struct IotMqttSerializer IotMqttSerializer_t;\r
+\r
+#endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */\r
+\r
+/**\r
+ * @ingroup mqtt_datatypes_paramstructs\r
+ * @brief Infomation on the transport-layer network connection for the new MQTT\r
+ * connection.\r
+ *\r
+ * @paramfor @ref mqtt_function_connect\r
+ *\r
+ * The MQTT library needs to be able to send and receive data over a network.\r
+ * This struct provides an interface for interacting with the network.\r
+ *\r
+ * @initializer{IotMqttNetworkInfo_t,IOT_MQTT_NETWORK_INFO_INITIALIZER}\r
+ */\r
+typedef struct IotMqttNetworkInfo\r
+{\r
+    /**\r
+     * @brief Whether a new network connection should be created.\r
+     *\r
+     * When this value is `true`, a new transport-layer network connection will\r
+     * be created along with the MQTT connection. #IotMqttNetworkInfo_t::pNetworkServerInfo\r
+     * and #IotMqttNetworkInfo_t::pNetworkCredentialInfo are valid when this value\r
+     * is `true`.\r
+     *\r
+     * When this value is `false`, the MQTT connection will use a transport-layer\r
+     * network connection that has already been established. The MQTT library will\r
+     * still set the appropriate receive callback even if the network connection\r
+     * has been established.\r
+     * #IotMqttNetworkInfo_t::pNetworkConnection, which represents an established\r
+     * network connection, is valid when this value is `false`.\r
+     */\r
+    bool createNetworkConnection;\r
+\r
+    union\r
+    {\r
+        struct\r
+        {\r
+            /**\r
+             * @brief Information on the MQTT server, passed as `pConnectionInfo` to\r
+             * #IotNetworkInterface_t::create.\r
+             *\r
+             * This member is opaque to the MQTT library. It is passed to the network\r
+             * interface when creating a new network connection. It is only valid when\r
+             * #IotMqttNetworkInfo_t::createNetworkConnection is `true`.\r
+             */\r
+            void * pNetworkServerInfo;\r
+\r
+            /**\r
+             * @brief Credentials for the MQTT server, passed as `pCredentialInfo` to\r
+             * #IotNetworkInterface_t::create.\r
+             *\r
+             * This member is opaque to the MQTT library. It is passed to the network\r
+             * interface when creating a new network connection. It is only valid when\r
+             * #IotMqttNetworkInfo_t::createNetworkConnection is `true`.\r
+             */\r
+            void * pNetworkCredentialInfo;\r
+        } setup;\r
+\r
+        /**\r
+         * @brief An established transport-layer network connection.\r
+         *\r
+         * This member is opaque to the MQTT library. It is passed to the network\r
+         * interface to reference an established network connection. It is only\r
+         * valid when #IotMqttNetworkInfo_t::createNetworkConnection is `false`.\r
+         */\r
+        void * pNetworkConnection;\r
+    } u /**< @brief Valid member depends of IotMqttNetworkInfo_t.createNetworkConnection. */;\r
+\r
+    /**\r
+     * @brief The network functions used by the new MQTT connection.\r
+     *\r
+     * @attention The function pointers of the network interface must remain valid\r
+     * for the lifetime of the MQTT connection.\r
+     */\r
+    const IotNetworkInterface_t * pNetworkInterface;\r
+\r
+    /**\r
+     * @brief A callback function to invoke when this MQTT connection is disconnected.\r
+     */\r
+    IotMqttCallbackInfo_t disconnectCallback;\r
+\r
+    #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
+\r
+        /**\r
+         * @brief MQTT packet serializer overrides used by the new MQTT connection.\r
+         *\r
+         * @attention The function pointers of the MQTT serializer overrides must\r
+         * remain valid for the lifetime of the MQTT connection.\r
+         */\r
+        const IotMqttSerializer_t * pMqttSerializer;\r
+    #endif\r
+} IotMqttNetworkInfo_t;\r
+\r
+/*------------------------- MQTT defined constants --------------------------*/\r
+\r
+/**\r
+ * @constantspage{mqtt,MQTT library}\r
+ *\r
+ * @section mqtt_constants_initializers MQTT Initializers\r
+ * @brief Provides default values for the data types of the MQTT library.\r
+ *\r
+ * @snippet this define_mqtt_initializers\r
+ *\r
+ * All user-facing data types of the MQTT library should be initialized using\r
+ * one of the following.\r
+ *\r
+ * @warning Failing to initialize an MQTT data type with the appropriate initializer\r
+ * may result in undefined behavior!\r
+ * @note The initializers may change at any time in future versions, but their\r
+ * names will remain the same.\r
+ *\r
+ * <b>Example</b>\r
+ * @code{c}\r
+ * IotMqttNetworkInfo_t networkInfo = IOT_MQTT_NETWORK_INFO_INITIALIZER;\r
+ * IotMqttSerializer_t serializer = IOT_MQTT_SERIALIZER_INITIALIZER;\r
+ * IotMqttConnectInfo_t connectInfo = IOT_MQTT_CONNECT_INFO_INITIALIZER;\r
+ * IotMqttPublishInfo_t publishInfo = IOT_MQTT_PUBLISH_INFO_INITIALIZER;\r
+ * IotMqttSubscription_t subscription = IOT_MQTT_SUBSCRIPTION_INITIALIZER;\r
+ * IotMqttCallbackInfo_t callbackInfo = IOT_MQTT_CALLBACK_INFO_INITIALIZER;\r
+ * IotMqttConnection_t connection = IOT_MQTT_CONNECTION_INITIALIZER;\r
+ * IotMqttOperation_t operation = IOT_MQTT_OPERATION_INITIALIZER;\r
+ * @endcode\r
+ *\r
+ * @section mqtt_constants_flags MQTT Function Flags\r
+ * @brief Flags that modify the behavior of MQTT library functions.\r
+ * - #IOT_MQTT_FLAG_WAITABLE <br>\r
+ *   @copybrief IOT_MQTT_FLAG_WAITABLE\r
+ * - #IOT_MQTT_FLAG_CLEANUP_ONLY <br>\r
+ *   @copybrief IOT_MQTT_FLAG_CLEANUP_ONLY\r
+ *\r
+ * Flags should be bitwise-ORed with each other to change the behavior of\r
+ * @ref mqtt_function_subscribe, @ref mqtt_function_unsubscribe,\r
+ * @ref mqtt_function_publish, or @ref mqtt_function_disconnect.\r
+ *\r
+ * @note The values of the flags may change at any time in future versions, but\r
+ * their names will remain the same. Additionally, flags that may be used together\r
+ * will be bitwise-exclusive of each other.\r
+ */\r
+\r
+/* @[define_mqtt_initializers] */\r
+/** @brief Initializer for #IotMqttNetworkInfo_t. */\r
+#define IOT_MQTT_NETWORK_INFO_INITIALIZER     { .createNetworkConnection = true }\r
+/** @brief Initializer for #IotMqttSerializer_t. */\r
+#define IOT_MQTT_SERIALIZER_INITIALIZER       { 0 }\r
+/** @brief Initializer for #IotMqttConnectInfo_t. */\r
+#define IOT_MQTT_CONNECT_INFO_INITIALIZER     { .cleanSession = true }\r
+/** @brief Initializer for #IotMqttPublishInfo_t. */\r
+#define IOT_MQTT_PUBLISH_INFO_INITIALIZER     { .qos = IOT_MQTT_QOS_0 }\r
+/** @brief Initializer for #IotMqttSubscription_t. */\r
+#define IOT_MQTT_SUBSCRIPTION_INITIALIZER     { .qos = IOT_MQTT_QOS_0 }\r
+/** @brief Initializer for #IotMqttCallbackInfo_t. */\r
+#define IOT_MQTT_CALLBACK_INFO_INITIALIZER    { 0 }\r
+/** @brief Initializer for #IotMqttConnection_t. */\r
+#define IOT_MQTT_CONNECTION_INITIALIZER       NULL\r
+/** @brief Initializer for #IotMqttOperation_t. */\r
+#define IOT_MQTT_OPERATION_INITIALIZER        NULL\r
+/* @[define_mqtt_initializers] */\r
+\r
+/**\r
+ * @brief Allows the use of @ref mqtt_function_wait for blocking until completion.\r
+ *\r
+ * This flag is always valid for @ref mqtt_function_subscribe and\r
+ * @ref mqtt_function_unsubscribe. If passed to @ref mqtt_function_publish,\r
+ * the parameter [pPublishInfo->qos](@ref IotMqttPublishInfo_t.qos) must not be `0`.\r
+ *\r
+ * An #IotMqttOperation_t <b>MUST</b> be provided if this flag is set. Additionally, an\r
+ * #IotMqttCallbackInfo_t <b>MUST NOT</b> be provided.\r
+ *\r
+ * @note If this flag is set, @ref mqtt_function_wait <b>MUST</b> be called to clean up\r
+ * resources.\r
+ */\r
+#define IOT_MQTT_FLAG_WAITABLE        ( 0x00000001 )\r
+\r
+/**\r
+ * @brief Causes @ref mqtt_function_disconnect to only free memory and not send\r
+ * an MQTT DISCONNECT packet.\r
+ *\r
+ * This flag is only valid for @ref mqtt_function_disconnect. It should be passed\r
+ * to @ref mqtt_function_disconnect if the network goes offline or is otherwise\r
+ * unusable.\r
+ */\r
+#define IOT_MQTT_FLAG_CLEANUP_ONLY    ( 0x00000001 )\r
+\r
+#endif /* ifndef IOT_MQTT_TYPES_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_ble_mqtt_serialize.c b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_ble_mqtt_serialize.c
new file mode 100644 (file)
index 0000000..143b442
--- /dev/null
@@ -0,0 +1,1528 @@
+/*\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 aws_mqtt_lib_ble.c\r
+ * @brief MQTT library for BLE.\r
+ */\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/* Standard includes. */\r
+#include <string.h>\r
+#include <stdio.h>\r
+\r
+/* FreeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+\r
+#include "iot_ble_config.h"\r
+\r
+\r
+/* MQTT internal includes. */\r
+#include "platform/iot_threads.h"\r
+#include "iot_serializer.h"\r
+#include "platform/iot_network_ble.h"\r
+#include "iot_ble_data_transfer.h"\r
+#include "iot_ble_mqtt_serialize.h"\r
+#include "private/iot_mqtt_internal.h"\r
+\r
+#define _INVALID_MQTT_PACKET_TYPE        ( 0xF0 )\r
+\r
+\r
+#define _IS_VALID_SERIALIZER_RET( ret, pSerializerBuf )                                \\r
+    (  ( ret == IOT_SERIALIZER_SUCCESS ) ||                                        \\r
+          (  ( !pSerializerBuf ) && ( ret == IOT_SERIALIZER_BUFFER_TOO_SMALL ) ) )\r
+\r
+#define _NUM_CONNECT_PARMAS                   ( 4 )\r
+#define _NUM_DEFAULT_PUBLISH_PARMAS           ( 4 )\r
+#define _NUM_PUBACK_PARMAS                    ( 2 )\r
+#define _NUM_SUBACK_PARAMS                    ( 4 )\r
+#define _NUM_UNSUBACK_PARAMS                  ( 3 )\r
+#define _NUM_DISCONNECT_PARAMS                ( 1 )\r
+#define _NUM_PINGREQUEST_PARAMS               ( 1 )\r
+\r
+const IotMqttSerializer_t IotBleMqttSerializer = {\r
+    .serialize.connect       = IotBleMqtt_SerializeConnect,\r
+    .serialize.publish       = IotBleMqtt_SerializePublish,\r
+    .serialize.publishSetDup = IotBleMqtt_PublishSetDup,\r
+    .serialize.puback        = IotBleMqtt_SerializePuback,\r
+    .serialize.subscribe     = IotBleMqtt_SerializeSubscribe,\r
+    .serialize.unsubscribe   = IotBleMqtt_SerializeUnsubscribe,\r
+    .serialize.pingreq       = IotBleMqtt_SerializePingreq,\r
+    .serialize.disconnect    = IotBleMqtt_SerializeDisconnect,\r
+    .freePacket              = IotBleMqtt_FreePacket,\r
+    .getPacketType           = IotBleMqtt_GetPacketType,\r
+    .getRemainingLength      = IotBleMqtt_GetRemainingLength,\r
+    .deserialize.connack     = IotBleMqtt_DeserializeConnack,\r
+    .deserialize.publish     = IotBleMqtt_DeserializePublish,\r
+    .deserialize.puback      = IotBleMqtt_DeserializePuback,\r
+    .deserialize.suback      = IotBleMqtt_DeserializeSuback,\r
+    .deserialize.unsuback    = IotBleMqtt_DeserializeUnsuback,\r
+    .deserialize.pingresp    = IotBleMqtt_DeserializePingresp\r
+};\r
+\r
+/**\r
+ * @brief Guards access to the packet identifier counter.\r
+ *\r
+ * Each packet should have a unique packet identifier. This mutex ensures that only\r
+ * one thread at a time may read the global packet identifer.\r
+ */\r
+\r
+\r
+/**\r
+ * @brief Generates a monotonically increasing identifier used in  MQTT message\r
+ *\r
+ * @return Identifier for the MQTT message\r
+ */\r
+static uint16_t _nextPacketIdentifier( void );\r
+\r
+\r
+static inline uint16_t _getNumPublishParams( const IotMqttPublishInfo_t * const pPublish )\r
+{\r
+   return ( pPublish->qos > 0 ) ?  ( _NUM_DEFAULT_PUBLISH_PARMAS + 1 ) : _NUM_DEFAULT_PUBLISH_PARMAS;\r
+}\r
+\r
+static IotSerializerError_t _serializeConnect( const IotMqttConnectInfo_t * const pConnectInfo,\r
+                                       uint8_t* const pBuffer,\r
+                                       size_t* const pSize );\r
+static IotSerializerError_t _serializePublish( const IotMqttPublishInfo_t * const pPublishInfo,\r
+                                                  uint8_t * pBuffer,\r
+                                                  size_t  * pSize,\r
+                                                  uint16_t packetIdentifier );\r
+static IotSerializerError_t _serializePubAck( uint16_t packetIdentifier,\r
+                                      uint8_t * pBuffer,\r
+                                      size_t  * pSize );\r
+\r
+\r
+\r
+static IotSerializerError_t _serializeSubscribe( const IotMqttSubscription_t * const pSubscriptionList,\r
+                                               size_t subscriptionCount,\r
+                                               uint8_t * const pBuffer,\r
+                                               size_t * const pSize,\r
+                                               uint16_t packetIdentifier );\r
+\r
+static IotSerializerError_t _serializeUnSubscribe( const IotMqttSubscription_t * const pSubscriptionList,\r
+                                               size_t subscriptionCount,\r
+                                               uint8_t * const pBuffer,\r
+                                               size_t * const pSize,\r
+                                               uint16_t packetIdentifier );\r
+\r
+static IotSerializerError_t _serializeDisconnect( uint8_t * const pBuffer,\r
+                                                size_t * const pSize );\r
+\r
+\r
+static IotSerializerError_t _serializePingRequest( uint8_t * const pBuffer,\r
+                                                size_t * const pSize );\r
+\r
+#if LIBRARY_LOG_LEVEL > AWS_IOT_LOG_NONE\r
+\r
+/**\r
+ * @brief If logging is enabled, define a log configuration that only prints the log\r
+ * string. This is used when printing out details of deserialized MQTT packets.\r
+ */\r
+static const IotLogConfig_t _logHideAll =\r
+{\r
+    .hideLibraryName = true,\r
+    .hideLogLevel    = true,\r
+    .hideTimestring  = true\r
+};\r
+#endif\r
+\r
+\r
+static IotMutex_t _packetIdentifierMutex;\r
+\r
+\r
+/* Declaration of snprintf. The header stdio.h is not included because it\r
+ * includes conflicting symbols on some platforms. */\r
+extern int snprintf( char * s,\r
+                     size_t n,\r
+                     const char * format,\r
+                     ... );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static uint16_t _nextPacketIdentifier( void )\r
+{\r
+    static uint16_t nextPacketIdentifier = 1;\r
+    uint16_t newPacketIdentifier = 0;\r
+\r
+    /* Lock the packet identifier mutex so that only one thread may read and\r
+         * modify nextPacketIdentifier. */\r
+     IotMutex_Lock( &_packetIdentifierMutex );\r
+\r
+    /* Read the next packet identifier. */\r
+    newPacketIdentifier = nextPacketIdentifier;\r
+\r
+    /* The next packet identifier will be greater by 2. This prevents packet\r
+     * identifiers from ever being 0, which is not allowed by MQTT 3.1.1. Packet\r
+     * identifiers will follow the sequence 1,3,5...65535,1,3,5... */\r
+    nextPacketIdentifier = ( uint16_t ) ( nextPacketIdentifier + ( ( uint16_t ) 2 ) );\r
+\r
+    /* Unlock the packet identifier mutex. */\r
+    IotMutex_Unlock( &_packetIdentifierMutex );\r
+\r
+    return newPacketIdentifier;\r
+}\r
+\r
+static IotSerializerError_t _serializeConnect( const IotMqttConnectInfo_t * const pConnectInfo,\r
+                                       uint8_t* const pBuffer,\r
+                                       size_t* const pSize )\r
+{\r
+    IotSerializerError_t error = IOT_SERIALIZER_SUCCESS;\r
+    IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM ;\r
+    IotSerializerEncoderObject_t connectMap = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP;\r
+    IotSerializerScalarData_t data = { 0 };\r
+\r
+    error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize );\r
+    if( error == IOT_SERIALIZER_SUCCESS )\r
+    {\r
+\r
+        error = IOT_BLE_MESG_ENCODER.openContainer(\r
+                &encoderObj,\r
+                &connectMap,\r
+                _NUM_CONNECT_PARMAS );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
+        data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_CONNECT;\r
+        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &connectMap, IOT_BLE_MQTT_MSG_TYPE, data );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        data.type = IOT_SERIALIZER_SCALAR_TEXT_STRING;\r
+        data.value.u.string.pString = ( uint8_t * ) pConnectInfo->pClientIdentifier;\r
+        data.value.u.string.length = pConnectInfo->clientIdentifierLength;\r
+        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &connectMap, IOT_BLE_MQTT_CLIENT_ID, data );\r
+    }\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        data.type = IOT_SERIALIZER_SCALAR_TEXT_STRING;\r
+        data.value.u.string.pString = ( uint8_t * ) clientcredentialMQTT_BROKER_ENDPOINT;\r
+        data.value.u.string.length = strlen( clientcredentialMQTT_BROKER_ENDPOINT );\r
+        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &connectMap, IOT_BLE_MQTT_BROKER_EP, data );\r
+    }\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        data.type = IOT_SERIALIZER_SCALAR_BOOL;\r
+        data.value.u.booleanValue = pConnectInfo->cleanSession;\r
+        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &connectMap, IOT_BLE_MQTT_CLEAN_SESSION, data );\r
+    }\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &connectMap );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        if( pBuffer == NULL )\r
+        {\r
+            *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj );\r
+        }\r
+        else\r
+        {\r
+            *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer );\r
+        }\r
+\r
+        IOT_BLE_MESG_ENCODER.destroy( &encoderObj );\r
+        error = IOT_SERIALIZER_SUCCESS;\r
+\r
+    }\r
+\r
+    return error;\r
+}\r
+\r
+static IotSerializerError_t _serializePublish( const IotMqttPublishInfo_t * const pPublishInfo,\r
+                                                  uint8_t * pBuffer,\r
+                                                  size_t  * pSize,\r
+                                                  uint16_t packetIdentifier )\r
+{\r
+    IotSerializerError_t error = IOT_SERIALIZER_SUCCESS;\r
+    IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM ;\r
+    IotSerializerEncoderObject_t publishMap = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP;\r
+    IotSerializerScalarData_t data = { 0 };\r
+    uint16_t numPublishParams = _getNumPublishParams( pPublishInfo );\r
+\r
+    error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize );\r
+\r
+    if( error == IOT_SERIALIZER_SUCCESS )\r
+    {\r
+\r
+\r
+        error = IOT_BLE_MESG_ENCODER.openContainer(\r
+                &encoderObj,\r
+                &publishMap,\r
+                numPublishParams );\r
+    }\r
+\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
+        data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_PUBLISH;\r
+        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &publishMap, IOT_BLE_MQTT_MSG_TYPE, data );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        data.type = IOT_SERIALIZER_SCALAR_TEXT_STRING;\r
+        data.value.u.string.pString = ( uint8_t * ) pPublishInfo->pTopicName;\r
+        data.value.u.string.length = pPublishInfo->topicNameLength;\r
+        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &publishMap, IOT_BLE_MQTT_TOPIC, data );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+\r
+        data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
+        data.value.u.signedInt = pPublishInfo->qos;\r
+        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &publishMap, IOT_BLE_MQTT_QOS, data );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        data.type = IOT_SERIALIZER_SCALAR_BYTE_STRING;\r
+        data.value.u.string.pString = ( uint8_t * ) pPublishInfo->pPayload;\r
+        data.value.u.string.length = pPublishInfo->payloadLength;\r
+        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &publishMap, IOT_BLE_MQTT_PAYLOAD, data );\r
+    }\r
+\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        if( pPublishInfo->qos != 0 )\r
+        {\r
+            data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
+            data.value.u.signedInt = packetIdentifier;\r
+            error = IOT_BLE_MESG_ENCODER.appendKeyValue( &publishMap, IOT_BLE_MQTT_MESSAGE_ID, data );\r
+\r
+        }\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+\r
+        error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &publishMap );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        if( pBuffer == NULL )\r
+        {\r
+            *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj );\r
+\r
+        }\r
+        else\r
+        {\r
+            *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer );\r
+        }\r
+        IOT_BLE_MESG_ENCODER.destroy( &encoderObj );\r
+        error = IOT_SERIALIZER_SUCCESS;\r
+    }\r
+\r
+\r
+    return error;\r
+}\r
+\r
+static IotSerializerError_t _serializePubAck( uint16_t packetIdentifier,\r
+                                      uint8_t * pBuffer,\r
+                                      size_t  * pSize )\r
+\r
+{\r
+    IotSerializerError_t error = IOT_SERIALIZER_SUCCESS;\r
+    IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM ;\r
+    IotSerializerEncoderObject_t pubAckMap = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP;\r
+    IotSerializerScalarData_t data = { 0 };\r
+\r
+    error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize );\r
+\r
+    if( error == IOT_SERIALIZER_SUCCESS )\r
+    {\r
+\r
+        error = IOT_BLE_MESG_ENCODER.openContainer(\r
+                &encoderObj,\r
+                &pubAckMap,\r
+                _NUM_PUBACK_PARMAS );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
+        data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_PUBACK;\r
+        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &pubAckMap, IOT_BLE_MQTT_MSG_TYPE, data );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
+        data.value.u.signedInt = packetIdentifier;\r
+        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &pubAckMap, IOT_BLE_MQTT_MESSAGE_ID, data );\r
+    }\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &pubAckMap );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        if( pBuffer == NULL )\r
+        {\r
+            *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj );\r
+        }\r
+        else\r
+        {\r
+            *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer );\r
+        }\r
+        IOT_BLE_MESG_ENCODER.destroy( &encoderObj );\r
+        error = IOT_SERIALIZER_SUCCESS;\r
+    }\r
+\r
+    return error;\r
+}\r
+\r
+\r
+static IotSerializerError_t _serializeSubscribe( const IotMqttSubscription_t * const pSubscriptionList,\r
+                                               size_t subscriptionCount,\r
+                                               uint8_t * const pBuffer,\r
+                                               size_t * const pSize,\r
+                                               uint16_t packetIdentifier )\r
+{\r
+    IotSerializerError_t error = IOT_SERIALIZER_SUCCESS;\r
+    IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM ;\r
+    IotSerializerEncoderObject_t subscribeMap = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP;\r
+    IotSerializerEncoderObject_t subscriptionArray = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_ARRAY;\r
+    IotSerializerScalarData_t data = { 0 };\r
+    uint16_t idx;\r
+\r
+    error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize );\r
+\r
+    if( error == IOT_SERIALIZER_SUCCESS )\r
+    {\r
+        error = IOT_BLE_MESG_ENCODER.openContainer(\r
+                &encoderObj,\r
+                &subscribeMap,\r
+                _NUM_SUBACK_PARAMS );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
+        data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_SUBSCRIBE;\r
+        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &subscribeMap, IOT_BLE_MQTT_MSG_TYPE, data );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+\r
+        error = IOT_BLE_MESG_ENCODER.openContainerWithKey(\r
+                &subscribeMap,\r
+                IOT_BLE_MQTT_TOPIC_LIST,\r
+                &subscriptionArray,\r
+                subscriptionCount );\r
+    }\r
+\r
+    for( idx = 0; idx < subscriptionCount; idx++ )\r
+    {\r
+        if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+        {\r
+            data.type = IOT_SERIALIZER_SCALAR_TEXT_STRING;\r
+            data.value.u.string.pString = ( uint8_t * ) pSubscriptionList[ idx ].pTopicFilter;\r
+            data.value.u.string.length = pSubscriptionList[ idx ].topicFilterLength;\r
+            error = IOT_BLE_MESG_ENCODER.append( &subscriptionArray, data );\r
+        }\r
+        else\r
+        {\r
+            break;\r
+        }\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        error = IOT_BLE_MESG_ENCODER.closeContainer( &subscribeMap, &subscriptionArray );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+\r
+        error = IOT_BLE_MESG_ENCODER.openContainerWithKey(\r
+                &subscribeMap,\r
+                IOT_BLE_MQTT_QOS_LIST,\r
+                &subscriptionArray,\r
+                subscriptionCount );\r
+    }\r
+\r
+\r
+    for( idx = 0; idx < subscriptionCount; idx++ )\r
+    {\r
+        if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+        {\r
+\r
+            data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
+            data.value.u.signedInt = pSubscriptionList[ idx ].qos;\r
+            error = IOT_BLE_MESG_ENCODER.append( &subscriptionArray, data );\r
+        }\r
+        else\r
+        {\r
+            break;\r
+        }\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        error = IOT_BLE_MESG_ENCODER.closeContainer( &subscribeMap, &subscriptionArray );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+\r
+        data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
+        data.value.u.signedInt = packetIdentifier;\r
+        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &subscribeMap, IOT_BLE_MQTT_MESSAGE_ID, data );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &subscribeMap );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        if( pBuffer == NULL )\r
+        {\r
+            *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj );\r
+        }\r
+        else\r
+        {\r
+            *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer );\r
+        }\r
+\r
+        IOT_BLE_MESG_ENCODER.destroy( &encoderObj );\r
+        error = IOT_SERIALIZER_SUCCESS;\r
+    }\r
+    return error;\r
+}\r
+\r
+static IotSerializerError_t _serializeUnSubscribe( const IotMqttSubscription_t * const pSubscriptionList,\r
+                                               size_t subscriptionCount,\r
+                                               uint8_t * const pBuffer,\r
+                                               size_t * const pSize,\r
+                                               uint16_t packetIdentifier )\r
+{\r
+    IotSerializerError_t error = IOT_SERIALIZER_SUCCESS;\r
+    IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM;\r
+    IotSerializerEncoderObject_t subscribeMap = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP;\r
+    IotSerializerEncoderObject_t subscriptionArray = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_ARRAY;\r
+    IotSerializerScalarData_t data = { 0 };\r
+    uint16_t idx;\r
+\r
+    error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize );\r
+\r
+    if( error == IOT_SERIALIZER_SUCCESS )\r
+    {\r
+\r
+        error = IOT_BLE_MESG_ENCODER.openContainer(\r
+                &encoderObj,\r
+                &subscribeMap,\r
+                _NUM_UNSUBACK_PARAMS );\r
+    }\r
+\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
+        data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_UNSUBSCRIBE;\r
+        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &subscribeMap, IOT_BLE_MQTT_MSG_TYPE, data );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        error = IOT_BLE_MESG_ENCODER.openContainerWithKey (\r
+                &subscribeMap,\r
+                IOT_BLE_MQTT_TOPIC_LIST,\r
+                &subscriptionArray,\r
+                subscriptionCount );\r
+    }\r
+\r
+    for( idx = 0; idx < subscriptionCount; idx++ )\r
+    {\r
+        if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+        {\r
+            data.type = IOT_SERIALIZER_SCALAR_TEXT_STRING;\r
+            data.value.u.string.pString = ( uint8_t * ) pSubscriptionList[ idx ].pTopicFilter;\r
+            data.value.u.string.length = pSubscriptionList[ idx ].topicFilterLength;\r
+            error = IOT_BLE_MESG_ENCODER.append( &subscriptionArray, data );\r
+        }\r
+        else\r
+        {\r
+            break;\r
+        }\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        error = IOT_BLE_MESG_ENCODER.closeContainer( &subscribeMap, &subscriptionArray );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
+        data.value.u.signedInt = packetIdentifier;\r
+        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &subscribeMap, IOT_BLE_MQTT_MESSAGE_ID, data );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &subscribeMap );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        if( pBuffer == NULL )\r
+        {\r
+            *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj );\r
+\r
+        }\r
+        else\r
+        {\r
+            *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer );\r
+        }\r
+        IOT_BLE_MESG_ENCODER.destroy( &encoderObj );\r
+        error = IOT_SERIALIZER_SUCCESS;\r
+    }\r
+\r
+    return error;\r
+}\r
+\r
+static IotSerializerError_t _serializeDisconnect( uint8_t * const pBuffer,\r
+                                                size_t * const pSize )\r
+{\r
+    IotSerializerError_t error = IOT_SERIALIZER_SUCCESS;\r
+    IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM;\r
+    IotSerializerEncoderObject_t disconnectMap = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP;\r
+    IotSerializerScalarData_t data = { 0 };\r
+\r
+    error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize );\r
+\r
+    if( error == IOT_SERIALIZER_SUCCESS )\r
+    {\r
+        error = IOT_BLE_MESG_ENCODER.openContainer(\r
+                &encoderObj,\r
+                &disconnectMap,\r
+                _NUM_DISCONNECT_PARAMS );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
+        data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_DISCONNECT;\r
+        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &disconnectMap, IOT_BLE_MQTT_MSG_TYPE, data );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &disconnectMap );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        if( pBuffer == NULL )\r
+        {\r
+            *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj );\r
+        }\r
+        else\r
+        {\r
+            *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer );\r
+        }\r
+        IOT_BLE_MESG_ENCODER.destroy( &encoderObj );\r
+        error = IOT_SERIALIZER_SUCCESS;\r
+    }\r
+\r
+    return error;\r
+}\r
+\r
+static IotSerializerError_t _serializePingRequest( uint8_t * const pBuffer,\r
+                                                   size_t * const pSize )\r
+{\r
+    IotSerializerError_t error = IOT_SERIALIZER_SUCCESS;\r
+    IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM;\r
+    IotSerializerEncoderObject_t pingRequest = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP;\r
+    IotSerializerScalarData_t data = { 0 };\r
+\r
+    error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize );\r
+\r
+    if( error == IOT_SERIALIZER_SUCCESS )\r
+    {\r
+        error = IOT_BLE_MESG_ENCODER.openContainer(\r
+                &encoderObj,\r
+                &pingRequest,\r
+                _NUM_PINGREQUEST_PARAMS );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
+         data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_PINGREQ;\r
+        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &pingRequest, IOT_BLE_MQTT_MSG_TYPE, data );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &pingRequest );\r
+    }\r
+\r
+    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
+    {\r
+        if( pBuffer == NULL )\r
+        {\r
+            *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj );\r
+        }\r
+        else\r
+        {\r
+            *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer );\r
+        }\r
+        IOT_BLE_MESG_ENCODER.destroy( &encoderObj );\r
+        error = IOT_SERIALIZER_SUCCESS;\r
+    }\r
+\r
+    return error;\r
+}\r
+\r
+\r
+bool IotBleMqtt_InitSerialize( void )\r
+{\r
+       /* Create the packet identifier mutex. */\r
+       return IotMutex_Create( &_packetIdentifierMutex, false );\r
+}\r
+\r
+void IotBleMqtt_CleanupSerialize( void )\r
+{\r
+       /* Destroy the packet identifier mutex */\r
+       IotMutex_Destroy( &_packetIdentifierMutex );\r
+}\r
+\r
+\r
+IotMqttError_t IotBleMqtt_SerializeConnect( const IotMqttConnectInfo_t * const pConnectInfo,\r
+                                                           uint8_t ** const pConnectPacket,\r
+                                                           size_t * const pPacketSize )\r
+{\r
+       uint8_t * pBuffer = NULL;\r
+       size_t bufLen = 0;\r
+       IotSerializerError_t error;\r
+       IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
+\r
+\r
+       error = _serializeConnect( pConnectInfo, NULL, &bufLen );\r
+       if( error != IOT_SERIALIZER_SUCCESS )\r
+       {\r
+           IotLogError( "Failed to find length of serialized CONNECT message, error = %d", error );\r
+           ret = IOT_MQTT_BAD_PARAMETER;\r
+       }\r
+\r
+       if( ret == IOT_MQTT_SUCCESS )\r
+       {\r
+\r
+           pBuffer = IotMqtt_MallocMessage( bufLen );\r
+\r
+           /* If Memory cannot be allocated log an error and return */\r
+           if( pBuffer == NULL )\r
+           {\r
+               IotLogError( "Failed to allocate memory for CONNECT packet." );\r
+               ret =  IOT_MQTT_NO_MEMORY;\r
+           }\r
+       }\r
+\r
+       if( ret == IOT_MQTT_SUCCESS )\r
+       {\r
+           error = _serializeConnect( pConnectInfo, pBuffer, &bufLen );\r
+           if( error != IOT_SERIALIZER_SUCCESS )\r
+           {\r
+               IotLogError( "Failed to serialize CONNECT message, error = %d", error );\r
+               ret = IOT_MQTT_BAD_PARAMETER;\r
+           }\r
+       }\r
+\r
+       if( ret == IOT_MQTT_SUCCESS )\r
+       {\r
+           *pConnectPacket = pBuffer;\r
+           *pPacketSize = bufLen;\r
+       }\r
+       else\r
+       {\r
+           *pConnectPacket = NULL;\r
+           *pPacketSize = 0;\r
+           if( pBuffer != NULL )\r
+           {\r
+               IotMqtt_FreeMessage( pBuffer );\r
+           }\r
+       }\r
+\r
+    return ret;\r
+}\r
+\r
+IotMqttError_t IotBleMqtt_DeserializeConnack( _mqttPacket_t * pConnack )\r
+{\r
+\r
+    IotSerializerDecoderObject_t decoderObj = { 0 }, decoderValue = { 0 };\r
+    IotSerializerError_t error;\r
+    IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
+    int64_t respCode = 0L;\r
+\r
+    error = IOT_BLE_MESG_DECODER.init( &decoderObj, ( uint8_t * ) pConnack->pRemainingData, pConnack->remainingLength );\r
+    if( ( error != IOT_SERIALIZER_SUCCESS )\r
+            || ( decoderObj.type != IOT_SERIALIZER_CONTAINER_MAP ) )\r
+    {\r
+        IotLogError( "Malformed CONNACK, decoding the packet failed, decoder error = %d, type: %d", error, decoderObj.type );\r
+        ret = IOT_MQTT_BAD_RESPONSE;\r
+    }\r
+\r
+\r
+    if( ret == IOT_MQTT_SUCCESS )\r
+    {\r
+\r
+        error = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_STATUS, &decoderValue );\r
+        if ( ( error != IOT_SERIALIZER_SUCCESS ) ||\r
+                ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) )\r
+        {\r
+            IotLogError( "Invalid CONNACK, response code decode failed, error = %d, decoded value type = %d", error, decoderValue.type );\r
+            ret = IOT_MQTT_BAD_RESPONSE;\r
+        }\r
+        else\r
+        {\r
+\r
+            respCode =  decoderValue.u.value.u.signedInt;\r
+            if( ( respCode != IOT_BLE_MQTT_STATUS_CONNECTING )\r
+                    && ( respCode != IOT_BLE_MQTT_STATUS_CONNECTED ) )\r
+            {\r
+                ret = IOT_MQTT_SERVER_REFUSED;\r
+            }\r
+        }\r
+    }\r
+\r
+    IOT_BLE_MESG_DECODER.destroy( &decoderObj );\r
+\r
+    return ret;\r
+}\r
+\r
+IotMqttError_t IotBleMqtt_SerializePublish( const IotMqttPublishInfo_t * const pPublishInfo,\r
+                                                  uint8_t ** const pPublishPacket,\r
+                                                  size_t * const pPacketSize,\r
+                                                  uint16_t * const pPacketIdentifier,\r
+                                                                                                 uint8_t ** pPacketIdentifierHigh )\r
+{\r
+\r
+    uint8_t * pBuffer = NULL;\r
+    size_t bufLen = 0;\r
+    uint16_t usPacketIdentifier = 0;\r
+    IotSerializerError_t error;\r
+    IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
+\r
+    (void)pPacketIdentifierHigh;\r
+\r
+    if( pPublishInfo->qos != 0 )\r
+    {\r
+        usPacketIdentifier = _nextPacketIdentifier();\r
+    }\r
+\r
+    error = _serializePublish( pPublishInfo, NULL, &bufLen, usPacketIdentifier );\r
+    if( error != IOT_SERIALIZER_SUCCESS  )\r
+    {\r
+        IotLogError( "Failed to find size of serialized PUBLISH message, error = %d", error );\r
+        ret = IOT_MQTT_BAD_PARAMETER;\r
+    }\r
+\r
+    if( ret == IOT_MQTT_SUCCESS )\r
+    {\r
+\r
+        pBuffer = IotMqtt_MallocMessage( bufLen );\r
+        /* If Memory cannot be allocated log an error and return */\r
+        if( pBuffer == NULL )\r
+        {\r
+            IotLogError( "Failed to allocate memory for PUBLISH packet." );\r
+            ret =  IOT_MQTT_NO_MEMORY;\r
+        }\r
+    }\r
+\r
+    if( ret == IOT_MQTT_SUCCESS )\r
+    {\r
+\r
+        error = _serializePublish( pPublishInfo, pBuffer, &bufLen, usPacketIdentifier );\r
+        if( error != IOT_SERIALIZER_SUCCESS )\r
+        {\r
+            IotLogError( "Failed to serialize PUBLISH message, error = %d", error );\r
+            ret = IOT_MQTT_BAD_PARAMETER;\r
+        }\r
+    }\r
+\r
+    if( ret == IOT_MQTT_SUCCESS )\r
+    {\r
+        *pPublishPacket = pBuffer;\r
+        *pPacketSize = bufLen;\r
+        *pPacketIdentifier = usPacketIdentifier;\r
+    }\r
+    else\r
+    {\r
+        if( pBuffer != NULL )\r
+        {\r
+            IotMqtt_FreeMessage( pBuffer );\r
+        }\r
+        *pPublishPacket = NULL;\r
+        *pPacketSize = 0;\r
+    }\r
+\r
+    return ret;\r
+}\r
+\r
+void IotBleMqtt_PublishSetDup( uint8_t * const pPublishPacket, uint8_t * pPacketIdentifierHigh, uint16_t * const pNewPacketIdentifier  )\r
+{\r
+       /** TODO: Currently DUP flag is not supported by BLE SDKs **/\r
+}\r
+\r
+IotMqttError_t IotBleMqtt_DeserializePublish( _mqttPacket_t * pPublish )\r
+{\r
+\r
+    IotSerializerDecoderObject_t decoderObj = { 0 }, decoderValue = { 0 };\r
+    IotSerializerError_t xSerializerRet;\r
+    IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
+\r
+    xSerializerRet = IOT_BLE_MESG_DECODER.init( &decoderObj, ( uint8_t * ) pPublish->pRemainingData, pPublish->remainingLength );\r
+    if ( (xSerializerRet != IOT_SERIALIZER_SUCCESS ) ||\r
+            ( decoderObj.type != IOT_SERIALIZER_CONTAINER_MAP ) )\r
+    {\r
+\r
+        IotLogError( "Decoding PUBLISH packet failed, decoder error = %d, object type = %d", xSerializerRet, decoderObj.type );\r
+        ret = IOT_MQTT_BAD_RESPONSE;\r
+    }\r
+\r
+    if( ret == IOT_MQTT_SUCCESS )\r
+    {\r
+        xSerializerRet = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_QOS, &decoderValue );\r
+        if ( ( xSerializerRet != IOT_SERIALIZER_SUCCESS ) ||\r
+                 ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) )\r
+        {\r
+            IotLogError( "QOS Value decode failed, error = %d, decoded value type = %d", xSerializerRet, decoderValue.type );\r
+            ret = IOT_MQTT_BAD_RESPONSE;\r
+        }\r
+        else\r
+        {\r
+               pPublish->u.pIncomingPublish->u.publish.publishInfo.qos = decoderValue.u.value.u.signedInt;\r
+        }\r
+    }\r
+\r
+    if( ret == IOT_MQTT_SUCCESS )\r
+    {\r
+        decoderValue.u.value.u.string.pString = NULL;\r
+        decoderValue.u.value.u.string.length = 0;\r
+        xSerializerRet = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_TOPIC, &decoderValue );\r
+\r
+        if( ( xSerializerRet != IOT_SERIALIZER_SUCCESS ) ||\r
+                ( decoderValue.type != IOT_SERIALIZER_SCALAR_TEXT_STRING ) )\r
+        {\r
+            IotLogError( "Topic value decode failed, error = %d", xSerializerRet );\r
+            ret = IOT_MQTT_BAD_RESPONSE;\r
+        }\r
+        else\r
+        {\r
+               pPublish->u.pIncomingPublish->u.publish.publishInfo.pTopicName = ( const char* ) decoderValue.u.value.u.string.pString;\r
+               pPublish->u.pIncomingPublish->u.publish.publishInfo.topicNameLength = decoderValue.u.value.u.string.length;\r
+        }\r
+    }\r
+\r
+    if( ret == IOT_MQTT_SUCCESS )\r
+    {\r
+        decoderValue.u.value.u.string.pString = NULL;\r
+        decoderValue.u.value.u.string.length = 0;\r
+        xSerializerRet = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_PAYLOAD, &decoderValue );\r
+\r
+        if( ( xSerializerRet != IOT_SERIALIZER_SUCCESS ) ||\r
+                ( decoderValue.type != IOT_SERIALIZER_SCALAR_BYTE_STRING ) )\r
+        {\r
+            IotLogError( "Payload value decode failed, error = %d", xSerializerRet );\r
+            ret = IOT_MQTT_BAD_RESPONSE;\r
+        }\r
+        else\r
+        {\r
+               pPublish->u.pIncomingPublish->u.publish.publishInfo.pPayload = ( const char* ) decoderValue.u.value.u.string.pString;\r
+               pPublish->u.pIncomingPublish->u.publish.publishInfo.payloadLength = decoderValue.u.value.u.string.length;\r
+        }\r
+    }\r
+\r
+    if( ret == IOT_MQTT_SUCCESS )\r
+    {\r
+        if( pPublish->u.pIncomingPublish->u.publish.publishInfo.qos != 0 )\r
+        {\r
+            xSerializerRet = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_MESSAGE_ID, &decoderValue );\r
+            if ( ( xSerializerRet != IOT_SERIALIZER_SUCCESS ) ||\r
+                    ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) )\r
+            {\r
+                IotLogError( "Message identifier decode failed, error = %d, decoded value type = %d", xSerializerRet, decoderValue.type );\r
+                ret = IOT_MQTT_BAD_RESPONSE;\r
+            }\r
+            else\r
+            {\r
+               pPublish->packetIdentifier  = ( uint16_t ) decoderValue.u.value.u.signedInt;\r
+            }\r
+        }\r
+    }\r
+\r
+    if( ret == IOT_MQTT_SUCCESS  )\r
+    {\r
+       pPublish->u.pIncomingPublish->u.publish.publishInfo.retain = false;\r
+    }\r
+\r
+    IOT_BLE_MESG_DECODER.destroy( &decoderObj );\r
+\r
+    return ret;\r
+}\r
+\r
+IotMqttError_t IotBleMqtt_SerializePuback( uint16_t packetIdentifier,\r
+                                                      uint8_t ** const pPubackPacket,\r
+                                                      size_t * const pPacketSize )\r
+{\r
+    uint8_t * pBuffer = NULL;\r
+    size_t bufLen = 0;\r
+    IotSerializerError_t error;\r
+    IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
+\r
+    error = _serializePubAck( packetIdentifier, NULL, &bufLen );\r
+\r
+    if( error != IOT_SERIALIZER_SUCCESS )\r
+    {\r
+        IotLogError( "Failed to find size of serialized PUBACK message, error = %d", error );\r
+        ret = IOT_MQTT_BAD_PARAMETER;\r
+    }\r
+\r
+\r
+    if( ret == IOT_MQTT_SUCCESS )\r
+    {\r
+        pBuffer = IotMqtt_MallocMessage( bufLen );\r
+\r
+        /* If Memory cannot be allocated log an error and return */\r
+        if( pBuffer == NULL )\r
+        {\r
+            IotLogError( "Failed to allocate memory for PUBACK packet, packet identifier = %d", packetIdentifier );\r
+            ret = IOT_MQTT_NO_MEMORY;\r
+        }\r
+    }\r
+\r
+\r
+    if( ret == IOT_MQTT_SUCCESS )\r
+    {\r
+        error = _serializePubAck( packetIdentifier, pBuffer, &bufLen );\r
+\r
+        if( error != IOT_SERIALIZER_SUCCESS )\r
+        {\r
+            IotLogError( "Failed to find size of serialized PUBACK message, error = %d", error );\r
+            ret = IOT_MQTT_BAD_PARAMETER;\r
+        }\r
+    }\r
+\r
+\r
+    if( ret == IOT_MQTT_SUCCESS )\r
+    {\r
+        *pPubackPacket = pBuffer;\r
+        *pPacketSize = bufLen;\r
+    }\r
+    else\r
+    {\r
+        if( pBuffer != NULL )\r
+        {\r
+            IotMqtt_FreeMessage( pBuffer );\r
+        }\r
+\r
+        *pPubackPacket = NULL;\r
+        *pPacketSize = 0;\r
+    }\r
+\r
+       return ret;\r
+\r
+}\r
+\r
+IotMqttError_t IotBleMqtt_DeserializePuback( _mqttPacket_t * pPuback )\r
+{\r
+\r
+    IotSerializerDecoderObject_t decoderObj = { 0 }, decoderValue = { 0 };\r
+    IotSerializerError_t error;\r
+    IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
+\r
+    error = IOT_BLE_MESG_DECODER.init( &decoderObj, ( uint8_t * ) pPuback->pRemainingData, pPuback->remainingLength );\r
+\r
+    if ( ( error != IOT_SERIALIZER_SUCCESS )\r
+            || ( decoderObj.type != IOT_SERIALIZER_CONTAINER_MAP ) )\r
+    {\r
+        IotLogError( "Malformed PUBACK, decoding the packet failed, decoder error = %d, object type: %d", error, decoderObj.type );\r
+        ret = IOT_MQTT_BAD_RESPONSE;\r
+    }\r
+\r
+\r
+    if( ret == IOT_MQTT_SUCCESS )\r
+    {\r
+\r
+        error = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_MESSAGE_ID, &decoderValue );\r
+\r
+        if ( ( error != IOT_SERIALIZER_SUCCESS ) ||\r
+                ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) )\r
+        {\r
+            IotLogError( "Message ID decode failed, error = %d, decoded value type = %d", error, decoderValue.type );\r
+            ret = IOT_MQTT_BAD_RESPONSE;\r
+        }\r
+        else\r
+        {\r
+               pPuback->packetIdentifier = ( uint16_t ) decoderValue.u.value.u.signedInt;\r
+        }\r
+    }\r
+\r
+    IOT_BLE_MESG_DECODER.destroy( &decoderObj );\r
+\r
+    return ret;\r
+\r
+}\r
+\r
+IotMqttError_t IotBleMqtt_SerializeSubscribe( const IotMqttSubscription_t * const pSubscriptionList,\r
+                                                         size_t subscriptionCount,\r
+                                                         uint8_t ** const pSubscribePacket,\r
+                                                         size_t * const pPacketSize,\r
+                                                         uint16_t * const pPacketIdentifier )\r
+{\r
+    uint8_t * pBuffer = NULL;\r
+    size_t bufLen = 0;\r
+    uint16_t usPacketIdentifier = 0;\r
+    IotSerializerError_t error;\r
+    IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
+\r
+    usPacketIdentifier = _nextPacketIdentifier();\r
+\r
+    error = _serializeSubscribe( pSubscriptionList, subscriptionCount, NULL, &bufLen, usPacketIdentifier );\r
+    if( error != IOT_SERIALIZER_SUCCESS )\r
+    {\r
+        IotLogError( "Failed to find serialized length of SUBSCRIBE message, error = %d", error );\r
+        ret = IOT_MQTT_BAD_PARAMETER;\r
+    }\r
+\r
+    if( ret == IOT_MQTT_SUCCESS )\r
+    {\r
+        pBuffer = IotMqtt_MallocMessage( bufLen );\r
+\r
+        /* If Memory cannot be allocated log an error and return */\r
+        if( pBuffer == NULL )\r
+        {\r
+            IotLogError( "Failed to allocate memory for SUBSCRIBE message." );\r
+            ret = IOT_MQTT_NO_MEMORY;\r
+        }\r
+    }\r
+\r
+    if( ret == IOT_MQTT_SUCCESS )\r
+    {\r
+        error = _serializeSubscribe( pSubscriptionList, subscriptionCount, pBuffer, &bufLen, usPacketIdentifier );\r
+        if( error != IOT_SERIALIZER_SUCCESS )\r
+        {\r
+            IotLogError( "Failed to serialize SUBSCRIBE message, error = %d", error );\r
+            ret = IOT_MQTT_BAD_PARAMETER;\r
+        }\r
+    }\r
+\r
+    if( ret == IOT_MQTT_SUCCESS )\r
+    {\r
+        *pSubscribePacket = pBuffer;\r
+        *pPacketSize = bufLen;\r
+        *pPacketIdentifier = usPacketIdentifier;\r
+    }\r
+    else\r
+    {\r
+        if( pBuffer != NULL )\r
+        {\r
+            IotMqtt_FreeMessage( pBuffer );\r
+        }\r
+\r
+        *pSubscribePacket = NULL;\r
+        *pPacketSize = 0;\r
+    }\r
+\r
+    return ret;\r
+}\r
+\r
+IotMqttError_t IotBleMqtt_DeserializeSuback( _mqttPacket_t * pSuback )\r
+{\r
+\r
+    IotSerializerDecoderObject_t decoderObj = { 0 }, decoderValue = { 0 };\r
+    IotSerializerError_t error;\r
+    int64_t subscriptionStatus;\r
+    IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
+\r
+    error = IOT_BLE_MESG_DECODER.init( &decoderObj, ( uint8_t * ) pSuback->pRemainingData, pSuback->remainingLength );\r
+\r
+    if ( ( error != IOT_SERIALIZER_SUCCESS )\r
+            || ( decoderObj.type != IOT_SERIALIZER_CONTAINER_MAP ) )\r
+    {\r
+        IotLogError( "Malformed SUBACK, decoding the packet failed, decoder error = %d, type: %d", error, decoderObj.type );\r
+        ret = IOT_MQTT_BAD_RESPONSE;\r
+    }\r
+\r
+    if( ret == IOT_MQTT_SUCCESS )\r
+    {\r
+\r
+        error = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_MESSAGE_ID, &decoderValue );\r
+        if ( ( error != IOT_SERIALIZER_SUCCESS ) ||\r
+                ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) )\r
+        {\r
+            IotLogError( "Message ID decode failed, error = %d, decoded value type = %d", error, decoderValue.type );\r
+            ret = IOT_MQTT_BAD_RESPONSE;\r
+        }\r
+        else\r
+        {\r
+               pSuback->packetIdentifier = ( uint16_t ) decoderValue.u.value.u.signedInt;\r
+        }\r
+    }\r
+\r
+    if( ret == IOT_MQTT_SUCCESS )\r
+    {\r
+        error = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_STATUS, &decoderValue );\r
+        if ( ( error != IOT_SERIALIZER_SUCCESS ) ||\r
+                ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) )\r
+        {\r
+            IotLogError( "Status code decode failed, error = %d, decoded value type = %d", error, decoderValue.type );\r
+            ret = IOT_MQTT_BAD_RESPONSE;\r
+        }\r
+        else\r
+        {\r
+            subscriptionStatus = ( uint16_t ) decoderValue.u.value.u.signedInt;\r
+            switch( subscriptionStatus )\r
+            {\r
+                case 0x00:\r
+                case 0x01:\r
+                case 0x02:\r
+                    IotLog( IOT_LOG_DEBUG,\r
+                               &_logHideAll,\r
+                               "Topic accepted, max QoS %hhu.", subscriptionStatus );\r
+                    ret = IOT_MQTT_SUCCESS;\r
+                    break;\r
+                case 0x80:\r
+                    IotLog( IOT_LOG_DEBUG,\r
+                               &_logHideAll,\r
+                               "Topic refused." );\r
+\r
+                    /* Remove a rejected subscription from the subscription manager. */\r
+                    _IotMqtt_RemoveSubscriptionByPacket(\r
+                               pSuback->u.pMqttConnection,\r
+                                                       pSuback->packetIdentifier,\r
+                            0 );\r
+                    ret = IOT_MQTT_SERVER_REFUSED;\r
+                    break;\r
+                default:\r
+                    IotLog( IOT_LOG_DEBUG,\r
+                               &_logHideAll,\r
+                               "Bad SUBSCRIBE status %hhu.", subscriptionStatus );\r
+\r
+                    ret = IOT_MQTT_BAD_RESPONSE;\r
+                    break;\r
+            }\r
+        }\r
+\r
+    }\r
+\r
+    IOT_BLE_MESG_DECODER.destroy( &decoderObj );\r
+\r
+       return ret;\r
+}\r
+\r
+IotMqttError_t IotBleMqtt_SerializeUnsubscribe( const IotMqttSubscription_t * const pSubscriptionList,\r
+               size_t subscriptionCount,\r
+               uint8_t ** const pUnsubscribePacket,\r
+               size_t * const pPacketSize,\r
+               uint16_t * const pPacketIdentifier )\r
+{\r
+\r
+       uint8_t * pBuffer = NULL;\r
+    size_t bufLen = 0;\r
+    uint16_t usPacketIdentifier = 0;\r
+    IotSerializerError_t error;\r
+    IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
+\r
+    usPacketIdentifier = _nextPacketIdentifier();\r
+\r
+    error = _serializeUnSubscribe( pSubscriptionList, subscriptionCount, NULL, &bufLen, usPacketIdentifier );\r
+    if( error != IOT_SERIALIZER_SUCCESS )\r
+    {\r
+        IotLogError( "Failed to find serialized length of UNSUBSCRIBE message, error = %d", error );\r
+        ret = IOT_MQTT_BAD_PARAMETER;\r
+    }\r
+\r
+    if( ret == IOT_MQTT_SUCCESS )\r
+    {\r
+        pBuffer = IotMqtt_MallocMessage( bufLen );\r
+\r
+        /* If Memory cannot be allocated log an error and return */\r
+        if( pBuffer == NULL )\r
+        {\r
+            IotLogError( "Failed to allocate memory for UNSUBSCRIBE message." );\r
+            ret = IOT_MQTT_NO_MEMORY;\r
+        }\r
+    }\r
+\r
+    if( ret == IOT_MQTT_SUCCESS )\r
+    {\r
+        error = _serializeUnSubscribe( pSubscriptionList, subscriptionCount, pBuffer, &bufLen, usPacketIdentifier );\r
+        if( error != IOT_SERIALIZER_SUCCESS )\r
+        {\r
+            IotLogError( "Failed to serialize UNSUBSCRIBE message, error = %d", error );\r
+            ret = IOT_MQTT_BAD_PARAMETER;\r
+        }\r
+    }\r
+\r
+    if( ret == IOT_MQTT_SUCCESS )\r
+    {\r
+        *pUnsubscribePacket = pBuffer;\r
+        *pPacketSize = bufLen;\r
+        *pPacketIdentifier = usPacketIdentifier;\r
+    }\r
+    else\r
+    {\r
+        if( pBuffer != NULL )\r
+        {\r
+            IotMqtt_FreeMessage( pBuffer );\r
+        }\r
+\r
+        *pUnsubscribePacket = NULL;\r
+        *pPacketSize = 0;\r
+    }\r
+\r
+    return ret;\r
+}\r
+\r
+IotMqttError_t IotBleMqtt_DeserializeUnsuback( _mqttPacket_t * pUnsuback )\r
+{\r
+    IotSerializerDecoderObject_t decoderObj = { 0 }, decoderValue = { 0 };\r
+    IotSerializerError_t error;\r
+    IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
+\r
+    error = IOT_BLE_MESG_DECODER.init( &decoderObj, ( uint8_t * ) pUnsuback->pRemainingData, pUnsuback->remainingLength );\r
+    if( ( error != IOT_SERIALIZER_SUCCESS )\r
+            || ( decoderObj.type != IOT_SERIALIZER_CONTAINER_MAP ) )\r
+    {\r
+        IotLogError( "Malformed UNSUBACK, decoding the packet failed, decoder error = %d, type:%d ", error, decoderObj.type );\r
+        ret = IOT_MQTT_BAD_RESPONSE;\r
+    }\r
+\r
+    if( ret == IOT_MQTT_SUCCESS )\r
+    {\r
+        error = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_MESSAGE_ID, &decoderValue );\r
+        if ( ( error != IOT_SERIALIZER_SUCCESS ) ||\r
+                ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) )\r
+        {\r
+            IotLogError( "UNSUBACK Message identifier decode failed, error = %d, decoded value type = %d", error, decoderValue.type );\r
+            ret = IOT_MQTT_BAD_RESPONSE;\r
+\r
+        }\r
+        else\r
+        {\r
+               pUnsuback->packetIdentifier = ( uint16_t ) decoderValue.u.value.u.signedInt;\r
+        }\r
+    }\r
+\r
+    IOT_BLE_MESG_DECODER.destroy( &decoderObj );\r
+\r
+       return IOT_MQTT_SUCCESS;\r
+}\r
+\r
+IotMqttError_t IotBleMqtt_SerializeDisconnect( uint8_t ** const pDisconnectPacket,\r
+                                                          size_t * const pPacketSize )\r
+{\r
+       uint8_t *pBuffer = NULL;\r
+       size_t bufLen = 0;\r
+       IotSerializerError_t error;\r
+       IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
+\r
+       error = _serializeDisconnect( NULL, &bufLen);\r
+       if( error != IOT_SERIALIZER_SUCCESS )\r
+       {\r
+           IotLogError( "Failed to find serialized length of DISCONNECT message, error = %d", error );\r
+           ret = IOT_MQTT_BAD_PARAMETER;\r
+       }\r
+\r
+       if( ret == IOT_MQTT_SUCCESS )\r
+       {\r
+           pBuffer = IotMqtt_MallocMessage( bufLen );\r
+\r
+           /* If Memory cannot be allocated log an error and return */\r
+           if( pBuffer == NULL )\r
+           {\r
+               IotLogError( "Failed to allocate memory for DISCONNECT message." );\r
+               ret = IOT_MQTT_NO_MEMORY;\r
+           }\r
+       }\r
+\r
+\r
+       if( ret == IOT_MQTT_SUCCESS )\r
+       {\r
+           error = _serializeDisconnect( pBuffer, &bufLen );\r
+           if( error != IOT_SERIALIZER_SUCCESS )\r
+           {\r
+               IotLogError( "Failed to serialize DISCONNECT message, error = %d", error );\r
+               ret = IOT_MQTT_BAD_PARAMETER;\r
+           }\r
+       }\r
+\r
+       if( ret == IOT_MQTT_SUCCESS )\r
+       {\r
+           *pDisconnectPacket = pBuffer;\r
+           *pPacketSize = bufLen;\r
+       }\r
+       else\r
+       {\r
+           if( pBuffer != NULL )\r
+           {\r
+               IotMqtt_FreeMessage( pBuffer );\r
+           }\r
+\r
+           *pDisconnectPacket = NULL;\r
+           *pPacketSize = 0;\r
+       }\r
+\r
+       return ret;\r
+}\r
+\r
+size_t IotBleMqtt_GetRemainingLength ( void * pNetworkConnection,\r
+                                       const IotNetworkInterface_t * pNetworkInterface )\r
+{\r
+    const uint8_t *pBuffer;\r
+    size_t length;\r
+\r
+    IotBleDataTransfer_PeekReceiveBuffer( *( IotBleDataTransferChannel_t ** ) ( pNetworkConnection ), &pBuffer, &length );\r
+\r
+    return length;\r
+}\r
+\r
+\r
+uint8_t IotBleMqtt_GetPacketType( void * pNetworkConnection, const IotNetworkInterface_t * pNetworkInterface )\r
+{\r
+\r
+    IotSerializerDecoderObject_t decoderObj = { 0 }, decoderValue = { 0 };\r
+    IotSerializerError_t error;\r
+    uint8_t value = 0xFF, packetType = _INVALID_MQTT_PACKET_TYPE;\r
+    const uint8_t *pBuffer;\r
+    size_t length;\r
+\r
+    IotBleDataTransfer_PeekReceiveBuffer( *( IotBleDataTransferChannel_t ** ) ( pNetworkConnection ), &pBuffer, &length );\r
+\r
+    error = IOT_BLE_MESG_DECODER.init( &decoderObj, pBuffer, length );\r
+\r
+    if( ( error == IOT_SERIALIZER_SUCCESS )\r
+            && ( decoderObj.type == IOT_SERIALIZER_CONTAINER_MAP ) )\r
+    {\r
+\r
+        error = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_MSG_TYPE, &decoderValue );\r
+\r
+        if ( ( error == IOT_SERIALIZER_SUCCESS ) &&\r
+                ( decoderValue.type == IOT_SERIALIZER_SCALAR_SIGNED_INT ) )\r
+        {\r
+            value = ( uint16_t ) decoderValue.u.value.u.signedInt;\r
+\r
+            /** Left shift by 4 bits as MQTT library expects packet type to be upper 4 bits **/\r
+            packetType = value << 4;\r
+        }\r
+        else\r
+        {\r
+            IotLogError( "Packet type decode failed, error = %d, decoded value type = %d", error, decoderValue.type );\r
+        }\r
+    }\r
+    else\r
+    {\r
+        IotLogError( "Decoding the packet failed, decoder error = %d, type = %d", error, decoderObj.type );\r
+    }\r
+\r
+    IOT_BLE_MESG_DECODER.destroy( &decoderObj );\r
+\r
+    return packetType;\r
+}\r
+\r
+IotMqttError_t IotBleMqtt_SerializePingreq( uint8_t ** const pPingreqPacket,\r
+                                            size_t * const pPacketSize )\r
+{\r
+    uint8_t *pBuffer = NULL;\r
+       size_t bufLen = 0;\r
+       IotSerializerError_t error;\r
+       IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
+\r
+       error = _serializePingRequest( NULL, &bufLen);\r
+       if( error != IOT_SERIALIZER_SUCCESS )\r
+       {\r
+           IotLogError( "Failed to find serialized length of DISCONNECT message, error = %d", error );\r
+           ret = IOT_MQTT_BAD_PARAMETER;\r
+       }\r
+\r
+       if( ret == IOT_MQTT_SUCCESS )\r
+       {\r
+           pBuffer = IotMqtt_MallocMessage( bufLen );\r
+\r
+           /* If Memory cannot be allocated log an error and return */\r
+           if( pBuffer == NULL )\r
+           {\r
+               IotLogError( "Failed to allocate memory for DISCONNECT message." );\r
+               ret = IOT_MQTT_NO_MEMORY;\r
+           }\r
+       }\r
+\r
+       if( ret == IOT_MQTT_SUCCESS )\r
+       {\r
+           error = _serializePingRequest( pBuffer, &bufLen );\r
+           if( error != IOT_SERIALIZER_SUCCESS )\r
+           {\r
+               IotLogError( "Failed to serialize DISCONNECT message, error = %d", error );\r
+               ret = IOT_MQTT_BAD_PARAMETER;\r
+           }\r
+       }\r
+\r
+       if( ret == IOT_MQTT_SUCCESS )\r
+       {\r
+           *pPingreqPacket = pBuffer;\r
+           *pPacketSize = bufLen;\r
+       }\r
+       else\r
+       {\r
+           if( pBuffer != NULL )\r
+           {\r
+               IotMqtt_FreeMessage( pBuffer );\r
+           }\r
+\r
+           *pPingreqPacket = NULL;\r
+           *pPacketSize = 0;\r
+       }\r
+\r
+    return ret;\r
+\r
+}\r
+\r
+IotMqttError_t IotBleMqtt_DeserializePingresp( _mqttPacket_t * pPingresp )\r
+{\r
+    /* Ping Response for BLE contains only packet type field in CBOR, which is already decoded\r
+       in IotBleMqtt_GetPacketType() function. Returning IOT_MQTT_SUCCESS. */\r
+    return IOT_MQTT_SUCCESS;\r
+}\r
+\r
+void IotBleMqtt_FreePacket( uint8_t * pPacket )\r
+{\r
+    IotMqtt_FreeMessage( pPacket );\r
+}\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_agent.c b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_agent.c
new file mode 100644 (file)
index 0000000..9a73b25
--- /dev/null
@@ -0,0 +1,794 @@
+/*\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_agent.c\r
+ * @brief MQTT Agent implementation. Provides backwards compatibility between\r
+ * MQTT v2 and MQTT v1.\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
+/* FreeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+#include "semphr.h"\r
+\r
+/* MQTT v1 includes. */\r
+#include "iot_mqtt_agent.h"\r
+#include "iot_mqtt_agent_config.h"\r
+#include "iot_mqtt_agent_config_defaults.h"\r
+\r
+/* MQTT v2 include. */\r
+#include "iot_mqtt.h"\r
+\r
+/* Platform network include. */\r
+#include "platform/iot_network_freertos.h"\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/**\r
+ * @brief Converts FreeRTOS ticks to milliseconds.\r
+ */\r
+#define mqttTICKS_TO_MS( xTicks )    ( xTicks * 1000 / configTICK_RATE_HZ )\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/**\r
+ * @brief Stores data to convert between the MQTT v1 subscription callback\r
+ * and the MQTT v2 subscription callback.\r
+ */\r
+#if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 )\r
+    typedef struct MQTTCallback\r
+    {\r
+        BaseType_t xInUse;                                                     /**< Whether this instance is in-use. */\r
+        MQTTPublishCallback_t xFunction;                                       /**< MQTT v1 callback function. */\r
+        void * pvParameter;                                                    /**< Parameter to xFunction. */\r
+\r
+        uint16_t usTopicFilterLength;                                          /**< Length of pcTopicFilter. */\r
+        char pcTopicFilter[ mqttconfigSUBSCRIPTION_MANAGER_MAX_TOPIC_LENGTH ]; /**< Topic filter. */\r
+    } MQTTCallback_t;\r
+#endif\r
+\r
+/**\r
+ * @brief Stores data on an active MQTT connection.\r
+ */\r
+typedef struct MQTTConnection\r
+{\r
+    IotMqttConnection_t xMQTTConnection; /**< MQTT v2 connection handle. */\r
+    MQTTAgentCallback_t pxCallback;      /**< MQTT v1 global callback. */\r
+    void * pvUserData;                   /**< Parameter to pxCallback. */\r
+    StaticSemaphore_t xConnectionMutex;  /**< Protects from concurrent accesses. */\r
+    #if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 )\r
+        MQTTCallback_t xCallbacks        /**< Conversion table of MQTT v1 to MQTT v2 subscription callbacks. */\r
+        [ mqttconfigSUBSCRIPTION_MANAGER_MAX_SUBSCRIPTIONS ];\r
+    #endif\r
+} MQTTConnection_t;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/**\r
+ * @brief Convert an MQTT v2 return code to an MQTT v1 return code.\r
+ *\r
+ * @param[in] xMqttStatus The MQTT v2 return code.\r
+ *\r
+ * @return An equivalent MQTT v1 return code.\r
+ */\r
+static inline MQTTAgentReturnCode_t prvConvertReturnCode( IotMqttError_t xMqttStatus );\r
+\r
+/**\r
+ * @brief Wraps an MQTT v1 publish callback.\r
+ *\r
+ * @param[in] pvParameter The MQTT connection.\r
+ * @param[in] pxPublish Information about the incoming publish.\r
+ */\r
+static void prvPublishCallbackWrapper( void * pvParameter,\r
+                                       IotMqttCallbackParam_t * const pxPublish );\r
+\r
+/**\r
+ * @brief Wraps an MQTT v1 disconnect callback.\r
+ *\r
+ * @param[in] pvCallbackContext The MQTT connection.\r
+ * @param[in] pxDisconnect Information about the disconnect.\r
+ */\r
+static void prvDisconnectCallbackWrapper( void * pvParameter,\r
+                                          IotMqttCallbackParam_t * pxDisconnect );\r
+\r
+#if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 )\r
+\r
+/**\r
+ * @brief Store an MQTT v1 callback in the conversion table.\r
+ *\r
+ * @param[in] pxConnection Where to store the callback.\r
+ * @param[in] pcTopicFilter Topic filter to store.\r
+ * @param[in] usTopicFilterLength Length of pcTopicFilter.\r
+ * @param[in] xCallback MQTT v1 callback to store.\r
+ * @param[in] pvParameter Parameter to xCallback.\r
+ *\r
+ * @return pdPASS if the callback was successfully stored; pdFAIL otherwise.\r
+ */\r
+    static BaseType_t prvStoreCallback( MQTTConnection_t * const pxConnection,\r
+                                        const char * const pcTopicFilter,\r
+                                        uint16_t usTopicFilterLength,\r
+                                        MQTTPublishCallback_t xCallback,\r
+                                        void * pvParameter );\r
+\r
+/**\r
+ * @brief Search the callback conversion table for the given topic filter.\r
+ *\r
+ * @param[in] pxConnection The connection containing the conversion table.\r
+ * @param[in] pcTopicFilter The topic filter to search for.\r
+ * @param[in] usTopicFilterLength The length of pcTopicFilter.\r
+ *\r
+ * @return A pointer to the callback entry if found; NULL otherwise.\r
+ * @note This function should be called with pxConnection->xConnectionMutex\r
+ * locked.\r
+ */\r
+    static MQTTCallback_t * prvFindCallback( MQTTConnection_t * const pxConnection,\r
+                                             const char * const pcTopicFilter,\r
+                                             uint16_t usTopicFilterLength );\r
+\r
+/**\r
+ * @brief Remove a topic filter from the callback conversion table.\r
+ *\r
+ * @param[in] pxConnection The connection containing the conversion table.\r
+ * @param[in] pcTopicFilter The topic filter to remove.\r
+ * @param[in] usTopicFilterLength The length of pcTopic.\r
+ */\r
+    static void prvRemoveCallback( MQTTConnection_t * const pxConnection,\r
+                                   const char * const pcTopicFilter,\r
+                                   uint16_t usTopicFilterLength );\r
+#endif /* if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) */\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/**\r
+ * @brief The number of available MQTT brokers, controlled by the constant\r
+ * mqttconfigMAX_BROKERS;\r
+ */\r
+static UBaseType_t uxAvailableBrokers = mqttconfigMAX_BROKERS;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static inline MQTTAgentReturnCode_t prvConvertReturnCode( IotMqttError_t xMqttStatus )\r
+{\r
+    MQTTAgentReturnCode_t xStatus = eMQTTAgentSuccess;\r
+\r
+    switch( xMqttStatus )\r
+    {\r
+        case IOT_MQTT_SUCCESS:\r
+        case IOT_MQTT_STATUS_PENDING:\r
+            xStatus = eMQTTAgentSuccess;\r
+            break;\r
+\r
+        case IOT_MQTT_TIMEOUT:\r
+            xStatus = eMQTTAgentTimeout;\r
+            break;\r
+\r
+        default:\r
+            xStatus = eMQTTAgentFailure;\r
+            break;\r
+    }\r
+\r
+    return xStatus;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvPublishCallbackWrapper( void * pvParameter,\r
+                                       IotMqttCallbackParam_t * const pxPublish )\r
+{\r
+    BaseType_t xStatus = pdPASS;\r
+    size_t xBufferSize = 0;\r
+    uint8_t * pucMqttBuffer = NULL;\r
+    MQTTBool_t xCallbackReturn = eMQTTFalse;\r
+    MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) pvParameter;\r
+    MQTTAgentCallbackParams_t xPublishData = { .xMQTTEvent = eMQTTAgentPublish };\r
+\r
+    /* Calculate the size of the MQTT buffer that must be allocated. */\r
+    if( xStatus == pdPASS )\r
+    {\r
+        xBufferSize = pxPublish->u.message.info.topicNameLength +\r
+                      pxPublish->u.message.info.payloadLength;\r
+\r
+        /* Check for overflow. */\r
+        if( ( xBufferSize < pxPublish->u.message.info.topicNameLength ) ||\r
+            ( xBufferSize < pxPublish->u.message.info.payloadLength ) )\r
+        {\r
+            mqttconfigDEBUG_LOG( ( "Incoming PUBLISH message and topic name length too large.\r\n" ) );\r
+            xStatus = pdFAIL;\r
+        }\r
+    }\r
+\r
+    /* Allocate an MQTT buffer for the callback. */\r
+    if( xStatus == pdPASS )\r
+    {\r
+        pucMqttBuffer = pvPortMalloc( xBufferSize );\r
+\r
+        if( pucMqttBuffer == NULL )\r
+        {\r
+            mqttconfigDEBUG_LOG( ( "Failed to allocate memory for MQTT buffer.\r\n" ) );\r
+            xStatus = pdFAIL;\r
+        }\r
+        else\r
+        {\r
+            /* Copy the topic name and payload. The topic name and payload must be\r
+             * copied in case the user decides to take ownership of the MQTT buffer.\r
+             * The original buffer containing the MQTT topic name and payload may\r
+             * contain further unprocessed packets and must remain property of the\r
+             * MQTT library. Therefore, the topic name and payload are copied into\r
+             * another buffer for the user. */\r
+            ( void ) memcpy( pucMqttBuffer,\r
+                             pxPublish->u.message.info.pTopicName,\r
+                             pxPublish->u.message.info.topicNameLength );\r
+            ( void ) memcpy( pucMqttBuffer + pxPublish->u.message.info.topicNameLength,\r
+                             pxPublish->u.message.info.pPayload,\r
+                             pxPublish->u.message.info.payloadLength );\r
+\r
+            /* Set the members of the callback parameter. */\r
+            xPublishData.xMQTTEvent = eMQTTAgentPublish;\r
+            xPublishData.u.xPublishData.pucTopic = pucMqttBuffer;\r
+            xPublishData.u.xPublishData.usTopicLength = pxPublish->u.message.info.topicNameLength;\r
+            xPublishData.u.xPublishData.pvData = pucMqttBuffer + pxPublish->u.message.info.topicNameLength;\r
+            xPublishData.u.xPublishData.ulDataLength = ( uint32_t ) pxPublish->u.message.info.payloadLength;\r
+            xPublishData.u.xPublishData.xQos = ( MQTTQoS_t ) pxPublish->u.message.info.qos;\r
+            xPublishData.u.xPublishData.xBuffer = pucMqttBuffer;\r
+        }\r
+    }\r
+\r
+    if( xStatus == pdPASS )\r
+    {\r
+        #if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 )\r
+            /* When subscription management is enabled, search for a matching subscription. */\r
+            MQTTCallback_t * pxCallbackEntry = prvFindCallback( pxConnection,\r
+                                                                pxPublish->u.message.pTopicFilter,\r
+                                                                pxPublish->u.message.topicFilterLength );\r
+\r
+            /* Check if a matching MQTT v1 subscription was found. */\r
+            if( pxCallbackEntry != NULL )\r
+            {\r
+                /* Invoke the topic-specific callback if it exists. */\r
+                if( pxCallbackEntry->xFunction != NULL )\r
+                {\r
+                    xCallbackReturn = pxCallbackEntry->xFunction( pxCallbackEntry->pvParameter,\r
+                                                                  &( xPublishData.u.xPublishData ) );\r
+                }\r
+                else\r
+                {\r
+                    /* Otherwise, invoke the global callback. */\r
+                    if( pxConnection->pxCallback != NULL )\r
+                    {\r
+                        xCallbackReturn = ( MQTTBool_t ) pxConnection->pxCallback( pxConnection->pvUserData,\r
+                                                                                   &xPublishData );\r
+                    }\r
+                }\r
+            }\r
+        #else /* if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) */\r
+\r
+            /* When subscription management is disabled, invoke the global callback\r
+             * if one exists. */\r
+\r
+            /* When subscription management is disabled, the topic filter must be "#". */\r
+            mqttconfigASSERT( *( xPublish.message.pTopicFilter ) == '#' );\r
+            mqttconfigASSERT( xPublish.message.topicFilterLength == 1 );\r
+\r
+            if( pxConnection->pxCallback != NULL )\r
+            {\r
+                xCallbackReturn = ( MQTTBool_t ) pxConnection->pxCallback( pxConnection->pvUserData,\r
+                                                                           &xPublishData );\r
+            }\r
+        #endif /* if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) */\r
+    }\r
+\r
+    /* Free the MQTT buffer if the user did not take ownership of it. */\r
+    if( ( xCallbackReturn == eMQTTFalse ) && ( pucMqttBuffer != NULL ) )\r
+    {\r
+        vPortFree( pucMqttBuffer );\r
+    }\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvDisconnectCallbackWrapper( void * pvParameter,\r
+                                          IotMqttCallbackParam_t * pxDisconnect )\r
+{\r
+    MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) pvParameter;\r
+    MQTTAgentCallbackParams_t xCallbackParams = { .xMQTTEvent = eMQTTAgentDisconnect };\r
+\r
+    ( void ) pxDisconnect;\r
+\r
+    /* This function should only be called if a callback was set. */\r
+    mqttconfigASSERT( pxConnection->pxCallback != NULL );\r
+\r
+    /* Invoke the MQTT v1 callback. Ignore the return value. */\r
+    pxConnection->pxCallback( pxConnection->pvUserData,\r
+                              &xCallbackParams );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 )\r
+    static BaseType_t prvStoreCallback( MQTTConnection_t * const pxConnection,\r
+                                        const char * const pcTopicFilter,\r
+                                        uint16_t usTopicFilterLength,\r
+                                        MQTTPublishCallback_t xCallback,\r
+                                        void * pvParameter )\r
+    {\r
+        MQTTCallback_t * pxCallback = NULL;\r
+        BaseType_t xStatus = pdFAIL, i = 0;\r
+\r
+        /* Prevent other tasks from modifying stored callbacks while this function\r
+         * runs. */\r
+        if( xSemaphoreTake( ( QueueHandle_t ) &( pxConnection->xConnectionMutex ),\r
+                            portMAX_DELAY ) == pdTRUE )\r
+        {\r
+            /* Check if the topic filter already has an entry. */\r
+            pxCallback = prvFindCallback( pxConnection, pcTopicFilter, usTopicFilterLength );\r
+\r
+            if( pxCallback == NULL )\r
+            {\r
+                /* If no entry was found, find a free entry. */\r
+                for( i = 0; i < mqttconfigSUBSCRIPTION_MANAGER_MAX_SUBSCRIPTIONS; i++ )\r
+                {\r
+                    if( pxConnection->xCallbacks[ i ].xInUse == pdFALSE )\r
+                    {\r
+                        pxConnection->xCallbacks[ i ].xInUse = pdTRUE;\r
+                        pxCallback = &( pxConnection->xCallbacks[ i ] );\r
+                        break;\r
+                    }\r
+                }\r
+            }\r
+\r
+            /* Set the members of the callback entry. */\r
+            if( i < mqttconfigSUBSCRIPTION_MANAGER_MAX_SUBSCRIPTIONS )\r
+            {\r
+                pxCallback->pvParameter = pvParameter;\r
+                pxCallback->usTopicFilterLength = usTopicFilterLength;\r
+                pxCallback->xFunction = xCallback;\r
+                ( void ) strncpy( pxCallback->pcTopicFilter, pcTopicFilter, usTopicFilterLength );\r
+                xStatus = pdPASS;\r
+            }\r
+\r
+            ( void ) xSemaphoreGive( ( QueueHandle_t ) &( pxConnection->xConnectionMutex ) );\r
+        }\r
+\r
+        return xStatus;\r
+    }\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+    static MQTTCallback_t * prvFindCallback( MQTTConnection_t * const pxConnection,\r
+                                             const char * const pcTopicFilter,\r
+                                             uint16_t usTopicFilterLength )\r
+    {\r
+        BaseType_t i = 0;\r
+        MQTTCallback_t * pxResult = NULL;\r
+\r
+        /* Search the callback conversion table for the topic filter. */\r
+        for( i = 0; i < mqttconfigSUBSCRIPTION_MANAGER_MAX_SUBSCRIPTIONS; i++ )\r
+        {\r
+            if( ( pxConnection->xCallbacks[ i ].usTopicFilterLength == usTopicFilterLength ) &&\r
+                ( strncmp( pxConnection->xCallbacks[ i ].pcTopicFilter,\r
+                           pcTopicFilter,\r
+                           usTopicFilterLength ) == 0 ) )\r
+            {\r
+                pxResult = &( pxConnection->xCallbacks[ i ] );\r
+                break;\r
+            }\r
+        }\r
+\r
+        return pxResult;\r
+    }\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+    static void prvRemoveCallback( MQTTConnection_t * const pxConnection,\r
+                                   const char * const pcTopicFilter,\r
+                                   uint16_t usTopicFilterLength )\r
+    {\r
+        MQTTCallback_t * pxCallback = NULL;\r
+\r
+        /* Prevent other tasks from modifying stored callbacks while this function\r
+         * runs. */\r
+        if( xSemaphoreTake( ( QueueHandle_t ) &( pxConnection->xConnectionMutex ),\r
+                            portMAX_DELAY ) == pdTRUE )\r
+        {\r
+            /* Find the given topic filter. */\r
+            pxCallback = prvFindCallback( pxConnection, pcTopicFilter, usTopicFilterLength );\r
+\r
+            if( pxCallback != NULL )\r
+            {\r
+                /* Clear the callback entry. */\r
+                mqttconfigASSERT( pxCallback->xInUse == pdTRUE );\r
+                ( void ) memset( pxCallback, 0x00, sizeof( MQTTCallback_t ) );\r
+            }\r
+\r
+            ( void ) xSemaphoreGive( ( QueueHandle_t ) &( pxConnection->xConnectionMutex ) );\r
+        }\r
+    }\r
+#endif /* if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) */\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttConnection_t MQTT_AGENT_Getv2Connection( MQTTAgentHandle_t xMQTTHandle )\r
+{\r
+    MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) xMQTTHandle;\r
+\r
+    return pxConnection->xMQTTConnection;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+BaseType_t MQTT_AGENT_Init( void )\r
+{\r
+    BaseType_t xStatus = pdFALSE;\r
+\r
+    /* Call the initialization function of MQTT v2. */\r
+    if( IotMqtt_Init() == IOT_MQTT_SUCCESS )\r
+    {\r
+        xStatus = pdTRUE;\r
+    }\r
+\r
+    return xStatus;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+MQTTAgentReturnCode_t MQTT_AGENT_Create( MQTTAgentHandle_t * const pxMQTTHandle )\r
+{\r
+    MQTTConnection_t * pxNewConnection = NULL;\r
+    MQTTAgentReturnCode_t xStatus = eMQTTAgentSuccess;\r
+\r
+    /* Check how many brokers are available; fail if all brokers are in use. */\r
+    taskENTER_CRITICAL();\r
+    {\r
+        if( uxAvailableBrokers == 0 )\r
+        {\r
+            xStatus = eMQTTAgentFailure;\r
+        }\r
+        else\r
+        {\r
+            uxAvailableBrokers--;\r
+            mqttconfigASSERT( uxAvailableBrokers <= mqttconfigMAX_BROKERS );\r
+        }\r
+    }\r
+    taskEXIT_CRITICAL();\r
+\r
+    /* Allocate memory for an MQTT connection. */\r
+    if( xStatus == eMQTTAgentSuccess )\r
+    {\r
+        pxNewConnection = pvPortMalloc( sizeof( MQTTConnection_t ) );\r
+\r
+        if( pxNewConnection == NULL )\r
+        {\r
+            xStatus = eMQTTAgentFailure;\r
+\r
+            taskENTER_CRITICAL();\r
+            {\r
+                uxAvailableBrokers++;\r
+                mqttconfigASSERT( uxAvailableBrokers <= mqttconfigMAX_BROKERS );\r
+            }\r
+            taskEXIT_CRITICAL();\r
+        }\r
+        else\r
+        {\r
+            ( void ) memset( pxNewConnection, 0x00, sizeof( MQTTConnection_t ) );\r
+            pxNewConnection->xMQTTConnection = IOT_MQTT_CONNECTION_INITIALIZER;\r
+        }\r
+    }\r
+\r
+    /* Create the connection mutex and set the output parameter. */\r
+    if( xStatus == eMQTTAgentSuccess )\r
+    {\r
+        ( void ) xSemaphoreCreateMutexStatic( &( pxNewConnection->xConnectionMutex ) );\r
+        *pxMQTTHandle = ( MQTTAgentHandle_t ) pxNewConnection;\r
+    }\r
+\r
+    return xStatus;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+MQTTAgentReturnCode_t MQTT_AGENT_Delete( MQTTAgentHandle_t xMQTTHandle )\r
+{\r
+    MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) xMQTTHandle;\r
+\r
+    /* Clean up any allocated MQTT or network resources. */\r
+    if( pxConnection->xMQTTConnection != IOT_MQTT_CONNECTION_INITIALIZER )\r
+    {\r
+        IotMqtt_Disconnect( pxConnection->xMQTTConnection, IOT_MQTT_FLAG_CLEANUP_ONLY );\r
+        pxConnection->xMQTTConnection = IOT_MQTT_CONNECTION_INITIALIZER;\r
+    }\r
+\r
+    /* Free memory used by the MQTT connection. */\r
+    vPortFree( pxConnection );\r
+\r
+    /* Increment the number of available brokers. */\r
+    taskENTER_CRITICAL();\r
+    {\r
+        uxAvailableBrokers++;\r
+        mqttconfigASSERT( uxAvailableBrokers <= mqttconfigMAX_BROKERS );\r
+    }\r
+    taskEXIT_CRITICAL();\r
+\r
+    return eMQTTAgentSuccess;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+MQTTAgentReturnCode_t MQTT_AGENT_Connect( MQTTAgentHandle_t xMQTTHandle,\r
+                                          const MQTTAgentConnectParams_t * const pxConnectParams,\r
+                                          TickType_t xTimeoutTicks )\r
+{\r
+    MQTTAgentReturnCode_t xStatus = eMQTTAgentSuccess;\r
+    IotMqttError_t xMqttStatus = IOT_MQTT_STATUS_PENDING;\r
+    MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) xMQTTHandle;\r
+    IotNetworkServerInfo_t xServerInfo = { 0 };\r
+    IotNetworkCredentials_t xCredentials = AWS_IOT_NETWORK_CREDENTIALS_AFR_INITIALIZER, * pxCredentials = NULL;\r
+    IotMqttNetworkInfo_t xNetworkInfo = IOT_MQTT_NETWORK_INFO_INITIALIZER;\r
+    IotMqttConnectInfo_t xMqttConnectInfo = IOT_MQTT_CONNECT_INFO_INITIALIZER;\r
+\r
+    /* Copy the global callback and parameter. */\r
+    pxConnection->pxCallback = pxConnectParams->pxCallback;\r
+    pxConnection->pvUserData = pxConnectParams->pvUserData;\r
+\r
+    /* Set the TLS info for a secured connection. */\r
+    if( ( pxConnectParams->xSecuredConnection == pdTRUE ) ||\r
+        ( ( pxConnectParams->xFlags & mqttagentREQUIRE_TLS ) == mqttagentREQUIRE_TLS ) )\r
+    {\r
+        pxCredentials = &xCredentials;\r
+\r
+        /* Set the server certificate. Other credentials are set by the initializer. */\r
+        xCredentials.pRootCa = pxConnectParams->pcCertificate;\r
+        xCredentials.rootCaSize = ( size_t ) pxConnectParams->ulCertificateSize;\r
+\r
+        /* Disable ALPN if requested. */\r
+        if( ( pxConnectParams->xFlags & mqttagentUSE_AWS_IOT_ALPN_443 ) == 0 )\r
+        {\r
+            xCredentials.pAlpnProtos = NULL;\r
+        }\r
+\r
+        /* Disable SNI if requested. */\r
+        if( ( pxConnectParams->xURLIsIPAddress == pdTRUE ) ||\r
+            ( ( pxConnectParams->xFlags & mqttagentURL_IS_IP_ADDRESS ) == mqttagentURL_IS_IP_ADDRESS ) )\r
+        {\r
+            xCredentials.disableSni = true;\r
+        }\r
+    }\r
+\r
+    /* Set the server info. */\r
+    xServerInfo.pHostName = pxConnectParams->pcURL;\r
+    xServerInfo.port = pxConnectParams->usPort;\r
+\r
+    /* Set the members of the network info. */\r
+    xNetworkInfo.createNetworkConnection = true;\r
+    xNetworkInfo.u.setup.pNetworkServerInfo = &xServerInfo;\r
+    xNetworkInfo.u.setup.pNetworkCredentialInfo = pxCredentials;\r
+    xNetworkInfo.pNetworkInterface = IOT_NETWORK_INTERFACE_AFR;\r
+\r
+    if( pxConnectParams->pxCallback != NULL )\r
+    {\r
+        xNetworkInfo.disconnectCallback.function = prvDisconnectCallbackWrapper;\r
+        xNetworkInfo.disconnectCallback.pCallbackContext = pxConnection;\r
+    }\r
+\r
+    /* Set the members of the MQTT connect info. */\r
+    xMqttConnectInfo.awsIotMqttMode = true;\r
+    xMqttConnectInfo.cleanSession = true;\r
+    xMqttConnectInfo.pClientIdentifier = ( const char * ) ( pxConnectParams->pucClientId );\r
+    xMqttConnectInfo.clientIdentifierLength = pxConnectParams->usClientIdLength;\r
+    xMqttConnectInfo.keepAliveSeconds = mqttconfigKEEP_ALIVE_INTERVAL_SECONDS;\r
+\r
+    /* Call MQTT v2's CONNECT function. */\r
+    xMqttStatus = IotMqtt_Connect( &xNetworkInfo,\r
+                                   &xMqttConnectInfo,\r
+                                   mqttTICKS_TO_MS( xTimeoutTicks ),\r
+                                   &( pxConnection->xMQTTConnection ) );\r
+    xStatus = prvConvertReturnCode( xMqttStatus );\r
+\r
+    /* Add a subscription to "#" to support the global callback when subscription\r
+     * manager is disabled. */\r
+    #if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 0 )\r
+        IotMqttSubscription_t xGlobalSubscription = IOT_MQTT_SUBSCRIPTION_INITIALIZER;\r
+        IotMqttReference_t xGlobalSubscriptionRef = IOT_MQTT_REFERENCE_INITIALIZER;\r
+\r
+        if( xStatus == eMQTTAgentSuccess )\r
+        {\r
+            xGlobalSubscription.pTopicFilter = "#";\r
+            xGlobalSubscription.topicFilterLength = 1;\r
+            xGlobalSubscription.qos = 0;\r
+            xGlobalSubscription.callback.param1 = pxConnection;\r
+            xGlobalSubscription.callback.function = prvPublishCallbackWrapper;\r
+\r
+            xMqttStatus = IotMqtt_Subscribe( pxConnection->xMQTTConnection,\r
+                                             &xGlobalSubscription,\r
+                                             1,\r
+                                             IOT_MQTT_FLAG_WAITABLE,\r
+                                             NULL,\r
+                                             &xGlobalSubscriptionRef );\r
+            xStatus = prvConvertReturnCode( xMqttStatus );\r
+        }\r
+\r
+        /* Wait for the subscription to "#" to complete. */\r
+        if( xStatus == eMQTTAgentSuccess )\r
+        {\r
+            xMqttStatus = IotMqtt_Wait( xGlobalSubscriptionRef,\r
+                                        mqttTICKS_TO_MS( xTimeoutTicks ) );\r
+            xStatus = prvConvertReturnCode( xMqttStatus );\r
+        }\r
+    #endif /* if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) */\r
+\r
+    return xStatus;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+MQTTAgentReturnCode_t MQTT_AGENT_Disconnect( MQTTAgentHandle_t xMQTTHandle,\r
+                                             TickType_t xTimeoutTicks )\r
+{\r
+    MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) xMQTTHandle;\r
+\r
+    /* MQTT v2's DISCONNECT function does not have a timeout argument. */\r
+    ( void ) xTimeoutTicks;\r
+\r
+    /* Check that the connection is established. */\r
+    if( pxConnection->xMQTTConnection != IOT_MQTT_CONNECTION_INITIALIZER )\r
+    {\r
+        /* Call MQTT v2's DISCONNECT function. */\r
+        IotMqtt_Disconnect( pxConnection->xMQTTConnection,\r
+                            0 );\r
+        pxConnection->xMQTTConnection = IOT_MQTT_CONNECTION_INITIALIZER;\r
+    }\r
+\r
+    return eMQTTAgentSuccess;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+MQTTAgentReturnCode_t MQTT_AGENT_Subscribe( MQTTAgentHandle_t xMQTTHandle,\r
+                                            const MQTTAgentSubscribeParams_t * const pxSubscribeParams,\r
+                                            TickType_t xTimeoutTicks )\r
+{\r
+    MQTTAgentReturnCode_t xStatus = eMQTTAgentSuccess;\r
+    IotMqttError_t xMqttStatus = IOT_MQTT_STATUS_PENDING;\r
+    MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) xMQTTHandle;\r
+    IotMqttSubscription_t xSubscription = IOT_MQTT_SUBSCRIPTION_INITIALIZER;\r
+\r
+    /* Store the topic filter if subscription management is enabled. */\r
+    #if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 )\r
+        /* Check topic filter length. */\r
+        if( pxSubscribeParams->usTopicLength > mqttconfigSUBSCRIPTION_MANAGER_MAX_TOPIC_LENGTH )\r
+        {\r
+            xStatus = eMQTTAgentFailure;\r
+        }\r
+\r
+        /* Store the subscription. */\r
+        if( prvStoreCallback( pxConnection,\r
+                              ( const char * ) pxSubscribeParams->pucTopic,\r
+                              pxSubscribeParams->usTopicLength,\r
+                              pxSubscribeParams->pxPublishCallback,\r
+                              pxSubscribeParams->pvPublishCallbackContext ) == pdFAIL )\r
+        {\r
+            xStatus = eMQTTAgentFailure;\r
+        }\r
+    #endif /* if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) */\r
+\r
+    /* Call MQTT v2 blocking SUBSCRIBE function. */\r
+    if( xStatus == eMQTTAgentSuccess )\r
+    {\r
+        /* Set the members of the MQTT subscription. */\r
+        xSubscription.pTopicFilter = ( const char * ) ( pxSubscribeParams->pucTopic );\r
+        xSubscription.topicFilterLength = pxSubscribeParams->usTopicLength;\r
+        xSubscription.qos = ( IotMqttQos_t ) pxSubscribeParams->xQoS;\r
+        xSubscription.callback.pCallbackContext = pxConnection;\r
+        xSubscription.callback.function = prvPublishCallbackWrapper;\r
+\r
+        xMqttStatus = IotMqtt_TimedSubscribe( pxConnection->xMQTTConnection,\r
+                                              &xSubscription,\r
+                                              1,\r
+                                              0,\r
+                                              mqttTICKS_TO_MS( xTimeoutTicks ) );\r
+        xStatus = prvConvertReturnCode( xMqttStatus );\r
+    }\r
+\r
+    return xStatus;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+MQTTAgentReturnCode_t MQTT_AGENT_Unsubscribe( MQTTAgentHandle_t xMQTTHandle,\r
+                                              const MQTTAgentUnsubscribeParams_t * const pxUnsubscribeParams,\r
+                                              TickType_t xTimeoutTicks )\r
+{\r
+    IotMqttError_t xMqttStatus = IOT_MQTT_STATUS_PENDING;\r
+    MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) xMQTTHandle;\r
+    IotMqttSubscription_t xSubscription = IOT_MQTT_SUBSCRIPTION_INITIALIZER;\r
+\r
+    /* Remove any subscription callback that may be registered. */\r
+    #if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 )\r
+        prvRemoveCallback( pxConnection,\r
+                           ( const char * ) ( pxUnsubscribeParams->pucTopic ),\r
+                           pxUnsubscribeParams->usTopicLength );\r
+    #endif\r
+\r
+    /* Set the members of the subscription to remove. */\r
+    xSubscription.pTopicFilter = ( const char * ) ( pxUnsubscribeParams->pucTopic );\r
+    xSubscription.topicFilterLength = pxUnsubscribeParams->usTopicLength;\r
+    xSubscription.callback.pCallbackContext = pxConnection;\r
+    xSubscription.callback.function = prvPublishCallbackWrapper;\r
+\r
+    /* Call MQTT v2 blocking UNSUBSCRIBE function. */\r
+    xMqttStatus = IotMqtt_TimedUnsubscribe( pxConnection->xMQTTConnection,\r
+                                            &xSubscription,\r
+                                            1,\r
+                                            0,\r
+                                            mqttTICKS_TO_MS( xTimeoutTicks ) );\r
+\r
+    return prvConvertReturnCode( xMqttStatus );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+MQTTAgentReturnCode_t MQTT_AGENT_Publish( MQTTAgentHandle_t xMQTTHandle,\r
+                                          const MQTTAgentPublishParams_t * const pxPublishParams,\r
+                                          TickType_t xTimeoutTicks )\r
+{\r
+    IotMqttError_t xMqttStatus = IOT_MQTT_STATUS_PENDING;\r
+    MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) xMQTTHandle;\r
+    IotMqttPublishInfo_t xPublishInfo = IOT_MQTT_PUBLISH_INFO_INITIALIZER;\r
+\r
+    /* Set the members of the publish info. */\r
+    xPublishInfo.pTopicName = ( const char * ) pxPublishParams->pucTopic;\r
+    xPublishInfo.topicNameLength = pxPublishParams->usTopicLength;\r
+    xPublishInfo.qos = ( IotMqttQos_t ) pxPublishParams->xQoS;\r
+    xPublishInfo.pPayload = ( const void * ) pxPublishParams->pvData;\r
+    xPublishInfo.payloadLength = pxPublishParams->ulDataLength;\r
+\r
+    /* Call the MQTT v2 blocking PUBLISH function. */\r
+    xMqttStatus = IotMqtt_TimedPublish( pxConnection->xMQTTConnection,\r
+                                        &xPublishInfo,\r
+                                        0,\r
+                                        mqttTICKS_TO_MS( xTimeoutTicks ) );\r
+\r
+    return prvConvertReturnCode( xMqttStatus );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+MQTTAgentReturnCode_t MQTT_AGENT_ReturnBuffer( MQTTAgentHandle_t xMQTTHandle,\r
+                                               MQTTBufferHandle_t xBufferHandle )\r
+{\r
+    ( void ) xMQTTHandle;\r
+\r
+    /* Free the MQTT buffer. */\r
+    vPortFree( xBufferHandle );\r
+\r
+    return eMQTTAgentSuccess;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_api.c b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_api.c
new file mode 100644 (file)
index 0000000..7df5326
--- /dev/null
@@ -0,0 +1,2018 @@
+/*\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_api.c\r
+ * @brief Implements most user-facing functions of the MQTT library.\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_clock.h"\r
+#include "platform/iot_threads.h"\r
+\r
+/* Validate MQTT configuration settings. */\r
+#if IOT_MQTT_ENABLE_ASSERTS != 0 && IOT_MQTT_ENABLE_ASSERTS != 1\r
+    #error "IOT_MQTT_ENABLE_ASSERTS must be 0 or 1."\r
+#endif\r
+#if IOT_MQTT_ENABLE_METRICS != 0 && IOT_MQTT_ENABLE_METRICS != 1\r
+    #error "IOT_MQTT_ENABLE_METRICS must be 0 or 1."\r
+#endif\r
+#if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES != 0 && IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES != 1\r
+    #error "IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES must be 0 or 1."\r
+#endif\r
+#if IOT_MQTT_RESPONSE_WAIT_MS <= 0\r
+    #error "IOT_MQTT_RESPONSE_WAIT_MS cannot be 0 or negative."\r
+#endif\r
+#if IOT_MQTT_RETRY_MS_CEILING <= 0\r
+    #error "IOT_MQTT_RETRY_MS_CEILING cannot be 0 or negative."\r
+#endif\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/**\r
+ * @brief Set the unsubscribed flag of an MQTT subscription.\r
+ *\r
+ * @param[in] pSubscriptionLink Pointer to the link member of an #_mqttSubscription_t.\r
+ * @param[in] pMatch Not used.\r
+ *\r
+ * @return Always returns `true`.\r
+ */\r
+static bool _mqttSubscription_setUnsubscribe( const IotLink_t * pSubscriptionLink,\r
+                                              void * pMatch );\r
+\r
+/**\r
+ * @brief Destroy an MQTT subscription if its reference count is 0.\r
+ *\r
+ * @param[in] pData The subscription to destroy. This parameter is of type\r
+ * `void*` for compatibility with [free]\r
+ * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
+ */\r
+static void _mqttSubscription_tryDestroy( void * pData );\r
+\r
+/**\r
+ * @brief Decrement the reference count of an MQTT operation and attempt to\r
+ * destroy it.\r
+ *\r
+ * @param[in] pData The operation data to destroy. This parameter is of type\r
+ * `void*` for compatibility with [free]\r
+ * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
+ */\r
+static void _mqttOperation_tryDestroy( void * pData );\r
+\r
+/**\r
+ * @brief Create a keep-alive job for an MQTT connection.\r
+ *\r
+ * @param[in] pNetworkInfo User-provided network information for the new\r
+ * connection.\r
+ * @param[in] keepAliveSeconds User-provided keep-alive interval.\r
+ * @param[out] pMqttConnection The MQTT connection associated with the keep-alive.\r
+ *\r
+ * @return `true` if the keep-alive job was successfully created; `false` otherwise.\r
+ */\r
+static bool _createKeepAliveJob( const IotMqttNetworkInfo_t * pNetworkInfo,\r
+                                 uint16_t keepAliveSeconds,\r
+                                 _mqttConnection_t * pMqttConnection );\r
+\r
+/**\r
+ * @brief Creates a new MQTT connection and initializes its members.\r
+ *\r
+ * @param[in] awsIotMqttMode Specifies if this connection is to an AWS IoT MQTT server.\r
+ * @param[in] pNetworkInfo User-provided network information for the new\r
+ * connection.\r
+ * @param[in] keepAliveSeconds User-provided keep-alive interval for the new connection.\r
+ *\r
+ * @return Pointer to a newly-created MQTT connection; `NULL` on failure.\r
+ */\r
+static _mqttConnection_t * _createMqttConnection( bool awsIotMqttMode,\r
+                                                  const IotMqttNetworkInfo_t * pNetworkInfo,\r
+                                                  uint16_t keepAliveSeconds );\r
+\r
+/**\r
+ * @brief Destroys the members of an MQTT connection.\r
+ *\r
+ * @param[in] pMqttConnection Which connection to destroy.\r
+ */\r
+static void _destroyMqttConnection( _mqttConnection_t * pMqttConnection );\r
+\r
+/**\r
+ * @brief The common component of both @ref mqtt_function_subscribe and @ref\r
+ * mqtt_function_unsubscribe.\r
+ *\r
+ * See @ref mqtt_function_subscribe or @ref mqtt_function_unsubscribe for a\r
+ * description of the parameters and return values.\r
+ */\r
+static IotMqttError_t _subscriptionCommon( IotMqttOperationType_t operation,\r
+                                           IotMqttConnection_t mqttConnection,\r
+                                           const IotMqttSubscription_t * pSubscriptionList,\r
+                                           size_t subscriptionCount,\r
+                                           uint32_t flags,\r
+                                           const IotMqttCallbackInfo_t * pCallbackInfo,\r
+                                           IotMqttOperation_t * pOperationReference );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static bool _mqttSubscription_setUnsubscribe( const IotLink_t * pSubscriptionLink,\r
+                                              void * pMatch )\r
+{\r
+    /* Because this function is called from a container function, the given link\r
+     * must never be NULL. */\r
+    IotMqtt_Assert( pSubscriptionLink != NULL );\r
+\r
+    _mqttSubscription_t * pSubscription = IotLink_Container( _mqttSubscription_t,\r
+                                                             pSubscriptionLink,\r
+                                                             link );\r
+\r
+    /* Silence warnings about unused parameters. */\r
+    ( void ) pMatch;\r
+\r
+    /* Set the unsubscribed flag. */\r
+    pSubscription->unsubscribed = true;\r
+\r
+    return true;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static void _mqttSubscription_tryDestroy( void * pData )\r
+{\r
+    _mqttSubscription_t * pSubscription = ( _mqttSubscription_t * ) pData;\r
+\r
+    /* Reference count must not be negative. */\r
+    IotMqtt_Assert( pSubscription->references >= 0 );\r
+\r
+    /* Unsubscribed flag should be set. */\r
+    IotMqtt_Assert( pSubscription->unsubscribed == true );\r
+\r
+    /* Free the subscription if it has no references. */\r
+    if( pSubscription->references == 0 )\r
+    {\r
+        IotMqtt_FreeSubscription( pSubscription );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static void _mqttOperation_tryDestroy( void * pData )\r
+{\r
+    _mqttOperation_t * pOperation = ( _mqttOperation_t * ) pData;\r
+    IotTaskPoolError_t taskPoolStatus = IOT_TASKPOOL_SUCCESS;\r
+\r
+    /* Incoming PUBLISH operations may always be freed. */\r
+    if( pOperation->incomingPublish == true )\r
+    {\r
+        /* Cancel the incoming PUBLISH operation's job. */\r
+        taskPoolStatus = IotTaskPool_TryCancel( IOT_SYSTEM_TASKPOOL,\r
+                                                pOperation->job,\r
+                                                NULL );\r
+\r
+        /* If the operation's 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
+        /* Check if the incoming PUBLISH job was canceled. */\r
+        if( taskPoolStatus == IOT_TASKPOOL_SUCCESS )\r
+        {\r
+            /* Job was canceled. Process incoming PUBLISH now to clean up. */\r
+            _IotMqtt_ProcessIncomingPublish( IOT_SYSTEM_TASKPOOL,\r
+                                             pOperation->job,\r
+                                             pOperation );\r
+        }\r
+        else\r
+        {\r
+            /* The executing job will process the PUBLISH, so nothing is done here. */\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        /* Decrement reference count and destroy operation if possible. */\r
+        if( _IotMqtt_DecrementOperationReferences( pOperation, true ) == true )\r
+        {\r
+            _IotMqtt_DestroyOperation( pOperation );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static bool _createKeepAliveJob( const IotMqttNetworkInfo_t * pNetworkInfo,\r
+                                 uint16_t keepAliveSeconds,\r
+                                 _mqttConnection_t * pMqttConnection )\r
+{\r
+    bool status = true;\r
+    IotMqttError_t serializeStatus = IOT_MQTT_SUCCESS;\r
+    IotTaskPoolError_t jobStatus = IOT_TASKPOOL_SUCCESS;\r
+\r
+    /* Network information is not used when MQTT packet serializers are disabled. */\r
+    ( void ) pNetworkInfo;\r
+\r
+    /* Default PINGREQ serializer function. */\r
+    IotMqttError_t ( * serializePingreq )( uint8_t **,\r
+                                           size_t * ) = _IotMqtt_SerializePingreq;\r
+\r
+    /* Convert the keep-alive interval to milliseconds. */\r
+    pMqttConnection->keepAliveMs = keepAliveSeconds * 1000;\r
+    pMqttConnection->nextKeepAliveMs = pMqttConnection->keepAliveMs;\r
+\r
+    /* Choose a PINGREQ serializer function. */\r
+    #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
+        if( pNetworkInfo->pMqttSerializer != NULL )\r
+        {\r
+            if( pNetworkInfo->pMqttSerializer->serialize.pingreq != NULL )\r
+            {\r
+                serializePingreq = pNetworkInfo->pMqttSerializer->serialize.pingreq;\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
+    /* Generate a PINGREQ packet. */\r
+    serializeStatus = serializePingreq( &( pMqttConnection->pPingreqPacket ),\r
+                                        &( pMqttConnection->pingreqPacketSize ) );\r
+\r
+    if( serializeStatus != IOT_MQTT_SUCCESS )\r
+    {\r
+        IotLogError( "Failed to allocate PINGREQ packet for new connection." );\r
+\r
+        status = false;\r
+    }\r
+    else\r
+    {\r
+        /* Create the task pool job that processes keep-alive. */\r
+        jobStatus = IotTaskPool_CreateJob( _IotMqtt_ProcessKeepAlive,\r
+                                           pMqttConnection,\r
+                                           &( pMqttConnection->keepAliveJobStorage ),\r
+                                           &( pMqttConnection->keepAliveJob ) );\r
+\r
+        /* Task pool job creation for a pre-allocated job should never fail.\r
+         * Abort the program if it does. */\r
+        if( jobStatus != IOT_TASKPOOL_SUCCESS )\r
+        {\r
+            IotLogError( "Failed to create keep-alive job for new connection." );\r
+\r
+            IotMqtt_Assert( false );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        /* Keep-alive references its MQTT connection, so increment reference. */\r
+        ( pMqttConnection->references )++;\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static _mqttConnection_t * _createMqttConnection( bool awsIotMqttMode,\r
+                                                  const IotMqttNetworkInfo_t * pNetworkInfo,\r
+                                                  uint16_t keepAliveSeconds )\r
+{\r
+    IOT_FUNCTION_ENTRY( bool, true );\r
+    _mqttConnection_t * pMqttConnection = NULL;\r
+    bool referencesMutexCreated = false, subscriptionMutexCreated = false;\r
+\r
+    /* Allocate memory for the new MQTT connection. */\r
+    pMqttConnection = IotMqtt_MallocConnection( sizeof( _mqttConnection_t ) );\r
+\r
+    if( pMqttConnection == NULL )\r
+    {\r
+        IotLogError( "Failed to allocate memory for new connection." );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( false );\r
+    }\r
+    else\r
+    {\r
+        /* Clear the MQTT connection, then copy the MQTT server mode, network\r
+         * interface, and disconnect callback. */\r
+        ( void ) memset( pMqttConnection, 0x00, sizeof( _mqttConnection_t ) );\r
+        pMqttConnection->awsIotMqttMode = awsIotMqttMode;\r
+        pMqttConnection->pNetworkInterface = pNetworkInfo->pNetworkInterface;\r
+        pMqttConnection->disconnectCallback = pNetworkInfo->disconnectCallback;\r
+\r
+        /* Start a new MQTT connection with a reference count of 1. */\r
+        pMqttConnection->references = 1;\r
+    }\r
+\r
+    /* Create the references mutex for a new connection. It is a recursive mutex. */\r
+    referencesMutexCreated = IotMutex_Create( &( pMqttConnection->referencesMutex ), true );\r
+\r
+    if( referencesMutexCreated == false )\r
+    {\r
+        IotLogError( "Failed to create references mutex for new connection." );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( false );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Create the subscription mutex for a new connection. */\r
+    subscriptionMutexCreated = IotMutex_Create( &( pMqttConnection->subscriptionMutex ), false );\r
+\r
+    if( subscriptionMutexCreated == false )\r
+    {\r
+        IotLogError( "Failed to create subscription mutex for new connection." );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( false );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Create the new connection's subscription and operation lists. */\r
+    IotListDouble_Create( &( pMqttConnection->subscriptionList ) );\r
+    IotListDouble_Create( &( pMqttConnection->pendingProcessing ) );\r
+    IotListDouble_Create( &( pMqttConnection->pendingResponse ) );\r
+\r
+    /* AWS IoT service limits set minimum and maximum values for keep-alive interval.\r
+     * Adjust the user-provided keep-alive interval based on these requirements. */\r
+    if( awsIotMqttMode == true )\r
+    {\r
+        if( keepAliveSeconds < AWS_IOT_MQTT_SERVER_MIN_KEEPALIVE )\r
+        {\r
+            keepAliveSeconds = AWS_IOT_MQTT_SERVER_MIN_KEEPALIVE;\r
+        }\r
+        else if( keepAliveSeconds > AWS_IOT_MQTT_SERVER_MAX_KEEPALIVE )\r
+        {\r
+            keepAliveSeconds = AWS_IOT_MQTT_SERVER_MAX_KEEPALIVE;\r
+        }\r
+        else if( keepAliveSeconds == 0 )\r
+        {\r
+            keepAliveSeconds = AWS_IOT_MQTT_SERVER_MAX_KEEPALIVE;\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Check if keep-alive is active for this connection. */\r
+    if( keepAliveSeconds != 0 )\r
+    {\r
+        if( _createKeepAliveJob( pNetworkInfo,\r
+                                 keepAliveSeconds,\r
+                                 pMqttConnection ) == false )\r
+        {\r
+            IOT_SET_AND_GOTO_CLEANUP( false );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Clean up mutexes and connection if this function failed. */\r
+    IOT_FUNCTION_CLEANUP_BEGIN();\r
+\r
+    if( status == false )\r
+    {\r
+        if( subscriptionMutexCreated == true )\r
+        {\r
+            IotMutex_Destroy( &( pMqttConnection->subscriptionMutex ) );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        if( referencesMutexCreated == true )\r
+        {\r
+            IotMutex_Destroy( &( pMqttConnection->referencesMutex ) );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        if( pMqttConnection != NULL )\r
+        {\r
+            IotMqtt_FreeConnection( pMqttConnection );\r
+            pMqttConnection = NULL;\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    return pMqttConnection;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static void _destroyMqttConnection( _mqttConnection_t * pMqttConnection )\r
+{\r
+    IotNetworkError_t networkStatus = IOT_NETWORK_SUCCESS;\r
+\r
+    /* Clean up keep-alive if still allocated. */\r
+    if( pMqttConnection->keepAliveMs != 0 )\r
+    {\r
+        IotLogDebug( "(MQTT connection %p) Cleaning up keep-alive.", pMqttConnection );\r
+\r
+        _IotMqtt_FreePacket( pMqttConnection->pPingreqPacket );\r
+\r
+        /* Clear data about the keep-alive. */\r
+        pMqttConnection->keepAliveMs = 0;\r
+        pMqttConnection->pPingreqPacket = NULL;\r
+        pMqttConnection->pingreqPacketSize = 0;\r
+\r
+        /* Decrement reference count. */\r
+        pMqttConnection->references--;\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* A connection to be destroyed should have no keep-alive and at most 1\r
+     * reference. */\r
+    IotMqtt_Assert( pMqttConnection->references <= 1 );\r
+    IotMqtt_Assert( pMqttConnection->keepAliveMs == 0 );\r
+    IotMqtt_Assert( pMqttConnection->pPingreqPacket == NULL );\r
+    IotMqtt_Assert( pMqttConnection->pingreqPacketSize == 0 );\r
+\r
+    /* Remove all subscriptions. */\r
+    IotMutex_Lock( &( pMqttConnection->subscriptionMutex ) );\r
+    IotListDouble_RemoveAllMatches( &( pMqttConnection->subscriptionList ),\r
+                                    _mqttSubscription_setUnsubscribe,\r
+                                    NULL,\r
+                                    _mqttSubscription_tryDestroy,\r
+                                    offsetof( _mqttSubscription_t, link ) );\r
+    IotMutex_Unlock( &( pMqttConnection->subscriptionMutex ) );\r
+\r
+    /* Destroy an owned network connection. */\r
+    if( pMqttConnection->ownNetworkConnection == true )\r
+    {\r
+        networkStatus = pMqttConnection->pNetworkInterface->destroy( pMqttConnection->pNetworkConnection );\r
+\r
+        if( networkStatus != IOT_NETWORK_SUCCESS )\r
+        {\r
+            IotLogWarn( "(MQTT connection %p) Failed to destroy network connection.",\r
+                        pMqttConnection );\r
+        }\r
+        else\r
+        {\r
+            IotLogInfo( "(MQTT connection %p) Network connection destroyed.",\r
+                        pMqttConnection );\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Destroy mutexes. */\r
+    IotMutex_Destroy( &( pMqttConnection->referencesMutex ) );\r
+    IotMutex_Destroy( &( pMqttConnection->subscriptionMutex ) );\r
+\r
+    IotLogDebug( "(MQTT connection %p) Connection destroyed.", pMqttConnection );\r
+\r
+    /* Free connection. */\r
+    IotMqtt_FreeConnection( pMqttConnection );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static IotMqttError_t _subscriptionCommon( IotMqttOperationType_t operation,\r
+                                           IotMqttConnection_t mqttConnection,\r
+                                           const IotMqttSubscription_t * pSubscriptionList,\r
+                                           size_t subscriptionCount,\r
+                                           uint32_t flags,\r
+                                           const IotMqttCallbackInfo_t * pCallbackInfo,\r
+                                           IotMqttOperation_t * pOperationReference )\r
+{\r
+    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
+    _mqttOperation_t * pSubscriptionOperation = NULL;\r
+\r
+    /* Subscription serializer function. */\r
+    IotMqttError_t ( * serializeSubscription )( const IotMqttSubscription_t *,\r
+                                                size_t,\r
+                                                uint8_t **,\r
+                                                size_t *,\r
+                                                uint16_t * ) = NULL;\r
+\r
+    /* This function should only be called for subscribe or unsubscribe. */\r
+    IotMqtt_Assert( ( operation == IOT_MQTT_SUBSCRIBE ) ||\r
+                    ( operation == IOT_MQTT_UNSUBSCRIBE ) );\r
+\r
+    /* Check that all elements in the subscription list are valid. */\r
+    if( _IotMqtt_ValidateSubscriptionList( operation,\r
+                                           mqttConnection->awsIotMqttMode,\r
+                                           pSubscriptionList,\r
+                                           subscriptionCount ) == false )\r
+    {\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Check that a reference pointer is provided for a waitable operation. */\r
+    if( ( flags & IOT_MQTT_FLAG_WAITABLE ) == IOT_MQTT_FLAG_WAITABLE )\r
+    {\r
+        if( pOperationReference == NULL )\r
+        {\r
+            IotLogError( "Reference must be provided for a waitable %s.",\r
+                         IotMqtt_OperationType( operation ) );\r
+\r
+            IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Choose a subscription serialize function. */\r
+    if( operation == IOT_MQTT_SUBSCRIBE )\r
+    {\r
+        serializeSubscription = _IotMqtt_SerializeSubscribe;\r
+\r
+        #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
+            if( mqttConnection->pSerializer != NULL )\r
+            {\r
+                if( mqttConnection->pSerializer->serialize.subscribe != NULL )\r
+                {\r
+                    serializeSubscription = mqttConnection->pSerializer->serialize.subscribe;\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
+    else\r
+    {\r
+        serializeSubscription = _IotMqtt_SerializeUnsubscribe;\r
+\r
+        #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
+            if( mqttConnection->pSerializer != NULL )\r
+            {\r
+                if( mqttConnection->pSerializer->serialize.unsubscribe != NULL )\r
+                {\r
+                    serializeSubscription = mqttConnection->pSerializer->serialize.unsubscribe;\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
+\r
+    /* Remove the MQTT subscription list for an UNSUBSCRIBE. */\r
+    if( operation == IOT_MQTT_UNSUBSCRIBE )\r
+    {\r
+        _IotMqtt_RemoveSubscriptionByTopicFilter( mqttConnection,\r
+                                                  pSubscriptionList,\r
+                                                  subscriptionCount );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Create a subscription operation. */\r
+    status = _IotMqtt_CreateOperation( mqttConnection,\r
+                                       flags,\r
+                                       pCallbackInfo,\r
+                                       &pSubscriptionOperation );\r
+\r
+    if( status != IOT_MQTT_SUCCESS )\r
+    {\r
+        IOT_GOTO_CLEANUP();\r
+    }\r
+\r
+    /* Check the subscription operation data and set the operation type. */\r
+    IotMqtt_Assert( pSubscriptionOperation->u.operation.status == IOT_MQTT_STATUS_PENDING );\r
+    IotMqtt_Assert( pSubscriptionOperation->u.operation.retry.limit == 0 );\r
+    pSubscriptionOperation->u.operation.type = operation;\r
+\r
+    /* Generate a subscription packet from the subscription list. */\r
+    status = serializeSubscription( pSubscriptionList,\r
+                                    subscriptionCount,\r
+                                    &( pSubscriptionOperation->u.operation.pMqttPacket ),\r
+                                    &( pSubscriptionOperation->u.operation.packetSize ),\r
+                                    &( pSubscriptionOperation->u.operation.packetIdentifier ) );\r
+\r
+    if( status != IOT_MQTT_SUCCESS )\r
+    {\r
+        IOT_GOTO_CLEANUP();\r
+    }\r
+\r
+    /* Check the serialized MQTT packet. */\r
+    IotMqtt_Assert( pSubscriptionOperation->u.operation.pMqttPacket != NULL );\r
+    IotMqtt_Assert( pSubscriptionOperation->u.operation.packetSize > 0 );\r
+\r
+    /* Add the subscription list for a SUBSCRIBE. */\r
+    if( operation == IOT_MQTT_SUBSCRIBE )\r
+    {\r
+        status = _IotMqtt_AddSubscriptions( mqttConnection,\r
+                                            pSubscriptionOperation->u.operation.packetIdentifier,\r
+                                            pSubscriptionList,\r
+                                            subscriptionCount );\r
+\r
+        if( status != IOT_MQTT_SUCCESS )\r
+        {\r
+            IOT_GOTO_CLEANUP();\r
+        }\r
+    }\r
+\r
+    /* Set the reference, if provided. */\r
+    if( pOperationReference != NULL )\r
+    {\r
+        *pOperationReference = pSubscriptionOperation;\r
+    }\r
+\r
+    /* Schedule the subscription operation for network transmission. */\r
+    status = _IotMqtt_ScheduleOperation( pSubscriptionOperation,\r
+                                         _IotMqtt_ProcessSend,\r
+                                         0 );\r
+\r
+    if( status != IOT_MQTT_SUCCESS )\r
+    {\r
+        IotLogError( "(MQTT connection %p) Failed to schedule %s for sending.",\r
+                     mqttConnection,\r
+                     IotMqtt_OperationType( operation ) );\r
+\r
+        if( operation == IOT_MQTT_SUBSCRIBE )\r
+        {\r
+            _IotMqtt_RemoveSubscriptionByPacket( mqttConnection,\r
+                                                 pSubscriptionOperation->u.operation.packetIdentifier,\r
+                                                 -1 );\r
+        }\r
+\r
+        /* Clear the previously set (and now invalid) reference. */\r
+        if( pOperationReference != NULL )\r
+        {\r
+            *pOperationReference = IOT_MQTT_OPERATION_INITIALIZER;\r
+        }\r
+\r
+        IOT_GOTO_CLEANUP();\r
+    }\r
+\r
+    /* Clean up if this function failed. */\r
+    IOT_FUNCTION_CLEANUP_BEGIN();\r
+\r
+    if( status != IOT_MQTT_SUCCESS )\r
+    {\r
+        if( pSubscriptionOperation != NULL )\r
+        {\r
+            _IotMqtt_DestroyOperation( pSubscriptionOperation );\r
+        }\r
+    }\r
+    else\r
+    {\r
+        status = IOT_MQTT_STATUS_PENDING;\r
+\r
+        IotLogInfo( "(MQTT connection %p) %s operation scheduled.",\r
+                    mqttConnection,\r
+                    IotMqtt_OperationType( operation ) );\r
+    }\r
+\r
+    IOT_FUNCTION_CLEANUP_END();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+bool _IotMqtt_IncrementConnectionReferences( _mqttConnection_t * pMqttConnection )\r
+{\r
+    bool disconnected = false;\r
+\r
+    /* Lock the mutex protecting the reference count. */\r
+    IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
+\r
+    /* Reference count must not be negative. */\r
+    IotMqtt_Assert( pMqttConnection->references >= 0 );\r
+\r
+    /* Read connection status. */\r
+    disconnected = pMqttConnection->disconnected;\r
+\r
+    /* Increment the connection's reference count if it is not disconnected. */\r
+    if( disconnected == false )\r
+    {\r
+        ( pMqttConnection->references )++;\r
+        IotLogDebug( "(MQTT connection %p) Reference count changed from %ld to %ld.",\r
+                     pMqttConnection,\r
+                     ( long int ) pMqttConnection->references - 1,\r
+                     ( long int ) pMqttConnection->references );\r
+    }\r
+    else\r
+    {\r
+        IotLogWarn( "(MQTT connection %p) Attempt to use closed connection.", pMqttConnection );\r
+    }\r
+\r
+    IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
+\r
+    return( disconnected == false );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void _IotMqtt_DecrementConnectionReferences( _mqttConnection_t * pMqttConnection )\r
+{\r
+    bool destroyConnection = false;\r
+\r
+    /* Lock the mutex protecting the reference count. */\r
+    IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
+\r
+    /* Decrement reference count. It must not be negative. */\r
+    ( pMqttConnection->references )--;\r
+    IotMqtt_Assert( pMqttConnection->references >= 0 );\r
+\r
+    IotLogDebug( "(MQTT connection %p) Reference count changed from %ld to %ld.",\r
+                 pMqttConnection,\r
+                 ( long int ) pMqttConnection->references + 1,\r
+                 ( long int ) pMqttConnection->references );\r
+\r
+    /* Check if this connection may be destroyed. */\r
+    if( pMqttConnection->references == 0 )\r
+    {\r
+        destroyConnection = true;\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
+\r
+    /* Destroy an unreferenced MQTT connection. */\r
+    if( destroyConnection == true )\r
+    {\r
+        IotLogDebug( "(MQTT connection %p) Connection will be destroyed now.",\r
+                     pMqttConnection );\r
+        _destroyMqttConnection( pMqttConnection );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t IotMqtt_Init( void )\r
+{\r
+    IotMqttError_t status = IOT_MQTT_SUCCESS;\r
+\r
+    /* Call any additional serializer initialization function if serializer\r
+     * overrides are enabled. */\r
+    #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
+        #ifdef _IotMqtt_InitSerializeAdditional\r
+            if( _IotMqtt_InitSerializeAdditional() == false )\r
+            {\r
+                status = IOT_MQTT_INIT_FAILED;\r
+            }\r
+            else\r
+            {\r
+                EMPTY_ELSE_MARKER;\r
+            }\r
+        #endif\r
+    #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */\r
+\r
+    /* Log initialization status. */\r
+    if( status != IOT_MQTT_SUCCESS )\r
+    {\r
+        IotLogError( "Failed to initialize MQTT library serializer. " );\r
+    }\r
+    else\r
+    {\r
+        IotLogInfo( "MQTT library successfully initialized." );\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void IotMqtt_Cleanup( void )\r
+{\r
+    /* Call any additional serializer cleanup initialization function if serializer\r
+     * overrides are enabled. */\r
+    #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
+        #ifdef _IotMqtt_CleanupSerializeAdditional\r
+            _IotMqtt_CleanupSerializeAdditional();\r
+        #endif\r
+    #endif\r
+\r
+    IotLogInfo( "MQTT library cleanup done." );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t IotMqtt_Connect( const IotMqttNetworkInfo_t * pNetworkInfo,\r
+                                const IotMqttConnectInfo_t * pConnectInfo,\r
+                                uint32_t timeoutMs,\r
+                                IotMqttConnection_t * const pMqttConnection )\r
+{\r
+    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
+    bool networkCreated = false, ownNetworkConnection = false;\r
+    IotNetworkError_t networkStatus = IOT_NETWORK_SUCCESS;\r
+    IotTaskPoolError_t taskPoolStatus = IOT_TASKPOOL_SUCCESS;\r
+    void * pNetworkConnection = NULL;\r
+    _mqttOperation_t * pOperation = NULL;\r
+    _mqttConnection_t * pNewMqttConnection = NULL;\r
+\r
+    /* Default CONNECT serializer function. */\r
+    IotMqttError_t ( * serializeConnect )( const IotMqttConnectInfo_t *,\r
+                                           uint8_t **,\r
+                                           size_t * ) = _IotMqtt_SerializeConnect;\r
+\r
+    /* Network info must not be NULL. */\r
+    if( pNetworkInfo == NULL )\r
+    {\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Validate network interface and connect info. */\r
+    if( _IotMqtt_ValidateConnect( pConnectInfo ) == false )\r
+    {\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* If will info is provided, check that it is valid. */\r
+    if( pConnectInfo->pWillInfo != NULL )\r
+    {\r
+        if( _IotMqtt_ValidatePublish( pConnectInfo->awsIotMqttMode,\r
+                                      pConnectInfo->pWillInfo ) == false )\r
+        {\r
+            IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
+        }\r
+        else if( pConnectInfo->pWillInfo->payloadLength > UINT16_MAX )\r
+        {\r
+            /* Will message payloads cannot be larger than 65535. This restriction\r
+             * applies only to will messages, and not normal PUBLISH messages. */\r
+            IotLogError( "Will payload cannot be larger than 65535." );\r
+\r
+            IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* If previous subscriptions are provided, check that they are valid. */\r
+    if( pConnectInfo->cleanSession == false )\r
+    {\r
+        if( pConnectInfo->pPreviousSubscriptions != NULL )\r
+        {\r
+            if( _IotMqtt_ValidateSubscriptionList( IOT_MQTT_SUBSCRIBE,\r
+                                                   pConnectInfo->awsIotMqttMode,\r
+                                                   pConnectInfo->pPreviousSubscriptions,\r
+                                                   pConnectInfo->previousSubscriptionCount ) == false )\r
+            {\r
+                IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
+            }\r
+            else\r
+            {\r
+                EMPTY_ELSE_MARKER;\r
+            }\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Create a new MQTT connection if requested. Otherwise, copy the existing\r
+     * network connection. */\r
+    if( pNetworkInfo->createNetworkConnection == true )\r
+    {\r
+        networkStatus = pNetworkInfo->pNetworkInterface->create( pNetworkInfo->u.setup.pNetworkServerInfo,\r
+                                                                 pNetworkInfo->u.setup.pNetworkCredentialInfo,\r
+                                                                 &pNetworkConnection );\r
+\r
+        if( networkStatus == IOT_NETWORK_SUCCESS )\r
+        {\r
+            networkCreated = true;\r
+\r
+            /* This MQTT connection owns the network connection it created and\r
+             * should destroy it on cleanup. */\r
+            ownNetworkConnection = true;\r
+        }\r
+        else\r
+        {\r
+            IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NETWORK_ERROR );\r
+        }\r
+    }\r
+    else\r
+    {\r
+        pNetworkConnection = pNetworkInfo->u.pNetworkConnection;\r
+        networkCreated = true;\r
+    }\r
+\r
+    IotLogInfo( "Establishing new MQTT connection." );\r
+\r
+    /* Initialize a new MQTT connection object. */\r
+    pNewMqttConnection = _createMqttConnection( pConnectInfo->awsIotMqttMode,\r
+                                                pNetworkInfo,\r
+                                                pConnectInfo->keepAliveSeconds );\r
+\r
+    if( pNewMqttConnection == NULL )\r
+    {\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NO_MEMORY );\r
+    }\r
+    else\r
+    {\r
+        /* Set the network connection associated with the MQTT connection. */\r
+        pNewMqttConnection->pNetworkConnection = pNetworkConnection;\r
+        pNewMqttConnection->ownNetworkConnection = ownNetworkConnection;\r
+\r
+        /* Set the MQTT packet serializer overrides. */\r
+        #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
+            pNewMqttConnection->pSerializer = pNetworkInfo->pMqttSerializer;\r
+        #endif\r
+    }\r
+\r
+    /* Set the MQTT receive callback. */\r
+    networkStatus = pNewMqttConnection->pNetworkInterface->setReceiveCallback( pNetworkConnection,\r
+                                                                               IotMqtt_ReceiveCallback,\r
+                                                                               pNewMqttConnection );\r
+\r
+    if( networkStatus != IOT_NETWORK_SUCCESS )\r
+    {\r
+        IotLogError( "Failed to set MQTT network receive callback." );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NETWORK_ERROR );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Create a CONNECT operation. */\r
+    status = _IotMqtt_CreateOperation( pNewMqttConnection,\r
+                                       IOT_MQTT_FLAG_WAITABLE,\r
+                                       NULL,\r
+                                       &pOperation );\r
+\r
+    if( status != IOT_MQTT_SUCCESS )\r
+    {\r
+        IOT_GOTO_CLEANUP();\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Ensure the members set by operation creation and serialization\r
+     * are appropriate for a blocking CONNECT. */\r
+    IotMqtt_Assert( pOperation->u.operation.status == IOT_MQTT_STATUS_PENDING );\r
+    IotMqtt_Assert( ( pOperation->u.operation.flags & IOT_MQTT_FLAG_WAITABLE )\r
+                    == IOT_MQTT_FLAG_WAITABLE );\r
+    IotMqtt_Assert( pOperation->u.operation.retry.limit == 0 );\r
+\r
+    /* Set the operation type. */\r
+    pOperation->u.operation.type = IOT_MQTT_CONNECT;\r
+\r
+    /* Add previous session subscriptions. */\r
+    if( pConnectInfo->pPreviousSubscriptions != NULL )\r
+    {\r
+        /* Previous subscription count should have been validated as nonzero. */\r
+        IotMqtt_Assert( pConnectInfo->previousSubscriptionCount > 0 );\r
+\r
+        status = _IotMqtt_AddSubscriptions( pNewMqttConnection,\r
+                                            2,\r
+                                            pConnectInfo->pPreviousSubscriptions,\r
+                                            pConnectInfo->previousSubscriptionCount );\r
+\r
+        if( status != IOT_MQTT_SUCCESS )\r
+        {\r
+            IOT_GOTO_CLEANUP();\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Choose a CONNECT serializer function. */\r
+    #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
+        if( pNewMqttConnection->pSerializer != NULL )\r
+        {\r
+            if( pNewMqttConnection->pSerializer->serialize.connect != NULL )\r
+            {\r
+                serializeConnect = pNewMqttConnection->pSerializer->serialize.connect;\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
+    /* Convert the connect info and will info objects to an MQTT CONNECT packet. */\r
+    status = serializeConnect( pConnectInfo,\r
+                               &( pOperation->u.operation.pMqttPacket ),\r
+                               &( pOperation->u.operation.packetSize ) );\r
+\r
+    if( status != IOT_MQTT_SUCCESS )\r
+    {\r
+        IOT_GOTO_CLEANUP();\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Check the serialized MQTT packet. */\r
+    IotMqtt_Assert( pOperation->u.operation.pMqttPacket != NULL );\r
+    IotMqtt_Assert( pOperation->u.operation.packetSize > 0 );\r
+\r
+    /* Add the CONNECT operation to the send queue for network transmission. */\r
+    status = _IotMqtt_ScheduleOperation( pOperation,\r
+                                         _IotMqtt_ProcessSend,\r
+                                         0 );\r
+\r
+    if( status != IOT_MQTT_SUCCESS )\r
+    {\r
+        IotLogError( "Failed to enqueue CONNECT for sending." );\r
+    }\r
+    else\r
+    {\r
+        /* Wait for the CONNECT operation to complete, i.e. wait for CONNACK. */\r
+        status = IotMqtt_Wait( pOperation,\r
+                               timeoutMs );\r
+\r
+        /* The call to wait cleans up the CONNECT operation, so set the pointer\r
+         * to NULL. */\r
+        pOperation = NULL;\r
+    }\r
+\r
+    /* When a connection is successfully established, schedule keep-alive job. */\r
+    if( status == IOT_MQTT_SUCCESS )\r
+    {\r
+        /* Check if a keep-alive job should be scheduled. */\r
+        if( pNewMqttConnection->keepAliveMs != 0 )\r
+        {\r
+            IotLogDebug( "Scheduling first MQTT keep-alive job." );\r
+\r
+            taskPoolStatus = IotTaskPool_ScheduleDeferred( IOT_SYSTEM_TASKPOOL,\r
+                                                           pNewMqttConnection->keepAliveJob,\r
+                                                           pNewMqttConnection->nextKeepAliveMs );\r
+\r
+            if( taskPoolStatus != IOT_TASKPOOL_SUCCESS )\r
+            {\r
+                IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_SCHEDULING_ERROR );\r
+            }\r
+            else\r
+            {\r
+                EMPTY_ELSE_MARKER;\r
+            }\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    IOT_FUNCTION_CLEANUP_BEGIN();\r
+\r
+    if( status != IOT_MQTT_SUCCESS )\r
+    {\r
+        IotLogError( "Failed to establish new MQTT connection, error %s.",\r
+                     IotMqtt_strerror( status ) );\r
+\r
+        /* The network connection must be closed if it was created. */\r
+        if( networkCreated == true )\r
+        {\r
+            networkStatus = pNetworkInfo->pNetworkInterface->close( pNetworkConnection );\r
+\r
+            if( networkStatus != IOT_NETWORK_SUCCESS )\r
+            {\r
+                IotLogWarn( "Failed to close network connection." );\r
+            }\r
+            else\r
+            {\r
+                IotLogInfo( "Network connection closed on error." );\r
+            }\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        if( pOperation != NULL )\r
+        {\r
+            _IotMqtt_DestroyOperation( pOperation );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        if( pNewMqttConnection != NULL )\r
+        {\r
+            _destroyMqttConnection( pNewMqttConnection );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        IotLogInfo( "New MQTT connection %p established.", pMqttConnection );\r
+\r
+        /* Set the output parameter. */\r
+        *pMqttConnection = pNewMqttConnection;\r
+    }\r
+\r
+    IOT_FUNCTION_CLEANUP_END();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void IotMqtt_Disconnect( IotMqttConnection_t mqttConnection,\r
+                         uint32_t flags )\r
+{\r
+    bool disconnected = false;\r
+    IotMqttError_t status = IOT_MQTT_STATUS_PENDING;\r
+    _mqttOperation_t * pOperation = NULL;\r
+\r
+    IotLogInfo( "(MQTT connection %p) Disconnecting connection.", mqttConnection );\r
+\r
+    /* Read the connection status. */\r
+    IotMutex_Lock( &( mqttConnection->referencesMutex ) );\r
+    disconnected = mqttConnection->disconnected;\r
+    IotMutex_Unlock( &( mqttConnection->referencesMutex ) );\r
+\r
+    /* Only send a DISCONNECT packet if the connection is active and the "cleanup only"\r
+     * flag is not set. */\r
+    if( disconnected == false )\r
+    {\r
+        if( ( flags & IOT_MQTT_FLAG_CLEANUP_ONLY ) == 0 )\r
+        {\r
+            /* Create a DISCONNECT operation. This function blocks until the DISCONNECT\r
+             * packet is sent, so it sets IOT_MQTT_FLAG_WAITABLE. */\r
+            status = _IotMqtt_CreateOperation( mqttConnection,\r
+                                               IOT_MQTT_FLAG_WAITABLE,\r
+                                               NULL,\r
+                                               &pOperation );\r
+\r
+            if( status == IOT_MQTT_SUCCESS )\r
+            {\r
+                /* Ensure that the members set by operation creation and serialization\r
+                 * are appropriate for a blocking DISCONNECT. */\r
+                IotMqtt_Assert( pOperation->u.operation.status == IOT_MQTT_STATUS_PENDING );\r
+                IotMqtt_Assert( ( pOperation->u.operation.flags & IOT_MQTT_FLAG_WAITABLE )\r
+                                == IOT_MQTT_FLAG_WAITABLE );\r
+                IotMqtt_Assert( pOperation->u.operation.retry.limit == 0 );\r
+\r
+                /* Set the operation type. */\r
+                pOperation->u.operation.type = IOT_MQTT_DISCONNECT;\r
+\r
+                /* Choose a disconnect serializer. */\r
+                IotMqttError_t ( * serializeDisconnect )( uint8_t **,\r
+                                                          size_t * ) = _IotMqtt_SerializeDisconnect;\r
+\r
+                #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
+                    if( mqttConnection->pSerializer != NULL )\r
+                    {\r
+                        if( mqttConnection->pSerializer->serialize.disconnect != NULL )\r
+                        {\r
+                            serializeDisconnect = mqttConnection->pSerializer->serialize.disconnect;\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
+                /* Generate a DISCONNECT packet. */\r
+                status = serializeDisconnect( &( pOperation->u.operation.pMqttPacket ),\r
+                                              &( pOperation->u.operation.packetSize ) );\r
+            }\r
+            else\r
+            {\r
+                EMPTY_ELSE_MARKER;\r
+            }\r
+\r
+            if( status == IOT_MQTT_SUCCESS )\r
+            {\r
+                /* Check the serialized MQTT packet. */\r
+                IotMqtt_Assert( pOperation->u.operation.pMqttPacket != NULL );\r
+                IotMqtt_Assert( pOperation->u.operation.packetSize > 0 );\r
+\r
+                /* Schedule the DISCONNECT operation for network transmission. */\r
+                if( _IotMqtt_ScheduleOperation( pOperation,\r
+                                                _IotMqtt_ProcessSend,\r
+                                                0 ) != IOT_MQTT_SUCCESS )\r
+                {\r
+                    IotLogWarn( "(MQTT connection %p) Failed to schedule DISCONNECT for sending.",\r
+                                mqttConnection );\r
+                    _IotMqtt_DestroyOperation( pOperation );\r
+                }\r
+                else\r
+                {\r
+                    /* Wait a short time for the DISCONNECT packet to be transmitted. */\r
+                    status = IotMqtt_Wait( pOperation,\r
+                                           IOT_MQTT_RESPONSE_WAIT_MS );\r
+\r
+                    /* A wait on DISCONNECT should only ever return SUCCESS, TIMEOUT,\r
+                     * or NETWORK ERROR. */\r
+                    if( status == IOT_MQTT_SUCCESS )\r
+                    {\r
+                        IotLogInfo( "(MQTT connection %p) Connection disconnected.", mqttConnection );\r
+                    }\r
+                    else\r
+                    {\r
+                        IotMqtt_Assert( ( status == IOT_MQTT_TIMEOUT ) ||\r
+                                        ( status == IOT_MQTT_NETWORK_ERROR ) );\r
+\r
+                        IotLogWarn( "(MQTT connection %p) DISCONNECT not sent, error %s.",\r
+                                    mqttConnection,\r
+                                    IotMqtt_strerror( status ) );\r
+                    }\r
+                }\r
+            }\r
+            else\r
+            {\r
+                EMPTY_ELSE_MARKER;\r
+            }\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Close the underlying network connection. This also cleans up keep-alive. */\r
+    _IotMqtt_CloseNetworkConnection( IOT_MQTT_DISCONNECT_CALLED,\r
+                                     mqttConnection );\r
+\r
+    /* Check if the connection may be destroyed. */\r
+    IotMutex_Lock( &( mqttConnection->referencesMutex ) );\r
+\r
+    /* At this point, the connection should be marked disconnected. */\r
+    IotMqtt_Assert( mqttConnection->disconnected == true );\r
+\r
+    /* Attempt cancel and destroy each operation in the connection's lists. */\r
+    IotListDouble_RemoveAll( &( mqttConnection->pendingProcessing ),\r
+                             _mqttOperation_tryDestroy,\r
+                             offsetof( _mqttOperation_t, link ) );\r
+\r
+    IotListDouble_RemoveAll( &( mqttConnection->pendingResponse ),\r
+                             _mqttOperation_tryDestroy,\r
+                             offsetof( _mqttOperation_t, link ) );\r
+\r
+    IotMutex_Unlock( &( mqttConnection->referencesMutex ) );\r
+\r
+    /* Decrement the connection reference count and destroy it if possible. */\r
+    _IotMqtt_DecrementConnectionReferences( mqttConnection );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t IotMqtt_Subscribe( IotMqttConnection_t mqttConnection,\r
+                                  const IotMqttSubscription_t * pSubscriptionList,\r
+                                  size_t subscriptionCount,\r
+                                  uint32_t flags,\r
+                                  const IotMqttCallbackInfo_t * pCallbackInfo,\r
+                                  IotMqttOperation_t * pSubscribeOperation )\r
+{\r
+    return _subscriptionCommon( IOT_MQTT_SUBSCRIBE,\r
+                                mqttConnection,\r
+                                pSubscriptionList,\r
+                                subscriptionCount,\r
+                                flags,\r
+                                pCallbackInfo,\r
+                                pSubscribeOperation );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t IotMqtt_TimedSubscribe( IotMqttConnection_t mqttConnection,\r
+                                       const IotMqttSubscription_t * pSubscriptionList,\r
+                                       size_t subscriptionCount,\r
+                                       uint32_t flags,\r
+                                       uint32_t timeoutMs )\r
+{\r
+    IotMqttError_t status = IOT_MQTT_STATUS_PENDING;\r
+    IotMqttOperation_t subscribeOperation = IOT_MQTT_OPERATION_INITIALIZER;\r
+\r
+    /* Flags are not used, but the parameter is present for future compatibility. */\r
+    ( void ) flags;\r
+\r
+    /* Call the asynchronous SUBSCRIBE function. */\r
+    status = IotMqtt_Subscribe( mqttConnection,\r
+                                pSubscriptionList,\r
+                                subscriptionCount,\r
+                                IOT_MQTT_FLAG_WAITABLE,\r
+                                NULL,\r
+                                &subscribeOperation );\r
+\r
+    /* Wait for the SUBSCRIBE operation to complete. */\r
+    if( status == IOT_MQTT_STATUS_PENDING )\r
+    {\r
+        status = IotMqtt_Wait( subscribeOperation, timeoutMs );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Ensure that a status was set. */\r
+    IotMqtt_Assert( status != IOT_MQTT_STATUS_PENDING );\r
+\r
+    return status;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t IotMqtt_Unsubscribe( IotMqttConnection_t mqttConnection,\r
+                                    const IotMqttSubscription_t * pSubscriptionList,\r
+                                    size_t subscriptionCount,\r
+                                    uint32_t flags,\r
+                                    const IotMqttCallbackInfo_t * pCallbackInfo,\r
+                                    IotMqttOperation_t * pUnsubscribeOperation )\r
+{\r
+    return _subscriptionCommon( IOT_MQTT_UNSUBSCRIBE,\r
+                                mqttConnection,\r
+                                pSubscriptionList,\r
+                                subscriptionCount,\r
+                                flags,\r
+                                pCallbackInfo,\r
+                                pUnsubscribeOperation );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t IotMqtt_TimedUnsubscribe( IotMqttConnection_t mqttConnection,\r
+                                         const IotMqttSubscription_t * pSubscriptionList,\r
+                                         size_t subscriptionCount,\r
+                                         uint32_t flags,\r
+                                         uint32_t timeoutMs )\r
+{\r
+    IotMqttError_t status = IOT_MQTT_STATUS_PENDING;\r
+    IotMqttOperation_t unsubscribeOperation = IOT_MQTT_OPERATION_INITIALIZER;\r
+\r
+    /* Flags are not used, but the parameter is present for future compatibility. */\r
+    ( void ) flags;\r
+\r
+    /* Call the asynchronous UNSUBSCRIBE function. */\r
+    status = IotMqtt_Unsubscribe( mqttConnection,\r
+                                  pSubscriptionList,\r
+                                  subscriptionCount,\r
+                                  IOT_MQTT_FLAG_WAITABLE,\r
+                                  NULL,\r
+                                  &unsubscribeOperation );\r
+\r
+    /* Wait for the UNSUBSCRIBE operation to complete. */\r
+    if( status == IOT_MQTT_STATUS_PENDING )\r
+    {\r
+        status = IotMqtt_Wait( unsubscribeOperation, timeoutMs );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Ensure that a status was set. */\r
+    IotMqtt_Assert( status != IOT_MQTT_STATUS_PENDING );\r
+\r
+    return status;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t IotMqtt_Publish( IotMqttConnection_t mqttConnection,\r
+                                const IotMqttPublishInfo_t * pPublishInfo,\r
+                                uint32_t flags,\r
+                                const IotMqttCallbackInfo_t * pCallbackInfo,\r
+                                IotMqttOperation_t * pPublishOperation )\r
+{\r
+    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
+    _mqttOperation_t * pOperation = NULL;\r
+    uint8_t ** pPacketIdentifierHigh = NULL;\r
+\r
+    /* Default PUBLISH serializer function. */\r
+    IotMqttError_t ( * serializePublish )( const IotMqttPublishInfo_t *,\r
+                                           uint8_t **,\r
+                                           size_t *,\r
+                                           uint16_t *,\r
+                                           uint8_t ** ) = _IotMqtt_SerializePublish;\r
+\r
+    /* Check that the PUBLISH information is valid. */\r
+    if( _IotMqtt_ValidatePublish( mqttConnection->awsIotMqttMode,\r
+                                  pPublishInfo ) == false )\r
+    {\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Check that no notification is requested for a QoS 0 publish. */\r
+    if( pPublishInfo->qos == IOT_MQTT_QOS_0 )\r
+    {\r
+        if( pCallbackInfo != NULL )\r
+        {\r
+            IotLogError( "QoS 0 PUBLISH should not have notification parameters set." );\r
+\r
+            IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
+        }\r
+        else if( ( flags & IOT_MQTT_FLAG_WAITABLE ) != 0 )\r
+        {\r
+            IotLogError( "QoS 0 PUBLISH should not have notification parameters set." );\r
+\r
+            IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        if( pPublishOperation != NULL )\r
+        {\r
+            IotLogWarn( "Ignoring reference parameter for QoS 0 publish." );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Check that a reference pointer is provided for a waitable operation. */\r
+    if( ( flags & IOT_MQTT_FLAG_WAITABLE ) == IOT_MQTT_FLAG_WAITABLE )\r
+    {\r
+        if( pPublishOperation == NULL )\r
+        {\r
+            IotLogError( "Reference must be provided for a waitable PUBLISH." );\r
+\r
+            IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Create a PUBLISH operation. */\r
+    status = _IotMqtt_CreateOperation( mqttConnection,\r
+                                       flags,\r
+                                       pCallbackInfo,\r
+                                       &pOperation );\r
+\r
+    if( status != IOT_MQTT_SUCCESS )\r
+    {\r
+        IOT_GOTO_CLEANUP();\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Check the PUBLISH operation data and set the operation type. */\r
+    IotMqtt_Assert( pOperation->u.operation.status == IOT_MQTT_STATUS_PENDING );\r
+    pOperation->u.operation.type = IOT_MQTT_PUBLISH_TO_SERVER;\r
+\r
+    /* Choose a PUBLISH serializer function. */\r
+    #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
+        if( mqttConnection->pSerializer != NULL )\r
+        {\r
+            if( mqttConnection->pSerializer->serialize.publish != NULL )\r
+            {\r
+                serializePublish = mqttConnection->pSerializer->serialize.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
+    /* In AWS IoT MQTT mode, a pointer to the packet identifier must be saved. */\r
+    if( mqttConnection->awsIotMqttMode == true )\r
+    {\r
+        pPacketIdentifierHigh = &( pOperation->u.operation.pPacketIdentifierHigh );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Generate a PUBLISH packet from pPublishInfo. */\r
+    status = serializePublish( pPublishInfo,\r
+                               &( pOperation->u.operation.pMqttPacket ),\r
+                               &( pOperation->u.operation.packetSize ),\r
+                               &( pOperation->u.operation.packetIdentifier ),\r
+                               pPacketIdentifierHigh );\r
+\r
+    if( status != IOT_MQTT_SUCCESS )\r
+    {\r
+        IOT_GOTO_CLEANUP();\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Check the serialized MQTT packet. */\r
+    IotMqtt_Assert( pOperation->u.operation.pMqttPacket != NULL );\r
+    IotMqtt_Assert( pOperation->u.operation.packetSize > 0 );\r
+\r
+    /* Initialize PUBLISH retry if retryLimit is set. */\r
+    if( pPublishInfo->retryLimit > 0 )\r
+    {\r
+        /* A QoS 0 PUBLISH may not be retried. */\r
+        if( pPublishInfo->qos != IOT_MQTT_QOS_0 )\r
+        {\r
+            pOperation->u.operation.retry.limit = pPublishInfo->retryLimit;\r
+            pOperation->u.operation.retry.nextPeriod = pPublishInfo->retryMs;\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Set the reference, if provided. */\r
+    if( pPublishInfo->qos != IOT_MQTT_QOS_0 )\r
+    {\r
+        if( pPublishOperation != NULL )\r
+        {\r
+            *pPublishOperation = pOperation;\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Add the PUBLISH operation to the send queue for network transmission. */\r
+    status = _IotMqtt_ScheduleOperation( pOperation,\r
+                                         _IotMqtt_ProcessSend,\r
+                                         0 );\r
+\r
+    if( status != IOT_MQTT_SUCCESS )\r
+    {\r
+        IotLogError( "(MQTT connection %p) Failed to enqueue PUBLISH for sending.",\r
+                     mqttConnection );\r
+\r
+        /* Clear the previously set (and now invalid) reference. */\r
+        if( pPublishInfo->qos != IOT_MQTT_QOS_0 )\r
+        {\r
+            if( pPublishOperation != NULL )\r
+            {\r
+                *pPublishOperation = IOT_MQTT_OPERATION_INITIALIZER;\r
+            }\r
+            else\r
+            {\r
+                EMPTY_ELSE_MARKER;\r
+            }\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        IOT_GOTO_CLEANUP();\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Clean up the PUBLISH operation if this function fails. Otherwise, set the\r
+     * appropriate return code based on QoS. */\r
+    IOT_FUNCTION_CLEANUP_BEGIN();\r
+\r
+    if( status != IOT_MQTT_SUCCESS )\r
+    {\r
+        if( pOperation != NULL )\r
+        {\r
+            _IotMqtt_DestroyOperation( pOperation );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        if( pPublishInfo->qos > IOT_MQTT_QOS_0 )\r
+        {\r
+            status = IOT_MQTT_STATUS_PENDING;\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        IotLogInfo( "(MQTT connection %p) MQTT PUBLISH operation queued.",\r
+                    mqttConnection );\r
+    }\r
+\r
+    IOT_FUNCTION_CLEANUP_END();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t IotMqtt_TimedPublish( IotMqttConnection_t mqttConnection,\r
+                                     const IotMqttPublishInfo_t * pPublishInfo,\r
+                                     uint32_t flags,\r
+                                     uint32_t timeoutMs )\r
+{\r
+    IotMqttError_t status = IOT_MQTT_STATUS_PENDING;\r
+    IotMqttOperation_t publishOperation = IOT_MQTT_OPERATION_INITIALIZER,\r
+                       * pPublishOperation = NULL;\r
+\r
+    /* Clear the flags. */\r
+    flags = 0;\r
+\r
+    /* Set the waitable flag and reference for QoS 1 PUBLISH. */\r
+    if( pPublishInfo->qos == IOT_MQTT_QOS_1 )\r
+    {\r
+        flags = IOT_MQTT_FLAG_WAITABLE;\r
+        pPublishOperation = &publishOperation;\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Call the asynchronous PUBLISH function. */\r
+    status = IotMqtt_Publish( mqttConnection,\r
+                              pPublishInfo,\r
+                              flags,\r
+                              NULL,\r
+                              pPublishOperation );\r
+\r
+    /* Wait for a queued QoS 1 PUBLISH to complete. */\r
+    if( pPublishInfo->qos == IOT_MQTT_QOS_1 )\r
+    {\r
+        if( status == IOT_MQTT_STATUS_PENDING )\r
+        {\r
+            status = IotMqtt_Wait( publishOperation, timeoutMs );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t IotMqtt_Wait( IotMqttOperation_t operation,\r
+                             uint32_t timeoutMs )\r
+{\r
+    IotMqttError_t status = IOT_MQTT_SUCCESS;\r
+    _mqttConnection_t * pMqttConnection = operation->pMqttConnection;\r
+\r
+    /* Validate the given operation reference. */\r
+    if( _IotMqtt_ValidateOperation( operation ) == false )\r
+    {\r
+        status = IOT_MQTT_BAD_PARAMETER;\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Check the MQTT connection status. */\r
+    if( status == IOT_MQTT_SUCCESS )\r
+    {\r
+        IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
+\r
+        if( pMqttConnection->disconnected == true )\r
+        {\r
+            IotLogError( "(MQTT connection %p, %s operation %p) MQTT connection is closed. "\r
+                         "Operation cannot be waited on.",\r
+                         pMqttConnection,\r
+                         IotMqtt_OperationType( operation->u.operation.type ),\r
+                         operation );\r
+\r
+            status = IOT_MQTT_NETWORK_ERROR;\r
+        }\r
+        else\r
+        {\r
+            IotLogInfo( "(MQTT connection %p, %s operation %p) Waiting for operation completion.",\r
+                        pMqttConnection,\r
+                        IotMqtt_OperationType( operation->u.operation.type ),\r
+                        operation );\r
+        }\r
+\r
+        IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
+\r
+        /* Only wait on an operation if the MQTT connection is active. */\r
+        if( status == IOT_MQTT_SUCCESS )\r
+        {\r
+            if( IotSemaphore_TimedWait( &( operation->u.operation.notify.waitSemaphore ),\r
+                                        timeoutMs ) == false )\r
+            {\r
+                status = IOT_MQTT_TIMEOUT;\r
+\r
+                /* Attempt to cancel the job of the timed out operation. */\r
+                ( void ) _IotMqtt_DecrementOperationReferences( operation, true );\r
+\r
+                /* Clean up lingering subscriptions from a timed-out SUBSCRIBE. */\r
+                if( operation->u.operation.type == IOT_MQTT_SUBSCRIBE )\r
+                {\r
+                    IotLogDebug( "(MQTT connection %p, SUBSCRIBE operation %p) Cleaning up"\r
+                                 " subscriptions of timed-out SUBSCRIBE.",\r
+                                 pMqttConnection,\r
+                                 operation );\r
+\r
+                    _IotMqtt_RemoveSubscriptionByPacket( pMqttConnection,\r
+                                                         operation->u.operation.packetIdentifier,\r
+                                                         -1 );\r
+                }\r
+                else\r
+                {\r
+                    EMPTY_ELSE_MARKER;\r
+                }\r
+            }\r
+            else\r
+            {\r
+                /* Retrieve the status of the completed operation. */\r
+                status = operation->u.operation.status;\r
+            }\r
+\r
+            IotLogInfo( "(MQTT connection %p, %s operation %p) Wait complete with result %s.",\r
+                        pMqttConnection,\r
+                        IotMqtt_OperationType( operation->u.operation.type ),\r
+                        operation,\r
+                        IotMqtt_strerror( status ) );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        /* Wait is finished; decrement operation reference count. */\r
+        if( _IotMqtt_DecrementOperationReferences( operation, false ) == true )\r
+        {\r
+            _IotMqtt_DestroyOperation( operation );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+const char * IotMqtt_strerror( IotMqttError_t status )\r
+{\r
+    const char * pMessage = NULL;\r
+\r
+    switch( status )\r
+    {\r
+        case IOT_MQTT_SUCCESS:\r
+            pMessage = "SUCCESS";\r
+            break;\r
+\r
+        case IOT_MQTT_STATUS_PENDING:\r
+            pMessage = "PENDING";\r
+            break;\r
+\r
+        case IOT_MQTT_INIT_FAILED:\r
+            pMessage = "INITIALIZATION FAILED";\r
+            break;\r
+\r
+        case IOT_MQTT_BAD_PARAMETER:\r
+            pMessage = "BAD PARAMETER";\r
+            break;\r
+\r
+        case IOT_MQTT_NO_MEMORY:\r
+            pMessage = "NO MEMORY";\r
+            break;\r
+\r
+        case IOT_MQTT_NETWORK_ERROR:\r
+            pMessage = "NETWORK ERROR";\r
+            break;\r
+\r
+        case IOT_MQTT_SCHEDULING_ERROR:\r
+            pMessage = "SCHEDULING ERROR";\r
+            break;\r
+\r
+        case IOT_MQTT_BAD_RESPONSE:\r
+            pMessage = "BAD RESPONSE RECEIVED";\r
+            break;\r
+\r
+        case IOT_MQTT_TIMEOUT:\r
+            pMessage = "TIMEOUT";\r
+            break;\r
+\r
+        case IOT_MQTT_SERVER_REFUSED:\r
+            pMessage = "SERVER REFUSED";\r
+            break;\r
+\r
+        case IOT_MQTT_RETRY_NO_RESPONSE:\r
+            pMessage = "NO RESPONSE";\r
+            break;\r
+\r
+        default:\r
+            pMessage = "INVALID STATUS";\r
+            break;\r
+    }\r
+\r
+    return pMessage;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+const char * IotMqtt_OperationType( IotMqttOperationType_t operation )\r
+{\r
+    const char * pMessage = NULL;\r
+\r
+    switch( operation )\r
+    {\r
+        case IOT_MQTT_CONNECT:\r
+            pMessage = "CONNECT";\r
+            break;\r
+\r
+        case IOT_MQTT_PUBLISH_TO_SERVER:\r
+            pMessage = "PUBLISH";\r
+            break;\r
+\r
+        case IOT_MQTT_PUBACK:\r
+            pMessage = "PUBACK";\r
+            break;\r
+\r
+        case IOT_MQTT_SUBSCRIBE:\r
+            pMessage = "SUBSCRIBE";\r
+            break;\r
+\r
+        case IOT_MQTT_UNSUBSCRIBE:\r
+            pMessage = "UNSUBSCRIBE";\r
+            break;\r
+\r
+        case IOT_MQTT_PINGREQ:\r
+            pMessage = "PINGREQ";\r
+            break;\r
+\r
+        case IOT_MQTT_DISCONNECT:\r
+            pMessage = "DISCONNECT";\r
+            break;\r
+\r
+        default:\r
+            pMessage = "INVALID OPERATION";\r
+            break;\r
+    }\r
+\r
+    return pMessage;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Provide access to internal functions and variables if testing. */\r
+#if IOT_BUILD_TESTS == 1\r
+    #include "iot_test_access_mqtt_api.c"\r
+#endif\r
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
new file mode 100644 (file)
index 0000000..169a292
--- /dev/null
@@ -0,0 +1,912 @@
+/*\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
+/*-----------------------------------------------------------*/\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
+\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
+            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
+                IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
+\r
+                if( pMqttConnection->keepAliveFailure == false )\r
+                {\r
+                    IotLogWarn( "(MQTT connection %p) Unexpected PINGRESP received.",\r
+                                pMqttConnection );\r
+                }\r
+                else\r
+                {\r
+                    IotLogDebug( "(MQTT connection %p) PINGRESP successfully parsed.",\r
+                                 pMqttConnection );\r
+\r
+                    pMqttConnection->keepAliveFailure = false;\r
+                }\r
+\r
+                IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\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 serializeStatus = IOT_MQTT_SUCCESS;\r
+    uint8_t * pPuback = NULL;\r
+    size_t pubackSize = 0, bytesSent = 0;\r
+\r
+    /* Default PUBACK serializer and free packet functions. */\r
+    IotMqttError_t ( * serializePuback )( uint16_t,\r
+                                          uint8_t **,\r
+                                          size_t * ) = _IotMqtt_SerializePuback;\r
+    void ( * freePacket )( uint8_t * ) = _IotMqtt_FreePacket;\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
+    #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
+            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
+    /* Generate a PUBACK packet from the packet identifier. */\r
+    serializeStatus = serializePuback( packetIdentifier,\r
+                                       &pPuback,\r
+                                       &pubackSize );\r
+\r
+    if( serializeStatus != IOT_MQTT_SUCCESS )\r
+    {\r
+        IotLogWarn( "(MQTT connection %p) Failed to generate PUBACK packet for "\r
+                    "received PUBLISH %hu.",\r
+                    pMqttConnection,\r
+                    packetIdentifier );\r
+    }\r
+    else\r
+    {\r
+        bytesSent = pMqttConnection->pNetworkInterface->send( pMqttConnection->pNetworkConnection,\r
+                                                              pPuback,\r
+                                                              pubackSize );\r
+\r
+        if( bytesSent != pubackSize )\r
+        {\r
+            IotLogWarn( "(MQTT connection %p) Failed to send PUBACK for received"\r
+                        " PUBLISH %hu.",\r
+                        pMqttConnection,\r
+                        packetIdentifier );\r
+        }\r
+        else\r
+        {\r
+            IotLogDebug( "(MQTT connection %p) PUBACK for received PUBLISH %hu sent.",\r
+                         pMqttConnection,\r
+                         packetIdentifier );\r
+        }\r
+\r
+        freePacket( pPuback );\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
+\r
+    /* Mark the MQTT connection as disconnected and the keep-alive as failed. */\r
+    IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
+    pMqttConnection->disconnected = true;\r
+    pMqttConnection->keepAliveFailure = true;\r
+\r
+    if( pMqttConnection->keepAliveMs != 0 )\r
+    {\r
+        /* Keep-alive must have a PINGREQ allocated. */\r
+        IotMqtt_Assert( pMqttConnection->pPingreqPacket != NULL );\r
+        IotMqtt_Assert( pMqttConnection->pingreqPacketSize != 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->keepAliveJob,\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
+            /* Clean up PINGREQ packet and job. */\r
+            _IotMqtt_FreePacket( pMqttConnection->pPingreqPacket );\r
+\r
+            /* Clear data about the keep-alive. */\r
+            pMqttConnection->keepAliveMs = 0;\r
+            pMqttConnection->pPingreqPacket = NULL;\r
+            pMqttConnection->pingreqPacketSize = 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
+    IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
+\r
+    /* Close the network connection. */\r
+    if( pMqttConnection->pNetworkInterface->close != NULL )\r
+    {\r
+        closeStatus = pMqttConnection->pNetworkInterface->close( pMqttConnection->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( pMqttConnection->disconnectCallback.function != NULL )\r
+    {\r
+        /* Set the members of the callback parameter. */\r
+        callbackParam.mqttConnection = pMqttConnection;\r
+        callbackParam.u.disconnectReason = disconnectReason;\r
+\r
+        pMqttConnection->disconnectCallback.function( pMqttConnection->disconnectCallback.pCallbackContext,\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
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
new file mode 100644 (file)
index 0000000..7923d62
--- /dev/null
@@ -0,0 +1,1332 @@
+/*\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_operation.c\r
+ * @brief Implements functions that process MQTT operations.\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_clock.h"\r
+#include "platform/iot_threads.h"\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/**\r
+ * @brief First parameter to #_mqttOperation_match.\r
+ */\r
+typedef struct _operationMatchParam\r
+{\r
+    IotMqttOperationType_t type;        /**< @brief The type of operation to look for. */\r
+    const uint16_t * pPacketIdentifier; /**< @brief The packet identifier associated with the operation.\r
+                                         * Set to `NULL` to ignore packet identifier. */\r
+} _operationMatchParam_t;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/**\r
+ * @brief Match an MQTT operation by type and packet identifier.\r
+ *\r
+ * @param[in] pOperationLink Pointer to the link member of an #_mqttOperation_t.\r
+ * @param[in] pMatch Pointer to an #_operationMatchParam_t.\r
+ *\r
+ * @return `true` if the operation matches the parameters in `pArgument`; `false`\r
+ * otherwise.\r
+ */\r
+static bool _mqttOperation_match( const IotLink_t * pOperationLink,\r
+                                  void * pMatch );\r
+\r
+/**\r
+ * @brief Check if an operation with retry has exceeded its retry limit.\r
+ *\r
+ * If a PUBLISH operation is available for retry, this function also sets any\r
+ * necessary DUP flags.\r
+ *\r
+ * @param[in] pOperation The operation to check.\r
+ *\r
+ * @return `true` if the operation may be retried; `false` otherwise.\r
+ */\r
+static bool _checkRetryLimit( _mqttOperation_t * pOperation );\r
+\r
+/**\r
+ * @brief Schedule the next send of an operation with retry.\r
+ *\r
+ * @param[in] pOperation The operation to schedule.\r
+ *\r
+ * @return `true` if the reschedule succeeded; `false` otherwise.\r
+ */\r
+static bool _scheduleNextRetry( _mqttOperation_t * pOperation );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static bool _mqttOperation_match( const IotLink_t * pOperationLink,\r
+                                  void * pMatch )\r
+{\r
+    bool match = false;\r
+\r
+    /* Because this function is called from a container function, the given link\r
+     * must never be NULL. */\r
+    IotMqtt_Assert( pOperationLink != NULL );\r
+\r
+    _mqttOperation_t * pOperation = IotLink_Container( _mqttOperation_t,\r
+                                                       pOperationLink,\r
+                                                       link );\r
+    _operationMatchParam_t * pParam = ( _operationMatchParam_t * ) pMatch;\r
+\r
+    /* Check for matching operations. */\r
+    if( pParam->type == pOperation->u.operation.type )\r
+    {\r
+        /* Check for matching packet identifiers. */\r
+        if( pParam->pPacketIdentifier == NULL )\r
+        {\r
+            match = true;\r
+        }\r
+        else\r
+        {\r
+            match = ( *( pParam->pPacketIdentifier ) == pOperation->u.operation.packetIdentifier );\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    return match;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static bool _checkRetryLimit( _mqttOperation_t * pOperation )\r
+{\r
+    _mqttConnection_t * pMqttConnection = pOperation->pMqttConnection;\r
+    bool status = true;\r
+\r
+    /* Choose a set DUP function. */\r
+    void ( * publishSetDup )( uint8_t *,\r
+                              uint8_t *,\r
+                              uint16_t * ) = _IotMqtt_PublishSetDup;\r
+\r
+    #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
+        if( pMqttConnection->pSerializer != NULL )\r
+        {\r
+            if( pMqttConnection->pSerializer->serialize.publishSetDup != NULL )\r
+            {\r
+                publishSetDup = pMqttConnection->pSerializer->serialize.publishSetDup;\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
+    /* Only PUBLISH may be retried. */\r
+    IotMqtt_Assert( pOperation->u.operation.type == IOT_MQTT_PUBLISH_TO_SERVER );\r
+\r
+    /* Check if the retry limit is exhausted. */\r
+    if( pOperation->u.operation.retry.count > pOperation->u.operation.retry.limit )\r
+    {\r
+        /* The retry count may be at most one more than the retry limit, which\r
+         * accounts for the final check for a PUBACK. */\r
+        IotMqtt_Assert( pOperation->u.operation.retry.count == pOperation->u.operation.retry.limit + 1 );\r
+\r
+        IotLogDebug( "(MQTT connection %p, PUBLISH operation %p) No response received after %lu retries.",\r
+                     pMqttConnection,\r
+                     pOperation,\r
+                     pOperation->u.operation.retry.limit );\r
+\r
+        status = false;\r
+    }\r
+    /* Check if this is the first retry. */\r
+    else if( pOperation->u.operation.retry.count == 1 )\r
+    {\r
+        /* Always set the DUP flag on the first retry. */\r
+        publishSetDup( pOperation->u.operation.pMqttPacket,\r
+                       pOperation->u.operation.pPacketIdentifierHigh,\r
+                       &( pOperation->u.operation.packetIdentifier ) );\r
+    }\r
+    else\r
+    {\r
+        /* In AWS IoT MQTT mode, the DUP flag (really a change to the packet\r
+         * identifier) must be reset on every retry. */\r
+        if( pMqttConnection->awsIotMqttMode == true )\r
+        {\r
+            publishSetDup( pOperation->u.operation.pMqttPacket,\r
+                           pOperation->u.operation.pPacketIdentifierHigh,\r
+                           &( pOperation->u.operation.packetIdentifier ) );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static bool _scheduleNextRetry( _mqttOperation_t * pOperation )\r
+{\r
+    bool firstRetry = false;\r
+    uint32_t scheduleDelay = 0;\r
+    IotMqttError_t status = IOT_MQTT_STATUS_PENDING;\r
+    _mqttConnection_t * pMqttConnection = pOperation->pMqttConnection;\r
+\r
+    /* This function should never be called with retry count greater than\r
+     * retry limit. */\r
+    IotMqtt_Assert( pOperation->u.operation.retry.count <= pOperation->u.operation.retry.limit );\r
+\r
+    /* Increment the retry count. */\r
+    ( pOperation->u.operation.retry.count )++;\r
+\r
+    /* Check for a response shortly for the final retry. Otherwise, calculate the\r
+     * next retry period. */\r
+    if( pOperation->u.operation.retry.count > pOperation->u.operation.retry.limit )\r
+    {\r
+        scheduleDelay = IOT_MQTT_RESPONSE_WAIT_MS;\r
+\r
+        IotLogDebug( "(MQTT connection %p, PUBLISH operation %p) Final retry was sent. Will check "\r
+                     "for response in %d ms.",\r
+                     pMqttConnection,\r
+                     pOperation,\r
+                     IOT_MQTT_RESPONSE_WAIT_MS );\r
+    }\r
+    else\r
+    {\r
+        scheduleDelay = pOperation->u.operation.retry.nextPeriod;\r
+\r
+        /* Double the retry period, subject to a ceiling value. */\r
+        pOperation->u.operation.retry.nextPeriod *= 2;\r
+\r
+        if( pOperation->u.operation.retry.nextPeriod > IOT_MQTT_RETRY_MS_CEILING )\r
+        {\r
+            pOperation->u.operation.retry.nextPeriod = IOT_MQTT_RETRY_MS_CEILING;\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        IotLogDebug( "(MQTT connection %p, PUBLISH operation %p) Scheduling retry %lu of %lu in %lu ms.",\r
+                     pMqttConnection,\r
+                     pOperation,\r
+                     ( unsigned long ) pOperation->u.operation.retry.count,\r
+                     ( unsigned long ) pOperation->u.operation.retry.limit,\r
+                     ( unsigned long ) scheduleDelay );\r
+\r
+        /* Check if this is the first retry. */\r
+        firstRetry = ( pOperation->u.operation.retry.count == 1 );\r
+\r
+        /* On the first retry, the PUBLISH will be moved from the pending processing\r
+         * list to the pending responses list. Lock the connection references mutex\r
+         * to manipulate the lists. */\r
+        if( firstRetry == true )\r
+        {\r
+            IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+\r
+    /* Reschedule the PUBLISH for another send. */\r
+    status = _IotMqtt_ScheduleOperation( pOperation,\r
+                                         _IotMqtt_ProcessSend,\r
+                                         scheduleDelay );\r
+\r
+    /* Check for successful reschedule. */\r
+    if( status == IOT_MQTT_SUCCESS )\r
+    {\r
+        /* Move a successfully rescheduled PUBLISH from the pending processing\r
+         * list to the pending responses list on the first retry. */\r
+        if( firstRetry == true )\r
+        {\r
+            /* Operation must be linked. */\r
+            IotMqtt_Assert( IotLink_IsLinked( &( pOperation->link ) ) == true );\r
+\r
+            /* Transfer to pending response list. */\r
+            IotListDouble_Remove( &( pOperation->link ) );\r
+            IotListDouble_InsertHead( &( pMqttConnection->pendingResponse ),\r
+                                      &( pOperation->link ) );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* The references mutex only needs to be unlocked on the first retry, since\r
+     * only the first retry manipulates the connection lists. */\r
+    if( firstRetry == true )\r
+    {\r
+        IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    return( status == IOT_MQTT_SUCCESS );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t _IotMqtt_CreateOperation( _mqttConnection_t * pMqttConnection,\r
+                                         uint32_t flags,\r
+                                         const IotMqttCallbackInfo_t * pCallbackInfo,\r
+                                         _mqttOperation_t ** pNewOperation )\r
+{\r
+    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
+    bool decrementOnError = false;\r
+    _mqttOperation_t * pOperation = NULL;\r
+    bool waitable = ( ( flags & IOT_MQTT_FLAG_WAITABLE ) == IOT_MQTT_FLAG_WAITABLE );\r
+\r
+    /* If the waitable flag is set, make sure that there's no callback. */\r
+    if( waitable == true )\r
+    {\r
+        if( pCallbackInfo != NULL )\r
+        {\r
+            IotLogError( "Callback should not be set for a waitable operation." );\r
+\r
+            return IOT_MQTT_BAD_PARAMETER;\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    IotLogDebug( "(MQTT connection %p) Creating new operation record.",\r
+                 pMqttConnection );\r
+\r
+    /* Increment the reference count for the MQTT connection when creating a new\r
+     * operation. */\r
+    if( _IotMqtt_IncrementConnectionReferences( pMqttConnection ) == false )\r
+    {\r
+        IotLogError( "(MQTT connection %p) New operation record cannot be created"\r
+                     " for a closed connection",\r
+                     pMqttConnection );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NETWORK_ERROR );\r
+    }\r
+    else\r
+    {\r
+        /* Reference count will need to be decremented on error. */\r
+        decrementOnError = true;\r
+    }\r
+\r
+    /* Allocate memory for a new operation. */\r
+    pOperation = IotMqtt_MallocOperation( sizeof( _mqttOperation_t ) );\r
+\r
+    if( pOperation == NULL )\r
+    {\r
+        IotLogError( "(MQTT connection %p) Failed to allocate memory for new "\r
+                     "operation record.",\r
+                     pMqttConnection );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NO_MEMORY );\r
+    }\r
+    else\r
+    {\r
+        /* Clear the operation data. */\r
+        ( void ) memset( pOperation, 0x00, sizeof( _mqttOperation_t ) );\r
+\r
+        /* Initialize some members of the new operation. */\r
+        pOperation->pMqttConnection = pMqttConnection;\r
+        pOperation->u.operation.jobReference = 1;\r
+        pOperation->u.operation.flags = flags;\r
+        pOperation->u.operation.status = IOT_MQTT_STATUS_PENDING;\r
+    }\r
+\r
+    /* Check if the waitable flag is set. If it is, create a semaphore to\r
+     * wait on. */\r
+    if( waitable == true )\r
+    {\r
+        /* Create a semaphore to wait on for a waitable operation. */\r
+        if( IotSemaphore_Create( &( pOperation->u.operation.notify.waitSemaphore ), 0, 1 ) == false )\r
+        {\r
+            IotLogError( "(MQTT connection %p) Failed to create semaphore for "\r
+                         "waitable operation.",\r
+                         pMqttConnection );\r
+\r
+            IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NO_MEMORY );\r
+        }\r
+        else\r
+        {\r
+            /* A waitable operation is created with an additional reference for the\r
+             * Wait function. */\r
+            ( pOperation->u.operation.jobReference )++;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        /* If the waitable flag isn't set but a callback is, copy the callback\r
+         * information. */\r
+        if( pCallbackInfo != NULL )\r
+        {\r
+            pOperation->u.operation.notify.callback = *pCallbackInfo;\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+\r
+    /* Add this operation to the MQTT connection's operation list. */\r
+    IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
+    IotListDouble_InsertHead( &( pMqttConnection->pendingProcessing ),\r
+                              &( pOperation->link ) );\r
+    IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
+\r
+    /* Set the output parameter. */\r
+    *pNewOperation = pOperation;\r
+\r
+    /* Clean up operation and decrement reference count if this function failed. */\r
+    IOT_FUNCTION_CLEANUP_BEGIN();\r
+\r
+    if( status != IOT_MQTT_SUCCESS )\r
+    {\r
+        if( decrementOnError == true )\r
+        {\r
+            _IotMqtt_DecrementConnectionReferences( pMqttConnection );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        if( pOperation != NULL )\r
+        {\r
+            IotMqtt_FreeOperation( pOperation );\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
+bool _IotMqtt_DecrementOperationReferences( _mqttOperation_t * pOperation,\r
+                                            bool cancelJob )\r
+{\r
+    bool destroyOperation = false;\r
+    IotTaskPoolError_t taskPoolStatus = IOT_TASKPOOL_SUCCESS;\r
+    _mqttConnection_t * pMqttConnection = pOperation->pMqttConnection;\r
+\r
+    /* Attempt to cancel the operation's job. */\r
+    if( cancelJob == true )\r
+    {\r
+        taskPoolStatus = IotTaskPool_TryCancel( IOT_SYSTEM_TASKPOOL,\r
+                                                pOperation->job,\r
+                                                NULL );\r
+\r
+        /* If the operation's 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
+        if( taskPoolStatus == IOT_TASKPOOL_SUCCESS )\r
+        {\r
+            IotLogDebug( "(MQTT connection %p, %s operation %p) Job canceled.",\r
+                         pMqttConnection,\r
+                         IotMqtt_OperationType( pOperation->u.operation.type ),\r
+                         pOperation );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Decrement job reference count. */\r
+    if( taskPoolStatus == IOT_TASKPOOL_SUCCESS )\r
+    {\r
+        IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
+        pOperation->u.operation.jobReference--;\r
+\r
+        IotLogDebug( "(MQTT connection %p, %s operation %p) Job reference changed"\r
+                     " from %ld to %ld.",\r
+                     pMqttConnection,\r
+                     IotMqtt_OperationType( pOperation->u.operation.type ),\r
+                     pOperation,\r
+                     pOperation->u.operation.jobReference + 1,\r
+                     pOperation->u.operation.jobReference );\r
+\r
+        /* The job reference count must be 0 or 1 after the decrement. */\r
+        IotMqtt_Assert( ( pOperation->u.operation.jobReference == 0 ) ||\r
+                        ( pOperation->u.operation.jobReference == 1 ) );\r
+\r
+        /* This operation may be destroyed if its reference count is 0. */\r
+        if( pOperation->u.operation.jobReference == 0 )\r
+        {\r
+            destroyOperation = true;\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    return destroyOperation;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void _IotMqtt_DestroyOperation( _mqttOperation_t * pOperation )\r
+{\r
+    _mqttConnection_t * pMqttConnection = pOperation->pMqttConnection;\r
+\r
+    /* Default free packet function. */\r
+    void ( * freePacket )( uint8_t * ) = _IotMqtt_FreePacket;\r
+\r
+    IotLogDebug( "(MQTT connection %p, %s operation %p) Destroying operation.",\r
+                 pMqttConnection,\r
+                 IotMqtt_OperationType( pOperation->u.operation.type ),\r
+                 pOperation );\r
+\r
+    /* The job reference count must be between 0 and 2. */\r
+    IotMqtt_Assert( ( pOperation->u.operation.jobReference >= 0 ) &&\r
+                    ( pOperation->u.operation.jobReference <= 2 ) );\r
+\r
+    /* Jobs to be destroyed should be removed from the MQTT connection's\r
+     * lists. */\r
+    IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
+\r
+    if( IotLink_IsLinked( &( pOperation->link ) ) == true )\r
+    {\r
+        IotLogDebug( "(MQTT connection %p, %s operation %p) Removed operation from connection lists.",\r
+                     pMqttConnection,\r
+                     IotMqtt_OperationType( pOperation->u.operation.type ),\r
+                     pOperation,\r
+                     pMqttConnection );\r
+\r
+        IotListDouble_Remove( &( pOperation->link ) );\r
+    }\r
+    else\r
+    {\r
+        IotLogDebug( "(MQTT connection %p, %s operation %p) Operation was not present in connection lists.",\r
+                     pMqttConnection,\r
+                     IotMqtt_OperationType( pOperation->u.operation.type ),\r
+                     pOperation );\r
+    }\r
+\r
+    IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
+\r
+    /* Free any allocated MQTT packet. */\r
+    if( pOperation->u.operation.pMqttPacket != NULL )\r
+    {\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
+                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
+        freePacket( pOperation->u.operation.pMqttPacket );\r
+\r
+        IotLogDebug( "(MQTT connection %p, %s operation %p) MQTT packet freed.",\r
+                     pMqttConnection,\r
+                     IotMqtt_OperationType( pOperation->u.operation.type ),\r
+                     pOperation );\r
+    }\r
+    else\r
+    {\r
+        IotLogDebug( "(MQTT connection %p, %s operation %p) Operation has no allocated MQTT packet.",\r
+                     pMqttConnection,\r
+                     IotMqtt_OperationType( pOperation->u.operation.type ),\r
+                     pOperation );\r
+    }\r
+\r
+    /* Check if a wait semaphore was created for this operation. */\r
+    if( ( pOperation->u.operation.flags & IOT_MQTT_FLAG_WAITABLE ) == IOT_MQTT_FLAG_WAITABLE )\r
+    {\r
+        IotSemaphore_Destroy( &( pOperation->u.operation.notify.waitSemaphore ) );\r
+\r
+        IotLogDebug( "(MQTT connection %p, %s operation %p) Wait semaphore destroyed.",\r
+                     pMqttConnection,\r
+                     IotMqtt_OperationType( pOperation->u.operation.type ),\r
+                     pOperation );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    IotLogDebug( "(MQTT connection %p, %s operation %p) Operation record destroyed.",\r
+                 pMqttConnection,\r
+                 IotMqtt_OperationType( pOperation->u.operation.type ),\r
+                 pOperation );\r
+\r
+    /* Free the memory used to hold operation data. */\r
+    IotMqtt_FreeOperation( pOperation );\r
+\r
+    /* Decrement the MQTT connection's reference count after destroying an\r
+     * operation. */\r
+    _IotMqtt_DecrementConnectionReferences( pMqttConnection );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void _IotMqtt_ProcessKeepAlive( IotTaskPool_t pTaskPool,\r
+                                IotTaskPoolJob_t pKeepAliveJob,\r
+                                void * pContext )\r
+{\r
+    bool status = true;\r
+    IotTaskPoolError_t taskPoolStatus = IOT_TASKPOOL_SUCCESS;\r
+    size_t bytesSent = 0;\r
+\r
+    /* Retrieve the MQTT connection from the context. */\r
+    _mqttConnection_t * pMqttConnection = ( _mqttConnection_t * ) pContext;\r
+\r
+    /* Check parameters. */\r
+    IotMqtt_Assert( pTaskPool == IOT_SYSTEM_TASKPOOL );\r
+    IotMqtt_Assert( pKeepAliveJob == pMqttConnection->keepAliveJob );\r
+\r
+    /* Check that keep-alive interval is valid. The MQTT spec states its maximum\r
+     * value is 65,535 seconds. */\r
+    IotMqtt_Assert( pMqttConnection->keepAliveMs <= 65535000 );\r
+\r
+    /* Only two values are valid for the next keep alive job delay. */\r
+    IotMqtt_Assert( ( pMqttConnection->nextKeepAliveMs == pMqttConnection->keepAliveMs ) ||\r
+                    ( pMqttConnection->nextKeepAliveMs == IOT_MQTT_RESPONSE_WAIT_MS ) );\r
+\r
+    IotLogDebug( "(MQTT connection %p) Keep-alive job started.", pMqttConnection );\r
+\r
+    /* Re-create the keep-alive job for rescheduling. This should never fail. */\r
+    taskPoolStatus = IotTaskPool_CreateJob( _IotMqtt_ProcessKeepAlive,\r
+                                            pContext,\r
+                                            IotTaskPool_GetJobStorageFromHandle( pKeepAliveJob ),\r
+                                            &pKeepAliveJob );\r
+    IotMqtt_Assert( taskPoolStatus == IOT_TASKPOOL_SUCCESS );\r
+\r
+    IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
+\r
+    /* Determine whether to send a PINGREQ or check for PINGRESP. */\r
+    if( pMqttConnection->nextKeepAliveMs == pMqttConnection->keepAliveMs )\r
+    {\r
+        IotLogDebug( "(MQTT connection %p) Sending PINGREQ.", pMqttConnection );\r
+\r
+        /* Because PINGREQ may be used to keep the MQTT connection alive, it is\r
+         * more important than other operations. Bypass the queue of jobs for\r
+         * operations by directly sending the PINGREQ in this job. */\r
+        bytesSent = pMqttConnection->pNetworkInterface->send( pMqttConnection->pNetworkConnection,\r
+                                                              pMqttConnection->pPingreqPacket,\r
+                                                              pMqttConnection->pingreqPacketSize );\r
+\r
+        if( bytesSent != pMqttConnection->pingreqPacketSize )\r
+        {\r
+            IotLogError( "(MQTT connection %p) Failed to send PINGREQ.", pMqttConnection );\r
+            status = false;\r
+        }\r
+        else\r
+        {\r
+            /* Assume the keep-alive will fail. The network receive callback will\r
+             * clear the failure flag upon receiving a PINGRESP. */\r
+            pMqttConnection->keepAliveFailure = true;\r
+\r
+            /* Schedule a check for PINGRESP. */\r
+            pMqttConnection->nextKeepAliveMs = IOT_MQTT_RESPONSE_WAIT_MS;\r
+\r
+            IotLogDebug( "(MQTT connection %p) PINGREQ sent. Scheduling check for PINGRESP in %d ms.",\r
+                         pMqttConnection,\r
+                         IOT_MQTT_RESPONSE_WAIT_MS );\r
+        }\r
+    }\r
+    else\r
+    {\r
+        IotLogDebug( "(MQTT connection %p) Checking for PINGRESP.", pMqttConnection );\r
+\r
+        if( pMqttConnection->keepAliveFailure == false )\r
+        {\r
+            IotLogDebug( "(MQTT connection %p) PINGRESP was received.", pMqttConnection );\r
+\r
+            /* PINGRESP was received. Schedule the next PINGREQ transmission. */\r
+            pMqttConnection->nextKeepAliveMs = pMqttConnection->keepAliveMs;\r
+        }\r
+        else\r
+        {\r
+            IotLogError( "(MQTT connection %p) Failed to receive PINGRESP within %d ms.",\r
+                         pMqttConnection,\r
+                         IOT_MQTT_RESPONSE_WAIT_MS );\r
+\r
+            /* The network receive callback did not clear the failure flag. */\r
+            status = false;\r
+        }\r
+    }\r
+\r
+    /* When a PINGREQ is successfully sent, reschedule this job to check for a\r
+     * response shortly. */\r
+    if( status == true )\r
+    {\r
+        taskPoolStatus = IotTaskPool_ScheduleDeferred( pTaskPool,\r
+                                                       pKeepAliveJob,\r
+                                                       pMqttConnection->nextKeepAliveMs );\r
+\r
+        if( taskPoolStatus == IOT_TASKPOOL_SUCCESS )\r
+        {\r
+            IotLogDebug( "(MQTT connection %p) Next keep-alive job in %d ms.",\r
+                         pMqttConnection,\r
+                         IOT_MQTT_RESPONSE_WAIT_MS );\r
+        }\r
+        else\r
+        {\r
+            IotLogError( "(MQTT connection %p) Failed to reschedule keep-alive job, error %s.",\r
+                         pMqttConnection,\r
+                         IotTaskPool_strerror( taskPoolStatus ) );\r
+\r
+            status = false;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Close the connection on failures. */\r
+    if( status == false )\r
+    {\r
+        _IotMqtt_CloseNetworkConnection( IOT_MQTT_KEEP_ALIVE_TIMEOUT,\r
+                                         pMqttConnection );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void _IotMqtt_ProcessIncomingPublish( IotTaskPool_t pTaskPool,\r
+                                      IotTaskPoolJob_t pPublishJob,\r
+                                      void * pContext )\r
+{\r
+    _mqttOperation_t * pOperation = pContext;\r
+    IotMqttCallbackParam_t callbackParam = { .mqttConnection = NULL };\r
+\r
+    /* Check parameters. The task pool and job parameter is not used when asserts\r
+     * are disabled. */\r
+    ( void ) pTaskPool;\r
+    ( void ) pPublishJob;\r
+    IotMqtt_Assert( pTaskPool == IOT_SYSTEM_TASKPOOL );\r
+    IotMqtt_Assert( pOperation->incomingPublish == true );\r
+    IotMqtt_Assert( pPublishJob == pOperation->job );\r
+\r
+    /* Remove the operation from the pending processing list. */\r
+    IotMutex_Lock( &( pOperation->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( &( pOperation->pMqttConnection->referencesMutex ) );\r
+\r
+    /* Process the current PUBLISH. */\r
+    callbackParam.u.message.info = pOperation->u.publish.publishInfo;\r
+\r
+    _IotMqtt_InvokeSubscriptionCallback( pOperation->pMqttConnection,\r
+                                         &callbackParam );\r
+\r
+    /* Free any buffers associated with the current PUBLISH message. */\r
+    if( pOperation->u.publish.pReceivedData != NULL )\r
+    {\r
+        IotMqtt_FreeMessage( ( void * ) pOperation->u.publish.pReceivedData );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Free the incoming PUBLISH operation. */\r
+    IotMqtt_FreeOperation( pOperation );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void _IotMqtt_ProcessSend( IotTaskPool_t pTaskPool,\r
+                           IotTaskPoolJob_t pSendJob,\r
+                           void * pContext )\r
+{\r
+    size_t bytesSent = 0;\r
+    bool destroyOperation = false, waitable = false, networkPending = false;\r
+    _mqttOperation_t * pOperation = ( _mqttOperation_t * ) pContext;\r
+    _mqttConnection_t * pMqttConnection = pOperation->pMqttConnection;\r
+\r
+    /* Check parameters. The task pool and job parameter is not used when asserts\r
+     * are disabled. */\r
+    ( void ) pTaskPool;\r
+    ( void ) pSendJob;\r
+    IotMqtt_Assert( pTaskPool == IOT_SYSTEM_TASKPOOL );\r
+    IotMqtt_Assert( pSendJob == pOperation->job );\r
+\r
+    /* The given operation must have an allocated packet and be waiting for a status. */\r
+    IotMqtt_Assert( pOperation->u.operation.pMqttPacket != NULL );\r
+    IotMqtt_Assert( pOperation->u.operation.packetSize != 0 );\r
+    IotMqtt_Assert( pOperation->u.operation.status == IOT_MQTT_STATUS_PENDING );\r
+\r
+    /* Check if this operation is waitable. */\r
+    waitable = ( pOperation->u.operation.flags & IOT_MQTT_FLAG_WAITABLE ) == IOT_MQTT_FLAG_WAITABLE;\r
+\r
+    /* Check PUBLISH retry counts and limits. */\r
+    if( pOperation->u.operation.retry.limit > 0 )\r
+    {\r
+        if( _checkRetryLimit( pOperation ) == false )\r
+        {\r
+            pOperation->u.operation.status = IOT_MQTT_RETRY_NO_RESPONSE;\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Send an operation that is waiting for a response. */\r
+    if( pOperation->u.operation.status == IOT_MQTT_STATUS_PENDING )\r
+    {\r
+        IotLogDebug( "(MQTT connection %p, %s operation %p) Sending MQTT packet.",\r
+                     pMqttConnection,\r
+                     IotMqtt_OperationType( pOperation->u.operation.type ),\r
+                     pOperation );\r
+\r
+        /* Transmit the MQTT packet from the operation over the network. */\r
+        bytesSent = pMqttConnection->pNetworkInterface->send( pMqttConnection->pNetworkConnection,\r
+                                                              pOperation->u.operation.pMqttPacket,\r
+                                                              pOperation->u.operation.packetSize );\r
+\r
+        /* Check transmission status. */\r
+        if( bytesSent != pOperation->u.operation.packetSize )\r
+        {\r
+            pOperation->u.operation.status = IOT_MQTT_NETWORK_ERROR;\r
+        }\r
+        else\r
+        {\r
+            /* DISCONNECT operations are considered successful upon successful\r
+             * transmission. In addition, non-waitable operations with no callback\r
+             * may also be considered successful. */\r
+            if( pOperation->u.operation.type == IOT_MQTT_DISCONNECT )\r
+            {\r
+                /* DISCONNECT operations are always waitable. */\r
+                IotMqtt_Assert( waitable == true );\r
+\r
+                pOperation->u.operation.status = IOT_MQTT_SUCCESS;\r
+            }\r
+            else if( waitable == false )\r
+            {\r
+                if( pOperation->u.operation.notify.callback.function == NULL )\r
+                {\r
+                    pOperation->u.operation.status = IOT_MQTT_SUCCESS;\r
+                }\r
+                else\r
+                {\r
+                    EMPTY_ELSE_MARKER;\r
+                }\r
+            }\r
+            else\r
+            {\r
+                EMPTY_ELSE_MARKER;\r
+            }\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Check if this operation requires further processing. */\r
+    if( pOperation->u.operation.status == IOT_MQTT_STATUS_PENDING )\r
+    {\r
+        /* Check if this operation should be scheduled for retransmission. */\r
+        if( pOperation->u.operation.retry.limit > 0 )\r
+        {\r
+            if( _scheduleNextRetry( pOperation ) == false )\r
+            {\r
+                pOperation->u.operation.status = IOT_MQTT_SCHEDULING_ERROR;\r
+            }\r
+            else\r
+            {\r
+                /* A successfully scheduled PUBLISH retry is awaiting a response\r
+                 * from the network. */\r
+                networkPending = true;\r
+            }\r
+        }\r
+        else\r
+        {\r
+            /* Decrement reference count to signal completion of send job. Check\r
+             * if the operation should be destroyed. */\r
+            if( waitable == true )\r
+            {\r
+                destroyOperation = _IotMqtt_DecrementOperationReferences( pOperation, false );\r
+            }\r
+            else\r
+            {\r
+                EMPTY_ELSE_MARKER;\r
+            }\r
+\r
+            /* If the operation should not be destroyed, transfer it from the\r
+             * pending processing to the pending response list. */\r
+            if( destroyOperation == false )\r
+            {\r
+                IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
+\r
+                /* Operation must be linked. */\r
+                IotMqtt_Assert( IotLink_IsLinked( &( pOperation->link ) ) );\r
+\r
+                /* Transfer to pending response list. */\r
+                IotListDouble_Remove( &( pOperation->link ) );\r
+                IotListDouble_InsertHead( &( pMqttConnection->pendingResponse ),\r
+                                          &( pOperation->link ) );\r
+\r
+                IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
+\r
+                /* This operation is now awaiting a response from the network. */\r
+                networkPending = true;\r
+            }\r
+            else\r
+            {\r
+                EMPTY_ELSE_MARKER;\r
+            }\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Destroy the operation or notify of completion if necessary. */\r
+    if( destroyOperation == true )\r
+    {\r
+        _IotMqtt_DestroyOperation( pOperation );\r
+    }\r
+    else\r
+    {\r
+        /* Do not check the operation status if a network response is pending,\r
+         * since a network response could modify the status. */\r
+        if( networkPending == false )\r
+        {\r
+            /* Notify of operation completion if this job set a status. */\r
+            if( pOperation->u.operation.status != IOT_MQTT_STATUS_PENDING )\r
+            {\r
+                _IotMqtt_Notify( pOperation );\r
+            }\r
+            else\r
+            {\r
+                EMPTY_ELSE_MARKER;\r
+            }\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void _IotMqtt_ProcessCompletedOperation( IotTaskPool_t pTaskPool,\r
+                                         IotTaskPoolJob_t pOperationJob,\r
+                                         void * pContext )\r
+{\r
+    _mqttOperation_t * pOperation = ( _mqttOperation_t * ) pContext;\r
+    IotMqttCallbackParam_t callbackParam = { 0 };\r
+\r
+    /* Check parameters. The task pool and job parameter is not used when asserts\r
+     * are disabled. */\r
+    ( void ) pTaskPool;\r
+    ( void ) pOperationJob;\r
+    IotMqtt_Assert( pTaskPool == IOT_SYSTEM_TASKPOOL );\r
+    IotMqtt_Assert( pOperationJob == pOperation->job );\r
+\r
+    /* The operation's callback function and status must be set. */\r
+    IotMqtt_Assert( pOperation->u.operation.notify.callback.function != NULL );\r
+    IotMqtt_Assert( pOperation->u.operation.status != IOT_MQTT_STATUS_PENDING );\r
+\r
+    callbackParam.mqttConnection = pOperation->pMqttConnection;\r
+    callbackParam.u.operation.type = pOperation->u.operation.type;\r
+    callbackParam.u.operation.reference = pOperation;\r
+    callbackParam.u.operation.result = pOperation->u.operation.status;\r
+\r
+    /* Invoke the user callback function. */\r
+    pOperation->u.operation.notify.callback.function( pOperation->u.operation.notify.callback.pCallbackContext,\r
+                                                      &callbackParam );\r
+\r
+    /* Attempt to destroy the operation once the user callback returns. */\r
+    if( _IotMqtt_DecrementOperationReferences( pOperation, false ) == true )\r
+    {\r
+        _IotMqtt_DestroyOperation( pOperation );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t _IotMqtt_ScheduleOperation( _mqttOperation_t * pOperation,\r
+                                           IotTaskPoolRoutine_t jobRoutine,\r
+                                           uint32_t delay )\r
+{\r
+    IotMqttError_t status = IOT_MQTT_SUCCESS;\r
+    IotTaskPoolError_t taskPoolStatus = IOT_TASKPOOL_SUCCESS;\r
+\r
+    /* Check that job routine is valid. */\r
+    IotMqtt_Assert( ( jobRoutine == _IotMqtt_ProcessSend ) ||\r
+                    ( jobRoutine == _IotMqtt_ProcessCompletedOperation ) ||\r
+                    ( jobRoutine == _IotMqtt_ProcessIncomingPublish ) );\r
+\r
+    /* Creating a new job should never fail when parameters are valid. */\r
+    taskPoolStatus = IotTaskPool_CreateJob( jobRoutine,\r
+                                            pOperation,\r
+                                            &( pOperation->jobStorage ),\r
+                                            &( pOperation->job ) );\r
+    IotMqtt_Assert( taskPoolStatus == IOT_TASKPOOL_SUCCESS );\r
+\r
+    /* Schedule the new job with a delay. */\r
+    taskPoolStatus = IotTaskPool_ScheduleDeferred( IOT_SYSTEM_TASKPOOL,\r
+                                                   pOperation->job,\r
+                                                   delay );\r
+\r
+    if( taskPoolStatus != IOT_TASKPOOL_SUCCESS )\r
+    {\r
+        /* Scheduling a newly-created job should never be invalid or illegal. */\r
+        IotMqtt_Assert( taskPoolStatus != IOT_TASKPOOL_BAD_PARAMETER );\r
+        IotMqtt_Assert( taskPoolStatus != IOT_TASKPOOL_ILLEGAL_OPERATION );\r
+\r
+        IotLogWarn( "(MQTT connection %p, %s operation %p) Failed to schedule operation job, error %s.",\r
+                    pOperation->pMqttConnection,\r
+                    IotMqtt_OperationType( pOperation->u.operation.type ),\r
+                    pOperation,\r
+                    IotTaskPool_strerror( taskPoolStatus ) );\r
+\r
+        status = IOT_MQTT_SCHEDULING_ERROR;\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+_mqttOperation_t * _IotMqtt_FindOperation( _mqttConnection_t * pMqttConnection,\r
+                                           IotMqttOperationType_t type,\r
+                                           const uint16_t * pPacketIdentifier )\r
+{\r
+    bool waitable = false;\r
+    IotTaskPoolError_t taskPoolStatus = IOT_TASKPOOL_SUCCESS;\r
+    _mqttOperation_t * pResult = NULL;\r
+    IotLink_t * pResultLink = NULL;\r
+    _operationMatchParam_t param = { .type = type, .pPacketIdentifier = pPacketIdentifier };\r
+\r
+    if( pPacketIdentifier != NULL )\r
+    {\r
+        IotLogDebug( "(MQTT connection %p) Searching for operation %s pending response "\r
+                     "with packet identifier %hu.",\r
+                     pMqttConnection,\r
+                     IotMqtt_OperationType( type ),\r
+                     *pPacketIdentifier );\r
+    }\r
+    else\r
+    {\r
+        IotLogDebug( "(MQTT connection %p) Searching for operation %s pending response.",\r
+                     pMqttConnection,\r
+                     IotMqtt_OperationType( type ) );\r
+    }\r
+\r
+    /* Find and remove the first matching element in the list. */\r
+    IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
+    pResultLink = IotListDouble_FindFirstMatch( &( pMqttConnection->pendingResponse ),\r
+                                                NULL,\r
+                                                _mqttOperation_match,\r
+                                                &param );\r
+\r
+    /* Check if a match was found. */\r
+    if( pResultLink != NULL )\r
+    {\r
+        /* Get operation pointer and check if it is waitable. */\r
+        pResult = IotLink_Container( _mqttOperation_t, pResultLink, link );\r
+        waitable = ( pResult->u.operation.flags & IOT_MQTT_FLAG_WAITABLE ) == IOT_MQTT_FLAG_WAITABLE;\r
+\r
+        /* Check if the matched operation is a PUBLISH with retry. If it is, cancel\r
+         * the retry job. */\r
+        if( pResult->u.operation.retry.limit > 0 )\r
+        {\r
+            taskPoolStatus = IotTaskPool_TryCancel( IOT_SYSTEM_TASKPOOL,\r
+                                                    pResult->job,\r
+                                                    NULL );\r
+\r
+            /* If the retry job could not be canceled, then it is currently\r
+             * executing. Ignore the operation. */\r
+            if( taskPoolStatus != IOT_TASKPOOL_SUCCESS )\r
+            {\r
+                pResult = NULL;\r
+            }\r
+            else\r
+            {\r
+                /* Check job reference counts. A waitable operation should have a\r
+                 * count of 2; a non-waitable operation should have a count of 1. */\r
+                IotMqtt_Assert( pResult->u.operation.jobReference == ( 1 + ( waitable == true ) ) );\r
+            }\r
+        }\r
+        else\r
+        {\r
+            /* An operation with no retry in the pending responses list should\r
+             * always have a job reference of 1. */\r
+            IotMqtt_Assert( pResult->u.operation.jobReference == 1 );\r
+\r
+            /* Increment job references of a waitable operation to prevent Wait from\r
+             * destroying this operation if it times out. */\r
+            if( waitable == true )\r
+            {\r
+                ( pResult->u.operation.jobReference )++;\r
+\r
+                IotLogDebug( "(MQTT connection %p, %s operation %p) Job reference changed from %ld to %ld.",\r
+                             pMqttConnection,\r
+                             IotMqtt_OperationType( type ),\r
+                             pResult,\r
+                             ( long int ) ( pResult->u.operation.jobReference - 1 ),\r
+                             ( long int ) ( pResult->u.operation.jobReference ) );\r
+            }\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    if( pResult != NULL )\r
+    {\r
+        IotLogDebug( "(MQTT connection %p) Found operation %s." ,\r
+                     pMqttConnection,\r
+                     IotMqtt_OperationType( type ) );\r
+\r
+        /* Remove the matched operation from the list. */\r
+        IotListDouble_Remove( &( pResult->link ) );\r
+    }\r
+    else\r
+    {\r
+        IotLogDebug( "(MQTT connection %p) Operation %s not found.",\r
+                     pMqttConnection,\r
+                     IotMqtt_OperationType( type ) );\r
+    }\r
+\r
+    IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
+\r
+    return pResult;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void _IotMqtt_Notify( _mqttOperation_t * pOperation )\r
+{\r
+    IotMqttError_t status = IOT_MQTT_SCHEDULING_ERROR;\r
+    _mqttConnection_t * pMqttConnection = pOperation->pMqttConnection;\r
+\r
+    /* Check if operation is waitable. */\r
+    bool waitable = ( pOperation->u.operation.flags & IOT_MQTT_FLAG_WAITABLE ) == IOT_MQTT_FLAG_WAITABLE;\r
+\r
+    /* Remove any lingering subscriptions if a SUBSCRIBE failed. Rejected\r
+     * subscriptions are removed by the deserializer, so not removed here. */\r
+    if( pOperation->u.operation.type == IOT_MQTT_SUBSCRIBE )\r
+    {\r
+        switch( pOperation->u.operation.status )\r
+        {\r
+            case IOT_MQTT_SUCCESS:\r
+                break;\r
+\r
+            case IOT_MQTT_SERVER_REFUSED:\r
+                break;\r
+\r
+            default:\r
+                _IotMqtt_RemoveSubscriptionByPacket( pOperation->pMqttConnection,\r
+                                                     pOperation->u.operation.packetIdentifier,\r
+                                                     -1 );\r
+                break;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Schedule callback invocation for non-waitable operation. */\r
+    if( waitable == false )\r
+    {\r
+        /* Non-waitable operation should have job reference of 1. */\r
+        IotMqtt_Assert( pOperation->u.operation.jobReference == 1 );\r
+\r
+        /* Schedule an invocation of the callback. */\r
+        if( pOperation->u.operation.notify.callback.function != NULL )\r
+        {\r
+            IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
+\r
+            status = _IotMqtt_ScheduleOperation( pOperation,\r
+                                                 _IotMqtt_ProcessCompletedOperation,\r
+                                                 0 );\r
+\r
+            if( status == IOT_MQTT_SUCCESS )\r
+            {\r
+                IotLogDebug( "(MQTT connection %p, %s operation %p) Callback scheduled.",\r
+                             pOperation->pMqttConnection,\r
+                             IotMqtt_OperationType( pOperation->u.operation.type ),\r
+                             pOperation );\r
+\r
+                /* Place the scheduled operation back in the list of operations pending\r
+                 * processing. */\r
+                if( IotLink_IsLinked( &( pOperation->link ) ) == true )\r
+                {\r
+                    IotListDouble_Remove( &( pOperation->link ) );\r
+                }\r
+                else\r
+                {\r
+                    EMPTY_ELSE_MARKER;\r
+                }\r
+\r
+                IotListDouble_InsertHead( &( pMqttConnection->pendingProcessing ),\r
+                                          &( pOperation->link ) );\r
+            }\r
+            else\r
+            {\r
+                IotLogWarn( "(MQTT connection %p, %s operation %p) Failed to schedule callback.",\r
+                            pOperation->pMqttConnection,\r
+                            IotMqtt_OperationType( pOperation->u.operation.type ),\r
+                            pOperation );\r
+            }\r
+\r
+            IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Operations that weren't scheduled may be destroyed. */\r
+    if( status == IOT_MQTT_SCHEDULING_ERROR )\r
+    {\r
+        /* Decrement reference count of operations not scheduled. */\r
+        if( _IotMqtt_DecrementOperationReferences( pOperation, false ) == true )\r
+        {\r
+            _IotMqtt_DestroyOperation( pOperation );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        /* Post to a waitable operation's semaphore. */\r
+        if( waitable == true )\r
+        {\r
+            IotLogDebug( "(MQTT connection %p, %s operation %p) Waitable operation "\r
+                         "notified of completion.",\r
+                         pOperation->pMqttConnection,\r
+                         IotMqtt_OperationType( pOperation->u.operation.type ),\r
+                         pOperation );\r
+\r
+            IotSemaphore_Post( &( pOperation->u.operation.notify.waitSemaphore ) );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        IotMqtt_Assert( status == IOT_MQTT_SUCCESS );\r
+    }\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_serialize.c b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_serialize.c
new file mode 100644 (file)
index 0000000..f42c80c
--- /dev/null
@@ -0,0 +1,1939 @@
+/*\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_serialize.c\r
+ * @brief Implements functions that generate and decode MQTT network packets.\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 includes. */\r
+#include "private/iot_mqtt_internal.h"\r
+\r
+/* Platform layer includes. */\r
+#include "platform/iot_threads.h"\r
+\r
+/* Atomic operations. */\r
+#include "iot_atomic.h"\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Macros for reading the high and low byte of a 2-byte unsigned int.\r
+ */\r
+#define UINT16_HIGH_BYTE( x )    ( ( uint8_t ) ( x >> 8 ) )            /**< @brief Get high byte. */\r
+#define UINT16_LOW_BYTE( x )     ( ( uint8_t ) ( x & 0x00ff ) )        /**< @brief Get low byte. */\r
+\r
+/**\r
+ * @brief Macro for decoding a 2-byte unsigned int from a sequence of bytes.\r
+ *\r
+ * @param[in] ptr A uint8_t* that points to the high byte.\r
+ */\r
+#define UINT16_DECODE( ptr )                                \\r
+    ( uint16_t ) ( ( ( ( uint16_t ) ( *( ptr ) ) ) << 8 ) | \\r
+                   ( ( uint16_t ) ( *( ptr + 1 ) ) ) )\r
+\r
+/**\r
+ * @brief Macro for setting a bit in a 1-byte unsigned int.\r
+ *\r
+ * @param[in] x The unsigned int to set.\r
+ * @param[in] position Which bit to set.\r
+ */\r
+#define UINT8_SET_BIT( x, position )      ( x = ( uint8_t ) ( x | ( 0x01 << position ) ) )\r
+\r
+/**\r
+ * @brief Macro for checking if a bit is set in a 1-byte unsigned int.\r
+ *\r
+ * @param[in] x The unsigned int to check.\r
+ * @param[in] position Which bit to check.\r
+ */\r
+#define UINT8_CHECK_BIT( x, position )    ( ( x & ( 0x01 << position ) ) == ( 0x01 << position ) )\r
+\r
+/*\r
+ * Positions of each flag in the "Connect Flag" field of an MQTT CONNECT\r
+ * packet.\r
+ */\r
+#define MQTT_CONNECT_FLAG_CLEAN                     ( 1 )  /**< @brief Clean session. */\r
+#define MQTT_CONNECT_FLAG_WILL                      ( 2 )  /**< @brief Will present. */\r
+#define MQTT_CONNECT_FLAG_WILL_QOS1                 ( 3 )  /**< @brief Will QoS1. */\r
+#define MQTT_CONNECT_FLAG_WILL_QOS2                 ( 4 )  /**< @brief Will QoS2. */\r
+#define MQTT_CONNECT_FLAG_WILL_RETAIN               ( 5 )  /**< @brief Will retain. */\r
+#define MQTT_CONNECT_FLAG_PASSWORD                  ( 6 )  /**< @brief Password present. */\r
+#define MQTT_CONNECT_FLAG_USERNAME                  ( 7 )  /**< @brief Username present. */\r
+\r
+/*\r
+ * Positions of each flag in the first byte of an MQTT PUBLISH packet's\r
+ * fixed header.\r
+ */\r
+#define MQTT_PUBLISH_FLAG_RETAIN                    ( 0 )  /**< @brief Message retain flag. */\r
+#define MQTT_PUBLISH_FLAG_QOS1                      ( 1 )  /**< @brief Publish QoS 1. */\r
+#define MQTT_PUBLISH_FLAG_QOS2                      ( 2 )  /**< @brief Publish QoS 2. */\r
+#define MQTT_PUBLISH_FLAG_DUP                       ( 3 )  /**< @brief Duplicate message. */\r
+\r
+/**\r
+ * @brief The constant specifying MQTT version 3.1.1. Placed in the CONNECT packet.\r
+ */\r
+#define MQTT_VERSION_3_1_1                          ( ( uint8_t ) 4U )\r
+\r
+/**\r
+ * @brief Per the MQTT 3.1.1 spec, the largest "Remaining Length" of an MQTT\r
+ * packet is this value.\r
+ */\r
+#define MQTT_MAX_REMAINING_LENGTH                   ( 268435455UL )\r
+\r
+/**\r
+ * @brief The maximum possible size of a CONNECT packet.\r
+ *\r
+ * All strings in a CONNECT packet are constrained to 2-byte lengths, giving a\r
+ * maximum length smaller than the max "Remaining Length" constant above.\r
+ */\r
+#define MQTT_PACKET_CONNECT_MAX_SIZE                ( 327700UL )\r
+\r
+/*\r
+ * Constants relating to CONNACK packets, defined by MQTT 3.1.1 spec.\r
+ */\r
+#define MQTT_PACKET_CONNACK_REMAINING_LENGTH        ( ( uint8_t ) 2 )    /**< @brief A CONNACK packet always has a "Remaining length" of 2. */\r
+#define MQTT_PACKET_CONNACK_SESSION_PRESENT_MASK    ( ( uint8_t ) 0x01 ) /**< @brief The "Session Present" bit is always the lowest bit. */\r
+\r
+/*\r
+ * Constants relating to PUBLISH and PUBACK packets, defined by MQTT\r
+ * 3.1.1 spec.\r
+ */\r
+#define MQTT_PACKET_PUBACK_SIZE                     ( 4 )               /**< @brief A PUBACK packet is always 4 bytes in size. */\r
+#define MQTT_PACKET_PUBACK_REMAINING_LENGTH         ( ( uint8_t ) 2 )   /**< @brief A PUBACK packet always has a "Remaining length" of 2. */\r
+\r
+/*\r
+ * Constants relating to SUBACK and UNSUBACK packets, defined by MQTT\r
+ * 3.1.1 spec.\r
+ */\r
+#define MQTT_PACKET_SUBACK_MINIMUM_SIZE             ( 5 )               /**< @brief The size of the smallest valid SUBACK packet. */\r
+#define MQTT_PACKET_UNSUBACK_REMAINING_LENGTH       ( ( uint8_t ) 2 )   /**< @brief An UNSUBACK packet always has a "Remaining length" of 2. */\r
+\r
+/*\r
+ * Constants relating to PINGREQ and PINGRESP packets, defined by MQTT 3.1.1 spec.\r
+ */\r
+#define MQTT_PACKET_PINGREQ_SIZE                    ( 2 ) /**< @brief A PINGREQ packet is always 2 bytes in size. */\r
+#define MQTT_PACKET_PINGRESP_REMAINING_LENGTH       ( 0 ) /**< @brief A PINGRESP packet always has a "Remaining length" of 0. */\r
+\r
+/*\r
+ * Constants relating to DISCONNECT packets, defined by MQTT 3.1.1 spec.\r
+ */\r
+#define MQTT_PACKET_DISCONNECT_SIZE                 ( 2 ) /**< @brief A DISCONNECT packet is always 2 bytes in size. */\r
+\r
+/* Username for metrics with AWS IoT. */\r
+#if AWS_IOT_MQTT_ENABLE_METRICS == 1 || DOXYGEN == 1\r
+    #ifndef AWS_IOT_METRICS_USERNAME\r
+\r
+/**\r
+ * @brief Specify C SDK and version.\r
+ */\r
+        #define AWS_IOT_METRICS_USERNAME           "?SDK=C&Version=4.0.0"\r
+\r
+/**\r
+ * @brief The length of #AWS_IOT_METRICS_USERNAME.\r
+ */\r
+        #define AWS_IOT_METRICS_USERNAME_LENGTH    ( ( uint16_t ) sizeof( AWS_IOT_METRICS_USERNAME ) - 1 )\r
+    #endif /* ifndef AWS_IOT_METRICS_USERNAME */\r
+#endif /* if AWS_IOT_MQTT_ENABLE_METRICS == 1 || DOXYGEN == 1 */\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/**\r
+ * @brief Generate and return a 2-byte packet identifier.\r
+ *\r
+ * This packet identifier will be nonzero.\r
+ *\r
+ * @return The packet identifier.\r
+ */\r
+static uint16_t _nextPacketIdentifier( void );\r
+\r
+/**\r
+ * @brief Calculate the number of bytes required to encode an MQTT\r
+ * "Remaining length" field.\r
+ *\r
+ * @param[in] length The value of the "Remaining length" to encode.\r
+ *\r
+ * @return The size of the encoding of length. This is always `1`, `2`, `3`, or `4`.\r
+ */\r
+static size_t _remainingLengthEncodedSize( size_t length );\r
+\r
+/**\r
+ * @brief Encode the "Remaining length" field per MQTT spec.\r
+ *\r
+ * @param[out] pDestination Where to write the encoded "Remaining length".\r
+ * @param[in] length The "Remaining length" to encode.\r
+ *\r
+ * @return Pointer to the end of the encoded "Remaining length", which is 1-4\r
+ * bytes greater than `pDestination`.\r
+ *\r
+ * @warning This function does not check the size of `pDestination`! Ensure that\r
+ * `pDestination` is large enough to hold the encoded "Remaining length" using\r
+ * the function #_remainingLengthEncodedSize to avoid buffer overflows.\r
+ */\r
+static uint8_t * _encodeRemainingLength( uint8_t * pDestination,\r
+                                         size_t length );\r
+\r
+/**\r
+ * @brief Encode a C string as a UTF-8 string, per MQTT 3.1.1 spec.\r
+ *\r
+ * @param[out] pDestination Where to write the encoded string.\r
+ * @param[in] source The string to encode.\r
+ * @param[in] sourceLength The length of source.\r
+ *\r
+ * @return Pointer to the end of the encoded string, which is `sourceLength+2`\r
+ * bytes greater than `pDestination`.\r
+ *\r
+ * @warning This function does not check the size of `pDestination`! Ensure that\r
+ * `pDestination` is large enough to hold `sourceLength+2` bytes to avoid a buffer\r
+ * overflow.\r
+ */\r
+static uint8_t * _encodeString( uint8_t * pDestination,\r
+                                const char * source,\r
+                                uint16_t sourceLength );\r
+\r
+/**\r
+ * @brief Calculate the size and "Remaining length" of a CONNECT packet generated\r
+ * from the given parameters.\r
+ *\r
+ * @param[in] pConnectInfo User-provided CONNECT information struct.\r
+ * @param[out] pRemainingLength Output for calculated "Remaining length" field.\r
+ * @param[out] pPacketSize Output for calculated total packet size.\r
+ *\r
+ * @return `true` if the packet is within the length allowed by MQTT 3.1.1 spec; `false`\r
+ * otherwise. If this function returns `false`, the output parameters should be ignored.\r
+ */\r
+static bool _connectPacketSize( const IotMqttConnectInfo_t * pConnectInfo,\r
+                                size_t * pRemainingLength,\r
+                                size_t * pPacketSize );\r
+\r
+/**\r
+ * @brief Calculate the size and "Remaining length" of a PUBLISH packet generated\r
+ * from the given parameters.\r
+ *\r
+ * @param[in] pPublishInfo User-provided PUBLISH information struct.\r
+ * @param[out] pRemainingLength Output for calculated "Remaining length" field.\r
+ * @param[out] pPacketSize Output for calculated total packet size.\r
+ *\r
+ * @return `true` if the packet is within the length allowed by MQTT 3.1.1 spec; `false`\r
+ * otherwise. If this function returns `false`, the output parameters should be ignored.\r
+ */\r
+static bool _publishPacketSize( const IotMqttPublishInfo_t * pPublishInfo,\r
+                                size_t * pRemainingLength,\r
+                                size_t * pPacketSize );\r
+\r
+/**\r
+ * @brief Calculate the size and "Remaining length" of a SUBSCRIBE or UNSUBSCRIBE\r
+ * packet generated from the given parameters.\r
+ *\r
+ * @param[in] type Either IOT_MQTT_SUBSCRIBE or IOT_MQTT_UNSUBSCRIBE.\r
+ * @param[in] pSubscriptionList User-provided array of subscriptions.\r
+ * @param[in] subscriptionCount Size of `pSubscriptionList`.\r
+ * @param[out] pRemainingLength Output for calculated "Remaining length" field.\r
+ * @param[out] pPacketSize Output for calculated total packet size.\r
+ *\r
+ * @return `true` if the packet is within the length allowed by MQTT 3.1.1 spec; `false`\r
+ * otherwise. If this function returns `false`, the output parameters should be ignored.\r
+ */\r
+static bool _subscriptionPacketSize( IotMqttOperationType_t type,\r
+                                     const IotMqttSubscription_t * pSubscriptionList,\r
+                                     size_t subscriptionCount,\r
+                                     size_t * pRemainingLength,\r
+                                     size_t * pPacketSize );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+#if LIBRARY_LOG_LEVEL > IOT_LOG_NONE\r
+\r
+/**\r
+ * @brief If logging is enabled, define a log configuration that only prints the log\r
+ * string. This is used when printing out details of deserialized MQTT packets.\r
+ */\r
+    static const IotLogConfig_t _logHideAll =\r
+    {\r
+        .hideLibraryName = true,\r
+        .hideLogLevel    = true,\r
+        .hideTimestring  = true\r
+    };\r
+#endif\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static uint16_t _nextPacketIdentifier( void )\r
+{\r
+    /* MQTT specifies 2 bytes for the packet identifier; however, operating on\r
+     * 32-bit integers is generally faster. */\r
+    static uint32_t nextPacketIdentifier = 1;\r
+\r
+    /* The next packet identifier will be greater by 2. This prevents packet\r
+     * identifiers from ever being 0, which is not allowed by MQTT 3.1.1. Packet\r
+     * identifiers will follow the sequence 1,3,5...65535,1,3,5... */\r
+    return ( uint16_t ) Atomic_Add_u32( &nextPacketIdentifier, 2 );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static size_t _remainingLengthEncodedSize( size_t length )\r
+{\r
+    size_t encodedSize = 0;\r
+\r
+    /* length should have already been checked before calling this function. */\r
+    IotMqtt_Assert( length <= MQTT_MAX_REMAINING_LENGTH );\r
+\r
+    /* Determine how many bytes are needed to encode length.\r
+     * The values below are taken from the MQTT 3.1.1 spec. */\r
+\r
+    /* 1 byte is needed to encode lengths between 0 and 127. */\r
+    if( length < 128 )\r
+    {\r
+        encodedSize = 1;\r
+    }\r
+    /* 2 bytes are needed to encode lengths between 128 and 16,383. */\r
+    else if( length < 16384 )\r
+    {\r
+        encodedSize = 2;\r
+    }\r
+    /* 3 bytes are needed to encode lengths between 16,384 and 2,097,151. */\r
+    else if( length < 2097152 )\r
+    {\r
+        encodedSize = 3;\r
+    }\r
+    /* 4 bytes are needed to encode lengths between 2,097,152 and 268,435,455. */\r
+    else\r
+    {\r
+        encodedSize = 4;\r
+    }\r
+\r
+    return encodedSize;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static uint8_t * _encodeRemainingLength( uint8_t * pDestination,\r
+                                         size_t length )\r
+{\r
+    uint8_t lengthByte = 0, * pLengthEnd = pDestination;\r
+\r
+    /* This algorithm is copied from the MQTT v3.1.1 spec. */\r
+    do\r
+    {\r
+        lengthByte = length % 128;\r
+        length = length / 128;\r
+\r
+        /* Set the high bit of this byte, indicating that there's more data. */\r
+        if( length > 0 )\r
+        {\r
+            UINT8_SET_BIT( lengthByte, 7 );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        /* Output a single encoded byte. */\r
+        *pLengthEnd = lengthByte;\r
+        pLengthEnd++;\r
+    } while( length > 0 );\r
+\r
+    return pLengthEnd;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static uint8_t * _encodeString( uint8_t * pDestination,\r
+                                const char * source,\r
+                                uint16_t sourceLength )\r
+{\r
+    /* The first byte of a UTF-8 string is the high byte of the string length. */\r
+    *pDestination = UINT16_HIGH_BYTE( sourceLength );\r
+    pDestination++;\r
+\r
+    /* The second byte of a UTF-8 string is the low byte of the string length. */\r
+    *pDestination = UINT16_LOW_BYTE( sourceLength );\r
+    pDestination++;\r
+\r
+    /* Copy the string into pDestination. */\r
+    ( void ) memcpy( pDestination, source, sourceLength );\r
+\r
+    /* Return the pointer to the end of the encoded string. */\r
+    pDestination += sourceLength;\r
+\r
+    return pDestination;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static bool _connectPacketSize( const IotMqttConnectInfo_t * pConnectInfo,\r
+                                size_t * pRemainingLength,\r
+                                size_t * pPacketSize )\r
+{\r
+    bool status = true;\r
+    size_t connectPacketSize = 0, remainingLength = 0;\r
+\r
+    /* The CONNECT packet will always include a 10-byte variable header. */\r
+    connectPacketSize += 10U;\r
+\r
+    /* Add the length of the client identifier if provided. */\r
+    if( pConnectInfo->clientIdentifierLength > 0 )\r
+    {\r
+        connectPacketSize += pConnectInfo->clientIdentifierLength + sizeof( uint16_t );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Add the lengths of the will message and topic name if provided. */\r
+    if( pConnectInfo->pWillInfo != NULL )\r
+    {\r
+        connectPacketSize += pConnectInfo->pWillInfo->topicNameLength + sizeof( uint16_t ) +\r
+                             pConnectInfo->pWillInfo->payloadLength + sizeof( uint16_t );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Depending on the status of metrics, add the length of the metrics username\r
+     * or the user-provided username. */\r
+    if( pConnectInfo->awsIotMqttMode == true )\r
+    {\r
+        #if AWS_IOT_MQTT_ENABLE_METRICS == 1\r
+            connectPacketSize += AWS_IOT_METRICS_USERNAME_LENGTH + sizeof( uint16_t );\r
+        #endif\r
+    }\r
+    else\r
+    {\r
+        /* Add the lengths of the username and password if provided and not\r
+         * connecting to an AWS IoT MQTT server. */\r
+        if( pConnectInfo->pUserName != NULL )\r
+        {\r
+            connectPacketSize += pConnectInfo->userNameLength + sizeof( uint16_t );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        if( pConnectInfo->pPassword != NULL )\r
+        {\r
+            connectPacketSize += pConnectInfo->passwordLength + sizeof( uint16_t );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+\r
+    /* At this point, the "Remaining Length" field of the MQTT CONNECT packet has\r
+     * been calculated. */\r
+    remainingLength = connectPacketSize;\r
+\r
+    /* Calculate the full size of the MQTT CONNECT packet by adding the size of\r
+     * the "Remaining Length" field plus 1 byte for the "Packet Type" field. */\r
+    connectPacketSize += 1 + _remainingLengthEncodedSize( connectPacketSize );\r
+\r
+    /* Check that the CONNECT packet is within the bounds of the MQTT spec. */\r
+    if( connectPacketSize > MQTT_PACKET_CONNECT_MAX_SIZE )\r
+    {\r
+        status = false;\r
+    }\r
+    else\r
+    {\r
+        *pRemainingLength = remainingLength;\r
+        *pPacketSize = connectPacketSize;\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static bool _publishPacketSize( const IotMqttPublishInfo_t * pPublishInfo,\r
+                                size_t * pRemainingLength,\r
+                                size_t * pPacketSize )\r
+{\r
+    bool status = true;\r
+    size_t publishPacketSize = 0, payloadLimit = 0;\r
+\r
+    /* The variable header of a PUBLISH packet always contains the topic name. */\r
+    publishPacketSize += pPublishInfo->topicNameLength + sizeof( uint16_t );\r
+\r
+    /* The variable header of a QoS 1 or 2 PUBLISH packet contains a 2-byte\r
+     * packet identifier. */\r
+    if( pPublishInfo->qos > IOT_MQTT_QOS_0 )\r
+    {\r
+        publishPacketSize += sizeof( uint16_t );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Calculate the maximum allowed size of the payload for the given parameters.\r
+     * This calculation excludes the "Remaining length" encoding, whose size is not\r
+     * yet known. */\r
+    payloadLimit = MQTT_MAX_REMAINING_LENGTH - publishPacketSize - 1;\r
+\r
+    /* Ensure that the given payload fits within the calculated limit. */\r
+    if( pPublishInfo->payloadLength > payloadLimit )\r
+    {\r
+        status = false;\r
+    }\r
+    else\r
+    {\r
+        /* Add the length of the PUBLISH payload. At this point, the "Remaining length"\r
+         * has been calculated. */\r
+        publishPacketSize += pPublishInfo->payloadLength;\r
+\r
+        /* Now that the "Remaining length" is known, recalculate the payload limit\r
+         * based on the size of its encoding. */\r
+        payloadLimit -= _remainingLengthEncodedSize( publishPacketSize );\r
+\r
+        /* Check that the given payload fits within the size allowed by MQTT spec. */\r
+        if( pPublishInfo->payloadLength > payloadLimit )\r
+        {\r
+            status = false;\r
+        }\r
+        else\r
+        {\r
+            /* Set the "Remaining length" output parameter and calculate the full\r
+             * size of the PUBLISH packet. */\r
+            *pRemainingLength = publishPacketSize;\r
+\r
+            publishPacketSize += 1 + _remainingLengthEncodedSize( publishPacketSize );\r
+            *pPacketSize = publishPacketSize;\r
+        }\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static bool _subscriptionPacketSize( IotMqttOperationType_t type,\r
+                                     const IotMqttSubscription_t * pSubscriptionList,\r
+                                     size_t subscriptionCount,\r
+                                     size_t * pRemainingLength,\r
+                                     size_t * pPacketSize )\r
+{\r
+    bool status = true;\r
+    size_t i = 0, subscriptionPacketSize = 0;\r
+\r
+    /* Only SUBSCRIBE and UNSUBSCRIBE operations should call this function. */\r
+    IotMqtt_Assert( ( type == IOT_MQTT_SUBSCRIBE ) || ( type == IOT_MQTT_UNSUBSCRIBE ) );\r
+\r
+    /* The variable header of a subscription packet consists of a 2-byte packet\r
+     * identifier. */\r
+    subscriptionPacketSize += sizeof( uint16_t );\r
+\r
+    /* Sum the lengths of all subscription topic filters; add 1 byte for each\r
+     * subscription's QoS if type is IOT_MQTT_SUBSCRIBE. */\r
+    for( i = 0; i < subscriptionCount; i++ )\r
+    {\r
+        /* Add the length of the topic filter. */\r
+        subscriptionPacketSize += pSubscriptionList[ i ].topicFilterLength + sizeof( uint16_t );\r
+\r
+        /* Only SUBSCRIBE packets include the QoS. */\r
+        if( type == IOT_MQTT_SUBSCRIBE )\r
+        {\r
+            subscriptionPacketSize += 1;\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+\r
+    /* At this point, the "Remaining length" has been calculated. Return error\r
+     * if the "Remaining length" exceeds what is allowed by MQTT 3.1.1. Otherwise,\r
+     * set the output parameter.*/\r
+    if( subscriptionPacketSize > MQTT_MAX_REMAINING_LENGTH )\r
+    {\r
+        status = false;\r
+    }\r
+    else\r
+    {\r
+        *pRemainingLength = subscriptionPacketSize;\r
+\r
+        /* Calculate the full size of the subscription packet by adding the size of the\r
+         * "Remaining length" field plus 1 byte for the "Packet type" field. Set the\r
+         * pPacketSize output parameter. */\r
+        subscriptionPacketSize += 1 + _remainingLengthEncodedSize( subscriptionPacketSize );\r
+        *pPacketSize = subscriptionPacketSize;\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+uint8_t _IotMqtt_GetPacketType( void * pNetworkConnection,\r
+                                const IotNetworkInterface_t * pNetworkInterface )\r
+{\r
+    uint8_t packetType = 0xff;\r
+\r
+    /* The MQTT packet type is in the first byte of the packet. */\r
+    ( void ) _IotMqtt_GetNextByte( pNetworkConnection,\r
+                                   pNetworkInterface,\r
+                                   &packetType );\r
+\r
+    return packetType;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+size_t _IotMqtt_GetRemainingLength( void * pNetworkConnection,\r
+                                    const IotNetworkInterface_t * pNetworkInterface )\r
+{\r
+    uint8_t encodedByte = 0;\r
+    size_t remainingLength = 0, multiplier = 1, bytesDecoded = 0, expectedSize = 0;\r
+\r
+    /* This algorithm is copied from the MQTT v3.1.1 spec. */\r
+    do\r
+    {\r
+        if( multiplier > 2097152 ) /* 128 ^ 3 */\r
+        {\r
+            remainingLength = MQTT_REMAINING_LENGTH_INVALID;\r
+            break;\r
+        }\r
+        else\r
+        {\r
+            if( _IotMqtt_GetNextByte( pNetworkConnection,\r
+                                      pNetworkInterface,\r
+                                      &encodedByte ) == true )\r
+            {\r
+                remainingLength += ( encodedByte & 0x7F ) * multiplier;\r
+                multiplier *= 128;\r
+                bytesDecoded++;\r
+            }\r
+            else\r
+            {\r
+                remainingLength = MQTT_REMAINING_LENGTH_INVALID;\r
+                break;\r
+            }\r
+        }\r
+    } while( ( encodedByte & 0x80 ) != 0 );\r
+\r
+    /* Check that the decoded remaining length conforms to the MQTT specification. */\r
+    if( remainingLength != MQTT_REMAINING_LENGTH_INVALID )\r
+    {\r
+        expectedSize = _remainingLengthEncodedSize( remainingLength );\r
+\r
+        if( bytesDecoded != expectedSize )\r
+        {\r
+            remainingLength = MQTT_REMAINING_LENGTH_INVALID;\r
+        }\r
+        else\r
+        {\r
+            /* Valid remaining length should be at most 4 bytes. */\r
+            IotMqtt_Assert( bytesDecoded <= 4 );\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    return remainingLength;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t _IotMqtt_SerializeConnect( const IotMqttConnectInfo_t * pConnectInfo,\r
+                                          uint8_t ** pConnectPacket,\r
+                                          size_t * pPacketSize )\r
+{\r
+    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
+    uint8_t connectFlags = 0;\r
+    size_t remainingLength = 0, connectPacketSize = 0;\r
+    uint8_t * pBuffer = NULL;\r
+\r
+    /* Calculate the "Remaining length" field and total packet size. If it exceeds\r
+     * what is allowed in the MQTT standard, return an error. */\r
+    if( _connectPacketSize( pConnectInfo, &remainingLength, &connectPacketSize ) == false )\r
+    {\r
+        IotLogError( "Connect packet length exceeds %lu, which is the maximum"\r
+                     " size allowed by MQTT 3.1.1.",\r
+                     MQTT_PACKET_CONNECT_MAX_SIZE );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Total size of the connect packet should be larger than the "Remaining length"\r
+     * field. */\r
+    IotMqtt_Assert( connectPacketSize > remainingLength );\r
+\r
+    /* Allocate memory to hold the CONNECT packet. */\r
+    pBuffer = IotMqtt_MallocMessage( connectPacketSize );\r
+\r
+    /* Check that sufficient memory was allocated. */\r
+    if( pBuffer == NULL )\r
+    {\r
+        IotLogError( "Failed to allocate memory for CONNECT packet." );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NO_MEMORY );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Set the output parameters. The remainder of this function always succeeds. */\r
+    *pConnectPacket = pBuffer;\r
+    *pPacketSize = connectPacketSize;\r
+\r
+    /* The first byte in the CONNECT packet is the control packet type. */\r
+    *pBuffer = MQTT_PACKET_TYPE_CONNECT;\r
+    pBuffer++;\r
+\r
+    /* The remaining length of the CONNECT packet is encoded starting from the\r
+     * second byte. The remaining length does not include the length of the fixed\r
+     * header or the encoding of the remaining length. */\r
+    pBuffer = _encodeRemainingLength( pBuffer, remainingLength );\r
+\r
+    /* The string "MQTT" is placed at the beginning of the CONNECT packet's variable\r
+     * header. This string is 4 bytes long. */\r
+    pBuffer = _encodeString( pBuffer, "MQTT", 4 );\r
+\r
+    /* The MQTT protocol version is the second byte of the variable header. */\r
+    *pBuffer = MQTT_VERSION_3_1_1;\r
+    pBuffer++;\r
+\r
+    /* Set the CONNECT flags based on the given parameters. */\r
+    if( pConnectInfo->cleanSession == true )\r
+    {\r
+        UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_CLEAN );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Username and password depend on MQTT mode. */\r
+    if( pConnectInfo->awsIotMqttMode == true )\r
+    {\r
+        /* Set the username flag for AWS IoT metrics. The AWS IoT MQTT server\r
+         * never uses a password. */\r
+        #if AWS_IOT_MQTT_ENABLE_METRICS == 1\r
+            UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_USERNAME );\r
+        #endif\r
+    }\r
+    else\r
+    {\r
+        /* Set the flags for username and password if provided. */\r
+        if( pConnectInfo->pUserName != NULL )\r
+        {\r
+            UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_USERNAME );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        if( pConnectInfo->pPassword != NULL )\r
+        {\r
+            UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_PASSWORD );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+\r
+    /* Set will flag if an LWT is provided. */\r
+    if( pConnectInfo->pWillInfo != NULL )\r
+    {\r
+        UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_WILL );\r
+\r
+        /* Flags only need to be changed for will QoS 1 and 2. */\r
+        switch( pConnectInfo->pWillInfo->qos )\r
+        {\r
+            case IOT_MQTT_QOS_1:\r
+                UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_WILL_QOS1 );\r
+                break;\r
+\r
+            case IOT_MQTT_QOS_2:\r
+                UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_WILL_QOS2 );\r
+                break;\r
+\r
+            default:\r
+                break;\r
+        }\r
+\r
+        if( pConnectInfo->pWillInfo->retain == true )\r
+        {\r
+            UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_WILL_RETAIN );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    *pBuffer = connectFlags;\r
+    pBuffer++;\r
+\r
+    /* Write the 2 bytes of the keep alive interval into the CONNECT packet. */\r
+    *pBuffer = UINT16_HIGH_BYTE( pConnectInfo->keepAliveSeconds );\r
+    *( pBuffer + 1 ) = UINT16_LOW_BYTE( pConnectInfo->keepAliveSeconds );\r
+    pBuffer += 2;\r
+\r
+    /* Write the client identifier into the CONNECT packet. */\r
+    pBuffer = _encodeString( pBuffer,\r
+                             pConnectInfo->pClientIdentifier,\r
+                             pConnectInfo->clientIdentifierLength );\r
+\r
+    /* Write the will topic name and message into the CONNECT packet if provided. */\r
+    if( pConnectInfo->pWillInfo != NULL )\r
+    {\r
+        pBuffer = _encodeString( pBuffer,\r
+                                 pConnectInfo->pWillInfo->pTopicName,\r
+                                 pConnectInfo->pWillInfo->topicNameLength );\r
+\r
+        pBuffer = _encodeString( pBuffer,\r
+                                 pConnectInfo->pWillInfo->pPayload,\r
+                                 ( uint16_t ) pConnectInfo->pWillInfo->payloadLength );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* If metrics are enabled, write the metrics username into the CONNECT packet.\r
+     * Otherwise, write the username and password only when not connecting to an\r
+     * AWS IoT MQTT server. */\r
+    if( pConnectInfo->awsIotMqttMode == true )\r
+    {\r
+        #if AWS_IOT_MQTT_ENABLE_METRICS == 1\r
+            IotLogInfo( "Anonymous metrics (SDK language, SDK version) will be provided to AWS IoT. "\r
+                        "Recompile with AWS_IOT_MQTT_ENABLE_METRICS set to 0 to disable." );\r
+\r
+            pBuffer = _encodeString( pBuffer,\r
+                                     AWS_IOT_METRICS_USERNAME,\r
+                                     AWS_IOT_METRICS_USERNAME_LENGTH );\r
+        #endif\r
+    }\r
+    else\r
+    {\r
+        if( pConnectInfo->pUserName != NULL )\r
+        {\r
+            pBuffer = _encodeString( pBuffer,\r
+                                     pConnectInfo->pUserName,\r
+                                     pConnectInfo->userNameLength );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        if( pConnectInfo->pPassword != NULL )\r
+        {\r
+            pBuffer = _encodeString( pBuffer,\r
+                                     pConnectInfo->pPassword,\r
+                                     pConnectInfo->passwordLength );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+\r
+    /* Ensure that the difference between the end and beginning of the buffer\r
+     * is equal to connectPacketSize, i.e. pBuffer did not overflow. */\r
+    IotMqtt_Assert( ( size_t ) ( pBuffer - *pConnectPacket ) == connectPacketSize );\r
+\r
+    /* Print out the serialized CONNECT packet for debugging purposes. */\r
+    IotLog_PrintBuffer( "MQTT CONNECT packet:", *pConnectPacket, connectPacketSize );\r
+\r
+    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t _IotMqtt_DeserializeConnack( _mqttPacket_t * pConnack )\r
+{\r
+    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
+    const uint8_t * pRemainingData = pConnack->pRemainingData;\r
+\r
+    /* If logging is enabled, declare the CONNACK response code strings. The\r
+     * fourth byte of CONNACK indexes into this array for the corresponding response. */\r
+    #if LIBRARY_LOG_LEVEL > IOT_LOG_NONE\r
+        static const char * pConnackResponses[ 6 ] =\r
+        {\r
+            "Connection accepted.",                               /* 0 */\r
+            "Connection refused: unacceptable protocol version.", /* 1 */\r
+            "Connection refused: identifier rejected.",           /* 2 */\r
+            "Connection refused: server unavailable",             /* 3 */\r
+            "Connection refused: bad user name or password.",     /* 4 */\r
+            "Connection refused: not authorized."                 /* 5 */\r
+        };\r
+    #endif\r
+\r
+    /* Check that the control packet type is 0x20. */\r
+    if( pConnack->type != MQTT_PACKET_TYPE_CONNACK )\r
+    {\r
+        IotLog( IOT_LOG_ERROR,\r
+                &_logHideAll,\r
+                "Bad control packet type 0x%02x.",\r
+                pConnack->type );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* According to MQTT 3.1.1, the second byte of CONNACK must specify a\r
+     * "Remaining length" of 2. */\r
+    if( pConnack->remainingLength != MQTT_PACKET_CONNACK_REMAINING_LENGTH )\r
+    {\r
+        IotLog( IOT_LOG_ERROR,\r
+                &_logHideAll,\r
+                "CONNACK does not have remaining length of %d.",\r
+                MQTT_PACKET_CONNACK_REMAINING_LENGTH );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Check the reserved bits in CONNACK. The high 7 bits of the second byte\r
+     * in CONNACK must be 0. */\r
+    if( ( pRemainingData[ 0 ] | 0x01 ) != 0x01 )\r
+    {\r
+        IotLog( IOT_LOG_ERROR,\r
+                &_logHideAll,\r
+                "Reserved bits in CONNACK incorrect." );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Determine if the "Session Present" bit it set. This is the lowest bit of\r
+     * the second byte in CONNACK. */\r
+    if( ( pRemainingData[ 0 ] & MQTT_PACKET_CONNACK_SESSION_PRESENT_MASK )\r
+        == MQTT_PACKET_CONNACK_SESSION_PRESENT_MASK )\r
+    {\r
+        IotLog( IOT_LOG_DEBUG,\r
+                &_logHideAll,\r
+                "CONNACK session present bit set." );\r
+\r
+        /* MQTT 3.1.1 specifies that the fourth byte in CONNACK must be 0 if the\r
+         * "Session Present" bit is set. */\r
+        if( pRemainingData[ 1 ] != 0 )\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
+        IotLog( IOT_LOG_DEBUG,\r
+                &_logHideAll,\r
+                "CONNACK session present bit not set." );\r
+    }\r
+\r
+    /* In MQTT 3.1.1, only values 0 through 5 are valid CONNACK response codes. */\r
+    if( pRemainingData[ 1 ] > 5 )\r
+    {\r
+        IotLog( IOT_LOG_DEBUG,\r
+                &_logHideAll,\r
+                "CONNACK response %hhu is not valid.",\r
+                pRemainingData[ 1 ] );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Print the appropriate message for the CONNACK response code if logs are\r
+     * enabled. */\r
+    #if LIBRARY_LOG_LEVEL > IOT_LOG_NONE\r
+        IotLog( IOT_LOG_DEBUG,\r
+                &_logHideAll,\r
+                "%s",\r
+                pConnackResponses[ pRemainingData[ 1 ] ] );\r
+    #endif\r
+\r
+    /* A nonzero CONNACK response code means the connection was refused. */\r
+    if( pRemainingData[ 1 ] > 0 )\r
+    {\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_SERVER_REFUSED );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t _IotMqtt_SerializePublish( const IotMqttPublishInfo_t * pPublishInfo,\r
+                                          uint8_t ** pPublishPacket,\r
+                                          size_t * pPacketSize,\r
+                                          uint16_t * pPacketIdentifier,\r
+                                          uint8_t ** pPacketIdentifierHigh )\r
+{\r
+    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
+    uint8_t publishFlags = 0;\r
+    uint16_t packetIdentifier = 0;\r
+    size_t remainingLength = 0, publishPacketSize = 0;\r
+    uint8_t * pBuffer = NULL;\r
+\r
+    /* Calculate the "Remaining length" field and total packet size. If it exceeds\r
+     * what is allowed in the MQTT standard, return an error. */\r
+    if( _publishPacketSize( pPublishInfo, &remainingLength, &publishPacketSize ) == false )\r
+    {\r
+        IotLogError( "Publish packet remaining length exceeds %lu, which is the "\r
+                     "maximum size allowed by MQTT 3.1.1.",\r
+                     MQTT_MAX_REMAINING_LENGTH );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Total size of the publish packet should be larger than the "Remaining length"\r
+     * field. */\r
+    IotMqtt_Assert( publishPacketSize > remainingLength );\r
+\r
+    /* Allocate memory to hold the PUBLISH packet. */\r
+    pBuffer = IotMqtt_MallocMessage( publishPacketSize );\r
+\r
+    /* Check that sufficient memory was allocated. */\r
+    if( pBuffer == NULL )\r
+    {\r
+        IotLogError( "Failed to allocate memory for PUBLISH packet." );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NO_MEMORY );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Set the output parameters. The remainder of this function always succeeds. */\r
+    *pPublishPacket = pBuffer;\r
+    *pPacketSize = publishPacketSize;\r
+\r
+    /* The first byte of a PUBLISH packet contains the packet type and flags. */\r
+    publishFlags = MQTT_PACKET_TYPE_PUBLISH;\r
+\r
+    if( pPublishInfo->qos == IOT_MQTT_QOS_1 )\r
+    {\r
+        UINT8_SET_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS1 );\r
+    }\r
+    else if( pPublishInfo->qos == IOT_MQTT_QOS_2 )\r
+    {\r
+        UINT8_SET_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS2 );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    if( pPublishInfo->retain == true )\r
+    {\r
+        UINT8_SET_BIT( publishFlags, MQTT_PUBLISH_FLAG_RETAIN );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    *pBuffer = publishFlags;\r
+    pBuffer++;\r
+\r
+    /* The "Remaining length" is encoded from the second byte. */\r
+    pBuffer = _encodeRemainingLength( pBuffer, remainingLength );\r
+\r
+    /* The topic name is placed after the "Remaining length". */\r
+    pBuffer = _encodeString( pBuffer,\r
+                             pPublishInfo->pTopicName,\r
+                             pPublishInfo->topicNameLength );\r
+\r
+    /* A packet identifier is required for QoS 1 and 2 messages. */\r
+    if( pPublishInfo->qos > IOT_MQTT_QOS_0 )\r
+    {\r
+        /* Get the next packet identifier. It should always be nonzero. */\r
+        packetIdentifier = _nextPacketIdentifier();\r
+        IotMqtt_Assert( packetIdentifier != 0 );\r
+\r
+        /* Set the packet identifier output parameters. */\r
+        *pPacketIdentifier = packetIdentifier;\r
+\r
+        if( pPacketIdentifierHigh != NULL )\r
+        {\r
+            *pPacketIdentifierHigh = pBuffer;\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        /* Place the packet identifier into the PUBLISH packet. */\r
+        *pBuffer = UINT16_HIGH_BYTE( packetIdentifier );\r
+        *( pBuffer + 1 ) = UINT16_LOW_BYTE( packetIdentifier );\r
+        pBuffer += 2;\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* The payload is placed after the packet identifier. */\r
+    if( pPublishInfo->payloadLength > 0 )\r
+    {\r
+        ( void ) memcpy( pBuffer, pPublishInfo->pPayload, pPublishInfo->payloadLength );\r
+        pBuffer += pPublishInfo->payloadLength;\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Ensure that the difference between the end and beginning of the buffer\r
+     * is equal to publishPacketSize, i.e. pBuffer did not overflow. */\r
+    IotMqtt_Assert( ( size_t ) ( pBuffer - *pPublishPacket ) == publishPacketSize );\r
+\r
+    /* Print out the serialized PUBLISH packet for debugging purposes. */\r
+    IotLog_PrintBuffer( "MQTT PUBLISH packet:", *pPublishPacket, publishPacketSize );\r
+\r
+    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void _IotMqtt_PublishSetDup( uint8_t * pPublishPacket,\r
+                             uint8_t * pPacketIdentifierHigh,\r
+                             uint16_t * pNewPacketIdentifier )\r
+{\r
+    uint16_t newPacketIdentifier = 0;\r
+\r
+    /* For an AWS IoT MQTT server, change the packet identifier. */\r
+    if( pPacketIdentifierHigh != NULL )\r
+    {\r
+        /* Output parameter for new packet identifier must be provided. */\r
+        IotMqtt_Assert( pNewPacketIdentifier != NULL );\r
+\r
+        /* Generate a new packet identifier. */\r
+        newPacketIdentifier = _nextPacketIdentifier();\r
+\r
+        IotLogDebug( "Changing PUBLISH packet identifier %hu to %hu.",\r
+                     UINT16_DECODE( pPacketIdentifierHigh ),\r
+                     newPacketIdentifier );\r
+\r
+        /* Replace the packet identifier. */\r
+        *pPacketIdentifierHigh = UINT16_HIGH_BYTE( newPacketIdentifier );\r
+        *( pPacketIdentifierHigh + 1 ) = UINT16_LOW_BYTE( newPacketIdentifier );\r
+        *pNewPacketIdentifier = newPacketIdentifier;\r
+    }\r
+    else\r
+    {\r
+        /* For a compliant MQTT 3.1.1 server, set the DUP flag. */\r
+        UINT8_SET_BIT( *pPublishPacket, MQTT_PUBLISH_FLAG_DUP );\r
+\r
+        IotLogDebug( "PUBLISH DUP flag set." );\r
+    }\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t _IotMqtt_DeserializePublish( _mqttPacket_t * pPublish )\r
+{\r
+    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
+    IotMqttPublishInfo_t * pOutput = &( pPublish->u.pIncomingPublish->u.publish.publishInfo );\r
+    uint8_t publishFlags = 0;\r
+    const uint8_t * pVariableHeader = pPublish->pRemainingData, * pPacketIdentifierHigh = NULL;\r
+\r
+    /* The flags are the lower 4 bits of the first byte in PUBLISH. */\r
+    publishFlags = pPublish->type;\r
+\r
+    /* Parse the Retain bit. */\r
+    pOutput->retain = UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_RETAIN );\r
+\r
+    IotLog( IOT_LOG_DEBUG,\r
+            &_logHideAll,\r
+            "Retain bit is %d.", pOutput->retain );\r
+\r
+    /* Check for QoS 2. */\r
+    if( UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS2 ) == true )\r
+    {\r
+        /* PUBLISH packet is invalid if both QoS 1 and QoS 2 bits are set. */\r
+        if( UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS1 ) == true )\r
+        {\r
+            IotLog( IOT_LOG_DEBUG,\r
+                    &_logHideAll,\r
+                    "Bad QoS: 3." );\r
+\r
+            IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        pOutput->qos = IOT_MQTT_QOS_2;\r
+    }\r
+    /* Check for QoS 1. */\r
+    else if( UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS1 ) == true )\r
+    {\r
+        pOutput->qos = IOT_MQTT_QOS_1;\r
+    }\r
+    /* If the PUBLISH isn't QoS 1 or 2, then it's QoS 0. */\r
+    else\r
+    {\r
+        pOutput->qos = IOT_MQTT_QOS_0;\r
+    }\r
+\r
+    IotLog( IOT_LOG_DEBUG,\r
+            &_logHideAll,\r
+            "QoS is %d.", pOutput->qos );\r
+\r
+    /* Parse the DUP bit. */\r
+    if( UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_DUP ) == true )\r
+    {\r
+        IotLog( IOT_LOG_DEBUG,\r
+                &_logHideAll,\r
+                "DUP is 1." );\r
+    }\r
+    else\r
+    {\r
+        IotLog( IOT_LOG_DEBUG,\r
+                &_logHideAll,\r
+                "DUP is 0." );\r
+    }\r
+\r
+    /* Sanity checks for "Remaining length". */\r
+    if( pOutput->qos == IOT_MQTT_QOS_0 )\r
+    {\r
+        /* A QoS 0 PUBLISH must have a remaining length of at least 3 to accommodate\r
+         * topic name length (2 bytes) and topic name (at least 1 byte). */\r
+        if( pPublish->remainingLength < 3 )\r
+        {\r
+            IotLog( IOT_LOG_DEBUG,\r
+                    &_logHideAll,\r
+                    "QoS 0 PUBLISH cannot have a remaining length less than 3." );\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
+        /* A QoS 1 or 2 PUBLISH must have a remaining length of at least 5 to\r
+         * accommodate a packet identifier as well as the topic name length and\r
+         * topic name. */\r
+        if( pPublish->remainingLength < 5 )\r
+        {\r
+            IotLog( IOT_LOG_DEBUG,\r
+                    &_logHideAll,\r
+                    "QoS 1 or 2 PUBLISH cannot have a remaining length less than 5." );\r
+\r
+            IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+\r
+    /* Extract the topic name starting from the first byte of the variable header.\r
+     * The topic name string starts at byte 3 in the variable header. */\r
+    pOutput->topicNameLength = UINT16_DECODE( pVariableHeader );\r
+\r
+    /* Sanity checks for topic name length and "Remaining length". */\r
+    if( pOutput->qos == IOT_MQTT_QOS_0 )\r
+    {\r
+        /* Check that the "Remaining length" is at least as large as the variable\r
+         * header. */\r
+        if( pPublish->remainingLength < pOutput->topicNameLength + sizeof( uint16_t ) )\r
+        {\r
+            IotLog( IOT_LOG_DEBUG,\r
+                    &_logHideAll,\r
+                    "Remaining length cannot be less than variable header length." );\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
+        /* Check that the "Remaining length" is at least as large as the variable\r
+         * header. */\r
+        if( pPublish->remainingLength < pOutput->topicNameLength + 2 * sizeof( uint16_t ) )\r
+        {\r
+            IotLog( IOT_LOG_DEBUG,\r
+                    &_logHideAll,\r
+                    "Remaining length cannot be less than variable header length." );\r
+\r
+            IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+\r
+    /* Parse the topic. */\r
+    pOutput->pTopicName = ( const char * ) ( pVariableHeader + sizeof( uint16_t ) );\r
+\r
+    IotLog( IOT_LOG_DEBUG,\r
+            &_logHideAll,\r
+            "Topic name length %hu: %.*s",\r
+            pOutput->topicNameLength,\r
+            pOutput->topicNameLength,\r
+            pOutput->pTopicName );\r
+\r
+    /* Extract the packet identifier for QoS 1 or 2 PUBLISH packets. Packet\r
+     * identifier starts immediately after the topic name. */\r
+    pPacketIdentifierHigh = ( const uint8_t * ) ( pOutput->pTopicName + pOutput->topicNameLength );\r
+\r
+    if( pOutput->qos > IOT_MQTT_QOS_0 )\r
+    {\r
+        pPublish->packetIdentifier = UINT16_DECODE( pPacketIdentifierHigh );\r
+\r
+        IotLog( IOT_LOG_DEBUG,\r
+                &_logHideAll,\r
+                "Packet identifier %hu.", pPublish->packetIdentifier );\r
+\r
+        /* Packet identifier cannot be 0. */\r
+        if( pPublish->packetIdentifier == 0 )\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
+    /* Calculate the length of the payload. QoS 1 or 2 PUBLISH packets contain\r
+     * a packet identifer, but QoS 0 PUBLISH packets do not. */\r
+    if( pOutput->qos == IOT_MQTT_QOS_0 )\r
+    {\r
+        pOutput->payloadLength = ( uint16_t ) ( pPublish->remainingLength - pOutput->topicNameLength - sizeof( uint16_t ) );\r
+        pOutput->pPayload = pPacketIdentifierHigh;\r
+    }\r
+    else\r
+    {\r
+        pOutput->payloadLength = ( uint16_t ) ( pPublish->remainingLength - pOutput->topicNameLength - 2 * sizeof( uint16_t ) );\r
+        pOutput->pPayload = pPacketIdentifierHigh + sizeof( uint16_t );\r
+    }\r
+\r
+    IotLog( IOT_LOG_DEBUG,\r
+            &_logHideAll,\r
+            "Payload length %hu.", pOutput->payloadLength );\r
+\r
+    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t _IotMqtt_SerializePuback( uint16_t packetIdentifier,\r
+                                         uint8_t ** pPubackPacket,\r
+                                         size_t * pPacketSize )\r
+{\r
+    IotMqttError_t status = IOT_MQTT_SUCCESS;\r
+\r
+    /* Allocate memory for PUBACK. */\r
+    uint8_t * pBuffer = IotMqtt_MallocMessage( MQTT_PACKET_PUBACK_SIZE );\r
+\r
+    if( pBuffer == NULL )\r
+    {\r
+        IotLogError( "Failed to allocate memory for PUBACK packet" );\r
+\r
+        status = IOT_MQTT_NO_MEMORY;\r
+    }\r
+    else\r
+    {\r
+        /* Set the output parameters. The remainder of this function always succeeds. */\r
+        *pPubackPacket = pBuffer;\r
+        *pPacketSize = MQTT_PACKET_PUBACK_SIZE;\r
+\r
+        /* Set the 4 bytes in PUBACK. */\r
+        pBuffer[ 0 ] = MQTT_PACKET_TYPE_PUBACK;\r
+        pBuffer[ 1 ] = MQTT_PACKET_PUBACK_REMAINING_LENGTH;\r
+        pBuffer[ 2 ] = UINT16_HIGH_BYTE( packetIdentifier );\r
+        pBuffer[ 3 ] = UINT16_LOW_BYTE( packetIdentifier );\r
+\r
+        /* Print out the serialized PUBACK packet for debugging purposes. */\r
+        IotLog_PrintBuffer( "MQTT PUBACK packet:", *pPubackPacket, MQTT_PACKET_PUBACK_SIZE );\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t _IotMqtt_DeserializePuback( _mqttPacket_t * pPuback )\r
+{\r
+    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
+\r
+    /* Check the "Remaining length" of the received PUBACK. */\r
+    if( pPuback->remainingLength != MQTT_PACKET_PUBACK_REMAINING_LENGTH )\r
+    {\r
+        IotLog( IOT_LOG_ERROR,\r
+                &_logHideAll,\r
+                "PUBACK does not have remaining length of %d.",\r
+                MQTT_PACKET_PUBACK_REMAINING_LENGTH );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Extract the packet identifier (third and fourth bytes) from PUBACK. */\r
+    pPuback->packetIdentifier = UINT16_DECODE( pPuback->pRemainingData );\r
+\r
+    IotLog( IOT_LOG_DEBUG,\r
+            &_logHideAll,\r
+            "Packet identifier %hu.", pPuback->packetIdentifier );\r
+\r
+    /* Packet identifier cannot be 0. */\r
+    if( pPuback->packetIdentifier == 0 )\r
+    {\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Check that the control packet type is 0x40 (this must be done after the\r
+     * packet identifier is parsed). */\r
+    if( pPuback->type != MQTT_PACKET_TYPE_PUBACK )\r
+    {\r
+        IotLog( IOT_LOG_ERROR,\r
+                &_logHideAll,\r
+                "Bad control packet type 0x%02x.",\r
+                pPuback->type );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t _IotMqtt_SerializeSubscribe( const IotMqttSubscription_t * pSubscriptionList,\r
+                                            size_t subscriptionCount,\r
+                                            uint8_t ** pSubscribePacket,\r
+                                            size_t * pPacketSize,\r
+                                            uint16_t * pPacketIdentifier )\r
+{\r
+    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
+    size_t i = 0, subscribePacketSize = 0, remainingLength = 0;\r
+    uint16_t packetIdentifier = 0;\r
+    uint8_t * pBuffer = NULL;\r
+\r
+    /* Calculate the "Remaining length" field and total packet size. If it exceeds\r
+     * what is allowed in the MQTT standard, return an error. */\r
+    if( _subscriptionPacketSize( IOT_MQTT_SUBSCRIBE,\r
+                                 pSubscriptionList,\r
+                                 subscriptionCount,\r
+                                 &remainingLength,\r
+                                 &subscribePacketSize ) == false )\r
+    {\r
+        IotLogError( "Subscribe packet remaining length exceeds %lu, which is the "\r
+                     "maximum size allowed by MQTT 3.1.1.",\r
+                     MQTT_MAX_REMAINING_LENGTH );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Total size of the subscribe packet should be larger than the "Remaining length"\r
+     * field. */\r
+    IotMqtt_Assert( subscribePacketSize > remainingLength );\r
+\r
+    /* Allocate memory to hold the SUBSCRIBE packet. */\r
+    pBuffer = IotMqtt_MallocMessage( subscribePacketSize );\r
+\r
+    /* Check that sufficient memory was allocated. */\r
+    if( pBuffer == NULL )\r
+    {\r
+        IotLogError( "Failed to allocate memory for SUBSCRIBE packet." );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NO_MEMORY );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Set the output parameters. The remainder of this function always succeeds. */\r
+    *pSubscribePacket = pBuffer;\r
+    *pPacketSize = subscribePacketSize;\r
+\r
+    /* The first byte in SUBSCRIBE is the packet type. */\r
+    *pBuffer = MQTT_PACKET_TYPE_SUBSCRIBE;\r
+    pBuffer++;\r
+\r
+    /* Encode the "Remaining length" starting from the second byte. */\r
+    pBuffer = _encodeRemainingLength( pBuffer, remainingLength );\r
+\r
+    /* Get the next packet identifier. It should always be nonzero. */\r
+    packetIdentifier = _nextPacketIdentifier();\r
+    *pPacketIdentifier = packetIdentifier;\r
+    IotMqtt_Assert( packetIdentifier != 0 );\r
+\r
+    /* Place the packet identifier into the SUBSCRIBE packet. */\r
+    *pBuffer = UINT16_HIGH_BYTE( packetIdentifier );\r
+    *( pBuffer + 1 ) = UINT16_LOW_BYTE( packetIdentifier );\r
+    pBuffer += 2;\r
+\r
+    /* Serialize each subscription topic filter and QoS. */\r
+    for( i = 0; i < subscriptionCount; i++ )\r
+    {\r
+        pBuffer = _encodeString( pBuffer,\r
+                                 pSubscriptionList[ i ].pTopicFilter,\r
+                                 pSubscriptionList[ i ].topicFilterLength );\r
+\r
+        /* Place the QoS in the SUBSCRIBE packet. */\r
+        *pBuffer = ( uint8_t ) ( pSubscriptionList[ i ].qos );\r
+        pBuffer++;\r
+    }\r
+\r
+    /* Ensure that the difference between the end and beginning of the buffer\r
+     * is equal to subscribePacketSize, i.e. pBuffer did not overflow. */\r
+    IotMqtt_Assert( ( size_t ) ( pBuffer - *pSubscribePacket ) == subscribePacketSize );\r
+\r
+    /* Print out the serialized SUBSCRIBE packet for debugging purposes. */\r
+    IotLog_PrintBuffer( "MQTT SUBSCRIBE packet:", *pSubscribePacket, subscribePacketSize );\r
+\r
+    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t _IotMqtt_DeserializeSuback( _mqttPacket_t * pSuback )\r
+{\r
+    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
+    size_t i = 0, remainingLength = pSuback->remainingLength;\r
+    uint8_t subscriptionStatus = 0;\r
+    const uint8_t * pVariableHeader = pSuback->pRemainingData;\r
+\r
+    /* A SUBACK must have a remaining length of at least 3 to accommodate the\r
+     * packet identifer and at least 1 return code. */\r
+    if( remainingLength < 3 )\r
+    {\r
+        IotLog( IOT_LOG_DEBUG,\r
+                &_logHideAll,\r
+                "SUBACK cannot have a remaining length less than 3." );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Extract the packet identifier (first 2 bytes of variable header) from SUBACK. */\r
+    pSuback->packetIdentifier = UINT16_DECODE( pVariableHeader );\r
+\r
+    IotLog( IOT_LOG_DEBUG,\r
+            &_logHideAll,\r
+            "Packet identifier %hu.", pSuback->packetIdentifier );\r
+\r
+    /* Check that the control packet type is 0x90 (this must be done after the\r
+     * packet identifier is parsed). */\r
+    if( pSuback->type != MQTT_PACKET_TYPE_SUBACK )\r
+    {\r
+        IotLog( IOT_LOG_ERROR,\r
+                &_logHideAll,\r
+                "Bad control packet type 0x%02x.",\r
+                pSuback->type );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Iterate through each status byte in the SUBACK packet. */\r
+    for( i = 0; i < remainingLength - sizeof( uint16_t ); i++ )\r
+    {\r
+        /* Read a single status byte in SUBACK. */\r
+        subscriptionStatus = *( pVariableHeader + sizeof( uint16_t ) + i );\r
+\r
+        /* MQTT 3.1.1 defines the following values as status codes. */\r
+        switch( subscriptionStatus )\r
+        {\r
+            case 0x00:\r
+            case 0x01:\r
+            case 0x02:\r
+                IotLog( IOT_LOG_DEBUG,\r
+                        &_logHideAll,\r
+                        "Topic filter %lu accepted, max QoS %hhu.",\r
+                        ( unsigned long ) i, subscriptionStatus );\r
+                break;\r
+\r
+            case 0x80:\r
+                IotLog( IOT_LOG_DEBUG,\r
+                        &_logHideAll,\r
+                        "Topic filter %lu refused.", ( unsigned long ) i );\r
+\r
+                /* Remove a rejected subscription from the subscription manager. */\r
+                _IotMqtt_RemoveSubscriptionByPacket( pSuback->u.pMqttConnection,\r
+                                                     pSuback->packetIdentifier,\r
+                                                     ( int32_t ) i );\r
+\r
+                status = IOT_MQTT_SERVER_REFUSED;\r
+\r
+                break;\r
+\r
+            default:\r
+                IotLog( IOT_LOG_DEBUG,\r
+                        &_logHideAll,\r
+                        "Bad SUBSCRIBE status %hhu.", subscriptionStatus );\r
+\r
+                status = IOT_MQTT_BAD_RESPONSE;\r
+\r
+                break;\r
+        }\r
+\r
+        /* Stop parsing the subscription statuses if a bad response was received. */\r
+        if( status == IOT_MQTT_BAD_RESPONSE )\r
+        {\r
+            break;\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+\r
+    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t _IotMqtt_SerializeUnsubscribe( const IotMqttSubscription_t * pSubscriptionList,\r
+                                              size_t subscriptionCount,\r
+                                              uint8_t ** pUnsubscribePacket,\r
+                                              size_t * pPacketSize,\r
+                                              uint16_t * pPacketIdentifier )\r
+{\r
+    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
+    size_t i = 0, unsubscribePacketSize = 0, remainingLength = 0;\r
+    uint16_t packetIdentifier = 0;\r
+    uint8_t * pBuffer = NULL;\r
+\r
+    /* Calculate the "Remaining length" field and total packet size. If it exceeds\r
+     * what is allowed in the MQTT standard, return an error. */\r
+    if( _subscriptionPacketSize( IOT_MQTT_UNSUBSCRIBE,\r
+                                 pSubscriptionList,\r
+                                 subscriptionCount,\r
+                                 &remainingLength,\r
+                                 &unsubscribePacketSize ) == false )\r
+    {\r
+        IotLogError( "Unsubscribe packet remaining length exceeds %lu, which is the "\r
+                     "maximum size allowed by MQTT 3.1.1.",\r
+                     MQTT_MAX_REMAINING_LENGTH );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Total size of the unsubscribe packet should be larger than the "Remaining length"\r
+     * field. */\r
+    IotMqtt_Assert( unsubscribePacketSize > remainingLength );\r
+\r
+    /* Allocate memory to hold the UNSUBSCRIBE packet. */\r
+    pBuffer = IotMqtt_MallocMessage( unsubscribePacketSize );\r
+\r
+    /* Check that sufficient memory was allocated. */\r
+    if( pBuffer == NULL )\r
+    {\r
+        IotLogError( "Failed to allocate memory for UNSUBSCRIBE packet." );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NO_MEMORY );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Set the output parameters. The remainder of this function always succeeds. */\r
+    *pUnsubscribePacket = pBuffer;\r
+    *pPacketSize = unsubscribePacketSize;\r
+\r
+    /* The first byte in UNSUBSCRIBE is the packet type. */\r
+    *pBuffer = MQTT_PACKET_TYPE_UNSUBSCRIBE;\r
+    pBuffer++;\r
+\r
+    /* Encode the "Remaining length" starting from the second byte. */\r
+    pBuffer = _encodeRemainingLength( pBuffer, remainingLength );\r
+\r
+    /* Get the next packet identifier. It should always be nonzero. */\r
+    packetIdentifier = _nextPacketIdentifier();\r
+    *pPacketIdentifier = packetIdentifier;\r
+    IotMqtt_Assert( packetIdentifier != 0 );\r
+\r
+    /* Place the packet identifier into the UNSUBSCRIBE packet. */\r
+    *pBuffer = UINT16_HIGH_BYTE( packetIdentifier );\r
+    *( pBuffer + 1 ) = UINT16_LOW_BYTE( packetIdentifier );\r
+    pBuffer += 2;\r
+\r
+    /* Serialize each subscription topic filter. */\r
+    for( i = 0; i < subscriptionCount; i++ )\r
+    {\r
+        pBuffer = _encodeString( pBuffer,\r
+                                 pSubscriptionList[ i ].pTopicFilter,\r
+                                 pSubscriptionList[ i ].topicFilterLength );\r
+    }\r
+\r
+    /* Ensure that the difference between the end and beginning of the buffer\r
+     * is equal to unsubscribePacketSize, i.e. pBuffer did not overflow. */\r
+    IotMqtt_Assert( ( size_t ) ( pBuffer - *pUnsubscribePacket ) == unsubscribePacketSize );\r
+\r
+    /* Print out the serialized UNSUBSCRIBE packet for debugging purposes. */\r
+    IotLog_PrintBuffer( "MQTT UNSUBSCRIBE packet:", *pUnsubscribePacket, unsubscribePacketSize );\r
+\r
+    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t _IotMqtt_DeserializeUnsuback( _mqttPacket_t * pUnsuback )\r
+{\r
+    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
+\r
+    /* Check the "Remaining length" (second byte) of the received UNSUBACK. */\r
+    if( pUnsuback->remainingLength != MQTT_PACKET_UNSUBACK_REMAINING_LENGTH )\r
+    {\r
+        IotLog( IOT_LOG_ERROR,\r
+                &_logHideAll,\r
+                "UNSUBACK does not have remaining length of %d.",\r
+                MQTT_PACKET_UNSUBACK_REMAINING_LENGTH );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Extract the packet identifier (third and fourth bytes) from UNSUBACK. */\r
+    pUnsuback->packetIdentifier = UINT16_DECODE( pUnsuback->pRemainingData );\r
+\r
+    /* Packet identifier cannot be 0. */\r
+    if( pUnsuback->packetIdentifier == 0 )\r
+    {\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    IotLog( IOT_LOG_DEBUG,\r
+            &_logHideAll,\r
+            "Packet identifier %hu.", pUnsuback->packetIdentifier );\r
+\r
+    /* Check that the control packet type is 0xb0 (this must be done after the\r
+     * packet identifier is parsed). */\r
+    if( pUnsuback->type != MQTT_PACKET_TYPE_UNSUBACK )\r
+    {\r
+        IotLog( IOT_LOG_ERROR,\r
+                &_logHideAll,\r
+                "Bad control packet type 0x%02x.",\r
+                pUnsuback->type );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t _IotMqtt_SerializePingreq( uint8_t ** pPingreqPacket,\r
+                                          size_t * pPacketSize )\r
+{\r
+    /* PINGREQ packets are always the same. */\r
+    static const uint8_t pPingreq[ MQTT_PACKET_PINGREQ_SIZE ] =\r
+    {\r
+        MQTT_PACKET_TYPE_PINGREQ,\r
+        0x00\r
+    };\r
+\r
+    /* Set the output parameters. */\r
+    *pPingreqPacket = ( uint8_t * ) pPingreq;\r
+    *pPacketSize = MQTT_PACKET_PINGREQ_SIZE;\r
+\r
+    /* Print out the PINGREQ packet for debugging purposes. */\r
+    IotLog_PrintBuffer( "MQTT PINGREQ packet:", pPingreq, MQTT_PACKET_PINGREQ_SIZE );\r
+\r
+    return IOT_MQTT_SUCCESS;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t _IotMqtt_DeserializePingresp( _mqttPacket_t * pPingresp )\r
+{\r
+    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
+\r
+    /* Check that the control packet type is 0xd0. */\r
+    if( pPingresp->type != MQTT_PACKET_TYPE_PINGRESP )\r
+    {\r
+        IotLog( IOT_LOG_ERROR,\r
+                &_logHideAll,\r
+                "Bad control packet type 0x%02x.",\r
+                pPingresp->type );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Check the "Remaining length" (second byte) of the received PINGRESP. */\r
+    if( pPingresp->remainingLength != MQTT_PACKET_PINGRESP_REMAINING_LENGTH )\r
+    {\r
+        IotLog( IOT_LOG_ERROR,\r
+                &_logHideAll,\r
+                "PINGRESP does not have remaining length of %d.",\r
+                MQTT_PACKET_PINGRESP_REMAINING_LENGTH );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t _IotMqtt_SerializeDisconnect( uint8_t ** pDisconnectPacket,\r
+                                             size_t * pPacketSize )\r
+{\r
+    /* DISCONNECT packets are always the same. */\r
+    static const uint8_t pDisconnect[ MQTT_PACKET_DISCONNECT_SIZE ] =\r
+    {\r
+        MQTT_PACKET_TYPE_DISCONNECT,\r
+        0x00\r
+    };\r
+\r
+    /* Set the output parameters. */\r
+    *pDisconnectPacket = ( uint8_t * ) pDisconnect;\r
+    *pPacketSize = MQTT_PACKET_DISCONNECT_SIZE;\r
+\r
+    /* Print out the DISCONNECT packet for debugging purposes. */\r
+    IotLog_PrintBuffer( "MQTT DISCONNECT packet:", pDisconnect, MQTT_PACKET_DISCONNECT_SIZE );\r
+\r
+    return IOT_MQTT_SUCCESS;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void _IotMqtt_FreePacket( uint8_t * pPacket )\r
+{\r
+    uint8_t packetType = *pPacket;\r
+\r
+    /* Don't call free on DISCONNECT and PINGREQ; those are allocated from static\r
+     * memory. */\r
+    if( packetType != MQTT_PACKET_TYPE_DISCONNECT )\r
+    {\r
+        if( packetType != MQTT_PACKET_TYPE_PINGREQ )\r
+        {\r
+            IotMqtt_FreeMessage( pPacket );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_static_memory.c b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_static_memory.c
new file mode 100644 (file)
index 0000000..000fcba
--- /dev/null
@@ -0,0 +1,207 @@
+/*\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_static_memory.c\r
+ * @brief Implementation of MQTT static memory functions.\r
+ */\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/* This file should only be compiled if dynamic memory allocation is forbidden. */\r
+#if IOT_STATIC_MEMORY_ONLY == 1\r
+\r
+/* Standard includes. */\r
+#include <stdbool.h>\r
+#include <stddef.h>\r
+#include <string.h>\r
+\r
+/* Static memory include. */\r
+#include "private/iot_static_memory.h"\r
+\r
+/* MQTT internal include. */\r
+#include "private/iot_mqtt_internal.h"\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/**\r
+ * @cond DOXYGEN_IGNORE\r
+ * Doxygen should ignore this section.\r
+ *\r
+ * Provide default values for undefined configuration constants.\r
+ */\r
+#ifndef IOT_MQTT_CONNECTIONS\r
+    #define IOT_MQTT_CONNECTIONS                   ( 1 )\r
+#endif\r
+#ifndef IOT_MQTT_MAX_IN_PROGRESS_OPERATIONS\r
+    #define IOT_MQTT_MAX_IN_PROGRESS_OPERATIONS    ( 10 )\r
+#endif\r
+#ifndef IOT_MQTT_SUBSCRIPTIONS\r
+    #define IOT_MQTT_SUBSCRIPTIONS                 ( 8 )\r
+#endif\r
+/** @endcond */\r
+\r
+/* Validate static memory configuration settings. */\r
+#if IOT_MQTT_CONNECTIONS <= 0\r
+    #error "IOT_MQTT_CONNECTIONS cannot be 0 or negative."\r
+#endif\r
+#if IOT_MQTT_MAX_IN_PROGRESS_OPERATIONS <= 0\r
+    #error "IOT_MQTT_MAX_IN_PROGRESS_OPERATIONS cannot be 0 or negative."\r
+#endif\r
+#if IOT_MQTT_SUBSCRIPTIONS <= 0\r
+    #error "IOT_MQTT_SUBSCRIPTIONS cannot be 0 or negative."\r
+#endif\r
+\r
+/**\r
+ * @brief The size of a static memory MQTT subscription.\r
+ *\r
+ * Since the pTopic member of #_mqttSubscription_t is variable-length, the constant\r
+ * #AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH is used for the length of\r
+ * #_mqttSubscription_t.pTopicFilter.\r
+ */\r
+#define MQTT_SUBSCRIPTION_SIZE    ( sizeof( _mqttSubscription_t ) + AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH )\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Static memory buffers and flags, allocated and zeroed at compile-time.\r
+ */\r
+static bool _pInUseMqttConnections[ IOT_MQTT_CONNECTIONS ] = { 0 };                               /**< @brief MQTT connection in-use flags. */\r
+static _mqttConnection_t _pMqttConnections[ IOT_MQTT_CONNECTIONS ] = { { 0 } };                   /**< @brief MQTT connections. */\r
+\r
+static bool _pInUseMqttOperations[ IOT_MQTT_MAX_IN_PROGRESS_OPERATIONS ] = { 0 };                        /**< @brief MQTT operation in-use flags. */\r
+static _mqttOperation_t _pMqttOperations[ IOT_MQTT_MAX_IN_PROGRESS_OPERATIONS ] = { { .link = { 0 } } }; /**< @brief MQTT operations. */\r
+\r
+static bool _pInUseMqttSubscriptions[ IOT_MQTT_SUBSCRIPTIONS ] = { 0 };                           /**< @brief MQTT subscription in-use flags. */\r
+static char _pMqttSubscriptions[ IOT_MQTT_SUBSCRIPTIONS ][ MQTT_SUBSCRIPTION_SIZE ] = { { 0 } };  /**< @brief MQTT subscriptions. */\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void * IotMqtt_MallocConnection( size_t size )\r
+{\r
+    int32_t freeIndex = -1;\r
+    void * pNewConnection = NULL;\r
+\r
+    /* Check size argument. */\r
+    if( size == sizeof( _mqttConnection_t ) )\r
+    {\r
+        /* Find a free MQTT connection. */\r
+        freeIndex = IotStaticMemory_FindFree( _pInUseMqttConnections,\r
+                                              IOT_MQTT_CONNECTIONS );\r
+\r
+        if( freeIndex != -1 )\r
+        {\r
+            pNewConnection = &( _pMqttConnections[ freeIndex ] );\r
+        }\r
+    }\r
+\r
+    return pNewConnection;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void IotMqtt_FreeConnection( void * ptr )\r
+{\r
+    /* Return the in-use MQTT connection. */\r
+    IotStaticMemory_ReturnInUse( ptr,\r
+                                 _pMqttConnections,\r
+                                 _pInUseMqttConnections,\r
+                                 IOT_MQTT_CONNECTIONS,\r
+                                 sizeof( _mqttConnection_t ) );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void * IotMqtt_MallocOperation( size_t size )\r
+{\r
+    int32_t freeIndex = -1;\r
+    void * pNewOperation = NULL;\r
+\r
+    /* Check size argument. */\r
+    if( size == sizeof( _mqttOperation_t ) )\r
+    {\r
+        /* Find a free MQTT operation. */\r
+        freeIndex = IotStaticMemory_FindFree( _pInUseMqttOperations,\r
+                                              IOT_MQTT_MAX_IN_PROGRESS_OPERATIONS );\r
+\r
+        if( freeIndex != -1 )\r
+        {\r
+            pNewOperation = &( _pMqttOperations[ freeIndex ] );\r
+        }\r
+    }\r
+\r
+    return pNewOperation;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void IotMqtt_FreeOperation( void * ptr )\r
+{\r
+    /* Return the in-use MQTT operation. */\r
+    IotStaticMemory_ReturnInUse( ptr,\r
+                                 _pMqttOperations,\r
+                                 _pInUseMqttOperations,\r
+                                 IOT_MQTT_MAX_IN_PROGRESS_OPERATIONS,\r
+                                 sizeof( _mqttOperation_t ) );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void * IotMqtt_MallocSubscription( size_t size )\r
+{\r
+    int32_t freeIndex = -1;\r
+    void * pNewSubscription = NULL;\r
+\r
+    if( size <= MQTT_SUBSCRIPTION_SIZE )\r
+    {\r
+        /* Get the index of a free MQTT subscription. */\r
+        freeIndex = IotStaticMemory_FindFree( _pInUseMqttSubscriptions,\r
+                                              IOT_MQTT_SUBSCRIPTIONS );\r
+\r
+        if( freeIndex != -1 )\r
+        {\r
+            pNewSubscription = &( _pMqttSubscriptions[ freeIndex ][ 0 ] );\r
+        }\r
+    }\r
+\r
+    return pNewSubscription;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void IotMqtt_FreeSubscription( void * ptr )\r
+{\r
+    /* Return the in-use MQTT subscription. */\r
+    IotStaticMemory_ReturnInUse( ptr,\r
+                                 _pMqttSubscriptions,\r
+                                 _pInUseMqttSubscriptions,\r
+                                 IOT_MQTT_SUBSCRIPTIONS,\r
+                                 MQTT_SUBSCRIPTION_SIZE );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+#endif\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_subscription.c b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_subscription.c
new file mode 100644 (file)
index 0000000..99664de
--- /dev/null
@@ -0,0 +1,648 @@
+/*\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_subscription.c\r
+ * @brief Implements functions that manage subscriptions for an MQTT connection.\r
+ */\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/* Standard includes. */\r
+#include <stdbool.h>\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
+/*-----------------------------------------------------------*/\r
+\r
+/**\r
+ * @brief First parameter to #_topicMatch.\r
+ */\r
+typedef struct _topicMatchParams\r
+{\r
+    const char * pTopicName;  /**< @brief The topic name to parse. */\r
+    uint16_t topicNameLength; /**< @brief Length of #_topicMatchParams_t.pTopicName. */\r
+    bool exactMatchOnly;      /**< @brief Whether to allow wildcards or require exact matches. */\r
+} _topicMatchParams_t;\r
+\r
+/**\r
+ * @brief First parameter to #_packetMatch.\r
+ */\r
+typedef struct _packetMatchParams\r
+{\r
+    uint16_t packetIdentifier; /**< Packet identifier to match. */\r
+    int32_t order;             /**< Order to match. Set to `-1` to ignore. */\r
+} _packetMatchParams_t;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/**\r
+ * @brief Matches a topic name (from a publish) with a topic filter (from a\r
+ * subscription).\r
+ *\r
+ * @param[in] pSubscriptionLink Pointer to the link member of an #_mqttSubscription_t.\r
+ * @param[in] pMatch Pointer to a #_topicMatchParams_t.\r
+ *\r
+ * @return `true` if the arguments match the subscription topic filter; `false`\r
+ * otherwise.\r
+ */\r
+static bool _topicMatch( const IotLink_t * pSubscriptionLink,\r
+                         void * pMatch );\r
+\r
+/**\r
+ * @brief Matches a packet identifier and order.\r
+ *\r
+ * @param[in] pSubscriptionLink Pointer to the link member of an #_mqttSubscription_t.\r
+ * @param[in] pMatch Pointer to a #_packetMatchParams_t.\r
+ *\r
+ * @return `true` if the arguments match the subscription's packet info; `false`\r
+ * otherwise.\r
+ */\r
+static bool _packetMatch( const IotLink_t * pSubscriptionLink,\r
+                          void * pMatch );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static bool _topicMatch( const IotLink_t * pSubscriptionLink,\r
+                         void * pMatch )\r
+{\r
+    IOT_FUNCTION_ENTRY( bool, false );\r
+    uint16_t nameIndex = 0, filterIndex = 0;\r
+\r
+    /* Because this function is called from a container function, the given link\r
+     * must never be NULL. */\r
+    IotMqtt_Assert( pSubscriptionLink != NULL );\r
+\r
+    _mqttSubscription_t * pSubscription = IotLink_Container( _mqttSubscription_t,\r
+                                                             pSubscriptionLink,\r
+                                                             link );\r
+    _topicMatchParams_t * pParam = ( _topicMatchParams_t * ) pMatch;\r
+\r
+    /* Extract the relevant strings and lengths from parameters. */\r
+    const char * pTopicName = pParam->pTopicName;\r
+    const char * pTopicFilter = pSubscription->pTopicFilter;\r
+    const uint16_t topicNameLength = pParam->topicNameLength;\r
+    const uint16_t topicFilterLength = pSubscription->topicFilterLength;\r
+\r
+    /* Check for an exact match. */\r
+    if( topicNameLength == topicFilterLength )\r
+    {\r
+        status = ( strncmp( pTopicName, pTopicFilter, topicNameLength ) == 0 );\r
+\r
+        IOT_GOTO_CLEANUP();\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* If the topic lengths are different but an exact match is required, return\r
+     * false. */\r
+    if( pParam->exactMatchOnly == true )\r
+    {\r
+        IOT_SET_AND_GOTO_CLEANUP( false );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    while( ( nameIndex < topicNameLength ) && ( filterIndex < topicFilterLength ) )\r
+    {\r
+        /* Check if the character in the topic name matches the corresponding\r
+         * character in the topic filter string. */\r
+        if( pTopicName[ nameIndex ] == pTopicFilter[ filterIndex ] )\r
+        {\r
+            /* Handle special corner cases as documented by the MQTT protocol spec. */\r
+\r
+            /* Filter "sport/#" also matches "sport" since # includes the parent level. */\r
+            if( nameIndex == topicNameLength - 1 )\r
+            {\r
+                if( filterIndex == topicFilterLength - 3 )\r
+                {\r
+                    if( pTopicFilter[ filterIndex + 1 ] == '/' )\r
+                    {\r
+                        if( pTopicFilter[ filterIndex + 2 ] == '#' )\r
+                        {\r
+                            IOT_SET_AND_GOTO_CLEANUP( true );\r
+                        }\r
+                        else\r
+                        {\r
+                            EMPTY_ELSE_MARKER;\r
+                        }\r
+                    }\r
+                    else\r
+                    {\r
+                        EMPTY_ELSE_MARKER;\r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    EMPTY_ELSE_MARKER;\r
+                }\r
+            }\r
+            else\r
+            {\r
+                EMPTY_ELSE_MARKER;\r
+            }\r
+\r
+            /* Filter "sport/+" also matches the "sport/" but not "sport". */\r
+            if( nameIndex == topicNameLength - 1 )\r
+            {\r
+                if( filterIndex == topicFilterLength - 2 )\r
+                {\r
+                    if( pTopicFilter[ filterIndex + 1 ] == '+' )\r
+                    {\r
+                        IOT_SET_AND_GOTO_CLEANUP( true );\r
+                    }\r
+                    else\r
+                    {\r
+                        EMPTY_ELSE_MARKER;\r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    EMPTY_ELSE_MARKER;\r
+                }\r
+            }\r
+            else\r
+            {\r
+                EMPTY_ELSE_MARKER;\r
+            }\r
+        }\r
+        else\r
+        {\r
+            /* Check for wildcards. */\r
+            if( pTopicFilter[ filterIndex ] == '+' )\r
+            {\r
+                /* Move topic name index to the end of the current level.\r
+                 * This is identified by '/'. */\r
+                while( nameIndex < topicNameLength && pTopicName[ nameIndex ] != '/' )\r
+                {\r
+                    nameIndex++;\r
+                }\r
+\r
+                /* Increment filter index to skip '/'. */\r
+                filterIndex++;\r
+                continue;\r
+            }\r
+            else if( pTopicFilter[ filterIndex ] == '#' )\r
+            {\r
+                /* Subsequent characters don't need to be checked if the for the\r
+                 * multi-level wildcard. */\r
+                IOT_SET_AND_GOTO_CLEANUP( true );\r
+            }\r
+            else\r
+            {\r
+                /* Any character mismatch other than '+' or '#' means the topic\r
+                 * name does not match the topic filter. */\r
+                IOT_SET_AND_GOTO_CLEANUP( false );\r
+            }\r
+        }\r
+\r
+        /* Increment indexes. */\r
+        nameIndex++;\r
+        filterIndex++;\r
+    }\r
+\r
+    /* If the end of both strings has been reached, they match. */\r
+    if( ( nameIndex == topicNameLength ) && ( filterIndex == topicFilterLength ) )\r
+    {\r
+        IOT_SET_AND_GOTO_CLEANUP( true );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static bool _packetMatch( const IotLink_t * pSubscriptionLink,\r
+                          void * pMatch )\r
+{\r
+    bool match = false;\r
+\r
+    /* Because this function is called from a container function, the given link\r
+     * must never be NULL. */\r
+    IotMqtt_Assert( pSubscriptionLink != NULL );\r
+\r
+    _mqttSubscription_t * pSubscription = IotLink_Container( _mqttSubscription_t,\r
+                                                             pSubscriptionLink,\r
+                                                             link );\r
+    _packetMatchParams_t * pParam = ( _packetMatchParams_t * ) pMatch;\r
+\r
+    /* Compare packet identifiers. */\r
+    if( pParam->packetIdentifier == pSubscription->packetInfo.identifier )\r
+    {\r
+        /* Compare orders if order is not -1. */\r
+        if( pParam->order == -1 )\r
+        {\r
+            match = true;\r
+        }\r
+        else\r
+        {\r
+            match = ( ( size_t ) pParam->order ) == pSubscription->packetInfo.order;\r
+        }\r
+    }\r
+\r
+    /* If this subscription should be removed, check the reference count. */\r
+    if( match == true )\r
+    {\r
+        /* Reference count must not be negative. */\r
+        IotMqtt_Assert( pSubscription->references >= 0 );\r
+\r
+        /* If the reference count is positive, this subscription cannot be\r
+         * removed yet because there are subscription callbacks using it. */\r
+        if( pSubscription->references > 0 )\r
+        {\r
+            match = false;\r
+\r
+            /* Set the unsubscribed flag. The last active subscription callback\r
+             * will remove and clean up this subscription. */\r
+            pSubscription->unsubscribed = true;\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    return match;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+IotMqttError_t _IotMqtt_AddSubscriptions( _mqttConnection_t * pMqttConnection,\r
+                                          uint16_t subscribePacketIdentifier,\r
+                                          const IotMqttSubscription_t * pSubscriptionList,\r
+                                          size_t subscriptionCount )\r
+{\r
+    IotMqttError_t status = IOT_MQTT_SUCCESS;\r
+    size_t i = 0;\r
+    _mqttSubscription_t * pNewSubscription = NULL;\r
+    IotLink_t * pSubscriptionLink = NULL;\r
+    _topicMatchParams_t topicMatchParams = { .exactMatchOnly = true };\r
+\r
+    IotMutex_Lock( &( pMqttConnection->subscriptionMutex ) );\r
+\r
+    for( i = 0; i < subscriptionCount; i++ )\r
+    {\r
+        /* Check if this topic filter is already registered. */\r
+        topicMatchParams.pTopicName = pSubscriptionList[ i ].pTopicFilter;\r
+        topicMatchParams.topicNameLength = pSubscriptionList[ i ].topicFilterLength;\r
+        pSubscriptionLink = IotListDouble_FindFirstMatch( &( pMqttConnection->subscriptionList ),\r
+                                                          NULL,\r
+                                                          _topicMatch,\r
+                                                          &topicMatchParams );\r
+\r
+        if( pSubscriptionLink != NULL )\r
+        {\r
+            pNewSubscription = IotLink_Container( _mqttSubscription_t, pSubscriptionLink, link );\r
+\r
+            /* The lengths of exactly matching topic filters must match. */\r
+            IotMqtt_Assert( pNewSubscription->topicFilterLength == pSubscriptionList[ i ].topicFilterLength );\r
+\r
+            /* Replace the callback and packet info with the new parameters. */\r
+            pNewSubscription->callback = pSubscriptionList[ i ].callback;\r
+            pNewSubscription->packetInfo.identifier = subscribePacketIdentifier;\r
+            pNewSubscription->packetInfo.order = i;\r
+        }\r
+        else\r
+        {\r
+            /* Allocate memory for a new subscription. */\r
+            pNewSubscription = IotMqtt_MallocSubscription( sizeof( _mqttSubscription_t ) +\r
+                                                           pSubscriptionList[ i ].topicFilterLength );\r
+\r
+            if( pNewSubscription == NULL )\r
+            {\r
+                status = IOT_MQTT_NO_MEMORY;\r
+                break;\r
+            }\r
+            else\r
+            {\r
+                /* Clear the new subscription. */\r
+                ( void ) memset( pNewSubscription,\r
+                                 0x00,\r
+                                 sizeof( _mqttSubscription_t ) + pSubscriptionList[ i ].topicFilterLength );\r
+\r
+                /* Set the members of the new subscription and add it to the list. */\r
+                pNewSubscription->packetInfo.identifier = subscribePacketIdentifier;\r
+                pNewSubscription->packetInfo.order = i;\r
+                pNewSubscription->callback = pSubscriptionList[ i ].callback;\r
+                pNewSubscription->topicFilterLength = pSubscriptionList[ i ].topicFilterLength;\r
+                ( void ) memcpy( pNewSubscription->pTopicFilter,\r
+                                 pSubscriptionList[ i ].pTopicFilter,\r
+                                 ( size_t ) ( pSubscriptionList[ i ].topicFilterLength ) );\r
+\r
+                IotListDouble_InsertHead( &( pMqttConnection->subscriptionList ),\r
+                                          &( pNewSubscription->link ) );\r
+            }\r
+        }\r
+    }\r
+\r
+    IotMutex_Unlock( &( pMqttConnection->subscriptionMutex ) );\r
+\r
+    /* If memory allocation failed, remove all previously added subscriptions. */\r
+    if( status != IOT_MQTT_SUCCESS )\r
+    {\r
+        _IotMqtt_RemoveSubscriptionByTopicFilter( pMqttConnection,\r
+                                                  pSubscriptionList,\r
+                                                  i );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void _IotMqtt_InvokeSubscriptionCallback( _mqttConnection_t * pMqttConnection,\r
+                                          IotMqttCallbackParam_t * pCallbackParam )\r
+{\r
+    _mqttSubscription_t * pSubscription = NULL;\r
+    IotLink_t * pCurrentLink = NULL, * pNextLink = NULL;\r
+    void * pCallbackContext = NULL;\r
+\r
+    void ( * callbackFunction )( void *,\r
+                                 IotMqttCallbackParam_t * ) = NULL;\r
+    _topicMatchParams_t topicMatchParams =\r
+    {\r
+        .pTopicName      = pCallbackParam->u.message.info.pTopicName,\r
+        .topicNameLength = pCallbackParam->u.message.info.topicNameLength,\r
+        .exactMatchOnly  = false\r
+    };\r
+\r
+    /* Prevent any other thread from modifying the subscription list while this\r
+     * function is searching. */\r
+    IotMutex_Lock( &( pMqttConnection->subscriptionMutex ) );\r
+\r
+    /* Search the subscription list for all matching subscriptions starting at\r
+     * the list head. */\r
+    while( true )\r
+    {\r
+        pCurrentLink = IotListDouble_FindFirstMatch( &( pMqttConnection->subscriptionList ),\r
+                                                     pCurrentLink,\r
+                                                     _topicMatch,\r
+                                                     &topicMatchParams );\r
+\r
+        /* No subscription found. Exit loop. */\r
+        if( pCurrentLink == NULL )\r
+        {\r
+            break;\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        /* Subscription found. Calculate pointer to subscription object. */\r
+        pSubscription = IotLink_Container( _mqttSubscription_t, pCurrentLink, link );\r
+\r
+        /* Subscription validation should not have allowed a NULL callback function. */\r
+        IotMqtt_Assert( pSubscription->callback.function != NULL );\r
+\r
+        /* Increment the subscription's reference count. */\r
+        ( pSubscription->references )++;\r
+\r
+        /* Copy the necessary members of the subscription before releasing the\r
+         * subscription list mutex. */\r
+        pCallbackContext = pSubscription->callback.pCallbackContext;\r
+        callbackFunction = pSubscription->callback.function;\r
+\r
+        /* Unlock the subscription list mutex. */\r
+        IotMutex_Unlock( &( pMqttConnection->subscriptionMutex ) );\r
+\r
+        /* Set the members of the callback parameter. */\r
+        pCallbackParam->mqttConnection = pMqttConnection;\r
+        pCallbackParam->u.message.pTopicFilter = pSubscription->pTopicFilter;\r
+        pCallbackParam->u.message.topicFilterLength = pSubscription->topicFilterLength;\r
+\r
+        /* Invoke the subscription callback. */\r
+        callbackFunction( pCallbackContext, pCallbackParam );\r
+\r
+        /* Lock the subscription list mutex to decrement the reference count. */\r
+        IotMutex_Lock( &( pMqttConnection->subscriptionMutex ) );\r
+\r
+        /* Decrement the reference count. It must still be positive. */\r
+        ( pSubscription->references )--;\r
+        IotMqtt_Assert( pSubscription->references >= 0 );\r
+\r
+        /* Save the pointer to the next link in case this subscription is freed. */\r
+        pNextLink = pCurrentLink->pNext;\r
+\r
+        /* Remove this subscription if it has no references and the unsubscribed\r
+         * flag is set. */\r
+        if( pSubscription->unsubscribed == true )\r
+        {\r
+            /* An unsubscribed subscription should have been removed from the list. */\r
+            IotMqtt_Assert( IotLink_IsLinked( &( pSubscription->link ) ) == false );\r
+\r
+            /* Free subscriptions with no references. */\r
+            if( pSubscription->references == 0 )\r
+            {\r
+                IotMqtt_FreeSubscription( pSubscription );\r
+            }\r
+            else\r
+            {\r
+                EMPTY_ELSE_MARKER;\r
+            }\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        /* Move current link pointer. */\r
+        pCurrentLink = pNextLink;\r
+    }\r
+\r
+    IotMutex_Unlock( &( pMqttConnection->subscriptionMutex ) );\r
+\r
+    _IotMqtt_DecrementConnectionReferences( pMqttConnection );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void _IotMqtt_RemoveSubscriptionByPacket( _mqttConnection_t * pMqttConnection,\r
+                                          uint16_t packetIdentifier,\r
+                                          int32_t order )\r
+{\r
+    const _packetMatchParams_t packetMatchParams =\r
+    {\r
+        .packetIdentifier = packetIdentifier,\r
+        .order            = order\r
+    };\r
+\r
+    IotMutex_Lock( &( pMqttConnection->subscriptionMutex ) );\r
+    IotListDouble_RemoveAllMatches( &( pMqttConnection->subscriptionList ),\r
+                                    _packetMatch,\r
+                                    ( void * ) ( &packetMatchParams ),\r
+                                    IotMqtt_FreeSubscription,\r
+                                    offsetof( _mqttSubscription_t, link ) );\r
+    IotMutex_Unlock( &( pMqttConnection->subscriptionMutex ) );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void _IotMqtt_RemoveSubscriptionByTopicFilter( _mqttConnection_t * pMqttConnection,\r
+                                               const IotMqttSubscription_t * pSubscriptionList,\r
+                                               size_t subscriptionCount )\r
+{\r
+    size_t i = 0;\r
+    _mqttSubscription_t * pSubscription = NULL;\r
+    IotLink_t * pSubscriptionLink = NULL;\r
+    _topicMatchParams_t topicMatchParams = { 0 };\r
+\r
+    /* Prevent any other thread from modifying the subscription list while this\r
+     * function is running. */\r
+    IotMutex_Lock( &( pMqttConnection->subscriptionMutex ) );\r
+\r
+    /* Find and remove each topic filter from the list. */\r
+    for( i = 0; i < subscriptionCount; i++ )\r
+    {\r
+        topicMatchParams.pTopicName = pSubscriptionList[ i ].pTopicFilter;\r
+        topicMatchParams.topicNameLength = pSubscriptionList[ i ].topicFilterLength;\r
+        topicMatchParams.exactMatchOnly = true;\r
+\r
+        pSubscriptionLink = IotListDouble_FindFirstMatch( &( pMqttConnection->subscriptionList ),\r
+                                                          NULL,\r
+                                                          _topicMatch,\r
+                                                          &topicMatchParams );\r
+\r
+        if( pSubscriptionLink != NULL )\r
+        {\r
+            pSubscription = IotLink_Container( _mqttSubscription_t, pSubscriptionLink, link );\r
+\r
+            /* Reference count must not be negative. */\r
+            IotMqtt_Assert( pSubscription->references >= 0 );\r
+\r
+            /* Remove subscription from list. */\r
+            IotListDouble_Remove( pSubscriptionLink );\r
+\r
+            /* Check the reference count. This subscription cannot be removed if\r
+             * there are subscription callbacks using it. */\r
+            if( pSubscription->references > 0 )\r
+            {\r
+                /* Set the unsubscribed flag. The last active subscription callback\r
+                 * will remove and clean up this subscription. */\r
+                pSubscription->unsubscribed = true;\r
+            }\r
+            else\r
+            {\r
+                /* Free a subscription with no references. */\r
+                IotMqtt_FreeSubscription( pSubscription );\r
+            }\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+\r
+    IotMutex_Unlock( &( pMqttConnection->subscriptionMutex ) );\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+bool IotMqtt_IsSubscribed( IotMqttConnection_t mqttConnection,\r
+                           const char * pTopicFilter,\r
+                           uint16_t topicFilterLength,\r
+                           IotMqttSubscription_t * pCurrentSubscription )\r
+{\r
+    bool status = false;\r
+    _mqttSubscription_t * pSubscription = NULL;\r
+    IotLink_t * pSubscriptionLink = NULL;\r
+    _topicMatchParams_t topicMatchParams =\r
+    {\r
+        .pTopicName      = pTopicFilter,\r
+        .topicNameLength = topicFilterLength,\r
+        .exactMatchOnly  = true\r
+    };\r
+\r
+    /* Prevent any other thread from modifying the subscription list while this\r
+     * function is running. */\r
+    IotMutex_Lock( &( mqttConnection->subscriptionMutex ) );\r
+\r
+    /* Search for a matching subscription. */\r
+    pSubscriptionLink = IotListDouble_FindFirstMatch( &( mqttConnection->subscriptionList ),\r
+                                                      NULL,\r
+                                                      _topicMatch,\r
+                                                      &topicMatchParams );\r
+\r
+    /* Check if a matching subscription was found. */\r
+    if( pSubscriptionLink != NULL )\r
+    {\r
+        pSubscription = IotLink_Container( _mqttSubscription_t, pSubscriptionLink, link );\r
+\r
+        /* Copy the matching subscription to the output parameter. */\r
+        if( pCurrentSubscription != NULL )\r
+        {\r
+            pCurrentSubscription->pTopicFilter = pTopicFilter;\r
+            pCurrentSubscription->topicFilterLength = topicFilterLength;\r
+            pCurrentSubscription->qos = IOT_MQTT_QOS_0;\r
+            pCurrentSubscription->callback = pSubscription->callback;\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        status = true;\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    IotMutex_Unlock( &( mqttConnection->subscriptionMutex ) );\r
+\r
+    return status;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Provide access to internal functions and variables if testing. */\r
+#if IOT_BUILD_TESTS == 1\r
+    #include "iot_test_access_mqtt_subscription.c"\r
+#endif\r
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
new file mode 100644 (file)
index 0000000..8556959
--- /dev/null
@@ -0,0 +1,593 @@
+/*\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_validate.c\r
+ * @brief Implements functions that validate the structs of the MQTT library.\r
+ */\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.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
+/*-----------------------------------------------------------*/\r
+\r
+bool _IotMqtt_ValidateConnect( const IotMqttConnectInfo_t * pConnectInfo )\r
+{\r
+    IOT_FUNCTION_ENTRY( bool, true );\r
+\r
+    /* Check for NULL. */\r
+    if( pConnectInfo == NULL )\r
+    {\r
+        IotLogError( "MQTT connection information cannot be NULL." );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( false );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Check that a client identifier was set. */\r
+    if( pConnectInfo->pClientIdentifier == NULL )\r
+    {\r
+        IotLogError( "Client identifier must be set." );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( false );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Check for a zero-length client identifier. Zero-length client identifiers\r
+     * are not allowed with clean sessions. */\r
+    if( pConnectInfo->clientIdentifierLength == 0 )\r
+    {\r
+        IotLogWarn( "A zero-length client identifier was provided." );\r
+\r
+        if( pConnectInfo->cleanSession == true )\r
+        {\r
+            IotLogError( "A zero-length client identifier cannot be used with a clean session." );\r
+\r
+            IOT_SET_AND_GOTO_CLEANUP( false );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Check that the number of persistent session subscriptions is valid. */\r
+    if( pConnectInfo->cleanSession == false )\r
+    {\r
+        if( pConnectInfo->pPreviousSubscriptions != NULL )\r
+        {\r
+            if( pConnectInfo->previousSubscriptionCount == 0 )\r
+            {\r
+                IotLogError( "Previous subscription count cannot be 0." );\r
+\r
+                IOT_SET_AND_GOTO_CLEANUP( false );\r
+            }\r
+            else\r
+            {\r
+                EMPTY_ELSE_MARKER;\r
+            }\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* In MQTT 3.1.1, servers are not obligated to accept client identifiers longer\r
+     * than 23 characters. */\r
+    if( pConnectInfo->clientIdentifierLength > 23 )\r
+    {\r
+        IotLogWarn( "A client identifier length of %hu is longer than 23, which is "\r
+                    "the longest client identifier a server must accept.",\r
+                    pConnectInfo->clientIdentifierLength );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Check for compatibility with the AWS IoT MQTT service limits. */\r
+    if( pConnectInfo->awsIotMqttMode == true )\r
+    {\r
+        /* Check that client identifier is within the service limit. */\r
+        if( pConnectInfo->clientIdentifierLength > AWS_IOT_MQTT_SERVER_MAX_CLIENTID )\r
+        {\r
+            IotLogError( "AWS IoT does not support client identifiers longer than %d bytes.",\r
+                         AWS_IOT_MQTT_SERVER_MAX_CLIENTID );\r
+\r
+            IOT_SET_AND_GOTO_CLEANUP( false );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        /* Check for compliance with AWS IoT keep-alive limits. */\r
+        if( pConnectInfo->keepAliveSeconds == 0 )\r
+        {\r
+            IotLogWarn( "AWS IoT does not support disabling keep-alive. Default keep-alive "\r
+                        "of %d seconds will be used.",\r
+                        AWS_IOT_MQTT_SERVER_MAX_KEEPALIVE );\r
+        }\r
+        else if( pConnectInfo->keepAliveSeconds < AWS_IOT_MQTT_SERVER_MIN_KEEPALIVE )\r
+        {\r
+            IotLogWarn( "AWS IoT does not support keep-alive intervals less than %d seconds. "\r
+                        "An interval of %d seconds will be used.",\r
+                        AWS_IOT_MQTT_SERVER_MIN_KEEPALIVE,\r
+                        AWS_IOT_MQTT_SERVER_MIN_KEEPALIVE );\r
+        }\r
+        else if( pConnectInfo->keepAliveSeconds > AWS_IOT_MQTT_SERVER_MAX_KEEPALIVE )\r
+        {\r
+            IotLogWarn( "AWS IoT does not support keep-alive intervals greater than %d seconds. "\r
+                        "An interval of %d seconds will be used.",\r
+                        AWS_IOT_MQTT_SERVER_MAX_KEEPALIVE,\r
+                        AWS_IOT_MQTT_SERVER_MAX_KEEPALIVE );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+bool _IotMqtt_ValidatePublish( bool awsIotMqttMode,\r
+                               const IotMqttPublishInfo_t * pPublishInfo )\r
+{\r
+    IOT_FUNCTION_ENTRY( bool, true );\r
+\r
+    /* Check for NULL. */\r
+    if( pPublishInfo == NULL )\r
+    {\r
+        IotLogError( "Publish information cannot be NULL." );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( false );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Check topic name for NULL or zero-length. */\r
+    if( pPublishInfo->pTopicName == NULL )\r
+    {\r
+        IotLogError( "Publish topic name must be set." );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    if( pPublishInfo->topicNameLength == 0 )\r
+    {\r
+        IotLogError( "Publish topic name length cannot be 0." );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( false );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Only allow NULL payloads with zero length. */\r
+    if( pPublishInfo->pPayload == NULL )\r
+    {\r
+        if( pPublishInfo->payloadLength != 0 )\r
+        {\r
+            IotLogError( "Nonzero payload length cannot have a NULL payload." );\r
+\r
+            IOT_SET_AND_GOTO_CLEANUP( false );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Check for a valid QoS. */\r
+    if( pPublishInfo->qos != IOT_MQTT_QOS_0 )\r
+    {\r
+        if( pPublishInfo->qos != IOT_MQTT_QOS_1 )\r
+        {\r
+            IotLogError( "Publish QoS must be either 0 or 1." );\r
+\r
+            IOT_SET_AND_GOTO_CLEANUP( false );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Check the retry parameters. */\r
+    if( pPublishInfo->retryLimit > 0 )\r
+    {\r
+        if( pPublishInfo->retryMs == 0 )\r
+        {\r
+            IotLogError( "Publish retry time must be positive." );\r
+\r
+            IOT_SET_AND_GOTO_CLEANUP( false );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Check for compatibility with AWS IoT MQTT server. */\r
+    if( awsIotMqttMode == true )\r
+    {\r
+        /* Check for retained message. */\r
+        if( pPublishInfo->retain == true )\r
+        {\r
+            IotLogError( "AWS IoT does not support retained publish messages." );\r
+\r
+            IOT_SET_AND_GOTO_CLEANUP( false );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        /* Check topic name length. */\r
+        if( pPublishInfo->topicNameLength > AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH )\r
+        {\r
+            IotLogError( "AWS IoT does not support topic names longer than %d bytes.",\r
+                         AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH );\r
+\r
+            IOT_SET_AND_GOTO_CLEANUP( false );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+bool _IotMqtt_ValidateOperation( IotMqttOperation_t operation )\r
+{\r
+    IOT_FUNCTION_ENTRY( bool, true );\r
+\r
+    /* Check for NULL. */\r
+    if( operation == NULL )\r
+    {\r
+        IotLogError( "Operation reference cannot be NULL." );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( false );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* Check that reference is waitable. */\r
+    if( ( operation->u.operation.flags & IOT_MQTT_FLAG_WAITABLE ) != IOT_MQTT_FLAG_WAITABLE )\r
+    {\r
+        IotLogError( "Operation is not waitable." );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( false );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+bool _IotMqtt_ValidateSubscriptionList( IotMqttOperationType_t operation,\r
+                                        bool awsIotMqttMode,\r
+                                        const IotMqttSubscription_t * pListStart,\r
+                                        size_t listSize )\r
+{\r
+    IOT_FUNCTION_ENTRY( bool, true );\r
+    size_t i = 0;\r
+    uint16_t j = 0;\r
+    const IotMqttSubscription_t * pListElement = NULL;\r
+\r
+    /* Operation must be either subscribe or unsubscribe. */\r
+    IotMqtt_Assert( ( operation == IOT_MQTT_SUBSCRIBE ) ||\r
+                    ( operation == IOT_MQTT_UNSUBSCRIBE ) );\r
+\r
+    /* Check for empty list. */\r
+    if( pListStart == NULL )\r
+    {\r
+        IotLogError( "Subscription list pointer cannot be NULL." );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( false );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    if( listSize == 0 )\r
+    {\r
+        IotLogError( "Empty subscription list." );\r
+\r
+        IOT_SET_AND_GOTO_CLEANUP( false );\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    /* AWS IoT supports at most 8 topic filters in a single SUBSCRIBE packet. */\r
+    if( awsIotMqttMode == true )\r
+    {\r
+        if( listSize > AWS_IOT_MQTT_SERVER_MAX_TOPIC_FILTERS_PER_SUBSCRIBE )\r
+        {\r
+            IotLogError( "AWS IoT does not support more than %d topic filters per "\r
+                         "subscription request.",\r
+                         AWS_IOT_MQTT_SERVER_MAX_TOPIC_FILTERS_PER_SUBSCRIBE );\r
+\r
+            IOT_SET_AND_GOTO_CLEANUP( false );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        EMPTY_ELSE_MARKER;\r
+    }\r
+\r
+    for( i = 0; i < listSize; i++ )\r
+    {\r
+        pListElement = &( pListStart[ i ] );\r
+\r
+        /* Check for a valid QoS and callback function when subscribing. */\r
+        if( operation == IOT_MQTT_SUBSCRIBE )\r
+        {\r
+            if( pListElement->qos != IOT_MQTT_QOS_0 )\r
+            {\r
+                if( pListElement->qos != IOT_MQTT_QOS_1 )\r
+                {\r
+                    IotLogError( "Subscription QoS must be either 0 or 1." );\r
+\r
+                    IOT_SET_AND_GOTO_CLEANUP( false );\r
+                }\r
+                else\r
+                {\r
+                    EMPTY_ELSE_MARKER;\r
+                }\r
+            }\r
+            else\r
+            {\r
+                EMPTY_ELSE_MARKER;\r
+            }\r
+\r
+            if( pListElement->callback.function == NULL )\r
+            {\r
+                IotLogError( "Callback function must be set." );\r
+\r
+                IOT_SET_AND_GOTO_CLEANUP( false );\r
+            }\r
+            else\r
+            {\r
+                EMPTY_ELSE_MARKER;\r
+            }\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        /* Check subscription topic filter. */\r
+        if( pListElement->pTopicFilter == NULL )\r
+        {\r
+            IotLogError( "Subscription topic filter cannot be NULL." );\r
+\r
+            IOT_SET_AND_GOTO_CLEANUP( false );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        if( pListElement->topicFilterLength == 0 )\r
+        {\r
+            IotLogError( "Subscription topic filter length cannot be 0." );\r
+\r
+            IOT_SET_AND_GOTO_CLEANUP( false );\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        /* Check for compatibility with AWS IoT MQTT server. */\r
+        if( awsIotMqttMode == true )\r
+        {\r
+            /* Check topic filter length. */\r
+            if( pListElement->topicFilterLength > AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH )\r
+            {\r
+                IotLogError( "AWS IoT does not support topic filters longer than %d bytes.",\r
+                             AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH );\r
+\r
+                IOT_SET_AND_GOTO_CLEANUP( false );\r
+            }\r
+            else\r
+            {\r
+                EMPTY_ELSE_MARKER;\r
+            }\r
+        }\r
+        else\r
+        {\r
+            EMPTY_ELSE_MARKER;\r
+        }\r
+\r
+        /* Check that the wildcards '+' and '#' are being used correctly. */\r
+        for( j = 0; j < pListElement->topicFilterLength; j++ )\r
+        {\r
+            switch( pListElement->pTopicFilter[ j ] )\r
+            {\r
+                /* Check that the single level wildcard '+' is used correctly. */\r
+                case '+':\r
+\r
+                    /* Unless '+' is the first character in the filter, it must be preceded by '/'. */\r
+                    if( j > 0 )\r
+                    {\r
+                        if( pListElement->pTopicFilter[ j - 1 ] != '/' )\r
+                        {\r
+                            IotLogError( "Invalid topic filter %.*s -- '+' must be preceded by '/'.",\r
+                                         pListElement->topicFilterLength,\r
+                                         pListElement->pTopicFilter );\r
+\r
+                            IOT_SET_AND_GOTO_CLEANUP( false );\r
+                        }\r
+                        else\r
+                        {\r
+                            EMPTY_ELSE_MARKER;\r
+                        }\r
+                    }\r
+                    else\r
+                    {\r
+                        EMPTY_ELSE_MARKER;\r
+                    }\r
+\r
+                    /* Unless '+' is the last character in the filter, it must be succeeded by '/'. */\r
+                    if( j < pListElement->topicFilterLength - 1 )\r
+                    {\r
+                        if( pListElement->pTopicFilter[ j + 1 ] != '/' )\r
+                        {\r
+                            IotLogError( "Invalid topic filter %.*s -- '+' must be succeeded by '/'.",\r
+                                         pListElement->topicFilterLength,\r
+                                         pListElement->pTopicFilter );\r
+\r
+                            IOT_SET_AND_GOTO_CLEANUP( false );\r
+                        }\r
+                        else\r
+                        {\r
+                            EMPTY_ELSE_MARKER;\r
+                        }\r
+                    }\r
+                    else\r
+                    {\r
+                        EMPTY_ELSE_MARKER;\r
+                    }\r
+\r
+                    break;\r
+\r
+                /* Check that the multi-level wildcard '#' is used correctly. */\r
+                case '#':\r
+\r
+                    /* '#' must be the last character in the filter. */\r
+                    if( j != pListElement->topicFilterLength - 1 )\r
+                    {\r
+                        IotLogError( "Invalid topic filter %.*s -- '#' must be the last character.",\r
+                                     pListElement->topicFilterLength,\r
+                                     pListElement->pTopicFilter );\r
+\r
+                        IOT_SET_AND_GOTO_CLEANUP( false );\r
+                    }\r
+                    else\r
+                    {\r
+                        EMPTY_ELSE_MARKER;\r
+                    }\r
+\r
+                    /* Unless '#' is standalone, it must be preceded by '/'. */\r
+                    if( pListElement->topicFilterLength > 1 )\r
+                    {\r
+                        if( pListElement->pTopicFilter[ j - 1 ] != '/' )\r
+                        {\r
+                            IotLogError( "Invalid topic filter %.*s -- '#' must be preceded by '/'.",\r
+                                         pListElement->topicFilterLength,\r
+                                         pListElement->pTopicFilter );\r
+\r
+                            IOT_SET_AND_GOTO_CLEANUP( false );\r
+                        }\r
+                        else\r
+                        {\r
+                            EMPTY_ELSE_MARKER;\r
+                        }\r
+                    }\r
+                    else\r
+                    {\r
+                        EMPTY_ELSE_MARKER;\r
+                    }\r
+\r
+                    break;\r
+\r
+                default:\r
+                    break;\r
+            }\r
+        }\r
+    }\r
+\r
+    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/private/iot_mqtt_internal.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/private/iot_mqtt_internal.h
new file mode 100644 (file)
index 0000000..80aef1c
--- /dev/null
@@ -0,0 +1,915 @@
+/*\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_internal.h\r
+ * @brief Internal header of MQTT library. This header should not be included in\r
+ * typical application code.\r
+ */\r
+\r
+#ifndef IOT_MQTT_INTERNAL_H_\r
+#define IOT_MQTT_INTERNAL_H_\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/* Linear containers (lists and queues) include. */\r
+#include "iot_linear_containers.h"\r
+\r
+/* MQTT include. */\r
+#include "iot_mqtt.h"\r
+\r
+/* Task pool include. */\r
+#include "iot_taskpool.h"\r
+\r
+/**\r
+ * @def IotMqtt_Assert( expression )\r
+ * @brief Assertion macro for the MQTT library.\r
+ *\r
+ * Set @ref IOT_MQTT_ENABLE_ASSERTS to `1` to enable assertions in the MQTT\r
+ * library.\r
+ *\r
+ * @param[in] expression Expression to be evaluated.\r
+ */\r
+#if IOT_MQTT_ENABLE_ASSERTS == 1\r
+    #ifndef IotMqtt_Assert\r
+        #include <assert.h>\r
+        #define IotMqtt_Assert( expression )    assert( expression )\r
+    #endif\r
+#else\r
+    #define IotMqtt_Assert( expression )\r
+#endif\r
+\r
+/* Configure logs for MQTT functions. */\r
+#ifdef IOT_LOG_LEVEL_MQTT\r
+    #define LIBRARY_LOG_LEVEL        IOT_LOG_LEVEL_MQTT\r
+#else\r
+    #ifdef IOT_LOG_LEVEL_GLOBAL\r
+        #define LIBRARY_LOG_LEVEL    IOT_LOG_LEVEL_GLOBAL\r
+    #else\r
+        #define LIBRARY_LOG_LEVEL    IOT_LOG_NONE\r
+    #endif\r
+#endif\r
+\r
+#define LIBRARY_LOG_NAME    ( "MQTT" )\r
+#include "iot_logging_setup.h"\r
+\r
+/*\r
+ * Provide default values for undefined memory allocation functions based on\r
+ * the usage of dynamic memory allocation.\r
+ */\r
+#if IOT_STATIC_MEMORY_ONLY == 1\r
+    #include "private/iot_static_memory.h"\r
+\r
+/**\r
+ * @brief Allocate an #_mqttConnection_t. This function should have the same\r
+ * signature as [malloc]\r
+ * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html).\r
+ */\r
+    void * IotMqtt_MallocConnection( size_t size );\r
+\r
+/**\r
+ * @brief Free an #_mqttConnection_t. This function should have the same\r
+ * signature as [free]\r
+ * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
+ */\r
+    void IotMqtt_FreeConnection( void * ptr );\r
+\r
+/**\r
+ * @brief Allocate memory for an MQTT packet. This function should have the\r
+ * same signature as [malloc]\r
+ * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html).\r
+ */\r
+    #define IotMqtt_MallocMessage    Iot_MallocMessageBuffer\r
+\r
+/**\r
+ * @brief Free an MQTT packet. This function should have the same signature\r
+ * as [free]\r
+ * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
+ */\r
+    #define IotMqtt_FreeMessage      Iot_FreeMessageBuffer\r
+\r
+/**\r
+ * @brief Allocate an #_mqttOperation_t. This function should have the same\r
+ * signature as [malloc]\r
+ * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html).\r
+ */\r
+    void * IotMqtt_MallocOperation( size_t size );\r
+\r
+/**\r
+ * @brief Free an #_mqttOperation_t. This function should have the same\r
+ * signature as [free]\r
+ * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
+ */\r
+    void IotMqtt_FreeOperation( void * ptr );\r
+\r
+/**\r
+ * @brief Allocate an #_mqttSubscription_t. This function should have the\r
+ * same signature as [malloc]\r
+ * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html).\r
+ */\r
+    void * IotMqtt_MallocSubscription( size_t size );\r
+\r
+/**\r
+ * @brief Free an #_mqttSubscription_t. This function should have the same\r
+ * signature as [free]\r
+ * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
+ */\r
+    void IotMqtt_FreeSubscription( void * ptr );\r
+#else /* if IOT_STATIC_MEMORY_ONLY == 1 */\r
+    #include <stdlib.h>\r
+\r
+    #ifndef IotMqtt_MallocConnection\r
+        #define IotMqtt_MallocConnection    malloc\r
+    #endif\r
+\r
+    #ifndef IotMqtt_FreeConnection\r
+        #define IotMqtt_FreeConnection    free\r
+    #endif\r
+\r
+    #ifndef IotMqtt_MallocMessage\r
+        #define IotMqtt_MallocMessage    malloc\r
+    #endif\r
+\r
+    #ifndef IotMqtt_FreeMessage\r
+        #define IotMqtt_FreeMessage    free\r
+    #endif\r
+\r
+    #ifndef IotMqtt_MallocOperation\r
+        #define IotMqtt_MallocOperation    malloc\r
+    #endif\r
+\r
+    #ifndef IotMqtt_FreeOperation\r
+        #define IotMqtt_FreeOperation    free\r
+    #endif\r
+\r
+    #ifndef IotMqtt_MallocSubscription\r
+        #define IotMqtt_MallocSubscription    malloc\r
+    #endif\r
+\r
+    #ifndef IotMqtt_FreeSubscription\r
+        #define IotMqtt_FreeSubscription    free\r
+    #endif\r
+#endif /* if IOT_STATIC_MEMORY_ONLY == 1 */\r
+\r
+/**\r
+ * @cond DOXYGEN_IGNORE\r
+ * Doxygen should ignore this section.\r
+ *\r
+ * Provide default values for undefined configuration constants.\r
+ */\r
+#ifndef AWS_IOT_MQTT_ENABLE_METRICS\r
+    #define AWS_IOT_MQTT_ENABLE_METRICS             ( 1 )\r
+#endif\r
+#ifndef IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES\r
+    #define IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES    ( 0 )\r
+#endif\r
+#ifndef IOT_MQTT_RESPONSE_WAIT_MS\r
+    #define IOT_MQTT_RESPONSE_WAIT_MS               ( 1000 )\r
+#endif\r
+#ifndef IOT_MQTT_RETRY_MS_CEILING\r
+    #define IOT_MQTT_RETRY_MS_CEILING               ( 60000 )\r
+#endif\r
+/** @endcond */\r
+\r
+/**\r
+ * @brief Marks the empty statement of an `else` branch.\r
+ *\r
+ * Does nothing, but allows test coverage to detect branches not taken. By default,\r
+ * this is defined to nothing. When running code coverage testing, this is defined\r
+ * to an assembly NOP.\r
+ */\r
+#ifndef EMPTY_ELSE_MARKER\r
+    #define EMPTY_ELSE_MARKER\r
+#endif\r
+\r
+/*\r
+ * Constants related to limits defined in AWS Service Limits.\r
+ *\r
+ * For details, see\r
+ * https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html\r
+ *\r
+ * Used to validate parameters if when connecting to an AWS IoT MQTT server.\r
+ */\r
+#define AWS_IOT_MQTT_SERVER_MIN_KEEPALIVE                      ( 30 )   /**< @brief Minumum keep-alive interval accepted by AWS IoT. */\r
+#define AWS_IOT_MQTT_SERVER_MAX_KEEPALIVE                      ( 1200 ) /**< @brief Maximum keep-alive interval accepted by AWS IoT. */\r
+#define AWS_IOT_MQTT_SERVER_MAX_CLIENTID                       ( 128 )  /**< @brief Maximum length of client identifier accepted by AWS IoT. */\r
+#define AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH                   ( 256 )  /**< @brief Maximum length of topic names or filters accepted by AWS IoT. */\r
+#define AWS_IOT_MQTT_SERVER_MAX_TOPIC_FILTERS_PER_SUBSCRIBE    ( 8 )    /**< @brief Maximum number of topic filters in a single SUBSCRIBE packet. */\r
+\r
+/*\r
+ * MQTT control packet type and flags. Always the first byte of an MQTT\r
+ * packet.\r
+ *\r
+ * For details, see\r
+ * http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/csprd02/mqtt-v3.1.1-csprd02.html#_Toc385349757\r
+ */\r
+#define MQTT_PACKET_TYPE_CONNECT                               ( ( uint8_t ) 0x10U ) /**< @brief CONNECT (client-to-server). */\r
+#define MQTT_PACKET_TYPE_CONNACK                               ( ( uint8_t ) 0x20U ) /**< @brief CONNACK (server-to-client). */\r
+#define MQTT_PACKET_TYPE_PUBLISH                               ( ( uint8_t ) 0x30U ) /**< @brief PUBLISH (bi-directional). */\r
+#define MQTT_PACKET_TYPE_PUBACK                                ( ( uint8_t ) 0x40U ) /**< @brief PUBACK (server-to-client). */\r
+#define MQTT_PACKET_TYPE_SUBSCRIBE                             ( ( uint8_t ) 0x82U ) /**< @brief SUBSCRIBE (client-to-server). */\r
+#define MQTT_PACKET_TYPE_SUBACK                                ( ( uint8_t ) 0x90U ) /**< @brief SUBACK (server-to-client). */\r
+#define MQTT_PACKET_TYPE_UNSUBSCRIBE                           ( ( uint8_t ) 0xa2U ) /**< @brief UNSUBSCRIBE (client-to-server). */\r
+#define MQTT_PACKET_TYPE_UNSUBACK                              ( ( uint8_t ) 0xb0U ) /**< @brief UNSUBACK (server-to-client). */\r
+#define MQTT_PACKET_TYPE_PINGREQ                               ( ( uint8_t ) 0xc0U ) /**< @brief PINGREQ (client-to-server). */\r
+#define MQTT_PACKET_TYPE_PINGRESP                              ( ( uint8_t ) 0xd0U ) /**< @brief PINGRESP (server-to-client). */\r
+#define MQTT_PACKET_TYPE_DISCONNECT                            ( ( uint8_t ) 0xe0U ) /**< @brief DISCONNECT (client-to-server). */\r
+\r
+/**\r
+ * @brief A value that represents an invalid remaining length.\r
+ *\r
+ * This value is greater than what is allowed by the MQTT specification.\r
+ */\r
+#define MQTT_REMAINING_LENGTH_INVALID                          ( ( size_t ) 268435456 )\r
+\r
+/*---------------------- MQTT internal data structures ----------------------*/\r
+\r
+/**\r
+ * @brief Represents an MQTT connection.\r
+ */\r
+typedef struct _mqttConnection\r
+{\r
+    bool awsIotMqttMode;                             /**< @brief Specifies if this connection is to an AWS IoT MQTT server. */\r
+    bool ownNetworkConnection;                       /**< @brief Whether this MQTT connection owns its network connection. */\r
+    void * pNetworkConnection;                       /**< @brief References the transport-layer network connection. */\r
+    const IotNetworkInterface_t * pNetworkInterface; /**< @brief Network interface provided to @ref mqtt_function_connect. */\r
+    IotMqttCallbackInfo_t disconnectCallback;        /**< @brief A function to invoke when this connection is disconnected. */\r
+\r
+    #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
+        const IotMqttSerializer_t * pSerializer; /**< @brief MQTT packet serializer overrides. */\r
+    #endif\r
+\r
+    bool disconnected;                              /**< @brief Tracks if this connection has been disconnected. */\r
+    IotMutex_t referencesMutex;                     /**< @brief Recursive mutex. Grants access to connection state and operation lists. */\r
+    int32_t references;                             /**< @brief Counts callbacks and operations using this connection. */\r
+    IotListDouble_t pendingProcessing;              /**< @brief List of operations waiting to be processed by a task pool routine. */\r
+    IotListDouble_t pendingResponse;                /**< @brief List of processed operations awaiting a server response. */\r
+\r
+    IotListDouble_t subscriptionList;               /**< @brief Holds subscriptions associated with this connection. */\r
+    IotMutex_t subscriptionMutex;                   /**< @brief Grants exclusive access to the subscription list. */\r
+\r
+    bool keepAliveFailure;                          /**< @brief Failure flag for keep-alive operation. */\r
+    uint32_t keepAliveMs;                           /**< @brief Keep-alive interval in milliseconds. Its max value (per spec) is 65,535,000. */\r
+    uint32_t nextKeepAliveMs;                       /**< @brief Relative delay for next keep-alive job. */\r
+    IotTaskPoolJobStorage_t keepAliveJobStorage;     /**< @brief Task pool job for processing this connection's keep-alive. */\r
+    IotTaskPoolJob_t keepAliveJob;                  /**< @brief Task pool job for processing this connection's keep-alive. */\r
+    uint8_t * pPingreqPacket;                       /**< @brief An MQTT PINGREQ packet, allocated if keep-alive is active. */\r
+    size_t pingreqPacketSize;                       /**< @brief The size of an allocated PINGREQ packet. */\r
+} _mqttConnection_t;\r
+\r
+/**\r
+ * @brief Represents a subscription stored in an MQTT connection.\r
+ */\r
+typedef struct _mqttSubscription\r
+{\r
+    IotLink_t link;     /**< @brief List link member. */\r
+\r
+    int32_t references; /**< @brief How many subscription callbacks are using this subscription. */\r
+\r
+    /**\r
+     * @brief Tracks whether @ref mqtt_function_unsubscribe has been called for\r
+     * this subscription.\r
+     *\r
+     * If there are active subscription callbacks, @ref mqtt_function_unsubscribe\r
+     * cannot remove this subscription. Instead, it will set this flag, which\r
+     * schedules the removal of this subscription once all subscription callbacks\r
+     * terminate.\r
+     */\r
+    bool unsubscribed;\r
+\r
+    struct\r
+    {\r
+        uint16_t identifier;        /**< @brief Packet identifier. */\r
+        size_t order;               /**< @brief Order in the packet's list of subscriptions. */\r
+    } packetInfo;                   /**< @brief Information about the SUBSCRIBE packet that registered this subscription. */\r
+\r
+    IotMqttCallbackInfo_t callback; /**< @brief Callback information for this subscription. */\r
+\r
+    uint16_t topicFilterLength;     /**< @brief Length of #_mqttSubscription_t.pTopicFilter. */\r
+    char pTopicFilter[];            /**< @brief The subscription topic filter. */\r
+} _mqttSubscription_t;\r
+\r
+/**\r
+ * @brief Internal structure representing a single MQTT operation, such as\r
+ * CONNECT, SUBSCRIBE, PUBLISH, etc.\r
+ *\r
+ * Queues of these structures keeps track of all in-progress MQTT operations.\r
+ */\r
+typedef struct _mqttOperation\r
+{\r
+    /* Pointers to neighboring queue elements. */\r
+    IotLink_t link;                      /**< @brief List link member. */\r
+\r
+    bool incomingPublish;                /**< @brief Set to true if this operation an incoming PUBLISH. */\r
+    _mqttConnection_t * pMqttConnection; /**< @brief MQTT connection associated with this operation. */\r
+\r
+    IotTaskPoolJobStorage_t jobStorage;  /**< @brief Task pool job storage associated with this operation. */\r
+    IotTaskPoolJob_t job;                /**< @brief Task pool job associated with this operation. */\r
+\r
+    union\r
+    {\r
+        /* If incomingPublish is false, this struct is valid. */\r
+        struct\r
+        {\r
+            /* Basic operation information. */\r
+            int32_t jobReference;        /**< @brief Tracks if a job is using this operation. Must always be 0, 1, or 2. */\r
+            IotMqttOperationType_t type; /**< @brief What operation this structure represents. */\r
+            uint32_t flags;              /**< @brief Flags passed to the function that created this operation. */\r
+            uint16_t packetIdentifier;   /**< @brief The packet identifier used with this operation. */\r
+\r
+            /* Serialized packet and size. */\r
+            uint8_t * pMqttPacket;           /**< @brief The MQTT packet to send over the network. */\r
+            uint8_t * pPacketIdentifierHigh; /**< @brief The location of the high byte of the packet identifier in the MQTT packet. */\r
+            size_t packetSize;               /**< @brief Size of `pMqttPacket`. */\r
+\r
+            /* How to notify of an operation's completion. */\r
+            union\r
+            {\r
+                IotSemaphore_t waitSemaphore;   /**< @brief Semaphore to be used with @ref mqtt_function_wait. */\r
+                IotMqttCallbackInfo_t callback; /**< @brief User-provided callback function and parameter. */\r
+            } notify;                           /**< @brief How to notify of this operation's completion. */\r
+            IotMqttError_t status;              /**< @brief Result of this operation. This is reported once a response is received. */\r
+\r
+            struct\r
+            {\r
+                uint32_t count;\r
+                uint32_t limit;\r
+                uint32_t nextPeriod;\r
+            } retry;\r
+        } operation;\r
+\r
+        /* If incomingPublish is true, this struct is valid. */\r
+        struct\r
+        {\r
+            IotMqttPublishInfo_t publishInfo; /**< @brief Deserialized PUBLISH. */\r
+            const void * pReceivedData;       /**< @brief Any buffer associated with this PUBLISH that should be freed. */\r
+        } publish;\r
+    } u;                                      /**< @brief Valid member depends on _mqttOperation_t.incomingPublish. */\r
+} _mqttOperation_t;\r
+\r
+/**\r
+ * @brief Represents an MQTT packet received from the network.\r
+ *\r
+ * This struct is used to hold parameters for the deserializers so that all\r
+ * deserializers have the same function signature.\r
+ */\r
+typedef struct _mqttPacket\r
+{\r
+    union\r
+    {\r
+        /**\r
+         * @brief (Input) MQTT connection associated with this packet. Only used\r
+         * when deserializing SUBACKs.\r
+         */\r
+        _mqttConnection_t * pMqttConnection;\r
+\r
+        /**\r
+         * @brief (Output) Operation representing an incoming PUBLISH. Only used\r
+         * when deserializing PUBLISHes.\r
+         */\r
+        _mqttOperation_t * pIncomingPublish;\r
+    } u;                       /**< @brief Valid member depends on packet being decoded. */\r
+\r
+    uint8_t * pRemainingData;  /**< @brief (Input) The remaining data in MQTT packet. */\r
+    size_t remainingLength;    /**< @brief (Input) Length of the remaining data in the MQTT packet. */\r
+    uint16_t packetIdentifier; /**< @brief (Output) MQTT packet identifier. */\r
+    uint8_t type;              /**< @brief (Input) A value identifying the packet type. */\r
+} _mqttPacket_t;\r
+\r
+/*-------------------- MQTT struct validation functions ---------------------*/\r
+\r
+/**\r
+ * @brief Check that an #IotMqttConnectInfo_t is valid.\r
+ *\r
+ * @param[in] pConnectInfo The #IotMqttConnectInfo_t to validate.\r
+ *\r
+ * @return `true` if `pConnectInfo` is valid; `false` otherwise.\r
+ */\r
+bool _IotMqtt_ValidateConnect( const IotMqttConnectInfo_t * pConnectInfo );\r
+\r
+/**\r
+ * @brief Check that an #IotMqttPublishInfo_t is valid.\r
+ *\r
+ * @param[in] awsIotMqttMode Specifies if this PUBLISH packet is being sent to\r
+ * an AWS IoT MQTT server.\r
+ * @param[in] pPublishInfo The #IotMqttPublishInfo_t to validate.\r
+ *\r
+ * @return `true` if `pPublishInfo` is valid; `false` otherwise.\r
+ */\r
+bool _IotMqtt_ValidatePublish( bool awsIotMqttMode,\r
+                               const IotMqttPublishInfo_t * pPublishInfo );\r
+\r
+/**\r
+ * @brief Check that an #IotMqttOperation_t is valid and waitable.\r
+ *\r
+ * @param[in] operation The #IotMqttOperation_t to validate.\r
+ *\r
+ * @return `true` if `operation` is valid; `false` otherwise.\r
+ */\r
+bool _IotMqtt_ValidateOperation( IotMqttOperation_t operation );\r
+\r
+/**\r
+ * @brief Check that a list of #IotMqttSubscription_t is valid.\r
+ *\r
+ * @param[in] operation Either #IOT_MQTT_SUBSCRIBE or #IOT_MQTT_UNSUBSCRIBE.\r
+ * Some parameters are not validated for #IOT_MQTT_UNSUBSCRIBE.\r
+ * @param[in] awsIotMqttMode Specifies if this SUBSCRIBE packet is being sent to\r
+ * an AWS IoT MQTT server.\r
+ * @param[in] pListStart First element of the list to validate.\r
+ * @param[in] listSize Number of elements in the subscription list.\r
+ *\r
+ * @return `true` if every element in the list is valid; `false` otherwise.\r
+ */\r
+bool _IotMqtt_ValidateSubscriptionList( IotMqttOperationType_t operation,\r
+                                        bool awsIotMqttMode,\r
+                                        const IotMqttSubscription_t * pListStart,\r
+                                        size_t listSize );\r
+\r
+/*-------------------- MQTT packet serializer functions ---------------------*/\r
+\r
+/**\r
+ * @brief Get the MQTT packet type from a stream of bytes off the network.\r
+ *\r
+ * @param[in] pNetworkConnection Reference to the network connection.\r
+ * @param[in] pNetworkInterface Function pointers used to interact with the\r
+ * network.\r
+ *\r
+ * @return One of the server-to-client MQTT packet types.\r
+ *\r
+ * @note This function is only used for incoming packets, and may not work\r
+ * correctly for outgoing packets.\r
+ */\r
+uint8_t _IotMqtt_GetPacketType( void * pNetworkConnection,\r
+                                const IotNetworkInterface_t * pNetworkInterface );\r
+\r
+/**\r
+ * @brief Get the remaining length from a stream of bytes off the network.\r
+ *\r
+ * @param[in] pNetworkConnection Reference to the network connection.\r
+ * @param[in] pNetworkInterface Function pointers used to interact with the\r
+ * network.\r
+ *\r
+ * @return The remaining length; #MQTT_REMAINING_LENGTH_INVALID on error.\r
+ */\r
+size_t _IotMqtt_GetRemainingLength( void * pNetworkConnection,\r
+                                    const IotNetworkInterface_t * pNetworkInterface );\r
+\r
+/**\r
+ * @brief Generate a CONNECT packet from the given parameters.\r
+ *\r
+ * @param[in] pConnectInfo User-provided CONNECT information.\r
+ * @param[out] pConnectPacket Where the CONNECT packet is written.\r
+ * @param[out] pPacketSize Size of the packet written to `pConnectPacket`.\r
+ *\r
+ * @return #IOT_MQTT_SUCCESS or #IOT_MQTT_NO_MEMORY.\r
+ */\r
+IotMqttError_t _IotMqtt_SerializeConnect( const IotMqttConnectInfo_t * pConnectInfo,\r
+                                          uint8_t ** pConnectPacket,\r
+                                          size_t * pPacketSize );\r
+\r
+/**\r
+ * @brief Deserialize a CONNACK packet.\r
+ *\r
+ * Converts the packet from a stream of bytes to an #IotMqttError_t. Also\r
+ * prints out debug log messages about the packet.\r
+ *\r
+ * @param[in,out] pConnack Pointer to an MQTT packet struct representing a CONNACK.\r
+ *\r
+ * @return #IOT_MQTT_SUCCESS if CONNACK specifies that CONNECT was accepted;\r
+ * #IOT_MQTT_SERVER_REFUSED if CONNACK specifies that CONNECT was rejected;\r
+ * #IOT_MQTT_BAD_RESPONSE if the CONNACK packet doesn't follow MQTT spec.\r
+ */\r
+IotMqttError_t _IotMqtt_DeserializeConnack( _mqttPacket_t * pConnack );\r
+\r
+/**\r
+ * @brief Generate a PUBLISH packet from the given parameters.\r
+ *\r
+ * @param[in] pPublishInfo User-provided PUBLISH information.\r
+ * @param[out] pPublishPacket Where the PUBLISH packet is written.\r
+ * @param[out] pPacketSize Size of the packet written to `pPublishPacket`.\r
+ * @param[out] pPacketIdentifier The packet identifier generated for this PUBLISH.\r
+ * @param[out] pPacketIdentifierHigh Where the high byte of the packet identifier\r
+ * is written.\r
+ *\r
+ * @return #IOT_MQTT_SUCCESS or #IOT_MQTT_NO_MEMORY.\r
+ */\r
+IotMqttError_t _IotMqtt_SerializePublish( const IotMqttPublishInfo_t * pPublishInfo,\r
+                                          uint8_t ** pPublishPacket,\r
+                                          size_t * pPacketSize,\r
+                                          uint16_t * pPacketIdentifier,\r
+                                          uint8_t ** pPacketIdentifierHigh );\r
+\r
+/**\r
+ * @brief Set the DUP bit in a QoS 1 PUBLISH packet.\r
+ *\r
+ * @param[in] pPublishPacket Pointer to the PUBLISH packet to modify.\r
+ * @param[in] pPacketIdentifierHigh The high byte of any packet identifier to modify.\r
+ * @param[out] pNewPacketIdentifier Since AWS IoT does not support the DUP flag,\r
+ * a new packet identifier is generated and should be written here. This parameter\r
+ * is only used when connected to an AWS IoT MQTT server.\r
+ *\r
+ * @note See #IotMqttPublishInfo_t for caveats with retransmission to the\r
+ * AWS IoT MQTT server.\r
+ */\r
+void _IotMqtt_PublishSetDup( uint8_t * pPublishPacket,\r
+                             uint8_t * pPacketIdentifierHigh,\r
+                             uint16_t * pNewPacketIdentifier );\r
+\r
+/**\r
+ * @brief Deserialize a PUBLISH packet received from the server.\r
+ *\r
+ * Converts the packet from a stream of bytes to an #IotMqttPublishInfo_t and\r
+ * extracts the packet identifier. Also prints out debug log messages about the\r
+ * packet.\r
+ *\r
+ * @param[in,out] pPublish Pointer to an MQTT packet struct representing a PUBLISH.\r
+ *\r
+ * @return #IOT_MQTT_SUCCESS if PUBLISH is valid; #IOT_MQTT_BAD_RESPONSE\r
+ * if the PUBLISH packet doesn't follow MQTT spec.\r
+ */\r
+IotMqttError_t _IotMqtt_DeserializePublish( _mqttPacket_t * pPublish );\r
+\r
+/**\r
+ * @brief Generate a PUBACK packet for the given packet identifier.\r
+ *\r
+ * @param[in] packetIdentifier The packet identifier to place in PUBACK.\r
+ * @param[out] pPubackPacket Where the PUBACK packet is written.\r
+ * @param[out] pPacketSize Size of the packet written to `pPubackPacket`.\r
+ *\r
+ * @return #IOT_MQTT_SUCCESS or #IOT_MQTT_NO_MEMORY.\r
+ */\r
+IotMqttError_t _IotMqtt_SerializePuback( uint16_t packetIdentifier,\r
+                                         uint8_t ** pPubackPacket,\r
+                                         size_t * pPacketSize );\r
+\r
+/**\r
+ * @brief Deserialize a PUBACK packet.\r
+ *\r
+ * Converts the packet from a stream of bytes to an #IotMqttError_t and extracts\r
+ * the packet identifier. Also prints out debug log messages about the packet.\r
+ *\r
+ * @param[in,out] pPuback Pointer to an MQTT packet struct representing a PUBACK.\r
+ *\r
+ * @return #IOT_MQTT_SUCCESS if PUBACK is valid; #IOT_MQTT_BAD_RESPONSE\r
+ * if the PUBACK packet doesn't follow MQTT spec.\r
+ */\r
+IotMqttError_t _IotMqtt_DeserializePuback( _mqttPacket_t * pPuback );\r
+\r
+/**\r
+ * @brief Generate a SUBSCRIBE packet from the given parameters.\r
+ *\r
+ * @param[in] pSubscriptionList User-provided array of subscriptions.\r
+ * @param[in] subscriptionCount Size of `pSubscriptionList`.\r
+ * @param[out] pSubscribePacket Where the SUBSCRIBE packet is written.\r
+ * @param[out] pPacketSize Size of the packet written to `pSubscribePacket`.\r
+ * @param[out] pPacketIdentifier The packet identifier generated for this SUBSCRIBE.\r
+ *\r
+ * @return #IOT_MQTT_SUCCESS or #IOT_MQTT_NO_MEMORY.\r
+ */\r
+IotMqttError_t _IotMqtt_SerializeSubscribe( const IotMqttSubscription_t * pSubscriptionList,\r
+                                            size_t subscriptionCount,\r
+                                            uint8_t ** pSubscribePacket,\r
+                                            size_t * pPacketSize,\r
+                                            uint16_t * pPacketIdentifier );\r
+\r
+/**\r
+ * @brief Deserialize a SUBACK packet.\r
+ *\r
+ * Converts the packet from a stream of bytes to an #IotMqttError_t and extracts\r
+ * the packet identifier. Also prints out debug log messages about the packet.\r
+ *\r
+ * @param[in,out] pSuback Pointer to an MQTT packet struct representing a SUBACK.\r
+ *\r
+ * @return #IOT_MQTT_SUCCESS if SUBACK is valid; #IOT_MQTT_BAD_RESPONSE\r
+ * if the SUBACK packet doesn't follow MQTT spec.\r
+ */\r
+IotMqttError_t _IotMqtt_DeserializeSuback( _mqttPacket_t * pSuback );\r
+\r
+/**\r
+ * @brief Generate an UNSUBSCRIBE packet from the given parameters.\r
+ *\r
+ * @param[in] pSubscriptionList User-provided array of subscriptions to remove.\r
+ * @param[in] subscriptionCount Size of `pSubscriptionList`.\r
+ * @param[out] pUnsubscribePacket Where the UNSUBSCRIBE packet is written.\r
+ * @param[out] pPacketSize Size of the packet written to `pUnsubscribePacket`.\r
+ * @param[out] pPacketIdentifier The packet identifier generated for this UNSUBSCRIBE.\r
+ *\r
+ * @return #IOT_MQTT_SUCCESS or #IOT_MQTT_NO_MEMORY.\r
+ */\r
+IotMqttError_t _IotMqtt_SerializeUnsubscribe( const IotMqttSubscription_t * pSubscriptionList,\r
+                                              size_t subscriptionCount,\r
+                                              uint8_t ** pUnsubscribePacket,\r
+                                              size_t * pPacketSize,\r
+                                              uint16_t * pPacketIdentifier );\r
+\r
+/**\r
+ * @brief Deserialize a UNSUBACK packet.\r
+ *\r
+ * Converts the packet from a stream of bytes to an #IotMqttError_t and extracts\r
+ * the packet identifier. Also prints out debug log messages about the packet.\r
+ *\r
+ * @param[in,out] pUnsuback Pointer to an MQTT packet struct representing an UNSUBACK.\r
+ *\r
+ * @return #IOT_MQTT_SUCCESS if UNSUBACK is valid; #IOT_MQTT_BAD_RESPONSE\r
+ * if the UNSUBACK packet doesn't follow MQTT spec.\r
+ */\r
+IotMqttError_t _IotMqtt_DeserializeUnsuback( _mqttPacket_t * pUnsuback );\r
+\r
+/**\r
+ * @brief Generate a PINGREQ packet.\r
+ *\r
+ * @param[out] pPingreqPacket Where the PINGREQ packet is written.\r
+ * @param[out] pPacketSize Size of the packet written to `pPingreqPacket`.\r
+ *\r
+ * @return Always returns #IOT_MQTT_SUCCESS.\r
+ */\r
+IotMqttError_t _IotMqtt_SerializePingreq( uint8_t ** pPingreqPacket,\r
+                                          size_t * pPacketSize );\r
+\r
+/**\r
+ * @brief Deserialize a PINGRESP packet.\r
+ *\r
+ * Converts the packet from a stream of bytes to an #IotMqttError_t. Also\r
+ * prints out debug log messages about the packet.\r
+ *\r
+ * @param[in,out] pPingresp Pointer to an MQTT packet struct representing a PINGRESP.\r
+ *\r
+ * @return #IOT_MQTT_SUCCESS if PINGRESP is valid; #IOT_MQTT_BAD_RESPONSE\r
+ * if the PINGRESP packet doesn't follow MQTT spec.\r
+ */\r
+IotMqttError_t _IotMqtt_DeserializePingresp( _mqttPacket_t * pPingresp );\r
+\r
+/**\r
+ * @brief Generate a DISCONNECT packet.\r
+ *\r
+ * @param[out] pDisconnectPacket Where the DISCONNECT packet is written.\r
+ * @param[out] pPacketSize Size of the packet written to `pDisconnectPacket`.\r
+ *\r
+ * @return Always returns #IOT_MQTT_SUCCESS.\r
+ */\r
+IotMqttError_t _IotMqtt_SerializeDisconnect( uint8_t ** pDisconnectPacket,\r
+                                             size_t * pPacketSize );\r
+\r
+/**\r
+ * @brief Free a packet generated by the serializer.\r
+ *\r
+ * @param[in] pPacket The packet to free.\r
+ */\r
+void _IotMqtt_FreePacket( uint8_t * pPacket );\r
+\r
+/*-------------------- MQTT operation record functions ----------------------*/\r
+\r
+/**\r
+ * @brief Create a record for a new in-progress MQTT operation.\r
+ *\r
+ * @param[in] pMqttConnection The MQTT connection to associate with the operation.\r
+ * @param[in] flags Flags variable passed to a user-facing MQTT function.\r
+ * @param[in] pCallbackInfo User-provided callback function and parameter.\r
+ * @param[out] pNewOperation Set to point to the new operation on success.\r
+ *\r
+ * @return #IOT_MQTT_SUCCESS, #IOT_MQTT_BAD_PARAMETER, or #IOT_MQTT_NO_MEMORY.\r
+ */\r
+IotMqttError_t _IotMqtt_CreateOperation( _mqttConnection_t * pMqttConnection,\r
+                                         uint32_t flags,\r
+                                         const IotMqttCallbackInfo_t * pCallbackInfo,\r
+                                         _mqttOperation_t ** pNewOperation );\r
+\r
+/**\r
+ * @brief Decrement the job reference count of an MQTT operation and optionally\r
+ * cancel its job.\r
+ *\r
+ * Checks if the operation may be destroyed afterwards.\r
+ *\r
+ * @param[in] pOperation The MQTT operation with the job to cancel.\r
+ * @param[in] cancelJob Whether to attempt cancellation of the operation's job.\r
+ *\r
+ * @return `true` if the the operation may be safely destroyed; `false` otherwise.\r
+ */\r
+bool _IotMqtt_DecrementOperationReferences( _mqttOperation_t * pOperation,\r
+                                            bool cancelJob );\r
+\r
+/**\r
+ * @brief Free resources used to record an MQTT operation. This is called when\r
+ * the operation completes.\r
+ *\r
+ * @param[in] pOperation The operation which completed.\r
+ */\r
+void _IotMqtt_DestroyOperation( _mqttOperation_t * pOperation );\r
+\r
+/**\r
+ * @brief Task pool routine for processing an MQTT connection's keep-alive.\r
+ *\r
+ * @param[in] pTaskPool Pointer to the system task pool.\r
+ * @param[in] pKeepAliveJob Pointer the an MQTT connection's keep-alive job.\r
+ * @param[in] pContext Pointer to an MQTT connection, passed as an opaque context.\r
+ */\r
+void _IotMqtt_ProcessKeepAlive( IotTaskPool_t pTaskPool,\r
+                                IotTaskPoolJob_t pKeepAliveJob,\r
+                                void * pContext );\r
+\r
+/**\r
+ * @brief Task pool routine for processing an incoming PUBLISH message.\r
+ *\r
+ * @param[in] pTaskPool Pointer to the system task pool.\r
+ * @param[in] pPublishJob Pointer to the incoming PUBLISH operation's job.\r
+ * @param[in] pContext Pointer to the incoming PUBLISH operation, passed as an\r
+ * opaque context.\r
+ */\r
+void _IotMqtt_ProcessIncomingPublish( IotTaskPool_t pTaskPool,\r
+                                      IotTaskPoolJob_t pPublishJob,\r
+                                      void * pContext );\r
+\r
+/**\r
+ * @brief Task pool routine for processing an MQTT operation to send.\r
+ *\r
+ * @param[in] pTaskPool Pointer to the system task pool.\r
+ * @param[in] pSendJob Pointer to an operation's job.\r
+ * @param[in] pContext Pointer to the operation to send, passed as an opaque\r
+ * context.\r
+ */\r
+void _IotMqtt_ProcessSend( IotTaskPool_t pTaskPool,\r
+                           IotTaskPoolJob_t pSendJob,\r
+                           void * pContext );\r
+\r
+/**\r
+ * @brief Task pool routine for processing a completed MQTT operation.\r
+ *\r
+ * @param[in] pTaskPool Pointer to the system task pool.\r
+ * @param[in] pOperationJob Pointer to the completed operation's job.\r
+ * @param[in] pContext Pointer to the completed operation, passed as an opaque\r
+ * context.\r
+ */\r
+void _IotMqtt_ProcessCompletedOperation( IotTaskPool_t pTaskPool,\r
+                                         IotTaskPoolJob_t pOperationJob,\r
+                                         void * pContext );\r
+\r
+/**\r
+ * @brief Schedule an operation for immediate processing.\r
+ *\r
+ * @param[in] pOperation The operation to schedule.\r
+ * @param[in] jobRoutine The routine to run for the job. Must be either\r
+ * #_IotMqtt_ProcessSend, #_IotMqtt_ProcessCompletedOperation, or\r
+ * #_IotMqtt_ProcessIncomingPublish.\r
+ * @param[in] delay A delay before the operation job should be executed. Pass\r
+ * `0` to execute ASAP.\r
+ *\r
+ * @return #IOT_MQTT_SUCCESS or #IOT_MQTT_SCHEDULING_ERROR.\r
+ */\r
+IotMqttError_t _IotMqtt_ScheduleOperation( _mqttOperation_t * pOperation,\r
+                                           IotTaskPoolRoutine_t jobRoutine,\r
+                                           uint32_t delay );\r
+\r
+/**\r
+ * @brief Search a list of MQTT operations pending responses using an operation\r
+ * name and packet identifier. Removes a matching operation from the list if found.\r
+ *\r
+ * @param[in] pMqttConnection The connection associated with the operation.\r
+ * @param[in] type The operation type to look for.\r
+ * @param[in] pPacketIdentifier A packet identifier to match. Pass `NULL` to ignore.\r
+ *\r
+ * @return Pointer to any matching operation; `NULL` if no match was found.\r
+ */\r
+_mqttOperation_t * _IotMqtt_FindOperation( _mqttConnection_t * pMqttConnection,\r
+                                           IotMqttOperationType_t type,\r
+                                           const uint16_t * pPacketIdentifier );\r
+\r
+/**\r
+ * @brief Notify of a completed MQTT operation.\r
+ *\r
+ * @param[in] pOperation The MQTT operation which completed.\r
+ *\r
+ * Depending on the parameters passed to a user-facing MQTT function, the\r
+ * notification will cause @ref mqtt_function_wait to return or invoke a\r
+ * user-provided callback.\r
+ */\r
+void _IotMqtt_Notify( _mqttOperation_t * pOperation );\r
+\r
+/*----------------- MQTT subscription management functions ------------------*/\r
+\r
+/**\r
+ * @brief Add an array of subscriptions to the subscription manager.\r
+ *\r
+ * @param[in] pMqttConnection The MQTT connection associated with the subscriptions.\r
+ * @param[in] subscribePacketIdentifier Packet identifier for the subscriptions'\r
+ * SUBSCRIBE packet.\r
+ * @param[in] pSubscriptionList The first element in the array.\r
+ * @param[in] subscriptionCount Number of elements in `pSubscriptionList`.\r
+ *\r
+ * @return #IOT_MQTT_SUCCESS or #IOT_MQTT_NO_MEMORY.\r
+ */\r
+IotMqttError_t _IotMqtt_AddSubscriptions( _mqttConnection_t * pMqttConnection,\r
+                                          uint16_t subscribePacketIdentifier,\r
+                                          const IotMqttSubscription_t * pSubscriptionList,\r
+                                          size_t subscriptionCount );\r
+\r
+/**\r
+ * @brief Process a received PUBLISH from the server, invoking any subscription\r
+ * callbacks that have a matching topic filter.\r
+ *\r
+ * @param[in] pMqttConnection The MQTT connection associated with the received\r
+ * PUBLISH.\r
+ * @param[in] pCallbackParam The parameter to pass to a PUBLISH callback.\r
+ */\r
+void _IotMqtt_InvokeSubscriptionCallback( _mqttConnection_t * pMqttConnection,\r
+                                          IotMqttCallbackParam_t * pCallbackParam );\r
+\r
+/**\r
+ * @brief Remove a single subscription from the subscription manager by\r
+ * packetIdentifier and order.\r
+ *\r
+ * @param[in] pMqttConnection The MQTT connection associated with the subscriptions.\r
+ * @param[in] packetIdentifier The packet identifier associated with the subscription's\r
+ * SUBSCRIBE packet.\r
+ * @param[in] order The order of the subscription in the SUBSCRIBE packet.\r
+ * Pass `-1` to ignore order and remove all subscriptions for `packetIdentifier`.\r
+ */\r
+void _IotMqtt_RemoveSubscriptionByPacket( _mqttConnection_t * pMqttConnection,\r
+                                          uint16_t packetIdentifier,\r
+                                          int32_t order );\r
+\r
+/**\r
+ * @brief Remove an array of subscriptions from the subscription manager by\r
+ * topic filter.\r
+ *\r
+ * @param[in] pMqttConnection The MQTT connection associated with the subscriptions.\r
+ * @param[in] pSubscriptionList The first element in the array.\r
+ * @param[in] subscriptionCount Number of elements in `pSubscriptionList`.\r
+ */\r
+void _IotMqtt_RemoveSubscriptionByTopicFilter( _mqttConnection_t * pMqttConnection,\r
+                                               const IotMqttSubscription_t * pSubscriptionList,\r
+                                               size_t subscriptionCount );\r
+\r
+/*------------------ MQTT connection management functions -------------------*/\r
+\r
+/**\r
+ * @brief Attempt to increment the reference count of an MQTT connection.\r
+ *\r
+ * @param[in] pMqttConnection The referenced MQTT connection.\r
+ *\r
+ * @return `true` if the reference count was incremented; `false` otherwise. The\r
+ * reference count will not be incremented for a disconnected connection.\r
+ */\r
+bool _IotMqtt_IncrementConnectionReferences( _mqttConnection_t * pMqttConnection );\r
+\r
+/**\r
+ * @brief Decrement the reference count of an MQTT connection.\r
+ *\r
+ * Also destroys an unreferenced MQTT connection.\r
+ *\r
+ * @param[in] pMqttConnection The referenced MQTT connection.\r
+ */\r
+void _IotMqtt_DecrementConnectionReferences( _mqttConnection_t * pMqttConnection );\r
+\r
+/**\r
+ * @brief Read the next available byte on a network connection.\r
+ *\r
+ * @param[in] pNetworkConnection Reference to the network connection.\r
+ * @param[in] pNetworkInterface Function pointers used to interact with the\r
+ * network.\r
+ * @param[out] pIncomingByte The byte read from the network.\r
+ *\r
+ * @return `true` if a byte was successfully received from the network; `false`\r
+ * otherwise.\r
+ */\r
+bool _IotMqtt_GetNextByte( void * pNetworkConnection,\r
+                           const IotNetworkInterface_t * pNetworkInterface,\r
+                           uint8_t * pIncomingByte );\r
+\r
+/**\r
+ * @brief Closes the network connection associated with an MQTT connection.\r
+ *\r
+ * A network disconnect function must be set in the network interface for the\r
+ * network connection to be closed.\r
+ *\r
+ * @param[in] disconnectReason A reason to pass to the connection's disconnect\r
+ * callback.\r
+ * @param[in] pMqttConnection The MQTT connection with the network connection\r
+ * to close.\r
+ */\r
+void _IotMqtt_CloseNetworkConnection( IotMqttDisconnectReason_t disconnectReason,\r
+                                      _mqttConnection_t * pMqttConnection );\r
+\r
+#endif /* ifndef IOT_MQTT_INTERNAL_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/freertos/include/platform/iot_network_freertos.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/freertos/include/platform/iot_network_freertos.h
deleted file mode 100644 (file)
index e4449ae..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*\r
- * Amazon FreeRTOS Platform V1.0.0\r
- * Copyright (C) 2019 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_network_freertos.h\r
- * @brief Declares the network stack functions specified in aws_iot_network.h for\r
- * Amazon FreeRTOS Secure Sockets.\r
- */\r
-\r
-#ifndef _IOT_NETWORK_AFR_H_\r
-#define _IOT_NETWORK_AFR_H_\r
-\r
-/* Standard includes. */\r
-#include <stdbool.h>\r
-\r
-/* Platform network include. */\r
-#include "platform/iot_network.h"\r
-\r
-/* Amazon FreeRTOS Secure Sockets include. */\r
-#include "iot_secure_sockets.h"\r
-\r
-/**\r
- * @brief Represents a network connection that uses Amazon FreeRTOS Secure Sockets.\r
- *\r
- * This is an incomplete type. In application code, only pointers to this type\r
- * should be used.\r
- */\r
-typedef struct _networkConnection IotNetworkConnectionAfr_t;\r
-\r
-/**\r
- * @brief Provides a default value for an #IotNetworkConnectionAfr_t.\r
- *\r
- * All instances of #IotNetworkConnectionAfr_t should be initialized with\r
- * this constant.\r
- *\r
- * @warning Failing to initialize an #IotNetworkConnectionAfr_t with this\r
- * initializer may result in undefined behavior!\r
- * @note This initializer may change at any time in future versions, but its\r
- * name will remain the same.\r
- */\r
-#define IOT_NETWORK_CONNECTION_AFR_INITIALIZER     { 0 }\r
-\r
-/**\r
- * @brief Generic initializer for an #IotNetworkServerInfo_t.\r
- *\r
- * @note This initializer may change at any time in future versions, but its\r
- * name will remain the same.\r
- */\r
-#define IOT_NETWORK_SERVER_INFO_AFR_INITIALIZER    { 0 }\r
-\r
-/**\r
- * @brief Generic initializer for an #IotNetworkCredentials_t.\r
- *\r
- * @note This initializer may change at any time in future versions, but its\r
- * name will remain the same.\r
- */\r
-#define IOT_NETWORK_CREDENTIALS_AFR_INITIALIZER    { 0 }\r
-\r
-/**\r
- * @brief Provides a pointer to an #IotNetworkInterface_t that uses the functions\r
- * declared in this file.\r
- */\r
-#define IOT_NETWORK_INTERFACE_AFR    ( &( IotNetworkAfr ) )\r
-\r
-/**\r
- * @brief An implementation of #IotNetworkInterface_t::create for Amazon FreeRTOS\r
- * Secure Sockets.\r
- */\r
-IotNetworkError_t IotNetworkAfr_Create( void * pConnectionInfo,\r
-                                        void * pCredentialInfo,\r
-                                        void ** const pConnection );\r
-\r
-/**\r
- * @brief An implementation of #IotNetworkInterface_t::setReceiveCallback for\r
- * Amazon FreeRTOS Secure Sockets.\r
- */\r
-IotNetworkError_t IotNetworkAfr_SetReceiveCallback( void * pConnection,\r
-                                                    IotNetworkReceiveCallback_t receiveCallback,\r
-                                                    void * pContext );\r
-\r
-/**\r
- * @brief An implementation of #IotNetworkInterface_t::send for Amazon FreeRTOS\r
- * Secure Sockets.\r
- */\r
-size_t IotNetworkAfr_Send( void * pConnection,\r
-                           const uint8_t * pMessage,\r
-                           size_t messageLength );\r
-\r
-/**\r
- * @brief An implementation of #IotNetworkInterface_t::receive for Amazon FreeRTOS\r
- * Secure Sockets.\r
- */\r
-size_t IotNetworkAfr_Receive( void * pConnection,\r
-                              uint8_t * pBuffer,\r
-                              size_t bytesRequested );\r
-\r
-/**\r
- * @brief An implementation of #IotNetworkInterface_t::close for Amazon FreeRTOS\r
- * Secure Sockets.\r
- */\r
-IotNetworkError_t IotNetworkAfr_Close( void * pConnection );\r
-\r
-/**\r
- * @brief An implementation of #IotNetworkInterface_t::destroy for Amazon FreeRTOS\r
- * Secure Sockets.\r
- */\r
-IotNetworkError_t IotNetworkAfr_Destroy( void * pConnection );\r
-\r
-/**\r
- * @cond DOXYGEN_IGNORE\r
- * Doxygen should ignore this section.\r
- *\r
- * Declaration of a network interface struct using the functions in this file.\r
- */\r
-extern const IotNetworkInterface_t IotNetworkAfr;\r
-/** @endcond */\r
-\r
-#endif /* ifndef _IOT_NETWORK_AFR_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/freertos/include/platform/iot_platform_types_freertos.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/freertos/include/platform/iot_platform_types_freertos.h
deleted file mode 100644 (file)
index e855343..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*\r
- * Amazon FreeRTOS Platform V1.0.0\r
- * Copyright (C) 2019 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_platform_types_posix.h\r
- * @brief Definitions of platform layer types on POSIX systems.\r
- */\r
-\r
-#ifndef _IOT_PLATFORM_TYPES_AFR_H_\r
-#define _IOT_PLATFORM_TYPES_AFR_H_\r
-\r
-#include "timers.h"\r
-\r
-typedef struct iot_mutex_internal\r
-{\r
-    StaticSemaphore_t xMutex;      /**< FreeRTOS mutex. */\r
-    BaseType_t recursive;                /**< Type; used for indicating if this is reentrant or normal. */\r
-} iot_mutex_internal_t;\r
-\r
-/**\r
- * @brief The native mutex type on AFR systems.\r
- */\r
-typedef iot_mutex_internal_t _IotSystemMutex_t;\r
-\r
-typedef struct iot_sem_internal\r
-{\r
-    StaticSemaphore_t xSemaphore;       /**< FreeRTOS semaphore. */\r
-} iot_sem_internal_t;\r
-\r
-/**\r
- * @brief The native semaphore type on AFR systems.\r
- */\r
-typedef iot_sem_internal_t _IotSystemSemaphore_t;\r
-\r
-/**\r
- * @brief Holds information about an active detached thread so that we can\r
- *        delete the FreeRTOS task when it completes\r
- */\r
-typedef struct threadInfo\r
-{\r
-    void * pArgument;                 /**< @brief Argument to `threadRoutine`. */\r
-    void ( *threadRoutine )( void * );/**< @brief Thread function to run. */\r
-} threadInfo_t;\r
-\r
-/**\r
- * @brief Holds information about an active timer.\r
- */\r
-typedef struct timerInfo\r
-{\r
-    TimerHandle_t timer;                    /**< @brief Underlying timer. */\r
-    void ( *threadRoutine )( void * );      /**< @brief Thread function to run on timer expiration. */\r
-    void * pArgument;                       /**< @brief First argument to threadRoutine. */\r
-    StaticTimer_t xTimerBuffer;             /**< Memory that holds the FreeRTOS timer. */\r
-    TickType_t xTimerPeriod;                /**< Period of this timer. */\r
-} timerInfo_t;\r
-\r
-/**\r
- * @brief Represents an #IotTimer_t on AFR systems.\r
- */\r
-typedef timerInfo_t _IotSystemTimer_t;\r
-\r
-#endif /* ifndef _IOT_PLATFORM_TYPES_POSIX_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/freertos/iot_clock_freertos.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/freertos/iot_clock_freertos.c
deleted file mode 100644 (file)
index 4d74b82..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-/*\r
- * Amazon FreeRTOS Platform V1.0.0\r
- * Copyright (C) 2019 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_clock_freertos.c\r
- * @brief Implementation of the functions in iot_clock.h for Amazon FreeRTOS systems.\r
- */\r
-\r
-/* The config header is always included first. */\r
-#include "iot_config.h"\r
-\r
-/* Standard includes. */\r
-#include <stdio.h>\r
-\r
-/* Platform clock include. */\r
-#include "platform/iot_platform_types_freertos.h"\r
-#include "platform/iot_clock.h"\r
-#include "task.h"\r
-\r
-/* Configure logs for the functions in this file. */\r
-#ifdef IOT_LOG_LEVEL_PLATFORM\r
-    #define LIBRARY_LOG_LEVEL        IOT_LOG_LEVEL_PLATFORM\r
-#else\r
-    #ifdef IOT_LOG_LEVEL_GLOBAL\r
-        #define LIBRARY_LOG_LEVEL    IOT_LOG_LEVEL_GLOBAL\r
-    #else\r
-        #define LIBRARY_LOG_LEVEL    IOT_LOG_NONE\r
-    #endif\r
-#endif\r
-\r
-#define LIBRARY_LOG_NAME    ( "CLOCK" )\r
-#include "iot_logging_setup.h"\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/*\r
- * Time conversion constants.\r
- */\r
-#define _MILLISECONDS_PER_SECOND    ( 1000 )                                          /**< @brief Milliseconds per second. */\r
-#define _MILLISECONDS_PER_TICK      ( _MILLISECONDS_PER_SECOND / configTICK_RATE_HZ ) /**< Milliseconds per FreeRTOS tick. */\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/*  Private Callback function for timer expiry, delegate work to a Task to free\r
- *  up the timer task for managing other timers */\r
-static void prvTimerCallback( TimerHandle_t xTimerHandle )\r
-{\r
-    _IotSystemTimer_t * pxTimer = ( _IotSystemTimer_t * ) pvTimerGetTimerID( xTimerHandle );\r
-\r
-    /* The value of the timer ID, set in timer_create, should not be NULL. */\r
-    configASSERT( pxTimer != NULL );\r
-\r
-    /* Restart the timer if it is periodic. */\r
-    if( pxTimer->xTimerPeriod > 0 )\r
-    {\r
-        xTimerChangePeriod( xTimerHandle, pxTimer->xTimerPeriod, 0 );\r
-    }\r
-\r
-    /* Call timer Callback from this task */\r
-    pxTimer->threadRoutine( ( void * ) pxTimer->pArgument );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-bool IotClock_GetTimestring( char * pBuffer,\r
-                             size_t bufferSize,\r
-                             size_t * pTimestringLength )\r
-{\r
-    uint64_t milliSeconds = IotClock_GetTimeMs();\r
-    int timestringLength = 0;\r
-\r
-    configASSERT( pBuffer != NULL );\r
-    configASSERT( pTimestringLength != NULL );\r
-\r
-    /* Convert the localTime struct to a string. */\r
-    timestringLength = snprintf( pBuffer, bufferSize, "%llu", milliSeconds );\r
-\r
-    /* Check for error from no string */\r
-    if( timestringLength == 0 )\r
-    {\r
-        return false;\r
-    }\r
-\r
-    /* Set the output parameter. */\r
-    *pTimestringLength = timestringLength;\r
-\r
-    return true;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-uint64_t IotClock_GetTimeMs( void )\r
-{\r
-    TimeOut_t xCurrentTime = { 0 };\r
-\r
-    /* This must be unsigned because the behavior of signed integer overflow is undefined. */\r
-    uint64_t ullTickCount = 0ULL;\r
-\r
-    /* Get the current tick count and overflow count. vTaskSetTimeOutState()\r
-     * is used to get these values because they are both static in tasks.c. */\r
-    vTaskSetTimeOutState( &xCurrentTime );\r
-\r
-    /* Adjust the tick count for the number of times a TickType_t has overflowed. */\r
-    ullTickCount = ( uint64_t ) ( xCurrentTime.xOverflowCount ) << ( sizeof( TickType_t ) * 8 );\r
-\r
-    /* Add the current tick count. */\r
-    ullTickCount += xCurrentTime.xTimeOnEntering;\r
-\r
-    /* Return the ticks converted to Milliseconds */\r
-    return ullTickCount * _MILLISECONDS_PER_TICK;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void IotClock_SleepMs( uint32_t sleepTimeMs )\r
-{\r
-    vTaskDelay( pdMS_TO_TICKS( sleepTimeMs ) );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-bool IotClock_TimerCreate( IotTimer_t * pNewTimer,\r
-                           IotThreadRoutine_t expirationRoutine,\r
-                           void * pArgument )\r
-{\r
-    _IotSystemTimer_t * pxTimer = ( _IotSystemTimer_t * ) pNewTimer;\r
-\r
-    configASSERT( pNewTimer != NULL );\r
-    configASSERT( expirationRoutine != NULL );\r
-\r
-    IotLogDebug( "Creating new timer %p.", pNewTimer );\r
-\r
-    /* Set the timer expiration routine, argument and period */\r
-    pxTimer->threadRoutine = expirationRoutine;\r
-    pxTimer->pArgument = pArgument;\r
-    pxTimer->xTimerPeriod = 0;\r
-\r
-    /* Create a new FreeRTOS timer. This call will not fail because the\r
-     * memory for it has already been allocated, so the output parameter is\r
-     * also set. */\r
-    pxTimer->timer = ( TimerHandle_t ) xTimerCreateStatic( "timer",                  /* Timer name. */\r
-                                                           portMAX_DELAY,            /* Initial timer period. Timers are created disarmed. */\r
-                                                           pdFALSE,                  /* Don't auto-reload timer. */\r
-                                                           ( void * ) pxTimer,       /* Timer id. */\r
-                                                           prvTimerCallback,         /* Timer expiration callback. */\r
-                                                           &pxTimer->xTimerBuffer ); /* Pre-allocated memory for timer. */\r
-\r
-    return true;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void IotClock_TimerDestroy( IotTimer_t * pTimer )\r
-{\r
-    _IotSystemTimer_t * pTimerInfo = ( _IotSystemTimer_t * ) pTimer;\r
-\r
-    configASSERT( pTimerInfo != NULL );\r
-    configASSERT( pTimerInfo->timer != NULL );\r
-\r
-    IotLogDebug( "Destroying timer %p.", pTimer );\r
-\r
-    if( xTimerIsTimerActive( pTimerInfo->timer ) == pdTRUE )\r
-    {\r
-        /* Stop the FreeRTOS timer. Because the timer is statically allocated, no call\r
-         * to xTimerDelete is necessary. The timer is stopped so that it's not referenced\r
-         * anywhere. xTimerStop will not fail when it has unlimited block time. */\r
-        ( void ) xTimerStop( pTimerInfo->timer, portMAX_DELAY );\r
-\r
-        /* Wait until the timer stop command is processed. */\r
-        while( xTimerIsTimerActive( pTimerInfo->timer ) == pdTRUE )\r
-        {\r
-            vTaskDelay( 1 );\r
-        }\r
-    }\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-bool IotClock_TimerArm( IotTimer_t * pTimer,\r
-                        uint32_t relativeTimeoutMs,\r
-                        uint32_t periodMs )\r
-{\r
-    _IotSystemTimer_t * pTimerInfo = ( _IotSystemTimer_t * ) pTimer;\r
-\r
-    configASSERT( pTimerInfo != NULL );\r
-\r
-    TimerHandle_t xTimerHandle = pTimerInfo->timer;\r
-\r
-    IotLogDebug( "Arming timer %p with timeout %llu and period %llu.",\r
-                 pTimer,\r
-                 relativeTimeoutMs,\r
-                 periodMs );\r
-\r
-    /* Set the timer period in ticks */\r
-    pTimerInfo->xTimerPeriod = pdMS_TO_TICKS( periodMs );\r
-\r
-    /* Set the timer to expire after relativeTimeoutMs, and restart it. */\r
-    ( void ) xTimerChangePeriod( xTimerHandle, pdMS_TO_TICKS( relativeTimeoutMs ), portMAX_DELAY );\r
-\r
-    return true;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/freertos/iot_network_freertos.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/freertos/iot_network_freertos.c
deleted file mode 100644 (file)
index 287a312..0000000
+++ /dev/null
@@ -1,627 +0,0 @@
-/*\r
- * Amazon FreeRTOS Platform V1.0.0\r
- * Copyright (C) 2019 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_network_freertos.c\r
- * @brief Implementation of the network-related functions from iot_network_freertos.h\r
- * for Amazon FreeRTOS secure sockets.\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
-/* FreeRTOS includes. */\r
-#include "semphr.h"\r
-#include "event_groups.h"\r
-\r
-/* Error handling include. */\r
-#include "private/iot_error.h"\r
-\r
-/* Amazon FreeRTOS network include. */\r
-#include "platform/iot_network_freertos.h"\r
-\r
-/* Configure logs for the functions in this file. */\r
-#ifdef IOT_LOG_LEVEL_NETWORK\r
-    #define LIBRARY_LOG_LEVEL        IOT_LOG_LEVEL_NETWORK\r
-#else\r
-    #ifdef IOT_LOG_LEVEL_GLOBAL\r
-        #define LIBRARY_LOG_LEVEL    IOT_LOG_LEVEL_GLOBAL\r
-    #else\r
-        #define LIBRARY_LOG_LEVEL    IOT_LOG_NONE\r
-    #endif\r
-#endif\r
-\r
-#define LIBRARY_LOG_NAME    ( "NET" )\r
-#include "iot_logging_setup.h"\r
-\r
-/* Provide a default value for the number of milliseconds for a socket poll.\r
- * This is a temporary workaround to deal with the lack of poll(). */\r
-#ifndef IOT_NETWORK_SOCKET_POLL_MS\r
-    #define IOT_NETWORK_SOCKET_POLL_MS    ( 1000 )\r
-#endif\r
-\r
-/**\r
- * @brief The event group bit to set when a connection's socket is shut down.\r
- */\r
-#define _FLAG_SHUTDOWN                ( 1 )\r
-\r
-/**\r
- * @brief The event group bit to set when a connection's receive task exits.\r
- */\r
-#define _FLAG_RECEIVE_TASK_EXITED     ( 2 )\r
-\r
-/**\r
- * @brief The event group bit to set when the connection is destroyed from the\r
- * receive task.\r
- */\r
-#define _FLAG_CONNECTION_DESTROYED    ( 4 )\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-typedef struct _networkConnection\r
-{\r
-    Socket_t socket;                             /**< @brief Amazon FreeRTOS Secure Sockets handle. */\r
-    StaticSemaphore_t socketMutex;               /**< @brief Prevents concurrent threads from sending on a socket. */\r
-    StaticEventGroup_t connectionFlags;          /**< @brief Synchronizes with the receive task. */\r
-    TaskHandle_t receiveTask;                    /**< @brief Handle of the receive task, if any. */\r
-    IotNetworkReceiveCallback_t receiveCallback; /**< @brief Network receive callback, if any. */\r
-    void * pReceiveContext;                      /**< @brief The context for the receive callback. */\r
-    bool bufferedByteValid;                      /**< @brief Used to determine if the buffered byte is valid. */\r
-    uint8_t bufferedByte;                        /**< @brief A single byte buffered from a receive, since AFR Secure Sockets does not have poll(). */\r
-} _networkConnection_t;\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/**\r
- * @brief An #IotNetworkInterface_t that uses the functions in this file.\r
- */\r
-const IotNetworkInterface_t IotNetworkAfr =\r
-{\r
-    .create             = IotNetworkAfr_Create,\r
-    .setReceiveCallback = IotNetworkAfr_SetReceiveCallback,\r
-    .send               = IotNetworkAfr_Send,\r
-    .receive            = IotNetworkAfr_Receive,\r
-    .close              = IotNetworkAfr_Close,\r
-    .destroy            = IotNetworkAfr_Destroy\r
-};\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/**\r
- * @brief Destroys a network connection.\r
- *\r
- * @param[in] pNetworkConnection The connection to destroy.\r
- */\r
-static void _destroyConnection( _networkConnection_t * pNetworkConnection )\r
-{\r
-    /* Call Secure Sockets close function to free resources. */\r
-    int32_t socketStatus = SOCKETS_Close( pNetworkConnection->socket );\r
-\r
-    if( socketStatus != SOCKETS_ERROR_NONE )\r
-    {\r
-        IotLogWarn( "Failed to destroy connection." );\r
-    }\r
-\r
-    /* Free the network connection. */\r
-    vPortFree( pNetworkConnection );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/**\r
- * @brief Task routine that waits on incoming network data.\r
- *\r
- * @param[in] pArgument The network connection.\r
- */\r
-static void _networkReceiveTask( void * pArgument )\r
-{\r
-    bool destroyConnection = false;\r
-    int32_t socketStatus = 0;\r
-    EventBits_t connectionFlags = 0;\r
-\r
-    /* Cast network connection to the correct type. */\r
-    _networkConnection_t * pNetworkConnection = pArgument;\r
-\r
-    while( true )\r
-    {\r
-        /* No buffered byte should be in the connection. */\r
-        configASSERT( pNetworkConnection->bufferedByteValid == false );\r
-\r
-        /* Block and wait for 1 byte of data. This simulates the behavior of poll().\r
-         * THIS IS A TEMPORARY WORKAROUND AND DOES NOT PROVIDE THREAD-SAFETY AGAINST\r
-         * MULTIPLE CALLS OF RECEIVE. */\r
-        do\r
-        {\r
-            socketStatus = SOCKETS_Recv( pNetworkConnection->socket,\r
-                                         &( pNetworkConnection->bufferedByte ),\r
-                                         1,\r
-                                         0 );\r
-\r
-            connectionFlags = xEventGroupGetBits( ( EventGroupHandle_t ) &( pNetworkConnection->connectionFlags ) );\r
-\r
-            if( ( connectionFlags & _FLAG_SHUTDOWN ) == _FLAG_SHUTDOWN )\r
-            {\r
-                socketStatus = SOCKETS_ECLOSED;\r
-            }\r
-\r
-            /* Check for timeout. Some ports return 0, some return EWOULDBLOCK. */\r
-        } while( ( socketStatus == 0 ) || ( socketStatus == SOCKETS_EWOULDBLOCK ) );\r
-\r
-        if( socketStatus <= 0 )\r
-        {\r
-            break;\r
-        }\r
-\r
-        pNetworkConnection->bufferedByteValid = true;\r
-\r
-        /* Invoke the network callback. */\r
-        pNetworkConnection->receiveCallback( pNetworkConnection,\r
-                                             pNetworkConnection->pReceiveContext );\r
-\r
-        /* Check if the connection was destroyed by the receive callback. This\r
-         * does not need to be thread-safe because the destroy connection function\r
-         * may only be called once (per its API doc). */\r
-        connectionFlags = xEventGroupGetBits( ( EventGroupHandle_t ) &( pNetworkConnection->connectionFlags ) );\r
-\r
-        if( ( connectionFlags & _FLAG_CONNECTION_DESTROYED ) == _FLAG_CONNECTION_DESTROYED )\r
-        {\r
-            destroyConnection = true;\r
-            break;\r
-        }\r
-    }\r
-\r
-    IotLogDebug( "Network receive task terminating." );\r
-\r
-    /* If necessary, destroy the network connection before exiting. */\r
-    if( destroyConnection == true )\r
-    {\r
-        _destroyConnection( pNetworkConnection );\r
-    }\r
-    else\r
-    {\r
-        /* Set the flag to indicate that the receive task has exited. */\r
-        ( void ) xEventGroupSetBits( ( EventGroupHandle_t ) &( pNetworkConnection->connectionFlags ),\r
-                                     _FLAG_RECEIVE_TASK_EXITED );\r
-    }\r
-\r
-    vTaskDelete( NULL );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/**\r
- * @brief Set up a secured TLS connection.\r
- *\r
- * @param[in] pAfrCredentials Credentials for the secured connection.\r
- * @param[in] tcpSocket An initialized socket to secure.\r
- * @param[in] pHostName Remote server name for SNI.\r
- * @param[in] hostnameLength The length of `pHostName`.\r
- *\r
- * @return #IOT_NETWORK_SUCCESS or #IOT_NETWORK_SYSTEM_ERROR.\r
- */\r
-static IotNetworkError_t _tlsSetup( const IotNetworkCredentials_t * pAfrCredentials,\r
-                                    Socket_t tcpSocket,\r
-                                    const char * pHostName,\r
-                                    size_t hostnameLength )\r
-{\r
-    IOT_FUNCTION_ENTRY( IotNetworkError_t, IOT_NETWORK_SUCCESS );\r
-    int32_t socketStatus = SOCKETS_ERROR_NONE;\r
-\r
-    /* ALPN options for AWS IoT. */\r
-    const char * ppcALPNProtos[] = { socketsAWS_IOT_ALPN_MQTT };\r
-\r
-    /* Set secured option. */\r
-    socketStatus = SOCKETS_SetSockOpt( tcpSocket,\r
-                                       0,\r
-                                       SOCKETS_SO_REQUIRE_TLS,\r
-                                       NULL,\r
-                                       0 );\r
-\r
-    if( socketStatus != SOCKETS_ERROR_NONE )\r
-    {\r
-        IotLogError( "Failed to set secured option for new connection." );\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_SYSTEM_ERROR );\r
-    }\r
-\r
-    /* Set ALPN option. */\r
-    if( pAfrCredentials->pAlpnProtos != NULL )\r
-    {\r
-        socketStatus = SOCKETS_SetSockOpt( tcpSocket,\r
-                                           0,\r
-                                           SOCKETS_SO_ALPN_PROTOCOLS,\r
-                                           ppcALPNProtos,\r
-                                           sizeof( ppcALPNProtos ) / sizeof( ppcALPNProtos[ 0 ] ) );\r
-\r
-        if( socketStatus != SOCKETS_ERROR_NONE )\r
-        {\r
-            IotLogError( "Failed to set ALPN option for new connection." );\r
-            IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_SYSTEM_ERROR );\r
-        }\r
-    }\r
-\r
-    /* Set SNI option. */\r
-    if( pAfrCredentials->disableSni == false )\r
-    {\r
-        socketStatus = SOCKETS_SetSockOpt( tcpSocket,\r
-                                           0,\r
-                                           SOCKETS_SO_SERVER_NAME_INDICATION,\r
-                                           pHostName,\r
-                                           hostnameLength + 1 );\r
-\r
-        if( socketStatus != SOCKETS_ERROR_NONE )\r
-        {\r
-            IotLogError( "Failed to set SNI option for new connection." );\r
-            IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_SYSTEM_ERROR );\r
-        }\r
-    }\r
-\r
-    /* Set custom server certificate. */\r
-    if( pAfrCredentials->pRootCa != NULL )\r
-    {\r
-        socketStatus = SOCKETS_SetSockOpt( tcpSocket,\r
-                                           0,\r
-                                           SOCKETS_SO_TRUSTED_SERVER_CERTIFICATE,\r
-                                           pAfrCredentials->pRootCa,\r
-                                           pAfrCredentials->rootCaSize );\r
-\r
-        if( socketStatus != SOCKETS_ERROR_NONE )\r
-        {\r
-            IotLogError( "Failed to set server certificate option for new connection." );\r
-            IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_SYSTEM_ERROR );\r
-        }\r
-    }\r
-\r
-    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotNetworkError_t IotNetworkAfr_Create( void * pConnectionInfo,\r
-                                        void * pCredentialInfo,\r
-                                        void ** pConnection )\r
-{\r
-    IOT_FUNCTION_ENTRY( IotNetworkError_t, IOT_NETWORK_SUCCESS );\r
-    Socket_t tcpSocket = SOCKETS_INVALID_SOCKET;\r
-    int32_t socketStatus = SOCKETS_ERROR_NONE;\r
-    SocketsSockaddr_t serverAddress = { 0 };\r
-    EventGroupHandle_t pConnectionFlags = NULL;\r
-    SemaphoreHandle_t pConnectionMutex = NULL;\r
-    const TickType_t receiveTimeout = pdMS_TO_TICKS( IOT_NETWORK_SOCKET_POLL_MS );\r
-    _networkConnection_t * pNewNetworkConnection = NULL;\r
-\r
-    /* Cast function parameters to correct types. */\r
-    const IotNetworkServerInfo_t * pServerInfo = pConnectionInfo;\r
-    const IotNetworkCredentials_t * pAfrCredentials = pCredentialInfo;\r
-    _networkConnection_t ** pNetworkConnection = ( _networkConnection_t ** ) pConnection;\r
-\r
-    /* Check host name length against the maximum length allowed by Secure\r
-     * Sockets. */\r
-    const size_t hostnameLength = strlen( pServerInfo->pHostName );\r
-\r
-    if( hostnameLength > ( size_t ) securesocketsMAX_DNS_NAME_LENGTH )\r
-    {\r
-        IotLogError( "Host name length exceeds %d, which is the maximum allowed.",\r
-                     securesocketsMAX_DNS_NAME_LENGTH );\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_BAD_PARAMETER );\r
-    }\r
-\r
-    pNewNetworkConnection = pvPortMalloc( sizeof( _networkConnection_t ) );\r
-\r
-    if( pNewNetworkConnection == NULL )\r
-    {\r
-        IotLogError( "Failed to allocate memory for new network connection." );\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_NO_MEMORY );\r
-    }\r
-\r
-    /* Clear the connection information. */\r
-    ( void ) memset( pNewNetworkConnection, 0x00, sizeof( _networkConnection_t ) );\r
-\r
-    /* Create a new TCP socket. */\r
-    tcpSocket = SOCKETS_Socket( SOCKETS_AF_INET,\r
-                                SOCKETS_SOCK_STREAM,\r
-                                SOCKETS_IPPROTO_TCP );\r
-\r
-    if( tcpSocket == SOCKETS_INVALID_SOCKET )\r
-    {\r
-        IotLogError( "Failed to create new socket." );\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_SYSTEM_ERROR );\r
-    }\r
-\r
-    /* Set up connection encryption if credentials are provided. */\r
-    if( pAfrCredentials != NULL )\r
-    {\r
-        status = _tlsSetup( pAfrCredentials, tcpSocket, pServerInfo->pHostName, hostnameLength );\r
-\r
-        if( status != IOT_NETWORK_SUCCESS )\r
-        {\r
-            IOT_GOTO_CLEANUP();\r
-        }\r
-    }\r
-\r
-    /* Establish connection. */\r
-    serverAddress.ucSocketDomain = SOCKETS_AF_INET;\r
-    serverAddress.usPort = SOCKETS_htons( pServerInfo->port );\r
-    serverAddress.ulAddress = SOCKETS_GetHostByName( pServerInfo->pHostName );\r
-\r
-    /* Check for errors from DNS lookup. */\r
-    if( serverAddress.ulAddress == 0 )\r
-    {\r
-        IotLogError( "Failed to resolve %s.", pServerInfo->pHostName );\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_SYSTEM_ERROR );\r
-    }\r
-\r
-    socketStatus = SOCKETS_Connect( tcpSocket,\r
-                                    &serverAddress,\r
-                                    sizeof( SocketsSockaddr_t ) );\r
-\r
-    if( socketStatus != SOCKETS_ERROR_NONE )\r
-    {\r
-        IotLogError( "Failed to establish new connection." );\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_SYSTEM_ERROR );\r
-    }\r
-\r
-    /* Set a long timeout for receive. */\r
-    socketStatus = SOCKETS_SetSockOpt( tcpSocket,\r
-                                       0,\r
-                                       SOCKETS_SO_RCVTIMEO,\r
-                                       &receiveTimeout,\r
-                                       sizeof( TickType_t ) );\r
-\r
-    if( socketStatus != SOCKETS_ERROR_NONE )\r
-    {\r
-        IotLogError( "Failed to set socket receive timeout." );\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_SYSTEM_ERROR );\r
-    }\r
-\r
-    IOT_FUNCTION_CLEANUP_BEGIN();\r
-\r
-    /* Clean up on failure. */\r
-    if( status != IOT_NETWORK_SUCCESS )\r
-    {\r
-        if( tcpSocket != SOCKETS_INVALID_SOCKET )\r
-        {\r
-            SOCKETS_Close( tcpSocket );\r
-        }\r
-\r
-        /* Clear the connection information. */\r
-        if( pNewNetworkConnection != NULL )\r
-        {\r
-            vPortFree( pNewNetworkConnection );\r
-        }\r
-    }\r
-    else\r
-    {\r
-        /* Set the socket. */\r
-        pNewNetworkConnection->socket = tcpSocket;\r
-\r
-        /* Create the connection event flags and mutex. */\r
-        pConnectionFlags = xEventGroupCreateStatic( &( pNewNetworkConnection->connectionFlags ) );\r
-        pConnectionMutex = xSemaphoreCreateMutexStatic( &( pNewNetworkConnection->socketMutex ) );\r
-\r
-        /* Static event flags and mutex creation should never fail. The handles\r
-         * should point inside the connection object. */\r
-        configASSERT( pConnectionFlags == ( EventGroupHandle_t ) &( pNewNetworkConnection->connectionFlags ) );\r
-        configASSERT( pConnectionMutex == ( SemaphoreHandle_t ) &( pNewNetworkConnection->socketMutex ) );\r
-\r
-        /* Set the output parameter. */\r
-        *pNetworkConnection = pNewNetworkConnection;\r
-    }\r
-\r
-    IOT_FUNCTION_CLEANUP_END();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotNetworkError_t IotNetworkAfr_SetReceiveCallback( void * pConnection,\r
-                                                    IotNetworkReceiveCallback_t receiveCallback,\r
-                                                    void * pContext )\r
-{\r
-    IotNetworkError_t status = IOT_NETWORK_SUCCESS;\r
-\r
-    /* Cast network connection to the correct type. */\r
-    _networkConnection_t * pNetworkConnection = ( _networkConnection_t * ) pConnection;\r
-\r
-    /* Set the receive callback and context. */\r
-    pNetworkConnection->receiveCallback = receiveCallback;\r
-    pNetworkConnection->pReceiveContext = pContext;\r
-\r
-    /* No flags should be set. */\r
-    configASSERT( xEventGroupGetBits( ( EventGroupHandle_t ) &( pNetworkConnection->connectionFlags ) ) == 0 );\r
-\r
-    /* Create task that waits for incoming data. */\r
-    if( xTaskCreate( _networkReceiveTask,\r
-                     "NetRecv",\r
-                     IOT_NETWORK_RECEIVE_TASK_STACK_SIZE,\r
-                     pNetworkConnection,\r
-                     IOT_NETWORK_RECEIVE_TASK_PRIORITY,\r
-                     &( pNetworkConnection->receiveTask ) ) != pdPASS )\r
-    {\r
-        IotLogError( "Failed to create network receive task." );\r
-\r
-        status = IOT_NETWORK_SYSTEM_ERROR;\r
-    }\r
-\r
-    return status;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-size_t IotNetworkAfr_Send( void * pConnection,\r
-                           const uint8_t * pMessage,\r
-                           size_t messageLength )\r
-{\r
-    size_t bytesSent = 0;\r
-    int32_t socketStatus = SOCKETS_ERROR_NONE;\r
-\r
-    /* Cast network connection to the correct type. */\r
-    _networkConnection_t * pNetworkConnection = ( _networkConnection_t * ) pConnection;\r
-\r
-    /* Only one thread at a time may send on the connection. Lock the socket\r
-     * mutex to prevent other threads from sending. */\r
-    if( xSemaphoreTake( ( QueueHandle_t ) &( pNetworkConnection->socketMutex ),\r
-                        portMAX_DELAY ) == pdTRUE )\r
-    {\r
-        socketStatus = SOCKETS_Send( pNetworkConnection->socket,\r
-                                     pMessage,\r
-                                     messageLength,\r
-                                     0 );\r
-\r
-        if( socketStatus > 0 )\r
-        {\r
-            bytesSent = ( size_t ) socketStatus;\r
-        }\r
-\r
-        xSemaphoreGive( ( QueueHandle_t ) &( pNetworkConnection->socketMutex ) );\r
-    }\r
-\r
-    return bytesSent;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-size_t IotNetworkAfr_Receive( void * pConnection,\r
-                              uint8_t * pBuffer,\r
-                              size_t bytesRequested )\r
-{\r
-    int32_t socketStatus = 0;\r
-    size_t bytesReceived = 0, bytesRemaining = bytesRequested;\r
-\r
-    /* Cast network connection to the correct type. */\r
-    _networkConnection_t * pNetworkConnection = ( _networkConnection_t * ) pConnection;\r
-\r
-    /* Write the buffered byte. THIS IS A TEMPORARY WORKAROUND AND ASSUMES THIS\r
-     * FUNCTION IS ALWAYS CALLED FROM THE RECEIVE CALLBACK. */\r
-    if( pNetworkConnection->bufferedByteValid == true )\r
-    {\r
-        *pBuffer = pNetworkConnection->bufferedByte;\r
-        bytesReceived = 1;\r
-        bytesRemaining--;\r
-        pNetworkConnection->bufferedByteValid = false;\r
-    }\r
-\r
-    /* Block and wait for incoming data. */\r
-    while( bytesRemaining > 0 )\r
-    {\r
-        socketStatus = SOCKETS_Recv( pNetworkConnection->socket,\r
-                                     pBuffer + bytesReceived,\r
-                                     bytesRemaining,\r
-                                     0 );\r
-\r
-        if( socketStatus == SOCKETS_EWOULDBLOCK )\r
-        {\r
-            /* The return value EWOULDBLOCK means no data was received within\r
-             * the socket timeout. Ignore it and try again. */\r
-            continue;\r
-        }\r
-        else if( socketStatus <= 0 )\r
-        {\r
-            IotLogError( "Error %ld while receiving data.", ( long int ) socketStatus );\r
-            break;\r
-        }\r
-        else\r
-        {\r
-            bytesReceived += ( size_t ) socketStatus;\r
-            bytesRemaining -= ( size_t ) socketStatus;\r
-\r
-            configASSERT( bytesReceived + bytesRemaining == bytesRequested );\r
-        }\r
-    }\r
-\r
-    if( bytesReceived < bytesRequested )\r
-    {\r
-        IotLogWarn( "Receive requested %lu bytes, but %lu bytes received instead.",\r
-                    ( unsigned long ) bytesRequested,\r
-                    ( unsigned long ) bytesReceived );\r
-    }\r
-    else\r
-    {\r
-        IotLogDebug( "Successfully received %lu bytes.",\r
-                     ( unsigned long ) bytesRequested );\r
-    }\r
-\r
-    return bytesReceived;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotNetworkError_t IotNetworkAfr_Close( void * pConnection )\r
-{\r
-    int32_t socketStatus = SOCKETS_ERROR_NONE;\r
-\r
-    /* Cast network connection to the correct type. */\r
-    _networkConnection_t * pNetworkConnection = ( _networkConnection_t * ) pConnection;\r
-\r
-    /* Call Secure Sockets shutdown function to close connection. */\r
-    socketStatus = SOCKETS_Shutdown( pNetworkConnection->socket,\r
-                                     SOCKETS_SHUT_RDWR );\r
-\r
-    if( socketStatus != SOCKETS_ERROR_NONE )\r
-    {\r
-        IotLogWarn( "Failed to close connection." );\r
-    }\r
-\r
-    /* Set the shutdown flag. */\r
-    ( void ) xEventGroupSetBits( ( EventGroupHandle_t ) &( pNetworkConnection->connectionFlags ),\r
-                                 _FLAG_SHUTDOWN );\r
-\r
-    return IOT_NETWORK_SUCCESS;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotNetworkError_t IotNetworkAfr_Destroy( void * pConnection )\r
-{\r
-    /* Cast network connection to the correct type. */\r
-    _networkConnection_t * pNetworkConnection = ( _networkConnection_t * ) pConnection;\r
-\r
-    /* Check if this function is being called from the receive task. */\r
-    if( xTaskGetCurrentTaskHandle() == pNetworkConnection->receiveTask )\r
-    {\r
-        /* Set the flag specifying that the connection is destroyed. */\r
-        ( void ) xEventGroupSetBits( ( EventGroupHandle_t ) &( pNetworkConnection->connectionFlags ),\r
-                                     _FLAG_CONNECTION_DESTROYED );\r
-    }\r
-    else\r
-    {\r
-        /* If a receive task was created, wait for it to exit. */\r
-        if( pNetworkConnection->receiveTask != NULL )\r
-        {\r
-            ( void ) xEventGroupWaitBits( ( EventGroupHandle_t ) &( pNetworkConnection->connectionFlags ),\r
-                                          _FLAG_RECEIVE_TASK_EXITED,\r
-                                          pdTRUE,\r
-                                          pdTRUE,\r
-                                          portMAX_DELAY );\r
-        }\r
-\r
-        _destroyConnection( pNetworkConnection );\r
-    }\r
-\r
-    return IOT_NETWORK_SUCCESS;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/freertos/iot_threads_freertos.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/freertos/iot_threads_freertos.c
deleted file mode 100644 (file)
index f4a5f97..0000000
+++ /dev/null
@@ -1,364 +0,0 @@
-/*\r
- * Amazon FreeRTOS Platform V1.0.0\r
- * Copyright (C) 2019 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_threads_freertos.c\r
- * @brief Implementation of the functions in iot_threads.h for POSIX systems.\r
- */\r
-\r
-/* The config header is always included first. */\r
-#include "iot_config.h"\r
-\r
-#include "semphr.h"\r
-\r
-/* Platform threads include. */\r
-#include "platform/iot_platform_types_freertos.h"\r
-#include "platform/iot_threads.h"\r
-#include "types/iot_platform_types.h"\r
-\r
-/* Configure logs for the functions in this file. */\r
-#ifdef IOT_LOG_LEVEL_PLATFORM\r
-    #define LIBRARY_LOG_LEVEL        IOT_LOG_LEVEL_PLATFORM\r
-#else\r
-    #ifdef IOT_LOG_LEVEL_GLOBAL\r
-        #define LIBRARY_LOG_LEVEL    IOT_LOG_LEVEL_GLOBAL\r
-    #else\r
-        #define LIBRARY_LOG_LEVEL    IOT_LOG_NONE\r
-    #endif\r
-#endif\r
-\r
-#define LIBRARY_LOG_NAME    ( "THREAD" )\r
-#include "iot_logging_setup.h"\r
-\r
-/*\r
- * Provide default values for undefined memory allocation functions based on\r
- * the usage of dynamic memory allocation.\r
- */\r
-#ifndef IotThreads_Malloc\r
-    #include <stdlib.h>\r
-\r
-/**\r
- * @brief Memory allocation. This function should have the same signature\r
- * as [malloc](http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html).\r
- */\r
-    #define IotThreads_Malloc    malloc\r
-#endif\r
-#ifndef IotThreads_Free\r
-    #include <stdlib.h>\r
-\r
-/**\r
- * @brief Free memory. This function should have the same signature as\r
- * [free](http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
- */\r
-    #define IotThreads_Free    free\r
-#endif\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static void _threadRoutineWrapper( void * pArgument )\r
-{\r
-    threadInfo_t * pThreadInfo = ( threadInfo_t * ) pArgument;\r
-\r
-    /* Run the thread routine. */\r
-    pThreadInfo->threadRoutine( pThreadInfo->pArgument );\r
-    IotThreads_Free( pThreadInfo );\r
-\r
-    vTaskDelete( NULL );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-bool Iot_CreateDetachedThread( IotThreadRoutine_t threadRoutine,\r
-                               void * pArgument,\r
-                               int32_t priority,\r
-                               size_t stackSize )\r
-{\r
-    bool status = true;\r
-\r
-    configASSERT( threadRoutine != NULL );\r
-\r
-    IotLogDebug( "Creating new thread." );\r
-    threadInfo_t * pThreadInfo = IotThreads_Malloc( sizeof( threadInfo_t ) );\r
-\r
-    if( pThreadInfo == NULL )\r
-    {\r
-        IotLogDebug( "Unable to allocate memory for threadRoutine %p.", threadRoutine );\r
-        status = false;\r
-    }\r
-\r
-    /* Create the FreeRTOS task that will run the thread. */\r
-    if( status )\r
-    {\r
-        pThreadInfo->threadRoutine = threadRoutine;\r
-        pThreadInfo->pArgument = pArgument;\r
-\r
-        if( xTaskCreate( _threadRoutineWrapper,\r
-                         "iot_thread",\r
-                         ( configSTACK_DEPTH_TYPE ) stackSize,\r
-                         pThreadInfo,\r
-                         priority,\r
-                         NULL ) != pdPASS )\r
-        {\r
-            /* Task creation failed. */\r
-            IotLogWarn( "Failed to create thread." );\r
-            IotThreads_Free( pThreadInfo );\r
-            status = false;\r
-        }\r
-    }\r
-\r
-    return status;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-bool IotMutex_Create( IotMutex_t * pNewMutex,\r
-                      bool recursive )\r
-{\r
-    _IotSystemMutex_t * internalMutex = ( _IotSystemMutex_t * ) pNewMutex;\r
-\r
-    configASSERT( internalMutex != NULL );\r
-\r
-    IotLogDebug( "Creating new mutex %p.", pNewMutex );\r
-\r
-    if( recursive )\r
-    {\r
-        ( void ) xSemaphoreCreateRecursiveMutexStatic( &internalMutex->xMutex );\r
-    }\r
-    else\r
-    {\r
-        ( void ) xSemaphoreCreateMutexStatic( &internalMutex->xMutex );\r
-    }\r
-\r
-    /* remember the type of mutex */\r
-    if( recursive )\r
-    {\r
-        internalMutex->recursive = pdTRUE;\r
-    }\r
-    else\r
-    {\r
-        internalMutex->recursive = pdFALSE;\r
-    }\r
-\r
-    return true;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void IotMutex_Destroy( IotMutex_t * pMutex )\r
-{\r
-    _IotSystemMutex_t * internalMutex = ( _IotSystemMutex_t * ) pMutex;\r
-\r
-    configASSERT( internalMutex != NULL );\r
-\r
-    vSemaphoreDelete( ( SemaphoreHandle_t ) &internalMutex->xMutex );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-bool prIotMutexTimedLock( IotMutex_t * pMutex,\r
-                          TickType_t timeout )\r
-{\r
-    _IotSystemMutex_t * internalMutex = ( _IotSystemMutex_t * ) pMutex;\r
-    BaseType_t lockResult;\r
-\r
-    configASSERT( internalMutex != NULL );\r
-\r
-    IotLogDebug( "Locking mutex %p.", internalMutex );\r
-\r
-    /* Call the correct FreeRTOS mutex take function based on mutex type. */\r
-    if( internalMutex->recursive == pdTRUE )\r
-    {\r
-        lockResult = xSemaphoreTakeRecursive( ( SemaphoreHandle_t ) &internalMutex->xMutex, timeout );\r
-    }\r
-    else\r
-    {\r
-        lockResult = xSemaphoreTake( ( SemaphoreHandle_t ) &internalMutex->xMutex, timeout );\r
-    }\r
-\r
-    return( lockResult == pdTRUE );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void IotMutex_Lock( IotMutex_t * pMutex )\r
-{\r
-    prIotMutexTimedLock( pMutex, portMAX_DELAY );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-bool IotMutex_TryLock( IotMutex_t * pMutex )\r
-{\r
-    return prIotMutexTimedLock( pMutex, 0 );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void IotMutex_Unlock( IotMutex_t * pMutex )\r
-{\r
-    _IotSystemMutex_t * internalMutex = ( _IotSystemMutex_t * ) pMutex;\r
-\r
-    configASSERT( internalMutex != NULL );\r
-\r
-    IotLogDebug( "Unlocking mutex %p.", internalMutex );\r
-\r
-    /* Call the correct FreeRTOS mutex unlock function based on mutex type. */\r
-    if( internalMutex->recursive == pdTRUE )\r
-    {\r
-        ( void ) xSemaphoreGiveRecursive( ( SemaphoreHandle_t ) &internalMutex->xMutex );\r
-    }\r
-    else\r
-    {\r
-        ( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &internalMutex->xMutex );\r
-    }\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-bool IotSemaphore_Create( IotSemaphore_t * pNewSemaphore,\r
-                          uint32_t initialValue,\r
-                          uint32_t maxValue )\r
-{\r
-    _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pNewSemaphore;\r
-\r
-    configASSERT( internalSemaphore != NULL );\r
-\r
-    IotLogDebug( "Creating new semaphore %p.", pNewSemaphore );\r
-\r
-    ( void ) xSemaphoreCreateCountingStatic( maxValue, initialValue, &internalSemaphore->xSemaphore );\r
-\r
-    return true;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-uint32_t IotSemaphore_GetCount( IotSemaphore_t * pSemaphore )\r
-{\r
-    _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;\r
-    UBaseType_t count = 0;\r
-\r
-    configASSERT( internalSemaphore != NULL );\r
-\r
-    count = uxSemaphoreGetCount( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore );\r
-\r
-    IotLogDebug( "Semaphore %p has count %d.", pSemaphore, count );\r
-\r
-    return ( uint32_t ) count;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void IotSemaphore_Destroy( IotSemaphore_t * pSemaphore )\r
-{\r
-    _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;\r
-\r
-    configASSERT( internalSemaphore != NULL );\r
-\r
-    IotLogDebug( "Destroying semaphore %p.", internalSemaphore );\r
-\r
-    vSemaphoreDelete( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void IotSemaphore_Wait( IotSemaphore_t * pSemaphore )\r
-{\r
-    _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;\r
-\r
-    configASSERT( internalSemaphore != NULL );\r
-\r
-    IotLogDebug( "Waiting on semaphore %p.", internalSemaphore );\r
-\r
-    /* Take the semaphore using the FreeRTOS API. */\r
-    if( xSemaphoreTake( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore,\r
-                        portMAX_DELAY ) != pdTRUE )\r
-    {\r
-        IotLogWarn( "Failed to wait on semaphore %p.",\r
-                    pSemaphore );\r
-\r
-        /* Assert here, debugging we always want to know that this happened because you think\r
-         *   that you are waiting successfully on the semaphore but you are not   */\r
-        configASSERT( false );\r
-    }\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-bool IotSemaphore_TryWait( IotSemaphore_t * pSemaphore )\r
-{\r
-    _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;\r
-\r
-    configASSERT( internalSemaphore != NULL );\r
-\r
-    IotLogDebug( "Attempting to wait on semaphore %p.", internalSemaphore );\r
-\r
-    return IotSemaphore_TimedWait( pSemaphore, 0 );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-bool IotSemaphore_TimedWait( IotSemaphore_t * pSemaphore,\r
-                             uint32_t timeoutMs )\r
-{\r
-    _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;\r
-\r
-    configASSERT( internalSemaphore != NULL );\r
-\r
-    /* Take the semaphore using the FreeRTOS API. Cast the calculation to 64 bit to avoid overflows*/\r
-    if( xSemaphoreTake( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore,\r
-                        pdMS_TO_TICKS( timeoutMs ) ) != pdTRUE )\r
-    {\r
-        /* Only warn if timeout > 0 */\r
-        if( timeoutMs > 0 )\r
-        {\r
-            IotLogWarn( "Timeout waiting on semaphore %p.",\r
-                        internalSemaphore );\r
-        }\r
-\r
-        return false;\r
-    }\r
-\r
-    return true;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void IotSemaphore_Post( IotSemaphore_t * pSemaphore )\r
-{\r
-    _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;\r
-\r
-    configASSERT( internalSemaphore != NULL );\r
-\r
-    IotLogDebug( "Posting to semaphore %p.", internalSemaphore );\r
-    /* Give the semaphore using the FreeRTOS API. */\r
-    BaseType_t result = xSemaphoreGive( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore );\r
-\r
-    if( result == pdFALSE )\r
-    {\r
-        IotLogDebug( "Unable to give semaphore over maximum", internalSemaphore );\r
-    }\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/include/platform/iot_clock.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/include/platform/iot_clock.h
deleted file mode 100644 (file)
index 93c7dcb..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-/*\r
- * Amazon FreeRTOS Platform V1.0.0\r
- * Copyright (C) 2019 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_clock.h\r
- * @brief Time-related functions used by libraries in this SDK.\r
- */\r
-\r
-#ifndef IOT_CLOCK_H_\r
-#define IOT_CLOCK_H_\r
-\r
-/* The config header is always included first. */\r
-#include "iot_config.h"\r
-\r
-/* Standard includes. */\r
-#include <stdbool.h>\r
-#include <stddef.h>\r
-#include <stdint.h>\r
-\r
-/* Platform layer types include. */\r
-#include "types/iot_platform_types.h"\r
-\r
-/**\r
- * @functionspage{platform_clock,platform clock component,Clock}\r
- * - @functionname{platform_clock_function_gettimestring}\r
- * - @functionname{platform_clock_function_gettimems}\r
- * - @functionname{platform_clock_function_sleepms}\r
- * - @functionname{platform_clock_function_timercreate}\r
- * - @functionname{platform_clock_function_timerdestroy}\r
- * - @functionname{platform_clock_function_timerarm}\r
- */\r
-\r
-/**\r
- * @functionpage{IotClock_GetTimestring,platform_clock,gettimestring}\r
- * @functionpage{IotClock_GetTimeMs,platform_clock,gettimems}\r
- * @functionpage{IotClock_SleepMs,platform_clock,sleepms}\r
- * @functionpage{IotClock_TimerCreate,platform_clock,timercreate}\r
- * @functionpage{IotClock_TimerDestroy,platform_clock,timerdestroy}\r
- * @functionpage{IotClock_TimerArm,platform_clock,timerarm}\r
- */\r
-\r
-/**\r
- * @brief Generates a human-readable timestring, such as "01 Jan 2018 12:00".\r
- *\r
- * This function uses the system clock to generate a human-readable timestring.\r
- * This timestring is printed by the [logging functions](@ref logging_functions).\r
- *\r
- * @param[out] pBuffer A buffer to store the timestring in.\r
- * @param[in] bufferSize The size of `pBuffer`.\r
- * @param[out] pTimestringLength The actual length of the timestring stored in\r
- * `pBuffer`.\r
- *\r
- * @return `true` if a timestring was successfully generated; `false` otherwise.\r
- *\r
- * @warning The implementation of this function must not call any [logging functions]\r
- * (@ref logging_functions).\r
- *\r
- * <b>Example</b>\r
- * @code{c}\r
- * char timestring[ 32 ];\r
- * size_t timestringLength = 0;\r
- *\r
- * if( IotClock_GetTimestring( timestring, 32, &timestringLength ) == true )\r
- * {\r
- *     printf( "Timestring: %.*s", timestringLength, timestring );\r
- * }\r
- * @endcode\r
- */\r
-/* @[declare_platform_clock_gettimestring] */\r
-bool IotClock_GetTimestring( char * pBuffer,\r
-                             size_t bufferSize,\r
-                             size_t * pTimestringLength );\r
-/* @[declare_platform_clock_gettimestring] */\r
-\r
-/**\r
- * @brief Returns a nonzero, monotonically-increasing system time in milliseconds.\r
- *\r
- * This function reads a millisecond-resolution system clock. The clock should\r
- * always be monotonically-increasing; therefore, real-time clocks that may be\r
- * set by another process are not suitable for this function's implementation.\r
- *\r
- * @return The value of the system clock. This function is not expected to fail.\r
- *\r
- * <b>Example</b>\r
- * @code{c}\r
- * // Get current time.\r
- * uint64_t currentTime = IotClock_GetTimeMs();\r
- * @endcode\r
- */\r
-/* @[declare_platform_clock_gettimems] */\r
-uint64_t IotClock_GetTimeMs( void );\r
-/* @[declare_platform_clock_gettimems] */\r
-\r
-/**\r
- * @brief Delay for the given number of milliseconds.\r
- *\r
- * This function suspends its calling thread for at least `sleepTimeMs` milliseconds.\r
- *\r
- * @param[in] sleepTimeMs Sleep time (in milliseconds).\r
- */\r
-/* @[declare_platform_clock_sleepms] */\r
-void IotClock_SleepMs( uint32_t sleepTimeMs );\r
-/* @[declare_platform_clock_sleepms] */\r
-\r
-/**\r
- * @brief Create a new timer.\r
- *\r
- * This function creates a new, unarmed timer. It must be called on an uninitialized\r
- * #IotTimer_t. This function must not be called on an already-initialized #IotTimer_t.\r
- *\r
- * @param[out] pNewTimer Set to a new timer handle on success.\r
- * @param[in] expirationRoutine The function to run when this timer expires. This\r
- * function should be called in its own <i>detached</i> thread.\r
- * @param[in] pArgument The argument to pass to `expirationRoutine`.\r
- *\r
- * @return `true` if the timer is successfully created; `false` otherwise.\r
- *\r
- * @see @ref platform_clock_function_timerdestroy, @ref platform_clock_function_timerarm\r
- */\r
-/* @[declare_platform_clock_timercreate] */\r
-bool IotClock_TimerCreate( IotTimer_t * pNewTimer,\r
-                           IotThreadRoutine_t expirationRoutine,\r
-                           void * pArgument );\r
-/* @[declare_platform_clock_timercreate] */\r
-\r
-/**\r
- * @brief Free resources used by a timer.\r
- *\r
- * This function frees resources used by a timer. It must be called on an initialized\r
- * #IotTimer_t. No other timer functions should be called on `pTimer` after calling\r
- * this function (unless the timer is re-created).\r
- *\r
- * This function will stop the `pTimer` if it is armed.\r
- *\r
- * @param[in] pTimer The timer to destroy.\r
- *\r
- * @see @ref platform_clock_function_timercreate, @ref platform_clock_function_timerarm\r
- */\r
-/* @[declare_platform_clock_timerdestroy] */\r
-void IotClock_TimerDestroy( IotTimer_t * pTimer );\r
-/* @[declare_platform_clock_timerdestroy] */\r
-\r
-/**\r
- * @brief Arm a timer to expire at the given relative timeout.\r
- *\r
- * This function arms a timer to run its expiration routine at the given time.\r
- *\r
- * If `periodMs` is nonzero, the timer should expire periodically at intervals\r
- * such as:\r
- * - `relativeTimeoutMs`\r
- * - `relativeTimeoutMs + periodMs`\r
- * - `relativeTimeoutMs + 2 * periodMs`\r
- * - Etc. (subject to some jitter).\r
- *\r
- * Setting `periodMs` to `0` arms a one-shot, non-periodic timer.\r
- *\r
- * @param[in] pTimer The timer to arm.\r
- * @param[in] relativeTimeoutMs When the timer should expire, relative to the time\r
- * this function is called.\r
- * @param[in] periodMs How often the timer should expire again after `relativeTimerMs`.\r
- *\r
- * @return `true` if the timer was successfully armed; `false` otherwise.\r
- *\r
- * @see @ref platform_clock_function_timercreate, @ref platform_clock_function_timerdestroy\r
- *\r
- * <b>Example</b>\r
- * @code{c}\r
- *\r
- * void timerExpirationRoutine( void * pArgument );\r
- *\r
- * void timerExample( void )\r
- * {\r
- *     IotTimer_t timer;\r
- *\r
- *     if( IotClock_TimerCreate( &timer, timerExpirationRoutine, NULL ) == true )\r
- *     {\r
- *         // Set the timer to periodically expire every 10 seconds.\r
- *         if( IotClock_TimerArm( &timer, 10000, 10000 ) == true )\r
- *         {\r
- *             // Wait for timer to expire.\r
- *         }\r
- *\r
- *         IotClock_TimerDestroy( &timer );\r
- *     }\r
- * }\r
- * @endcode\r
- */\r
-/* @[declare_platform_clock_timerarm] */\r
-bool IotClock_TimerArm( IotTimer_t * pTimer,\r
-                        uint32_t relativeTimeoutMs,\r
-                        uint32_t periodMs );\r
-/* @[declare_platform_clock_timerarm] */\r
-\r
-#endif /* ifndef IOT_CLOCK_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/include/platform/iot_metrics.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/include/platform/iot_metrics.h
deleted file mode 100644 (file)
index 74eb4f6..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*\r
- * Amazon FreeRTOS Platform V1.0.0\r
- * Copyright (C) 2019 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_metrics.h\r
- * @brief Functions for retrieving [Device Defender](@ref defender) metrics.\r
- *\r
- * The functions in this header are only required by Device Defender. They do not\r
- * need to be implemented if Device Defender is not used.\r
- */\r
-\r
-#ifndef IOT_METRICS_H_\r
-#define IOT_METRICS_H_\r
-\r
-/* The config header is always included first. */\r
-#include "iot_config.h"\r
-\r
-/* Standard includes. */\r
-#include <stdbool.h>\r
-\r
-/* Linear containers (lists and queues) include. */\r
-#include "iot_linear_containers.h"\r
-\r
-/**\r
- * @functionspage{platform_metrics,platform metrics component,Metrics}\r
- * - @functionname{platform_metrics_function_init}\r
- * - @functionname{platform_metrics_function_cleanup}\r
- * - @functionname{platform_metrics_function_gettcpconnections}\r
- */\r
-\r
-/**\r
- * @functionpage{IotMetrics_Init,platform_metrics,init}\r
- * @functionpage{IotMetrics_Cleanup,platform_metrics,cleanup}\r
- * @functionpage{IotMetrics_GetTcpConnections,platform_metrics,gettcpconnections}\r
- */\r
-\r
-/**\r
- * @brief One-time initialization function for the platform metrics component.\r
- *\r
- * This function initializes the platform metrics component. <b>It must be called\r
- * once (and only once) before calling any other metrics or [Device Defender function]\r
- * (@ref defender_functions).</b> Calling this function more than once without first\r
- * calling @ref platform_metrics_function_cleanup may result in a crash.\r
- *\r
- * @return `true` is initialization succeeded; `false` otherwise.\r
- *\r
- * @warning No thread-safety guarantees are provided for this function.\r
- */\r
-/* @[declare_platform_metrics_init] */\r
-bool IotMetrics_Init( void );\r
-/* @[declare_platform_metrics_init] */\r
-\r
-/**\r
- * @brief One-time deinitialization function for the platform metrics component.\r
- *\r
- * This function frees resources taken in @ref platform_metrics_function_init.\r
- * No other metrics or [Device Defender functions](@ref defender_functions) may\r
- * be called unless @ref platform_metrics_function_init is called again.\r
- *\r
- * @warning No thread-safety guarantees are provided for this function.\r
- */\r
-/* @[declare_platform_metrics_cleanup] */\r
-void IotMetrics_Cleanup( void );\r
-/* @[declare_platform_metrics_cleanup] */\r
-\r
-/**\r
- * @brief Retrieve a list of active TCP connections from the system.\r
- *\r
- * The provided connections are reported by Device Defender.\r
- *\r
- * @param[in] pContext Context passed as the first parameter of `metricsCallback`.\r
- * @param[in] metricsCallback Called by this function to provide the list of TCP\r
- * connections. The list given by this function is should not be used after the\r
- * callback returns.\r
- */\r
-/* @[declare_platform_metrics_gettcpconnections] */\r
-void IotMetrics_GetTcpConnections( void * pContext,\r
-                                   void ( * metricsCallback )( void *, const IotListDouble_t * ) );\r
-/* @[declare_platform_metrics_gettcpconnections] */\r
-\r
-#endif /* ifndef IOT_METRICS_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/include/platform/iot_network.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/include/platform/iot_network.h
deleted file mode 100644 (file)
index f52e4bb..0000000
+++ /dev/null
@@ -1,294 +0,0 @@
-/*\r
- * Amazon FreeRTOS Platform V1.0.0\r
- * Copyright (C) 2019 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_network.h\r
- * @brief Abstraction of network functions used by libraries in this SDK.\r
- */\r
-\r
-#ifndef IOT_NETWORK_H_\r
-#define IOT_NETWORK_H_\r
-\r
-/* Standard includes. */\r
-#include <stdbool.h>\r
-#include <stdint.h>\r
-#include <stdlib.h>\r
-\r
-/**\r
- * @ingroup platform_datatypes_enums\r
- * @brief Return codes for [network functions](@ref platform_network_functions).\r
- */\r
-typedef enum IotNetworkError\r
-{\r
-    IOT_NETWORK_SUCCESS = 0,   /**< Function successfully completed. */\r
-    IOT_NETWORK_FAILURE,       /**< Generic failure not covered by other values. */\r
-    IOT_NETWORK_BAD_PARAMETER, /**< At least one parameter was invalid. */\r
-    IOT_NETWORK_NO_MEMORY,     /**< Memory allocation failed. */\r
-    IOT_NETWORK_SYSTEM_ERROR   /**< An error occurred when calling a system API. */\r
-} IotNetworkError_t;\r
-\r
-/**\r
- * @page platform_network_functions Networking\r
- * @brief Functions of the network abstraction component.\r
- *\r
- * The network abstraction component does not declare functions, but uses function\r
- * pointers instead. This allows multiple network stacks to be used at the same time.\r
- * Libraries that require the network will request an #IotNetworkInterface_t\r
- * parameter. The members of the #IotNetworkInterface_t will be called whenever\r
- * the library interacts with the network.\r
- *\r
- * The following function pointers are associated with an #IotNetworkInterface_t.\r
- * Together, they represent a network stack.\r
- * - @functionname{platform_network_function_create}\r
- * - @functionname{platform_network_function_setreceivecallback}\r
- * - @functionname{platform_network_function_send}\r
- * - @functionname{platform_network_function_receive}\r
- * - @functionname{platform_network_function_close}\r
- * - @functionname{platform_network_function_destroy}\r
- * - @functionname{platform_network_function_receivecallback}\r
- */\r
-\r
-/**\r
- * @functionpage{IotNetworkInterface_t::create,platform_network,create}\r
- * @functionpage{IotNetworkInterface_t::setReceiveCallback,platform_network,setreceivecallback}\r
- * @functionpage{IotNetworkInterface_t::send,platform_network,send}\r
- * @functionpage{IotNetworkInterface_t::receive,platform_network,receive}\r
- * @functionpage{IotNetworkInterface_t::close,platform_network,close}\r
- * @functionpage{IotNetworkInterface_t::destroy,platform_network,destroy}\r
- * @functionpage{IotNetworkReceiveCallback_t,platform_network,receivecallback}\r
- */\r
-\r
-/**\r
- * @brief Provide an asynchronous notification of incoming network data.\r
- *\r
- * A function with this signature may be set with @ref platform_network_function_setreceivecallback\r
- * to be invoked when data is available on the network.\r
- *\r
- * @param[in] pConnection The connection on which data is available, defined by\r
- * the network stack.\r
- * @param[in] pContext The third argument passed to @ref platform_network_function_setreceivecallback.\r
- */\r
-/* @[declare_platform_network_receivecallback] */\r
-typedef void ( * IotNetworkReceiveCallback_t )( void * pConnection,\r
-                                                void * pContext );\r
-/* @[declare_platform_network_receivecallback] */\r
-\r
-/**\r
- * @ingroup platform_datatypes_paramstructs\r
- * @brief Represents the functions of a network stack.\r
- *\r
- * Functions that match these signatures should be implemented against a system's\r
- * network stack. See the `platform` directory for existing implementations.\r
- */\r
-typedef struct IotNetworkInterface\r
-{\r
-    /**\r
-     * @brief Create a new network connection.\r
-     *\r
-     * This function allocates resources and establishes a new network connection.\r
-     * @param[in] pConnectionInfo Represents information needed to set up the\r
-     * new connection, defined by the network stack.\r
-     * @param[in] pCredentialInfo Represents information needed to secure the\r
-     * new connection, defined by the network stack.\r
-     * @param[out] pConnection Set to represent a new connection, defined by the\r
-     * network stack.\r
-     *\r
-     * @return Any #IotNetworkError_t, as defined by the network stack.\r
-     */\r
-    /* @[declare_platform_network_create] */\r
-    IotNetworkError_t ( * create )( void * pConnectionInfo,\r
-                                    void * pCredentialInfo,\r
-                                    void ** pConnection );\r
-    /* @[declare_platform_network_create] */\r
-\r
-    /**\r
-     * @brief Register an @ref platform_network_function_receivecallback.\r
-     *\r
-     * Sets an @ref platform_network_function_receivecallback to be called\r
-     * asynchronously when data arrives on the network. The network stack\r
-     * should invoke this function "as if" it were the thread routine of a\r
-     * detached thread.\r
-     *\r
-     * Each network connection may only have one receive callback at any time.\r
-     * @ref platform_network_function_close is expected to remove any active\r
-     * receive callbacks.\r
-     *\r
-     * @param[in] pConnection The connection to associate with the receive callback.\r
-     * @param[in] receiveCallback The function to invoke for incoming network data.\r
-     * @param[in] pContext A value to pass as the first parameter to the receive callback.\r
-     *\r
-     * @return Any #IotNetworkError_t, as defined by the network stack.\r
-     *\r
-     * @see platform_network_function_receivecallback\r
-     */\r
-    /* @[declare_platform_network_setreceivecallback] */\r
-    IotNetworkError_t ( * setReceiveCallback )( void * pConnection,\r
-                                                IotNetworkReceiveCallback_t receiveCallback,\r
-                                                void * pContext );\r
-    /* @[declare_platform_network_setreceivecallback] */\r
-\r
-    /**\r
-     * @brief Send data over a return connection.\r
-     *\r
-     * Attempts to transmit `messageLength` bytes of `pMessage` across the\r
-     * connection represented by `pConnection`. Returns the number of bytes\r
-     * actually sent, `0` on failure.\r
-     *\r
-     * @param[in] pConnection The connection used to send data, defined by the\r
-     * network stack.\r
-     * @param[in] pMessage The message to send.\r
-     * @param[in] messageLength The length of `pMessage`.\r
-     *\r
-     * @return The number of bytes successfully sent, `0` on failure.\r
-     */\r
-    /* @[declare_platform_network_send] */\r
-    size_t ( * send )( void * pConnection,\r
-                       const uint8_t * pMessage,\r
-                       size_t messageLength );\r
-    /* @[declare_platform_network_send] */\r
-\r
-    /**\r
-     * @brief Block and wait for incoming network data.\r
-     *\r
-     * Wait for a message of size `bytesRequested` to arrive on the network and\r
-     * place it in `pBuffer`.\r
-     *\r
-     * @param[in] pConnection The connection to wait on, defined by the network\r
-     * stack.\r
-     * @param[out] pBuffer Where to place the incoming network data. This buffer\r
-     * must be at least `bytesRequested` in size.\r
-     * @param[in] bytesRequested How many bytes to wait for. `pBuffer` must be at\r
-     * least this size.\r
-     *\r
-     * @return The number of bytes successfully received. This should be\r
-     * `bytesRequested` when successful. Any other value may indicate an error.\r
-     */\r
-    /* @[declare_platform_network_receive] */\r
-    size_t ( * receive )( void * pConnection,\r
-                          uint8_t * pBuffer,\r
-                          size_t bytesRequested );\r
-    /* @[declare_platform_network_receive] */\r
-\r
-    /**\r
-     * @brief Close a network connection.\r
-     *\r
-     * This function closes the connection, but does not release the resources\r
-     * used by the connection. This allows calls to other networking functions\r
-     * to return an error and handle a closed connection without the risk of\r
-     * crashing. Once it can be guaranteed that `pConnection` will no longer be\r
-     * used, the connection can be destroyed with @ref platform_network_function_destroy.\r
-     *\r
-     * In addition to closing the connection, this function should also remove\r
-     * any active [receive callback](@ref platform_network_function_receivecallback).\r
-     *\r
-     * @param[in] pConnection The network connection to close, defined by the\r
-     * network stack.\r
-     *\r
-     * @return Any #IotNetworkError_t, as defined by the network stack.\r
-     *\r
-     * @note It must be safe to call this function on an already-closed connection.\r
-     */\r
-    /* @[declare_platform_network_close] */\r
-    IotNetworkError_t ( * close )( void * pConnection );\r
-    /* @[declare_platform_network_close] */\r
-\r
-    /**\r
-     * @brief Free resources used by a network connection.\r
-     *\r
-     * This function releases the resources of a closed connection. It should be\r
-     * called after @ref platform_network_function_close.\r
-     *\r
-     * @param[in] pConnection The network connection to destroy, defined by\r
-     * the network stack.\r
-     *\r
-     * @return Any #IotNetworkError_t, as defined by the network stack.\r
-     *\r
-     * @attention No function should be called on the network connection after\r
-     * calling this function. This function must be safe to call from a\r
-     * [receive callback](@ref platform_network_function_receivecallback).\r
-     */\r
-    /* @[declare_platform_network_destroy] */\r
-    IotNetworkError_t ( * destroy )( void * pConnection );\r
-    /* @[declare_platform_network_destroy] */\r
-} IotNetworkInterface_t;\r
-\r
-/**\r
- * @ingroup platform_datatypes_paramstructs\r
- * @brief Information on the remote server for connection setup.\r
- *\r
- * May be passed to #IotNetworkInterface_t.create as `pConnectionInfo`. This\r
- * structure contains commonly-used parameters, but may be replaced with an\r
- * alternative.\r
- */\r
-typedef struct IotNetworkServerInfo\r
-{\r
-    const char * pHostName; /**< @brief Server host name. Must be NULL-terminated. */\r
-    uint16_t port;          /**< @brief Server port in host-order. */\r
-} IotNetworkServerInfo_t;\r
-\r
-/**\r
- * @ingroup platform_datatypes_paramstructs\r
- * @brief Contains the credentials necessary for connection setup.\r
- *\r
- * May be passed to #IotNetworkInterface_t.create as `pCredentialInfo`. This\r
- * structure contains commonly-used parameters, but may be replaced with an\r
- * alternative.\r
- */\r
-typedef struct IotNetworkCredentials\r
-{\r
-    /**\r
-     * @brief Set this to a non-NULL value to use ALPN.\r
-     *\r
-     * This string must be NULL-terminated.\r
-     *\r
-     * See [this link]\r
-     * (https://aws.amazon.com/blogs/iot/mqtt-with-tls-client-authentication-on-port-443-why-it-is-useful-and-how-it-works/)\r
-     * for more information.\r
-     */\r
-    const char * pAlpnProtos;\r
-\r
-    /**\r
-     * @brief Set this to a non-zero value to use TLS max fragment length\r
-     * negotiation (TLS MFLN).\r
-     *\r
-     * @note The network stack may have a minimum value for this parameter and\r
-     * may return an error if this parameter is too small.\r
-     */\r
-    size_t maxFragmentLength;\r
-\r
-    /**\r
-     * @brief Disable server name indication (SNI) for a TLS session.\r
-     */\r
-    bool disableSni;\r
-\r
-    const char * pRootCa;     /**< @brief String representing a trusted server root certificate. */\r
-    size_t rootCaSize;        /**< @brief Size associated with #IotNetworkCredentials_t.pRootCa. */\r
-    const char * pClientCert; /**< @brief String representing the client certificate. */\r
-    size_t clientCertSize;    /**< @brief Size associated with #IotNetworkCredentials_t.pClientCert. */\r
-    const char * pPrivateKey; /**< @brief String representing the client certificate's private key. */\r
-    size_t privateKeySize;    /**< @brief Size associated with #IotNetworkCredentials_t.pPrivateKey. */\r
-} IotNetworkCredentials_t;\r
-\r
-#endif /* ifndef IOT_NETWORK_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/include/platform/iot_threads.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/include/platform/iot_threads.h
deleted file mode 100644 (file)
index 58571d8..0000000
+++ /dev/null
@@ -1,355 +0,0 @@
-/*\r
- * Amazon FreeRTOS Platform V1.0.0\r
- * Copyright (C) 2019 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_threads.h\r
- * @brief Threading and synchronization functions used by libraries in this SDK.\r
- */\r
-\r
-#ifndef IOT_THREADS_H_\r
-#define IOT_THREADS_H_\r
-\r
-/* The config header is always included first. */\r
-#include "iot_config.h"\r
-\r
-/* Standard includes. */\r
-#include <stdbool.h>\r
-#include <stdint.h>\r
-\r
-/* Platform layer types include. */\r
-#include "types/iot_platform_types.h"\r
-\r
-/**\r
- * @functionspage{platform_threads,platform thread management,Thread Management}\r
- * - @functionname{platform_threads_function_createdetachedthread}\r
- * - @functionname{platform_threads_function_mutexcreate}\r
- * - @functionname{platform_threads_function_mutexdestroy}\r
- * - @functionname{platform_threads_function_mutexlock}\r
- * - @functionname{platform_threads_function_mutextrylock}\r
- * - @functionname{platform_threads_function_mutexunlock}\r
- * - @functionname{platform_threads_function_semaphorecreate}\r
- * - @functionname{platform_threads_function_semaphoredestroy}\r
- * - @functionname{platform_threads_function_semaphoregetcount}\r
- * - @functionname{platform_threads_function_semaphorewait}\r
- * - @functionname{platform_threads_function_semaphoretrywait}\r
- * - @functionname{platform_threads_function_semaphoretimedwait}\r
- * - @functionname{platform_threads_function_semaphorepost}\r
- */\r
-\r
-/**\r
- * @functionpage{Iot_CreateDetachedThread,platform_threads,createdetachedthread}\r
- * @functionpage{IotMutex_Create,platform_threads,mutexcreate}\r
- * @functionpage{IotMutex_Destroy,platform_threads,mutexdestroy}\r
- * @functionpage{IotMutex_Lock,platform_threads,mutexlock}\r
- * @functionpage{IotMutex_TryLock,platform_threads,mutextrylock}\r
- * @functionpage{IotMutex_Unlock,platform_threads,mutexunlock}\r
- * @functionpage{IotSemaphore_Create,platform_threads,semaphorecreate}\r
- * @functionpage{IotSemaphore_Destroy,platform_threads,semaphoredestroy}\r
- * @functionpage{IotSemaphore_GetCount,platform_threads,semaphoregetcount}\r
- * @functionpage{IotSemaphore_Wait,platform_threads,semaphorewait}\r
- * @functionpage{IotSemaphore_TryWait,platform_threads,semaphoretrywait}\r
- * @functionpage{IotSemaphore_TimedWait,platform_threads,semaphoretimedwait}\r
- * @functionpage{IotSemaphore_Post,platform_threads,semaphorepost}\r
- */\r
-\r
-/**\r
- * @brief Create a new detached thread, i.e. a thread that cleans up after itself.\r
- *\r
- * This function creates a new thread. Threads created by this function exit\r
- * upon returning from the thread routine. Any resources taken must be freed\r
- * by the exiting thread.\r
- *\r
- * @param[in] threadRoutine The function this thread should run.\r
- * @param[in] pArgument The argument passed to `threadRoutine`.\r
- * @param[in] priority Represents the priority of the new thread, as defined by\r
- * the system. The value #IOT_THREAD_DEFAULT_PRIORITY (i.e. `0`) must be used to\r
- * represent the system default for thread priority.\r
- * @param[in] stackSize Represents the stack size of the new thread, as defined\r
- * by the system. The value #IOT_THREAD_DEFAULT_STACK_SIZE (i.e. `0`) must be used\r
- * to represent the system default for stack size.\r
- *\r
- * @return `true` if the new thread was successfully created; `false` otherwise.\r
- *\r
- * @code{c}\r
- * // Thread routine.\r
- * void threadRoutine( void * pArgument );\r
- *\r
- * // Run threadRoutine in a detached thread, using default priority and stack size.\r
- * if( Iot_CreateDetachedThread( threadRoutine,\r
- *                               NULL,\r
- *                               IOT_THREAD_DEFAULT_PRIORITY,\r
- *                               IOT_THREAD_DEFAULT_STACK_SIZE ) == true )\r
- * {\r
- *     // Success\r
- * }\r
- * else\r
- * {\r
- *     // Failure, no thread was created.\r
- * }\r
- * @endcode\r
- */\r
-/* @[declare_platform_threads_createdetachedthread] */\r
-bool Iot_CreateDetachedThread( IotThreadRoutine_t threadRoutine,\r
-                               void * pArgument,\r
-                               int32_t priority,\r
-                               size_t stackSize );\r
-/* @[declare_platform_threads_createdetachedthread] */\r
-\r
-/**\r
- * @brief Create a new mutex.\r
- *\r
- * This function creates a new, unlocked mutex. It must be called on an uninitialized\r
- * #IotMutex_t. This function must not be called on an already-initialized #IotMutex_t.\r
- *\r
- * @param[in] pNewMutex Pointer to the memory that will hold the new mutex.\r
- * @param[in] recursive Set to `true` to create a recursive mutex, i.e. a mutex that\r
- * may be locked multiple times by the same thread. If the system does not support\r
- * recursive mutexes, this function should do nothing and return `false`.\r
- *\r
- * @return `true` if mutex creation succeeds; `false` otherwise.\r
- *\r
- * @see @ref platform_threads_function_mutexdestroy\r
- *\r
- * <b>Example</b>\r
- * @code{c}\r
- * IotMutex_t mutex;\r
- *\r
- * // Create non-recursive mutex.\r
- * if( IotMutex_Create( &mutex, false ) == true )\r
- * {\r
- *     // Lock and unlock the mutex...\r
- *\r
- *     // Destroy the mutex when it's no longer needed.\r
- *     IotMutex_Destroy( &mutex );\r
- * }\r
- * @endcode\r
- */\r
-/* @[declare_platform_threads_mutexcreate] */\r
-bool IotMutex_Create( IotMutex_t * pNewMutex, bool recursive );\r
-/* @[declare_platform_threads_mutexcreate] */\r
-\r
-/**\r
- * @brief Free resources used by a mutex.\r
- *\r
- * This function frees resources used by a mutex. It must be called on an initialized\r
- * #IotMutex_t. No other mutex functions should be called on `pMutex` after calling\r
- * this function (unless the mutex is re-created).\r
- *\r
- * @param[in] pMutex The mutex to destroy.\r
- *\r
- * @warning This function must not be called on a locked mutex.\r
- * @see @ref platform_threads_function_mutexcreate\r
- */\r
-/* @[declare_platform_threads_mutexdestroy] */\r
-void IotMutex_Destroy( IotMutex_t * pMutex );\r
-/* @[declare_platform_threads_mutexdestroy] */\r
-\r
-/**\r
- * @brief Lock a mutex. This function should only return when the mutex is locked;\r
- * it is not expected to fail.\r
- *\r
- * This function blocks and waits until a mutex is available. It waits forever\r
- * (deadlocks) if `pMutex` is already locked and never unlocked.\r
- *\r
- * @param[in] pMutex The mutex to lock.\r
- *\r
- * @see @ref platform_threads_function_mutextrylock for a nonblocking lock.\r
- */\r
-/* @[declare_platform_threads_mutexlock] */\r
-void IotMutex_Lock( IotMutex_t * pMutex );\r
-/* @[declare_platform_threads_mutexlock] */\r
-\r
-/**\r
- * @brief Attempt to lock a mutex. Return immediately if the mutex is not available.\r
- *\r
- * If `pMutex` is available, this function immediately locks it and returns.\r
- * Otherwise, this function returns without locking `pMutex`.\r
- *\r
- * @param[in] pMutex The mutex to lock.\r
- *\r
- * @return `true` if the mutex was successfully locked; `false` if the mutex was\r
- * not available.\r
- *\r
- * @see @ref platform_threads_function_mutexlock for a blocking lock.\r
- */\r
-/* @[declare_platform_threads_mutextrylock] */\r
-bool IotMutex_TryLock( IotMutex_t * pMutex );\r
-/* @[declare_platform_threads_mutextrylock] */\r
-\r
-/**\r
- * @brief Unlock a mutex. This function should only return when the mutex is unlocked;\r
- * it is not expected to fail.\r
- *\r
- * Unlocks a locked mutex. `pMutex` must have been locked by the thread calling\r
- * this function.\r
- *\r
- * @param[in] pMutex The mutex to unlock.\r
- *\r
- * @note This function should not be called on a mutex that is already unlocked.\r
- */\r
-/* @[declare_platform_threads_mutexunlock] */\r
-void IotMutex_Unlock( IotMutex_t * pMutex );\r
-/* @[declare_platform_threads_mutexunlock] */\r
-\r
-/**\r
- * @brief Create a new counting semaphore.\r
- *\r
- * This function creates a new counting semaphore with a given intial and\r
- * maximum value. It must be called on an uninitialized #IotSemaphore_t.\r
- * This function must not be called on an already-initialized #IotSemaphore_t.\r
- *\r
- * @param[in] pNewSemaphore Pointer to the memory that will hold the new semaphore.\r
- * @param[in] initialValue The semaphore should be initialized with this value.\r
- * @param[in] maxValue The maximum value the semaphore will reach.\r
- *\r
- * @return `true` if semaphore creation succeeds; `false` otherwise.\r
- *\r
- * @see @ref platform_threads_function_semaphoredestroy\r
- *\r
- * <b>Example</b>\r
- * @code{c}\r
- * IotSemaphore_t sem;\r
- *\r
- * // Create a locked binary semaphore.\r
- * if( IotSemaphore_Create( &sem, 0, 1 ) == true )\r
- * {\r
- *     // Unlock the semaphore.\r
- *     IotSemaphore_Post( &sem );\r
- *\r
- *     // Destroy the semaphore when it's no longer needed.\r
- *     IotSemaphore_Destroy( &sem );\r
- * }\r
- * @endcode\r
- */\r
-/* @[declare_platform_threads_semaphorecreate] */\r
-bool IotSemaphore_Create( IotSemaphore_t * pNewSemaphore,\r
-                          uint32_t initialValue,\r
-                          uint32_t maxValue );\r
-/* @[declare_platform_threads_semaphorecreate] */\r
-\r
-/**\r
- * @brief Free resources used by a semaphore.\r
- *\r
- * This function frees resources used by a semaphore. It must be called on an initialized\r
- * #IotSemaphore_t. No other semaphore functions should be called on `pSemaphore` after\r
- * calling this function (unless the semaphore is re-created).\r
- *\r
- * @param[in] pSemaphore The semaphore to destroy.\r
- *\r
- * @warning This function must not be called on a semaphore with waiting threads.\r
- * @see @ref platform_threads_function_semaphorecreate\r
- */\r
-/* @[declare_platform_threads_semaphoredestroy] */\r
-void IotSemaphore_Destroy( IotSemaphore_t * pSemaphore );\r
-/* @[declare_platform_threads_semaphoredestroy] */\r
-\r
-/**\r
- * @brief Query the current count of the semaphore.\r
- *\r
- * This function queries a counting semaphore for its current value. A counting\r
- * semaphore's value is always 0 or positive.\r
- *\r
- * @param[in] pSemaphore The semaphore to query.\r
- *\r
- * @return The current count of the semaphore. This function should not fail.\r
- */\r
-/* @[declare_platform_threads_semaphoregetcount] */\r
-uint32_t IotSemaphore_GetCount( IotSemaphore_t * pSemaphore );\r
-/* @[declare_platform_threads_semaphoregetcount] */\r
-\r
-/**\r
- * @brief Wait on (lock) a semaphore. This function should only return when the\r
- * semaphore wait succeeds; it is not expected to fail.\r
- *\r
- * This function blocks and waits until a counting semaphore is positive. It\r
- * waits forever (deadlocks) if `pSemaphore` has a count `0` that is never\r
- * [incremented](@ref platform_threads_function_semaphorepost).\r
- *\r
- * @param[in] pSemaphore The semaphore to lock.\r
- *\r
- * @see @ref platform_threads_function_semaphoretrywait for a nonblocking wait;\r
- * @ref platform_threads_function_semaphoretimedwait for a wait with timeout.\r
- */\r
-/* @[declare_platform_threads_semaphorewait] */\r
-void IotSemaphore_Wait( IotSemaphore_t * pSemaphore );\r
-/* @[declare_platform_threads_semaphorewait] */\r
-\r
-/**\r
- * @brief Attempt to wait on (lock) a semaphore. Return immediately if the semaphore\r
- * is not available.\r
- *\r
- * If the count of `pSemaphore` is positive, this function immediately decrements\r
- * the semaphore and returns. Otherwise, this function returns without decrementing\r
- * `pSemaphore`.\r
- *\r
- * @param[in] pSemaphore The semaphore to lock.\r
- *\r
- * @return `true` if the semaphore wait succeeded; `false` if the semaphore has\r
- * a count of `0`.\r
- *\r
- * @see @ref platform_threads_function_semaphorewait for a blocking wait;\r
- * @ref platform_threads_function_semaphoretimedwait for a wait with timeout.\r
- */\r
-/* @[declare_platform_threads_semaphoretrywait] */\r
-bool IotSemaphore_TryWait( IotSemaphore_t * pSemaphore );\r
-/* @[declare_platform_threads_semaphoretrywait] */\r
-\r
-/**\r
- * @brief Attempt to wait on (lock) a semaphore with a timeout.\r
- *\r
- * This function blocks and waits until a counting semaphore is positive\r
- * <i>or</i> its timeout expires (whichever is sooner). It decrements\r
- * `pSemaphore` and returns `true` if the semaphore is positive at some\r
- * time during the wait. If `pSemaphore` is always `0` during the wait,\r
- * this function returns `false`.\r
- *\r
- * @param[in] pSemaphore The semaphore to lock.\r
- * @param[in] timeoutMs Relative timeout of semaphore lock. This function returns\r
- * false if the semaphore couldn't be locked within this timeout.\r
- *\r
- * @return `true` if the semaphore wait succeeded; `false` if it timed out.\r
- *\r
- * @see @ref platform_threads_function_semaphoretrywait for a nonblocking wait;\r
- * @ref platform_threads_function_semaphorewait for a blocking wait.\r
- */\r
-/* @[declare_platform_threads_semaphoretimedwait] */\r
-bool IotSemaphore_TimedWait( IotSemaphore_t * pSemaphore,\r
-                             uint32_t timeoutMs );\r
-/* @[declare_platform_threads_semaphoretimedwait] */\r
-\r
-/**\r
- * @brief Post to (unlock) a semaphore. This function should only return when the\r
- * semaphore post succeeds; it is not expected to fail.\r
- *\r
- * This function increments the count of a semaphore. Any thread may call this\r
- * function to increment a semaphore's count.\r
- *\r
- * @param[in] pSemaphore The semaphore to unlock.\r
- */\r
-/* @[declare_platform_threads_semaphorepost] */\r
-void IotSemaphore_Post( IotSemaphore_t * pSemaphore );\r
-/* @[declare_platform_threads_semaphorepost] */\r
-\r
-#endif /* ifndef IOT_THREADS_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/include/types/iot_platform_types.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/include/types/iot_platform_types.h
deleted file mode 100644 (file)
index e9fc785..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-/*\r
- * Amazon FreeRTOS Platform V1.0.0\r
- * Copyright (C) 2019 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_platform_types.h\r
- * @brief Types of the platform layer.\r
- */\r
-\r
-#ifndef IOT_PLATFORM_TYPES_H_\r
-#define IOT_PLATFORM_TYPES_H_\r
-\r
-/* The config header is always included first. */\r
-#include "iot_config.h"\r
-\r
-/* Linear containers (lists and queues) include for metrics types. */\r
-#include "iot_linear_containers.h"\r
-\r
-/*------------------------- Thread management types -------------------------*/\r
-\r
-/**\r
- * @brief A value representing the system default for new thread priority.\r
- */\r
-#ifndef IOT_THREAD_DEFAULT_PRIORITY\r
-    #define IOT_THREAD_DEFAULT_PRIORITY      0\r
-#endif\r
-\r
-/**\r
- * @brief A value representhing the system default for new thread stack size.\r
- */\r
-#ifndef IOT_THREAD_DEFAULT_STACK_SIZE\r
-    #define IOT_THREAD_DEFAULT_STACK_SIZE    0\r
-#endif\r
-\r
-/**\r
- * @ingroup platform_datatypes_handles\r
- * @brief The type used to represent mutexes, configured with the type\r
- * `_IotSystemMutex_t`.\r
- *\r
- * <span style="color:red;font-weight:bold">\r
- * `_IotSystemMutex_t` will be automatically configured during build and generally\r
- * does not need to be defined.\r
- * </span>\r
- *\r
- * Mutexes should only be released by the threads that take them.\r
- *\r
- * <b>Example</b> <br>\r
- * To change the type of #IotMutex_t to `long`:\r
- * @code{c}\r
- * typedef long _IotSystemMutex_t;\r
- * #include "iot_threads.h"\r
- * @endcode\r
- */\r
-typedef _IotSystemMutex_t       IotMutex_t;\r
-\r
-/**\r
- * @ingroup platform_datatypes_handles\r
- * @brief The type used to represent semaphores, configured with the type\r
- * `_IotSystemSemaphore_t`.\r
- *\r
- * <span style="color:red;font-weight:bold">\r
- * `_IotSystemSemaphore_t` will be automatically configured during build and\r
- * generally does not need to be defined.\r
- * </span>\r
- *\r
- * Semaphores must be counting, and any thread may take (wait on) or release\r
- * (post to) a semaphore.\r
- *\r
- * <b>Example</b> <br>\r
- * To change the type of #IotSemaphore_t to `long`:\r
- * @code{c}\r
- * typedef long _IotSystemSemaphore_t;\r
- * #include "iot_threads.h"\r
- * @endcode\r
- */\r
-typedef _IotSystemSemaphore_t   IotSemaphore_t;\r
-\r
-/**\r
- * @brief Thread routine function.\r
- *\r
- * @param[in] void * The argument passed to the @ref\r
- * platform_threads_function_createdetachedthread. For application use.\r
- */\r
-typedef void ( * IotThreadRoutine_t )( void * );\r
-\r
-/*-------------------------- Clock and timer types --------------------------*/\r
-\r
-/**\r
- * @ingroup platform_datatypes_handles\r
- * @brief The type used to represent timers, configured with the type\r
- * `_IotSystemTimer_t`.\r
- *\r
- * <span style="color:red;font-weight:bold">\r
- * `_IotSystemTimer_t` will be automatically configured during build and generally\r
- * does not need to be defined.\r
- * </span>\r
- *\r
- * <b>Example</b> <br>\r
- * To change the type of #IotTimer_t to `long`:\r
- * @code{c}\r
- * typedef long _IotSystemTimer_t;\r
- * #include "iot_clock.h"\r
- * @endcode\r
- */\r
-typedef _IotSystemTimer_t IotTimer_t;\r
-\r
-/*------------------------------ Metrics types ------------------------------*/\r
-\r
-/**\r
- * @brief The length of the buffer used to store IP addresses for metrics.\r
- *\r
- * This is the length of the longest IPv6 address plus space for the port number\r
- * and NULL terminator.\r
- */\r
-#define IOT_METRICS_IP_ADDRESS_LENGTH    54\r
-\r
-/**\r
- * @brief Represents a TCP connection to a remote IPv4 server.\r
- *\r
- * A list of these is provided by @ref platform_metrics_function_gettcpconnections.\r
- */\r
-typedef struct IotMetricsTcpConnection\r
-{\r
-    IotLink_t link;         /**< @brief List link member. */\r
-    void * pNetworkContext; /**< @brief Context that may be used by metrics or Defender. */\r
-    size_t addressLength;   /**< @brief The length of the address stored in #IotMetricsTcpConnection_t.pRemoteAddress. */\r
-\r
-    /**\r
-     * @brief NULL-terminated IP address and port in text format.\r
-     *\r
-     * IPv4 addresses will be in the format `xxx.xxx.xxx.xxx:port`.\r
-     * IPv6 addresses will be in the format `[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]:port`.\r
-     */\r
-    char pRemoteAddress[ IOT_METRICS_IP_ADDRESS_LENGTH ];\r
-} IotMetricsTcpConnection_t;\r
-\r
-#endif /* ifndef IOT_PLATFORM_TYPES_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/secure_sockets/freertos_plus_tcp/iot_secure_sockets.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/secure_sockets/freertos_plus_tcp/iot_secure_sockets.c
deleted file mode 100644 (file)
index af809c2..0000000
+++ /dev/null
@@ -1,342 +0,0 @@
-/*\r
- * Amazon FreeRTOS Secure Sockets V1.1.5\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
-/* Define _SECURE_SOCKETS_WRAPPER_NOT_REDEFINE to prevent secure sockets functions\r
- * from redefining in iot_secure_sockets_wrapper_metrics.h */\r
-#define _SECURE_SOCKETS_WRAPPER_NOT_REDEFINE\r
-\r
-/* FreeRTOS includes. */\r
-#include "FreeRTOS.h"\r
-#include "FreeRTOSIPConfig.h"\r
-#include "list.h"\r
-#include "semphr.h"\r
-#include "FreeRTOS_IP.h"\r
-#include "FreeRTOS_Sockets.h"\r
-#include "iot_secure_sockets.h"\r
-#include "task.h"\r
-\r
-#undef _SECURE_SOCKETS_WRAPPER_NOT_REDEFINE\r
-\r
-/* Internal context structure. */\r
-typedef struct SSOCKETContext\r
-{\r
-    Socket_t xSocket;\r
-    char * pcDestination;\r
-    BaseType_t xSendFlags;\r
-    BaseType_t xRecvFlags;\r
-    BaseType_t xConnectAttempted;\r
-} SSOCKETContext_t, * SSOCKETContextPtr_t;\r
-\r
-/*\r
- * Helper routines.\r
- */\r
-\r
-/*\r
- * @brief Network send callback.\r
- */\r
-static BaseType_t prvNetworkSend( void * pvContext,\r
-                                  const unsigned char * pucData,\r
-                                  size_t xDataLength )\r
-{\r
-    SSOCKETContextPtr_t pxContext = ( SSOCKETContextPtr_t ) pvContext; /*lint !e9087 cast used for portability. */\r
-\r
-    return FreeRTOS_send( pxContext->xSocket, pucData, xDataLength, pxContext->xSendFlags );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-/*\r
- * @brief Network receive callback.\r
- */\r
-static BaseType_t prvNetworkRecv( void * pvContext,\r
-                                  unsigned char * pucReceiveBuffer,\r
-                                  size_t xReceiveLength )\r
-{\r
-    SSOCKETContextPtr_t pxContext = ( SSOCKETContextPtr_t ) pvContext; /*lint !e9087 cast used for portability. */\r
-\r
-    return FreeRTOS_recv( pxContext->xSocket, pucReceiveBuffer, xReceiveLength, pxContext->xRecvFlags );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-/*\r
- * Interface routines.\r
- */\r
-\r
-int32_t SOCKETS_Close( Socket_t xSocket )\r
-{\r
-    SSOCKETContextPtr_t pxContext = ( SSOCKETContextPtr_t ) xSocket; /*lint !e9087 cast used for portability. */\r
-    int32_t lReturn;\r
-\r
-    if( ( xSocket != SOCKETS_INVALID_SOCKET ) && ( NULL != pxContext ) )\r
-    {\r
-        /* Clean-up destination string. */\r
-        if( NULL != pxContext->pcDestination )\r
-        {\r
-            vPortFree( pxContext->pcDestination );\r
-        }\r
-\r
-        /* Close the underlying socket handle. */\r
-        ( void ) FreeRTOS_closesocket( pxContext->xSocket );\r
-\r
-        /* Free the context. */\r
-        vPortFree( pxContext );\r
-        lReturn = SOCKETS_ERROR_NONE;\r
-    }\r
-    else\r
-    {\r
-        lReturn = SOCKETS_EINVAL;\r
-    }\r
-\r
-    return lReturn;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-int32_t SOCKETS_Connect( Socket_t xSocket,\r
-                         SocketsSockaddr_t * pxAddress,\r
-                         Socklen_t xAddressLength )\r
-{\r
-    int32_t lStatus = SOCKETS_ERROR_NONE;\r
-    SSOCKETContextPtr_t pxContext = ( SSOCKETContextPtr_t ) xSocket; /*lint !e9087 cast used for portability. */\r
-    struct freertos_sockaddr xTempAddress = { 0 };\r
-\r
-    if( ( pxContext != SOCKETS_INVALID_SOCKET ) && ( pxAddress != NULL ) )\r
-    {\r
-        /* A connection was attempted. If this function fails, then the socket is invalid and the user\r
-         * must call SOCKETS_Close(), on this socket, and SOCKETS_Socket() to get a new socket. */\r
-        pxContext->xConnectAttempted = pdTRUE;\r
-\r
-        /* Connect the wrapped socket. */\r
-        xTempAddress.sin_addr = pxAddress->ulAddress;\r
-        xTempAddress.sin_family = pxAddress->ucSocketDomain;\r
-        xTempAddress.sin_len = ( uint8_t ) sizeof( xTempAddress );\r
-        xTempAddress.sin_port = pxAddress->usPort;\r
-        lStatus = FreeRTOS_connect( pxContext->xSocket, &xTempAddress, xAddressLength );\r
-    }\r
-    else\r
-    {\r
-        lStatus = SOCKETS_SOCKET_ERROR;\r
-    }\r
-\r
-    return lStatus;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-uint32_t SOCKETS_GetHostByName( const char * pcHostName )\r
-{\r
-    return FreeRTOS_gethostbyname( pcHostName );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-int32_t SOCKETS_Recv( Socket_t xSocket,\r
-                      void * pvBuffer,\r
-                      size_t xBufferLength,\r
-                      uint32_t ulFlags )\r
-{\r
-    int32_t lStatus = SOCKETS_SOCKET_ERROR;\r
-    SSOCKETContextPtr_t pxContext = ( SSOCKETContextPtr_t ) xSocket; /*lint !e9087 cast used for portability. */\r
-\r
-    if( ( xSocket != SOCKETS_INVALID_SOCKET ) &&\r
-        ( pvBuffer != NULL ) )\r
-    {\r
-        pxContext->xRecvFlags = ( BaseType_t ) ulFlags;\r
-\r
-        /* Receive unencrypted. */\r
-        lStatus = prvNetworkRecv( pxContext, pvBuffer, xBufferLength );\r
-    }\r
-    else\r
-    {\r
-        lStatus = SOCKETS_EINVAL;\r
-    }\r
-\r
-    return lStatus;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-int32_t SOCKETS_Send( Socket_t xSocket,\r
-                      const void * pvBuffer,\r
-                      size_t xDataLength,\r
-                      uint32_t ulFlags )\r
-{\r
-    int32_t lStatus = SOCKETS_SOCKET_ERROR;\r
-    SSOCKETContextPtr_t pxContext = ( SSOCKETContextPtr_t ) xSocket; /*lint !e9087 cast used for portability. */\r
-\r
-    if( ( xSocket != SOCKETS_INVALID_SOCKET ) &&\r
-        ( pvBuffer != NULL ) )\r
-    {\r
-        pxContext->xSendFlags = ( BaseType_t ) ulFlags;\r
-\r
-        /* Send unencrypted. */\r
-        lStatus = prvNetworkSend( pxContext, pvBuffer, xDataLength );\r
-    }\r
-    else\r
-    {\r
-        lStatus = SOCKETS_EINVAL;\r
-    }\r
-\r
-    return lStatus;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-int32_t SOCKETS_SetSockOpt( Socket_t xSocket,\r
-                            int32_t lLevel,\r
-                            int32_t lOptionName,\r
-                            const void * pvOptionValue,\r
-                            size_t xOptionLength )\r
-{\r
-    int32_t lStatus = SOCKETS_ERROR_NONE;\r
-    TickType_t xTimeout;\r
-    SSOCKETContextPtr_t pxContext = ( SSOCKETContextPtr_t ) xSocket; /*lint !e9087 cast used for portability. */\r
-\r
-    if( ( xSocket != SOCKETS_INVALID_SOCKET ) && ( xSocket != NULL ) )\r
-    {\r
-        switch( lOptionName )\r
-        {\r
-            case SOCKETS_SO_NONBLOCK:\r
-                xTimeout = 0;\r
-\r
-                /* Non-blocking connect is not supported.  Socket may be set to nonblocking\r
-                 * only after a connection is made. */\r
-                if( pdTRUE == pxContext->xConnectAttempted )\r
-                {\r
-                    lStatus = FreeRTOS_setsockopt( pxContext->xSocket,\r
-                                                   lLevel,\r
-                                                   SOCKETS_SO_RCVTIMEO,\r
-                                                   &xTimeout,\r
-                                                   sizeof( xTimeout ) );\r
-\r
-                    if( lStatus == SOCKETS_ERROR_NONE )\r
-                    {\r
-                        lStatus = FreeRTOS_setsockopt( pxContext->xSocket,\r
-                                                       lLevel,\r
-                                                       SOCKETS_SO_SNDTIMEO,\r
-                                                       &xTimeout,\r
-                                                       sizeof( xTimeout ) );\r
-                    }\r
-                }\r
-                else\r
-                {\r
-                    lStatus = SOCKETS_EISCONN;\r
-                }\r
-\r
-                break;\r
-\r
-            case SOCKETS_SO_RCVTIMEO:\r
-            case SOCKETS_SO_SNDTIMEO:\r
-                /* Comply with Berkeley standard - a 0 timeout is wait forever. */\r
-                xTimeout = *( ( const TickType_t * ) pvOptionValue ); /*lint !e9087 pvOptionValue passed should be of TickType_t */\r
-\r
-                if( xTimeout == 0U )\r
-                {\r
-                    xTimeout = portMAX_DELAY;\r
-                }\r
-\r
-                lStatus = FreeRTOS_setsockopt( pxContext->xSocket,\r
-                                               lLevel,\r
-                                               lOptionName,\r
-                                               &xTimeout,\r
-                                               xOptionLength );\r
-                break;\r
-\r
-            default:\r
-                lStatus = FreeRTOS_setsockopt( pxContext->xSocket,\r
-                                               lLevel,\r
-                                               lOptionName,\r
-                                               pvOptionValue,\r
-                                               xOptionLength );\r
-                break;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        lStatus = SOCKETS_EINVAL;\r
-    }\r
-\r
-    return lStatus;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-int32_t SOCKETS_Shutdown( Socket_t xSocket,\r
-                          uint32_t ulHow )\r
-{\r
-    int32_t lReturn;\r
-    SSOCKETContextPtr_t pxContext = ( SSOCKETContextPtr_t ) xSocket; /*lint !e9087 cast used for portability. */\r
-\r
-    if( ( xSocket != SOCKETS_INVALID_SOCKET ) && ( xSocket != NULL ) )\r
-    {\r
-        lReturn = FreeRTOS_shutdown( pxContext->xSocket, ( BaseType_t ) ulHow );\r
-    }\r
-    else\r
-    {\r
-        lReturn = SOCKETS_EINVAL;\r
-    }\r
-\r
-    return lReturn;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-Socket_t SOCKETS_Socket( int32_t lDomain,\r
-                         int32_t lType,\r
-                         int32_t lProtocol )\r
-{\r
-    SSOCKETContextPtr_t pxContext = NULL;\r
-    Socket_t xSocket;\r
-\r
-    /* Ensure that only supported values are supplied. */\r
-    configASSERT( lDomain == SOCKETS_AF_INET );\r
-    configASSERT( lType == SOCKETS_SOCK_STREAM );\r
-    configASSERT( lProtocol == SOCKETS_IPPROTO_TCP );\r
-\r
-    /* Create the wrapped socket. */\r
-    xSocket = FreeRTOS_socket( lDomain, lType, lProtocol );\r
-\r
-    if( xSocket != FREERTOS_INVALID_SOCKET )\r
-    {\r
-        /* Allocate the internal context structure. */\r
-        if( NULL == ( pxContext = pvPortMalloc( sizeof( SSOCKETContext_t ) ) ) )\r
-        {\r
-            /* Need to close socket. */\r
-            ( void ) FreeRTOS_closesocket( xSocket );\r
-            pxContext = SOCKETS_INVALID_SOCKET;\r
-        }\r
-        else\r
-        {\r
-            memset( pxContext, 0, sizeof( SSOCKETContext_t ) );\r
-            pxContext->xSocket = xSocket;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        pxContext = SOCKETS_INVALID_SOCKET;\r
-    }\r
-\r
-    return pxContext;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-BaseType_t SOCKETS_Init( void )\r
-{\r
-    /* Empty initialization for this port. */\r
-    return pdPASS;\r
-}\r
-/*-----------------------------------------------------------*/\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/secure_sockets/include/iot_secure_sockets.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/secure_sockets/include/iot_secure_sockets.h
deleted file mode 100644 (file)
index d7c794a..0000000
+++ /dev/null
@@ -1,609 +0,0 @@
-/*\r
- * Amazon FreeRTOS Secure Sockets V1.1.5\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_secure_sockets.h\r
- * @brief Secure Sockets Interface.\r
- *\r
- * Secure sockets is a portable layer for establishing a TCP/IP\r
- * connection, with the option of using TLS.\r
- *\r
- * Secure sockets is based on the Berkeley sockets API.\r
- * A few difference general differences between Berkeley and SOCKETS are:\r
- * - SOCKETS has additional socket options to enable TLS, server name\r
- * indication, and per-socket root of trust server certificates.  See\r
- * SOCKETS_SetSockOpt() for more information.\r
- * - SOCKETS API return an error code, rather than returning -1 and setting\r
- * a global errno value.\r
- *\r
- */\r
-\r
-#ifndef _AWS_SECURE_SOCKETS_H_\r
-#define _AWS_SECURE_SOCKETS_H_\r
-\r
-/*\r
- #ifdef __cplusplus\r
- *  extern "C" {\r
- #endif\r
- */\r
-#include <stdint.h>\r
-#include <stddef.h>\r
-#include "iot_secure_sockets_config.h"\r
-#include "iot_secure_sockets_config_defaults.h"\r
-#include "iot_secure_sockets_wrapper_metrics.h"\r
-#include "iot_lib_init.h"\r
-\r
-/**\r
- * @ingroup SecureSockets_datatypes_handles\r
- * @brief The socket handle data type.\r
- *\r
- * For detail of socket, refer to [Network Sockets]\r
- * (https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/socket.html)\r
- *\r
- * Data contained by the Socket_t type is port specific.\r
- */\r
-typedef void * Socket_t;\r
-\r
-/**\r
- * @brief The "size_t" of secure sockets.\r
- *\r
- * This type is used for compatibility with the expected Berkeley sockets\r
- * naming.\r
- */\r
-#define Socklen_t    uint32_t\r
-\r
-/**\r
- * @anchor SocketsErrors\r
- * @name SocketsErrors\r
- * @brief Error codes returned by the SOCKETS API.\r
- *\r
- * Note that SOCKETS API may also propagate port-specific\r
- * error codes when they are more descriptive. See your\r
- * port's error codes for more details.\r
- * PORT_SPECIFIC_LINK\r
- */\r
-/**@{ */\r
-\r
-#define SOCKETS_ERROR_NONE               ( 0 )     /*!< No error. */\r
-#define SOCKETS_SOCKET_ERROR             ( -1 )    /*!< Catch-all sockets error code. */\r
-#define SOCKETS_EWOULDBLOCK              ( -11 )   /*!< A resource is temporarily unavailable. */\r
-#define SOCKETS_ENOMEM                   ( -12 )   /*!< Memory allocation failed. */\r
-#define SOCKETS_EINVAL                   ( -22 )   /*!< Invalid argument. */\r
-#define SOCKETS_ENOPROTOOPT              ( -109 )  /*!< A bad option was specified . */\r
-#define SOCKETS_ENOTCONN                 ( -126 )  /*!< The supplied socket is not connected. */\r
-#define SOCKETS_EISCONN                  ( -127 )  /*!< The supplied socket is already connected. */\r
-#define SOCKETS_ECLOSED                  ( -128 )  /*!< The supplied socket has already been closed. */\r
-#define SOCKETS_TLS_INIT_ERROR           ( -1001 ) /*!< TLS initialization failed. */\r
-#define SOCKETS_TLS_HANDSHAKE_ERROR      ( -1002 ) /*!< TLS handshake failed. */\r
-#define SOCKETS_TLS_SERVER_UNVERIFIED    ( -1003 ) /*!< A connection was made but the server could not be verified.  It is recommended that the socket be closed. */\r
-#define SOCKETS_TLS_RECV_ERROR           ( -1004 ) /*!< TLS receive operation failed. */\r
-#define SOCKETS_TLS_SEND_ERROR           ( -1005 ) /*!< TLS send operation failed. */\r
-#define SOCKETS_PERIPHERAL_RESET         ( -1006 ) /*!< Communications peripheral has been reset. */\r
-/**@} */\r
-\r
-/**\r
- * @brief Assigned to an Socket_t variable when the socket is not valid.\r
- */\r
-#define SOCKETS_INVALID_SOCKET    ( ( Socket_t ) ~0U )\r
-\r
-/**\r
- * @anchor SocketDomains\r
- * @name SocketDomains\r
- *\r
- * @brief Options for the lDomain parameter of SOCKETS_Socket()\r
- * function.\r
- *\r
- * These select the protocol family to be used for communication.\r
- */\r
-/**@{ */\r
-#define SOCKETS_AF_INET     ( 2 )           /*!< IPv4 Internet Protocols. */\r
-#define SOCKETS_PF_INET     SOCKETS_AF_INET /*!< IPv4 Internet Protocol. */\r
-#define SOCKETS_AF_INET6    ( 10 )          /*!< IPv6 Internet Protocols. This option is currently not supported. */\r
-/**@} */\r
-\r
-/**\r
- * @anchor SocketTypes\r
- * @name SocketTypes\r
- *\r
- * @brief Options for the lType parameter of SOCKETS_Socket()\r
- * function.\r
- *\r
- * These specify the communication semantics.\r
- */\r
-/**@{ */\r
-#define SOCKETS_SOCK_DGRAM     ( 2 )    /*!< Datagram. */\r
-#define SOCKETS_SOCK_STREAM    ( 1 )    /*!< Byte-stream. */\r
-/**@} */\r
-\r
-/**\r
- * @anchor Protocols\r
- * @name Protocols\r
- *\r
- * @brief Options for the lProtocol parameter of SOCKETS_Socket() function.\r
- *\r
- */\r
-/**@{ */\r
-#define SOCKETS_IPPROTO_UDP    ( 17 )   /*!< UDP. This option is currently not supported. */\r
-#define SOCKETS_IPPROTO_TCP    ( 6 )    /*!< TCP. */\r
-/**@} */\r
-\r
-/**\r
- * @anchor SetSockOptOptions\r
- * @name SetSockOptOptions\r
- *\r
- * @brief Options for lOptionName in SOCKETS_SetSockOpt().\r
- *\r
- */\r
-/**@{ */\r
-#define SOCKETS_SO_RCVTIMEO                      ( 0 )  /**< Set the receive timeout. */\r
-#define SOCKETS_SO_SNDTIMEO                      ( 1 )  /**< Set the send timeout. */\r
-#define SOCKETS_SO_SNDBUF                        ( 4 )  /**< Set the size of the send buffer (TCP only). */\r
-#define SOCKETS_SO_RCVBUF                        ( 5 )  /**< Set the size of the receive buffer (TCP only). */\r
-#define SOCKETS_SO_SERVER_NAME_INDICATION        ( 6 )  /**< Toggle client use of TLS SNI. */\r
-#define SOCKETS_SO_TRUSTED_SERVER_CERTIFICATE    ( 7 )  /**< Override default TLS server certificate trust. Must be PEM encoded and length must include null terminator. */\r
-#define SOCKETS_SO_REQUIRE_TLS                   ( 8 )  /**< Toggle client enforcement of TLS. */\r
-#define SOCKETS_SO_NONBLOCK                      ( 9 )  /**< Socket is nonblocking. */\r
-#define SOCKETS_SO_ALPN_PROTOCOLS                ( 10 ) /**< Application protocol list to be included in TLS ClientHello. */\r
-#define SOCKETS_SO_WAKEUP_CALLBACK               ( 17 ) /**< Set the callback to be called whenever there is data available on the socket for reading. */\r
-\r
-/**@} */\r
-\r
-/**\r
- * @anchor ShutdownFlags <br>\r
- * @name ShutdownFlags\r
- *\r
- * @brief Options for the ulHow parameter in SOCKETS_Shutdown().\r
- */\r
-/**@{ */\r
-#define SOCKETS_SHUT_RD      ( 0 )  /**< No further receives. */\r
-#define SOCKETS_SHUT_WR      ( 1 )  /**< No further sends. */\r
-#define SOCKETS_SHUT_RDWR    ( 2 )  /**< No further send or receive. */\r
-/**@} */\r
-\r
-/**\r
- * @brief Maximum length of an ASCII DNS name.\r
- */\r
-#define securesocketsMAX_DNS_NAME_LENGTH    ( 253 )\r
-\r
-/**\r
- * @ingroup SecureSockets_datatypes_paramstructs\r
- * @brief Socket address.\r
- *\r
- * \sa PORT_SPECIFIC_LINK\r
- */\r
-typedef struct SocketsSockaddr\r
-{\r
-    uint8_t ucLength;       /**< Length of SocketsSockaddr structure. */\r
-    uint8_t ucSocketDomain; /**< Only SOCKETS_AF_INET is supported. */\r
-    uint16_t usPort;        /**< Port number. Convention is to call this sin_port. */\r
-    uint32_t ulAddress;     /**< IP Address. Convention is to call this sin_addr. */\r
-} SocketsSockaddr_t;\r
-\r
-/**\r
- * @brief Well-known port numbers.\r
- */\r
-#define securesocketsDEFAULT_TLS_DESTINATION_PORT    443\r
-\r
-/**\r
- * @brief Secure Sockets library initialization function.\r
- *\r
- * This function does general initialization and setup. It must be called once\r
- * and only once before calling any other function.\r
- *\r
- * @return\r
- * * `pdPASS` if everything succeeds\r
- * * `pdFAIL` otherwise.\r
- */\r
-lib_initDECLARE_LIB_INIT( SOCKETS_Init );\r
-\r
-/**\r
- * @brief Creates a TCP socket.\r
- *\r
- * See the [FreeRTOS+TCP networking tutorial]\r
- * (https://freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Networking_Tutorial.html)\r
- * for more information on TCP sockets.\r
- *\r
- * See the [Berkeley Sockets API]\r
- * (https://en.wikipedia.org/wiki/Berkeley_sockets#Socket_API_functions)\r
- * in wikipedia\r
- *\r
- * @sa SOCKETS_Close()\r
- *\r
- * @param[in] lDomain Must be set to SOCKETS_AF_INET. See @ref SocketDomains.\r
- * @param[in] lType Set to SOCKETS_SOCK_STREAM to create a TCP socket.\r
- * No other value is valid.  See @ref SocketTypes.\r
- * @param[in] lProtocol Set to SOCKETS_IPPROTO_TCP to create a TCP socket.\r
- * No other value is valid. See @ref Protocols.\r
- *\r
- * @return\r
- * * If a socket is created successfully, then the socket handle is\r
- * returned\r
- * * @ref SOCKETS_INVALID_SOCKET is returned if an error occurred.\r
- */\r
-\r
-/*\r
- * This call allocates memory and claims a socket resource.\r
- */\r
-/* @[declare_secure_sockets_socket] */\r
-Socket_t SOCKETS_Socket( int32_t lDomain,\r
-                         int32_t lType,\r
-                         int32_t lProtocol );\r
-/* @[declare_secure_sockets_socket] */\r
-\r
-\r
-/**\r
- * @brief Connects the socket to the specified IP address and port.\r
- *\r
- * The socket must first have been successfully created by a call to SOCKETS_Socket().\r
- *\r
- * \note To create a secure socket, SOCKETS_SetSockOpt() should be called with the\r
- * SOCKETS_SO_REQUIRE_TLS option \a before SOCKETS_Connect() is called.\r
- *\r
- * If this function returns an error the socket is considered invalid.\r
- *\r
- * \warning SOCKETS_Connect() is not safe to be called on the same socket\r
- * from multiple threads simultaneously with SOCKETS_Connect(),\r
- * SOCKETS_SetSockOpt(), SOCKETS_Shutdown(), SOCKETS_Close().\r
- *\r
- * See the [Berkeley Sockets API]\r
- * (https://en.wikipedia.org/wiki/Berkeley_sockets#Socket_API_functions)\r
- * in wikipedia\r
- *\r
- * @param[in] xSocket The handle of the socket to be connected.\r
- * @param[in] pxAddress A pointer to a SocketsSockaddr_t structure that contains the\r
- * the address to connect the socket to.\r
- * @param[in] xAddressLength Should be set to sizeof( @ref SocketsSockaddr_t ).\r
- *\r
- * @return\r
- * * @ref SOCKETS_ERROR_NONE if a connection is established.\r
- * * If an error occurred, a negative value is returned. @ref SocketsErrors\r
- */\r
-/* @[declare_secure_sockets_connect] */\r
-int32_t SOCKETS_Connect( Socket_t xSocket,\r
-                         SocketsSockaddr_t * pxAddress,\r
-                         Socklen_t xAddressLength );\r
-/* @[declare_secure_sockets_connect] */\r
-\r
-/**\r
- * @brief Receive data from a TCP socket.\r
- *\r
- * The socket must have already been created using a call to SOCKETS_Socket()\r
- * and connected to a remote socket using SOCKETS_Connect().\r
- *\r
- * See the [Berkeley Sockets API]\r
- * (https://en.wikipedia.org/wiki/Berkeley_sockets#Socket_API_functions)\r
- * in wikipedia\r
- *\r
- * @param[in] xSocket The handle of the socket from which data is being received.\r
- * @param[out] pvBuffer The buffer into which the received data will be placed.\r
- * @param[in] xBufferLength The maximum number of bytes which can be received.\r
- * pvBuffer must be at least xBufferLength bytes long.\r
- * @param[in] ulFlags Not currently used. Should be set to 0.\r
- *\r
- * @return\r
- * * If the receive was successful then the number of bytes received (placed in the\r
- *   buffer pointed to by pvBuffer) is returned.\r
- * * If a timeout occurred before data could be received then 0 is returned (timeout\r
- *   is set using @ref SOCKETS_SO_RCVTIMEO).\r
- * * If an error occurred, a negative value is returned. @ref SocketsErrors\r
- */\r
-/* @[declare_secure_sockets_recv] */\r
-int32_t SOCKETS_Recv( Socket_t xSocket,\r
-                      void * pvBuffer,\r
-                      size_t xBufferLength,\r
-                      uint32_t ulFlags );\r
-/* @[declare_secure_sockets_recv] */\r
-\r
-/**\r
- * @brief Transmit data to the remote socket.\r
- *\r
- * The socket must have already been created using a call to SOCKETS_Socket() and\r
- * connected to a remote socket using SOCKETS_Connect().\r
- *\r
- * See the [Berkeley Sockets API]\r
- * (https://en.wikipedia.org/wiki/Berkeley_sockets#Socket_API_functions)\r
- * in wikipedia\r
- *\r
- * @param[in] xSocket The handle of the sending socket.\r
- * @param[in] pvBuffer The buffer containing the data to be sent.\r
- * @param[in] xDataLength The length of the data to be sent.\r
- * @param[in] ulFlags Not currently used. Should be set to 0.\r
- *\r
- * @return\r
- * * On success, the number of bytes actually sent is returned.\r
- * * If an error occurred, a negative value is returned. @ref SocketsErrors\r
- */\r
-/* @[declare_secure_sockets_send] */\r
-int32_t SOCKETS_Send( Socket_t xSocket,\r
-                      const void * pvBuffer,\r
-                      size_t xDataLength,\r
-                      uint32_t ulFlags );\r
-/* @[declare_secure_sockets_send] */\r
-\r
-/**\r
- * @brief Closes all or part of a full-duplex connection on the socket.\r
- *\r
- * Disable reads and writes on a connected TCP socket. A connected TCP socket must be gracefully\r
- * shut down before it can be closed.\r
- *\r
- * See the [Berkeley Sockets API]\r
- * (https://en.wikipedia.org/wiki/Berkeley_sockets#Socket_API_functions)\r
- * in wikipedia\r
- *\r
- * \warning SOCKETS_Shutdown() is not safe to be called on the same socket\r
- * from multiple threads simultaneously with SOCKETS_Connect(),\r
- * SOCKETS_SetSockOpt(), SOCKETS_Shutdown(), SOCKETS_Close().\r
- *\r
- * @param[in] xSocket The handle of the socket to shutdown.\r
- * @param[in] ulHow SOCKETS_SHUT_RD, SOCKETS_SHUT_WR or SOCKETS_SHUT_RDWR.\r
- * @ref ShutdownFlags\r
- *\r
- * @return\r
- * * If the operation was successful, 0 is returned.\r
- * * If an error occurred, a negative value is returned. @ref SocketsErrors\r
- */\r
-/* @[declare_secure_sockets_shutdown] */\r
-int32_t SOCKETS_Shutdown( Socket_t xSocket,\r
-                          uint32_t ulHow );\r
-/* @[declare_secure_sockets_shutdown] */\r
-\r
-/**\r
- * @brief Closes the socket and frees the related resources.\r
- *\r
- * A socket should be shutdown gracefully before it is closed, and cannot be used after it has been closed.\r
- *\r
- * See the [Berkeley Sockets API]\r
- * (https://en.wikipedia.org/wiki/Berkeley_sockets#Socket_API_functions)\r
- * in wikipedia\r
- *\r
- * \warning SOCKETS_Close() is not safe to be called on the same socket\r
- * from multiple threads simultaneously with SOCKETS_Connect(),\r
- * SOCKETS_SetSockOpt(), SOCKETS_Shutdown(), SOCKETS_Close().\r
- *\r
- * @param[in] xSocket The handle of the socket to close.\r
- *\r
- * @return\r
- * * On success, 0 is returned.\r
- * * If an error occurred, a negative value is returned. @ref SocketsErrors\r
- */\r
-/* @[declare_secure_sockets_close] */\r
-int32_t SOCKETS_Close( Socket_t xSocket );\r
-/* @[declare_secure_sockets_close] */\r
-\r
-/**\r
- * @brief AWS IoT ALPN protocol name for MQTT over TLS on server port 443.\r
- */\r
-#define socketsAWS_IOT_ALPN_MQTT    "x-amzn-mqtt-ca"\r
-\r
-/**\r
- * @brief Manipulates the options for the socket.\r
- *\r
- * See the [Berkeley Sockets API]\r
- * (https://en.wikipedia.org/wiki/Berkeley_sockets#Socket_API_functions)\r
- * in wikipedia\r
- *\r
- * @param[in] xSocket The handle of the socket to set the option for.\r
- * @param[in] lLevel Not currently used. Should be set to 0.\r
- * @param[in] lOptionName See @ref SetSockOptOptions.\r
- * @param[in] pvOptionValue A buffer containing the value of the option to set.\r
- * @param[in] xOptionLength The length of the buffer pointed to by pvOptionValue.\r
- *\r
- * \warning SOCKETS_Close() is not safe to be called on the same socket\r
- * from multiple threads simultaneously with SOCKETS_Connect(),\r
- * SOCKETS_SetSockOpt(), SOCKETS_Shutdown(), SOCKETS_Close().\r
- *\r
- * @note Socket option support and possible values vary by port. Please see\r
- * PORT_SPECIFIC_LINK to check the valid options and limitations of your device.\r
- *\r
- *  - Berkeley Socket Options\r
- *    - @ref SOCKETS_SO_RCVTIMEO\r
- *      - Sets the receive timeout\r
- *      - pvOptionValue (TickType_t) is the number of milliseconds that the\r
- *      receive function should wait before timing out.\r
- *      - Setting pvOptionValue = 0 causes receive to wait forever.\r
- *      - See PORT_SPECIFIC_LINK for device limitations.\r
- *    - @ref SOCKETS_SO_SNDTIMEO\r
- *      - Sets the send timeout\r
- *      - pvOptionValue (TickType_t) is the number of milliseconds that the\r
- *      send function should wait before timing out.\r
- *      - Setting pvOptionValue = 0 causes send to wait forever.\r
- *      - See PORT_SPECIFIC_LINK for device limitations.\r
- *  - Non-Standard Options\r
- *    - @ref SOCKETS_SO_NONBLOCK\r
- *      - Makes a socket non-blocking.\r
- *      - Non-blocking connect is not supported - socket option should be\r
- *        called after connect.\r
- *      - pvOptionValue is ignored for this option.\r
- *    - @ref SOCKETS_SO_WAKEUP_CALLBACK\r
- *      - Set the callback to be called whenever there is data available on\r
- *      the socket for reading\r
- *      - This option provides an asynchronous way to handle received data\r
- *      - pvOptionValue is a pointer to the callback function\r
- *      - See PORT_SPECIFIC_LINK for device limitations.\r
- *  - Security Sockets Options\r
- *    - @ref SOCKETS_SO_REQUIRE_TLS\r
- *      - Use TLS for all connect, send, and receive on this socket.\r
- *      - This socket options MUST be set for TLS to be used, even\r
- *        if other secure socket options are set.\r
- *      - This socket option should be set before SOCKETS_Connect() is\r
- *        called.\r
- *      - pvOptionValue is ignored for this option.\r
- *    - @ref SOCKETS_SO_TRUSTED_SERVER_CERTIFICATE\r
- *      - Set the root of trust server certificate for the socket.\r
- *      - This socket option only takes effect if @ref SOCKETS_SO_REQUIRE_TLS\r
- *        is also set.  If @ref SOCKETS_SO_REQUIRE_TLS is not set,\r
- *        this option will be ignored.\r
- *      - pvOptionValue is a pointer to the formatted server certificate.\r
- *        TODO: Link to description of how to format certificates with \n\r
- *      - xOptionLength (BaseType_t) is the length of the certificate\r
- *        in bytes.\r
- *    - @ref SOCKETS_SO_SERVER_NAME_INDICATION\r
- *      - Use Server Name Indication (SNI)\r
- *      - This socket option only takes effect if @ref SOCKETS_SO_REQUIRE_TLS\r
- *        is also set.  If @ref SOCKETS_SO_REQUIRE_TLS is not set,\r
- *        this option will be ignored.\r
- *      - pvOptionValue is a pointer to a string containing the hostname\r
- *      - xOptionLength is the length of the hostname string in bytes.\r
- *    - @ref SOCKETS_SO_ALPN_PROTOCOLS\r
- *      - Negotiate an application protocol along with TLS.\r
- *      - The ALPN list is expressed as an array of NULL-terminated ANSI\r
- *        strings.\r
- *      - xOptionLength is the number of items in the array.\r
- *\r
- * @return\r
- * * On success, 0 is returned.\r
- * * If an error occurred, a negative value is returned. @ref SocketsErrors\r
- */\r
-/* @[declare_secure_sockets_setsockopt] */\r
-int32_t SOCKETS_SetSockOpt( Socket_t xSocket,\r
-                            int32_t lLevel,\r
-                            int32_t lOptionName,\r
-                            const void * pvOptionValue,\r
-                            size_t xOptionLength );\r
-/* @[declare_secure_sockets_setsockopt] */\r
-\r
-/**\r
- * @brief Resolve a host name using Domain Name Service.\r
- *\r
- * See the [Berkeley Sockets API]\r
- * (https://en.wikipedia.org/wiki/Berkeley_sockets#Socket_API_functions)\r
- * in wikipedia\r
- *\r
- * @param[in] pcHostName The host name to resolve.\r
- * @return\r
- * * The IPv4 address of the specified host.\r
- * * If an error has occurred, 0 is returned.\r
- */\r
-/* @[declare_secure_sockets_gethostbyname] */\r
-uint32_t SOCKETS_GetHostByName( const char * pcHostName );\r
-/* @[declare_secure_sockets_gethostbyname] */\r
-\r
-\r
-\r
-/**\r
- * @brief Convert an unsigned thirty-two-bit value from host endianness to network\r
- * endianness.\r
- *\r
- * @param[in] usIn The unsigned thirty-two-bit value to convert.\r
- */\r
-#if defined( socketsconfigBYTE_ORDER ) && ( socketsconfigBYTE_ORDER == pdLITTLE_ENDIAN )\r
-    #define SOCKETS_htonl( ulIn )    ( ( uint32_t ) ( ( ( ulIn & 0xFF ) << 24 ) | ( ( ulIn & 0xFF00 ) << 8 ) | ( ( ulIn & 0xFF0000 ) >> 8 ) | ( ( ulIn & 0xFF000000 ) >> 24 ) ) )\r
-#else\r
-    #define SOCKETS_htonl( usIn )    ( ( uint32_t ) ( usIn ) )\r
-#endif\r
-\r
-/**\r
- * @brief Convert an unsigned thirty-two-bit value from network endianness to host\r
- * endianness.\r
- *\r
- * @param[in] usIn The unsigned thirty-two-bit value to convert.\r
- */\r
-#define SOCKETS_ntohl( usIn )    SOCKETS_htonl( usIn )\r
-\r
-\r
-/**\r
- * @brief Convert an unsigned sixteen-bit value from host endianness to network\r
- * endianness.\r
- *\r
- * @param[in] usIn The unsigned sixteen-bit value to convert.\r
- */\r
-\r
-#if defined( socketsconfigBYTE_ORDER ) && ( socketsconfigBYTE_ORDER == pdLITTLE_ENDIAN )\r
-    #define SOCKETS_htons( usIn )    ( ( uint16_t ) ( ( ( usIn ) << 8U ) | ( ( usIn ) >> 8U ) ) )\r
-#else\r
-    #define SOCKETS_htons( usIn )    ( ( uint16_t ) ( usIn ) )\r
-#endif\r
-\r
-\r
-/**\r
- * @brief Convert an unsigned sixteen-bit value from network endianness to host\r
- * endianness.\r
- *\r
- * @param[in] usIn The unsigned sixteen-bit value to convert.\r
- */\r
-#define SOCKETS_ntohs( usIn )    SOCKETS_htons( usIn )\r
-\r
-/**\r
- * @brief Convert an IP address expressed as four separate numeric octets into a an IP address expressed as a 32-bit number in network byte order\r
- * (for example 192, 168, 0, 100)\r
- *\r
- * @param[in] ucOctet0 0th IP Octet\r
- * @param[in] ucOctet1 1st IP Octet\r
- * @param[in] ucOctet2 2nd IP Octet\r
- * @param[in] ucOctet3 3rd IP Octet\r
- */\r
-#if defined( socketsconfigBYTE_ORDER ) && ( socketsconfigBYTE_ORDER == pdLITTLE_ENDIAN )\r
-\r
-    #define SOCKETS_inet_addr_quick( ucOctet0, ucOctet1, ucOctet2, ucOctet3 ) \\r
-    ( ( ( ( uint32_t ) ( ucOctet3 ) ) << 24UL ) |                             \\r
-      ( ( ( uint32_t ) ( ucOctet2 ) ) << 16UL ) |                             \\r
-      ( ( ( uint32_t ) ( ucOctet1 ) ) << 8UL ) |                              \\r
-      ( ( uint32_t ) ( ucOctet0 ) ) )\r
-\r
-/**\r
- * @brief Convert an IP address expressed as a 32-bit number in network byte order to a string in decimal dot notation.\r
- * (for example "192.168.0.100")\r
- *\r
- * @param[in] ulIPAddress An IP address expressed as a 32-bit value in network byte order.\r
- * @param[in] pucBuffer A pointer to a buffer into which the IP address will be written in decimal dot notation.\r
- */\r
-    #define SOCKETS_inet_ntoa( ulIPAddress, pucBuffer )               \\r
-    sprintf( ( char * ) ( pucBuffer ), "%u.%u.%u.%u",                 \\r
-             ( ( unsigned ) ( ( ulIPAddress ) & 0xffUL ) ),           \\r
-             ( ( unsigned ) ( ( ( ulIPAddress ) >> 8 ) & 0xffUL ) ),  \\r
-             ( ( unsigned ) ( ( ( ulIPAddress ) >> 16 ) & 0xffUL ) ), \\r
-             ( ( unsigned ) ( ( ulIPAddress ) >> 24 ) ) )\r
-\r
-#else /* socketsconfigBYTE_ORDER. */\r
-\r
-    #define SOCKETS_inet_addr_quick( ucOctet0, ucOctet1, ucOctet2, ucOctet3 ) \\r
-    ( ( ( ( uint32_t ) ( ucOctet0 ) ) << 24UL ) |                             \\r
-      ( ( ( uint32_t ) ( ucOctet1 ) ) << 16UL ) |                             \\r
-      ( ( ( uint32_t ) ( ucOctet2 ) ) << 8UL ) |                              \\r
-      ( ( uint32_t ) ( ucOctet3 ) ) )\r
-\r
-/**\r
- * @brief Convert an IP address expressed as a 32-bit number in network byte order to a string in decimal dot notation.\r
- * (for example "192.168.0.100")\r
- *\r
- * @param[in] ulIPAddress An IP address expressed as a 32-bit value in network byte order.\r
- * @param[in] pucBuffer A pointer to a buffer into which the IP address will be written in decimal dot notation.\r
- */\r
-    #define SOCKETS_inet_ntoa( ulIPAddress, pucBuffer )               \\r
-    sprintf( ( char * ) ( pucBuffer ), "%u.%u.%u.%u",                 \\r
-             ( ( unsigned ) ( ( ulIPAddress ) >> 24 ) ),              \\r
-             ( ( unsigned ) ( ( ( ulIPAddress ) >> 16 ) & 0xffUL ) ), \\r
-             ( ( unsigned ) ( ( ( ulIPAddress ) >> 8 ) & 0xffUL ) ),  \\r
-             ( ( unsigned ) ( ( ulIPAddress ) & 0xffUL ) ) )\r
-\r
-#endif /* socketsconfigBYTE_ORDER. */\r
-\r
-/*\r
- #ifdef __cplusplus\r
- *  }\r
- #endif\r
- */\r
-\r
-#endif /* _AWS_SECURE_SOCKETS_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/secure_sockets/include/iot_secure_sockets_config_defaults.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/secure_sockets/include/iot_secure_sockets_config_defaults.h
deleted file mode 100644 (file)
index 498ac5d..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*\r
- * Amazon FreeRTOS Secure Sockets V1.1.5\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_secure_sockets_config_defaults.h\r
- * @brief Ensures that the required sockets configuration options are supplied\r
- * and the optional ones are set to sane values if the user does not supply.\r
- */\r
-\r
-#ifndef AWS_INC_SECURE_SOCKETS_CONFIG_DEFAULTS_H_\r
-#define AWS_INC_SECURE_SOCKETS_CONFIG_DEFAULTS_H_\r
-\r
-/**\r
- * @brief Byte order of the target MCU must be defined.\r
- *\r
- * Valid values are pdLITTLE_ENDIAN and pdBIG_ENDIAN.\r
- */\r
-#ifndef socketsconfigBYTE_ORDER\r
-    #error "socketsconfigBYTE_ORDER must be defined."\r
-#endif\r
-\r
-/**\r
- * @brief Default socket send timeout.\r
- *\r
- * The user can change the send timeout for a socket using the SOCKETS_SetSockOpt API\r
- * with the SOCKETS_SO_SNDTIMEO option.\r
- */\r
-#ifndef socketsconfigDEFAULT_SEND_TIMEOUT\r
-    #define socketsconfigDEFAULT_SEND_TIMEOUT    ( 10000 )\r
-#endif\r
-\r
-/**\r
- * @brief Default socket receive timeout.\r
- *\r
- * The user can change the receive timeout for a socket using the SOCKETS_SetSockOpt API\r
- * with the SOCKETS_SO_RCVTIMEO option.\r
- */\r
-#ifndef socketsconfigDEFAULT_RECV_TIMEOUT\r
-    #define socketsconfigDEFAULT_RECV_TIMEOUT    ( 10000 )\r
-#endif\r
-\r
-/**\r
- * @brief By default, metrics of secure socket is disabled.\r
- *\r
- */\r
-#ifndef AWS_IOT_SECURE_SOCKETS_METRICS_ENABLED\r
-    #define AWS_IOT_SECURE_SOCKETS_METRICS_ENABLED    ( 0 )\r
-#endif\r
-\r
-#endif /* AWS_INC_SECURE_SOCKETS_CONFIG_DEFAULTS_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/secure_sockets/include/iot_secure_sockets_wrapper_metrics.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/secure_sockets/include/iot_secure_sockets_wrapper_metrics.h
deleted file mode 100644 (file)
index a5282a2..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*\r
- * Amazon FreeRTOS Secure Sockets V1.1.5\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
-#ifndef _AWS_SECURE_SOCKETS_WRAPPER_METRICS_\r
-#define _AWS_SECURE_SOCKETS_WRAPPER_METRICS_\r
-\r
-/* This file redefines Secure Sockets functions to be called through a wrapper macro,\r
- * but only if metrics is enabled explicitly. */\r
-#if AWS_IOT_SECURE_SOCKETS_METRICS_ENABLED == 1\r
-\r
-/* This macro is included in aws_secure_socket.c and aws_secure_socket_wrapper_metrics.c.\r
- * It will prevent the redefine in those source files. */\r
-    #ifndef _SECURE_SOCKETS_WRAPPER_NOT_REDEFINE\r
-        #define SOCKETS_Init        Sockets_MetricsInit\r
-        #define SOCKETS_Connect     Sockets_MetricsConnect\r
-        #define SOCKETS_Shutdown    Sockets_MetricsShutdown\r
-    #endif\r
-\r
-#endif\r
-\r
-#endif /* ifndef _AWS_SECURE_SOCKETS_WRAPPER_METRICS_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/iot_atomic.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/iot_atomic.h
deleted file mode 100644 (file)
index ff2a219..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*\r
- * Amazon FreeRTOS Common V1.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_atomic.h\r
- * @brief Chooses the appropriate atomic operations header.\r
- *\r
- * On FreeRTOS, this file chooses the atomic header provided with the FreeRTOS\r
- * kernel.\r
- */\r
-\r
-#ifndef IOT_ATOMIC_H_\r
-#define IOT_ATOMIC_H_\r
-\r
-#include "atomic.h"\r
-\r
-#endif /* ifndef IOT_ATOMIC_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/iot_init.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/iot_init.h
deleted file mode 100644 (file)
index 5e27cf8..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*\r
- * Amazon FreeRTOS Common V1.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_init.h\r
- * @brief Provides function signatures for common initialization and cleanup of\r
- * this SDK.\r
- */\r
-\r
-#ifndef IOT_INIT_H_\r
-#define IOT_INIT_H_\r
-\r
-/* The config header is always included first. */\r
-#include "iot_config.h"\r
-\r
-/* Standard includes. */\r
-#include <stdbool.h>\r
-\r
-/**\r
- * @brief One-time initialization function for this SDK.\r
- *\r
- * This function initializes common libraries, such as static memory and task\r
- * pool. <b>It must be called once (and only once) before calling any other\r
- * function in this SDK.</b> Calling this function more than once without first\r
- * calling `IotSdk_Cleanup` may result in a crash.\r
- *\r
- * @return `true` if initialization succeeded; `false` otherwise. Logs may be\r
- * printed in case of failure.\r
- *\r
- * @warning No thread-safety guarantees are provided for this function.\r
- */\r
-bool IotSdk_Init( void );\r
-\r
-/**\r
- * @brief One-time deinitialization function for all common libraries.\r
- *\r
- * This function frees resources taken in `IotSdk_Init`. No other function\r
- * in this SDK may be called after calling this function unless `IotSdk_Init`\r
- * is called again.\r
- *\r
- * @warning No thread-safety guarantees are provided for this function.\r
- */\r
-void IotSdk_Cleanup( void );\r
-\r
-#endif /* IOT_INIT_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/iot_linear_containers.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/iot_linear_containers.h
deleted file mode 100644 (file)
index dc5ac25..0000000
+++ /dev/null
@@ -1,956 +0,0 @@
-/*\r
- * Amazon FreeRTOS Common V1.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_linear_containers.h\r
- * @brief Declares and implements doubly-linked lists and queues.\r
- */\r
-\r
-#ifndef IOT_LINEAR_CONTAINERS_H_\r
-#define IOT_LINEAR_CONTAINERS_H_\r
-\r
-/* The config header is always included first. */\r
-#include "iot_config.h"\r
-\r
-/* Standard includes. */\r
-#include <stdbool.h>\r
-#include <stddef.h>\r
-#include <stdint.h>\r
-\r
-/**\r
- * @defgroup linear_containers_datatypes_listqueue List and queue\r
- * @brief Structures that represent a list or queue.\r
- */\r
-\r
-/**\r
- * @ingroup linear_containers_datatypes_listqueue\r
- * @brief Link member placed in structs of a list or queue.\r
- *\r
- * All elements in a list or queue must contain one of these members. The macro\r
- * #IotLink_Container can be used to calculate the starting address of the\r
- * link's container.\r
- */\r
-typedef struct IotLink\r
-{\r
-    struct IotLink * pPrevious; /**< @brief Pointer to the previous element. */\r
-    struct IotLink * pNext;     /**< @brief Pointer to the next element. */\r
-} IotLink_t;\r
-\r
-/**\r
- * @ingroup linear_containers_datatypes_listqueue\r
- * @brief Represents a doubly-linked list.\r
- */\r
-typedef IotLink_t   IotListDouble_t;\r
-\r
-/**\r
- * @ingroup linear_containers_datatypes_listqueue\r
- * @brief Represents a queue.\r
- */\r
-typedef IotLink_t   IotDeQueue_t;\r
-\r
-/**\r
- * @constantspage{linear_containers,linear containers library}\r
- *\r
- * @section linear_containers_constants_initializers Linear Containers Initializers\r
- * @brief Provides default values for initializing the linear containers data types.\r
- *\r
- * @snippet this define_linear_containers_initializers\r
- *\r
- * All user-facing data types of the linear containers library should be initialized\r
- * using one of the following.\r
- *\r
- * @warning Failure to initialize a linear containers data type with the appropriate\r
- * initializer may result in a runtime error!\r
- * @note The initializers may change at any time in future versions, but their\r
- * names will remain the same.\r
- */\r
-/* @[define_linear_containers_initializers] */\r
-#define IOT_LINK_INITIALIZER           { 0 }                /**< @brief Initializer for an #IotLink_t. */\r
-#define IOT_LIST_DOUBLE_INITIALIZER    IOT_LINK_INITIALIZER /**< @brief Initializer for an #IotListDouble_t. */\r
-#define IOT_DEQUEUE_INITIALIZER        IOT_LINK_INITIALIZER /**< @brief Initializer for an #IotDeQueue_t. */\r
-/* @[define_linear_containers_initializers] */\r
-\r
-/**\r
- * @def IotContainers_Assert( expression )\r
- * @brief Assertion macro for the linear containers library.\r
- *\r
- * Set @ref IOT_CONTAINERS_ENABLE_ASSERTS to `1` to enable assertions in the linear\r
- * containers library.\r
- *\r
- * @param[in] expression Expression to be evaluated.\r
- */\r
-#if IOT_CONTAINERS_ENABLE_ASSERTS == 1\r
-    #ifndef IotContainers_Assert\r
-        #include <assert.h>\r
-        #define IotContainers_Assert( expression )    assert( expression )\r
-    #endif\r
-#else\r
-    #define IotContainers_Assert( expression )\r
-#endif\r
-\r
-/**\r
- * @brief Calculates the starting address of a containing struct.\r
- *\r
- * @param[in] type Type of the containing struct.\r
- * @param[in] pLink Pointer to a link member.\r
- * @param[in] linkName Name of the #IotLink_t in the containing struct.\r
- */\r
-#define IotLink_Container( type, pLink, linkName ) \\r
-    ( ( type * ) ( void * ) ( ( ( uint8_t * ) ( pLink ) ) - offsetof( type, linkName ) ) )\r
-\r
-/**\r
- * @brief Iterates through all elements of a linear container.\r
- *\r
- * Container elements must not be freed or removed while iterating.\r
- *\r
- * @param[in] pStart The first element to iterate from.\r
- * @param[out] pLink Pointer to a container element.\r
- */\r
-#define IotContainers_ForEach( pStart, pLink )  \\r
-    for( ( pLink ) = ( pStart )->pNext;         \\r
-         ( pLink ) != ( pStart );               \\r
-         ( pLink ) = ( pLink )->pNext )\r
-\r
-/**\r
- * @functionspage{linear_containers,linear containers library}\r
- * - @functionname{linear_containers_function_link_islinked}\r
- * - @functionname{linear_containers_function_list_double_create}\r
- * - @functionname{linear_containers_function_list_double_count}\r
- * - @functionname{linear_containers_function_list_double_isempty}\r
- * - @functionname{linear_containers_function_list_double_peekhead}\r
- * - @functionname{linear_containers_function_list_double_peektail}\r
- * - @functionname{linear_containers_function_list_double_inserthead}\r
- * - @functionname{linear_containers_function_list_double_inserttail}\r
- * - @functionname{linear_containers_function_list_double_insertbefore}\r
- * - @functionname{linear_containers_function_list_double_insertafter}\r
- * - @functionname{linear_containers_function_list_double_insertsorted}\r
- * - @functionname{linear_containers_function_list_double_remove}\r
- * - @functionname{linear_containers_function_list_double_removehead}\r
- * - @functionname{linear_containers_function_list_double_removetail}\r
- * - @functionname{linear_containers_function_list_double_removeall}\r
- * - @functionname{linear_containers_function_list_double_findfirstmatch}\r
- * - @functionname{linear_containers_function_list_double_removefirstmatch}\r
- * - @functionname{linear_containers_function_list_double_removeallmatches}\r
- * - @functionname{linear_containers_function_queue_create}\r
- * - @functionname{linear_containers_function_queue_count}\r
- * - @functionname{linear_containers_function_queue_isempty}\r
- * - @functionname{linear_containers_function_queue_peekhead}\r
- * - @functionname{linear_containers_function_queue_peektail}\r
- * - @functionname{linear_containers_function_queue_enqueuehead}\r
- * - @functionname{linear_containers_function_queue_dequeuehead}\r
- * - @functionname{linear_containers_function_queue_enqueuetail}\r
- * - @functionname{linear_containers_function_queue_dequeuetail}\r
- * - @functionname{linear_containers_function_queue_remove}\r
- * - @functionname{linear_containers_function_queue_removeall}\r
- * - @functionname{linear_containers_function_queue_removeallmatches}\r
- */\r
-\r
-/**\r
- * @functionpage{IotLink_IsLinked,linear_containers,link_islinked}\r
- * @functionpage{IotListDouble_Create,linear_containers,list_double_create}\r
- * @functionpage{IotListDouble_Count,linear_containers,list_double_count}\r
- * @functionpage{IotListDouble_IsEmpty,linear_containers,list_double_isempty}\r
- * @functionpage{IotListDouble_PeekHead,linear_containers,list_double_peekhead}\r
- * @functionpage{IotListDouble_PeekTail,linear_containers,list_double_peektail}\r
- * @functionpage{IotListDouble_InsertHead,linear_containers,list_double_inserthead}\r
- * @functionpage{IotListDouble_InsertTail,linear_containers,list_double_inserttail}\r
- * @functionpage{IotListDouble_InsertBefore,linear_containers,list_double_insertbefore}\r
- * @functionpage{IotListDouble_InsertAfter,linear_containers,list_double_insertafter}\r
- * @functionpage{IotListDouble_InsertSorted,linear_containers,list_double_insertsorted}\r
- * @functionpage{IotListDouble_Remove,linear_containers,list_double_remove}\r
- * @functionpage{IotListDouble_RemoveHead,linear_containers,list_double_removehead}\r
- * @functionpage{IotListDouble_RemoveTail,linear_containers,list_double_removetail}\r
- * @functionpage{IotListDouble_RemoveAll,linear_containers,list_double_removeall}\r
- * @functionpage{IotListDouble_FindFirstMatch,linear_containers,list_double_findfirstmatch}\r
- * @functionpage{IotListDouble_RemoveFirstMatch,linear_containers,list_double_removefirstmatch}\r
- * @functionpage{IotListDouble_RemoveAllMatches,linear_containers,list_double_removeallmatches}\r
- * @functionpage{IotDeQueue_Create,linear_containers,queue_create}\r
- * @functionpage{IotDeQueue_Count,linear_containers,queue_count}\r
- * @functionpage{IotDeQueue_IsEmpty,linear_containers,queue_isempty}\r
- * @functionpage{IotDeQueue_PeekHead,linear_containers,queue_peekhead}\r
- * @functionpage{IotDeQueue_PeekTail,linear_containers,queue_peektail}\r
- * @functionpage{IotDeQueue_EnqueueHead,linear_containers,queue_enqueuehead}\r
- * @functionpage{IotDeQueue_DequeueHead,linear_containers,queue_dequeuehead}\r
- * @functionpage{IotDeQueue_EnqueueTail,linear_containers,queue_enqueuetail}\r
- * @functionpage{IotDeQueue_DequeueTail,linear_containers,queue_dequeuetail}\r
- * @functionpage{IotDeQueue_Remove,linear_containers,queue_remove}\r
- * @functionpage{IotDeQueue_RemoveAll,linear_containers,queue_removeall}\r
- * @functionpage{IotDeQueue_RemoveAllMatches,linear_containers,queue_removeallmatches}\r
- */\r
-\r
-/**\r
- * @brief Check if an #IotLink_t is linked in a list or queue.\r
- *\r
- * @param[in] pLink The link to check.\r
- *\r
- * @return `true` if `pCurrent` is linked in a list or queue; `false` otherwise.\r
- */\r
-/* @[declare_linear_containers_link_islinked] */\r
-static inline bool IotLink_IsLinked( const IotLink_t * const pLink )\r
-/* @[declare_linear_containers_link_islinked] */\r
-{\r
-    bool isLinked = false;\r
-\r
-    if( pLink != NULL )\r
-    {\r
-        isLinked = ( pLink->pNext != NULL ) && ( pLink->pPrevious != NULL );\r
-    }\r
-\r
-    return isLinked;\r
-}\r
-\r
-/**\r
- * @brief Create a new doubly-linked list.\r
- *\r
- * This function initializes a new doubly-linked list. It must be called on an\r
- * uninitialized #IotListDouble_t before calling any other doubly-linked list\r
- * function. This function must not be called on an already-initialized\r
- * #IotListDouble_t.\r
- *\r
- * This function will not fail. The function @ref linear_containers_function_list_double_removeall\r
- * may be called to destroy a list.\r
- *\r
- * @param[in] pList Pointer to the memory that will hold the new doubly-linked list.\r
- */\r
-/* @[declare_linear_containers_list_double_create] */\r
-static inline void IotListDouble_Create( IotListDouble_t * const pList )\r
-/* @[declare_linear_containers_list_double_create] */\r
-{\r
-    /* This function must not be called with a NULL parameter. */\r
-    IotContainers_Assert( pList != NULL );\r
-\r
-    /* An empty list is a link pointing to itself. */\r
-    pList->pPrevious = pList;\r
-    pList->pNext = pList;\r
-}\r
-\r
-/**\r
- * @brief Return the number of elements contained in an #IotListDouble_t.\r
- *\r
- * @param[in] pList The doubly-linked list with the elements to count.\r
- *\r
- * @return The number of elements in the doubly-linked list.\r
- */\r
-/* @[declare_linear_containers_list_double_count] */\r
-static inline size_t IotListDouble_Count( const IotListDouble_t * const pList )\r
-/* @[declare_linear_containers_list_double_count] */\r
-{\r
-    size_t count = 0;\r
-\r
-    if( pList != NULL )\r
-    {\r
-        /* Get the list head. */\r
-        const IotLink_t * pCurrent = pList->pNext;\r
-\r
-        /* Iterate through the list to count the elements. */\r
-        while( pCurrent != pList )\r
-        {\r
-            count++;\r
-            pCurrent = pCurrent->pNext;\r
-        }\r
-    }\r
-\r
-    return count;\r
-}\r
-\r
-/**\r
- * @brief Check if a doubly-linked list is empty.\r
- *\r
- * @param[in] pList The doubly-linked list to check.\r
- *\r
- * @return `true` if the list is empty; `false` otherwise.\r
- */\r
-/* @[declare_linear_containers_list_double_isempty] */\r
-static inline bool IotListDouble_IsEmpty( const IotListDouble_t * const pList )\r
-/* @[declare_linear_containers_list_double_isempty] */\r
-{\r
-    /* An empty list is NULL link, or a link pointing to itself. */\r
-    return( ( pList == NULL ) || ( pList->pNext == pList ) );\r
-}\r
-\r
-/**\r
- * @brief Return an #IotLink_t representing the first element in a doubly-linked list\r
- * without removing it.\r
- *\r
- * @param[in] pList The list to peek.\r
- *\r
- * @return Pointer to an #IotLink_t representing the element at the head of the\r
- * list; `NULL` if the list is empty. The macro #IotLink_Container may be used to\r
- * determine the address of the link's container.\r
- */\r
-/* @[declare_linear_containers_list_double_peekhead] */\r
-static inline IotLink_t * IotListDouble_PeekHead( const IotListDouble_t * const pList )\r
-/* @[declare_linear_containers_list_double_peekhead] */\r
-{\r
-    IotLink_t * pHead = NULL;\r
-\r
-    if( pList != NULL )\r
-    {\r
-        if( IotListDouble_IsEmpty( pList ) == false )\r
-        {\r
-            pHead = pList->pNext;\r
-        }\r
-    }\r
-\r
-    return pHead;\r
-}\r
-\r
-/**\r
- * @brief Return an #IotLink_t representing the last element in a doubly-linked\r
- * list without removing it.\r
- *\r
- * @param[in] pList The list to peek.\r
- *\r
- * @return Pointer to an #IotLink_t representing the element at the tail of the\r
- * list; `NULL` if the list is empty. The macro #IotLink_Container may be used to\r
- * determine the address of the link's container.\r
- */\r
-/* @[declare_linear_containers_list_double_peektail] */\r
-static inline IotLink_t * IotListDouble_PeekTail( const IotListDouble_t * const pList )\r
-/* @[declare_linear_containers_list_double_peektail] */\r
-{\r
-    IotLink_t * pTail = NULL;\r
-\r
-    if( pList != NULL )\r
-    {\r
-        if( IotListDouble_IsEmpty( pList ) == false )\r
-        {\r
-            pTail = pList->pPrevious;\r
-        }\r
-    }\r
-\r
-    return pTail;\r
-}\r
-\r
-/**\r
- * @brief Insert an element at the head of a doubly-linked list.\r
- *\r
- * @param[in] pList The doubly-linked list that will hold the new element.\r
- * @param[in] pLink Pointer to the new element's link member.\r
- */\r
-/* @[declare_linear_containers_list_double_inserthead] */\r
-static inline void IotListDouble_InsertHead( IotListDouble_t * const pList,\r
-                                             IotLink_t * const pLink )\r
-/* @[declare_linear_containers_list_double_inserthead] */\r
-{\r
-    /* This function must not be called with NULL parameters. */\r
-    IotContainers_Assert( pList != NULL );\r
-    IotContainers_Assert( pLink != NULL );\r
-\r
-    /* Save current list head. */\r
-    IotLink_t * pHead = pList->pNext;\r
-\r
-    /* Place new element before list head. */\r
-    pLink->pNext = pHead;\r
-    pLink->pPrevious = pList;\r
-\r
-    /* Assign new list head. */\r
-    pHead->pPrevious = pLink;\r
-    pList->pNext = pLink;\r
-}\r
-\r
-/**\r
- * @brief Insert an element at the tail of a doubly-linked list.\r
- *\r
- * @param[in] pList The double-linked list that will hold the new element.\r
- * @param[in] pLink Pointer to the new element's link member.\r
- */\r
-/* @[declare_linear_containers_list_double_inserttail] */\r
-static inline void IotListDouble_InsertTail( IotListDouble_t * const pList,\r
-                                             IotLink_t * const pLink )\r
-/* @[declare_linear_containers_list_double_inserttail] */\r
-{\r
-    /* This function must not be called with NULL parameters. */\r
-    IotContainers_Assert( pList != NULL );\r
-    IotContainers_Assert( pLink != NULL );\r
-\r
-    /* Save current list tail. */\r
-    IotLink_t * pTail = pList->pPrevious;\r
-\r
-    pLink->pNext = pList;\r
-    pLink->pPrevious = pTail;\r
-\r
-    pList->pPrevious = pLink;\r
-    pTail->pNext = pLink;\r
-}\r
-\r
-/**\r
- * @brief Insert an element before another element in a doubly-linked list.\r
- *\r
- * @param[in] pElement The new element will be placed before this element.\r
- * @param[in] pLink Pointer to the new element's link member.\r
- */\r
-/* @[declare_linear_containers_list_double_insertbefore] */\r
-static inline void IotListDouble_InsertBefore( IotLink_t * const pElement,\r
-                                               IotLink_t * const pLink )\r
-/* @[declare_linear_containers_list_double_insertbefore] */\r
-{\r
-    IotListDouble_InsertTail( pElement, pLink );\r
-}\r
-\r
-/**\r
- * @brief Insert an element after another element in a doubly-linked list.\r
- *\r
- * @param[in] pElement The new element will be placed after this element.\r
- * @param[in] pLink Pointer to the new element's link member.\r
- */\r
-/* @[declare_linear_containers_list_double_insertafter] */\r
-static inline void IotListDouble_InsertAfter( IotLink_t * const pElement,\r
-                                              IotLink_t * const pLink )\r
-/* @[declare_linear_containers_list_double_insertafter] */\r
-{\r
-    IotListDouble_InsertHead( pElement, pLink );\r
-}\r
-\r
-/**\r
- * @brief Insert an element in a sorted doubly-linked list.\r
- *\r
- * Places an element into a list by sorting it into order. The function\r
- * `compare` is used to determine where to place the new element.\r
- *\r
- * @param[in] pList The list that will hold the new element.\r
- * @param[in] pLink Pointer to the new element's link member.\r
- * @param[in] compare Determines the order of the list. Returns a negative\r
- * value if its first argument is less than its second argument; returns\r
- * zero if its first argument is equal to its second argument; returns a\r
- * positive value if its first argument is greater than its second argument.\r
- * The parameters to this function are #IotLink_t, so the macro #IotLink_Container\r
- * may be used to determine the address of the link's container.\r
- */\r
-/* @[declare_linear_containers_list_double_insertsorted] */\r
-static inline void IotListDouble_InsertSorted( IotListDouble_t * const pList,\r
-                                               IotLink_t * const pLink,\r
-                                               int32_t ( *compare )( const IotLink_t * const, const IotLink_t * const ) )\r
-/* @[declare_linear_containers_list_double_insertsorted] */\r
-{\r
-    /* This function must not be called with NULL parameters. */\r
-    IotContainers_Assert( pList != NULL );\r
-    IotContainers_Assert( pLink != NULL );\r
-    IotContainers_Assert( compare != NULL );\r
-\r
-    /* Insert at head for empty list. */\r
-    if( IotListDouble_IsEmpty( pList ) == true )\r
-    {\r
-        IotListDouble_InsertHead( pList, pLink );\r
-    }\r
-    else\r
-    {\r
-        bool inserted = false;\r
-        IotLink_t * pCurrent = pList->pNext;\r
-\r
-        /* Iterate through the list to find the correct position. */\r
-        while( pCurrent != pList )\r
-        {\r
-            /* Comparing for '<' preserves the order of insertion. */\r
-            if( compare( pLink, pCurrent ) < 0 )\r
-            {\r
-                IotListDouble_InsertBefore( pCurrent, pLink );\r
-                inserted = true;\r
-\r
-                break;\r
-            }\r
-\r
-            pCurrent = pCurrent->pNext;\r
-        }\r
-\r
-        /* New element is greater than all elements in list. Insert at tail. */\r
-        if( inserted == false )\r
-        {\r
-            IotListDouble_InsertTail( pList, pLink );\r
-        }\r
-    }\r
-}\r
-\r
-/**\r
- * @brief Remove a single element from a doubly-linked list.\r
- *\r
- * @param[in] pLink The element to remove.\r
- */\r
-/* @[declare_linear_containers_list_double_remove] */\r
-static inline void IotListDouble_Remove( IotLink_t * const pLink )\r
-/* @[declare_linear_containers_list_double_remove] */\r
-{\r
-    /* This function must not be called with a NULL parameter. */\r
-    IotContainers_Assert( pLink != NULL );\r
-\r
-    /* This function must be called on a linked element. */\r
-    IotContainers_Assert( IotLink_IsLinked( pLink ) == true );\r
-\r
-    pLink->pPrevious->pNext = pLink->pNext;\r
-    pLink->pNext->pPrevious = pLink->pPrevious;\r
-    pLink->pPrevious = NULL;\r
-    pLink->pNext = NULL;\r
-}\r
-\r
-/**\r
- * @brief Remove the element at the head of a doubly-linked list.\r
- *\r
- * @param[in] pList The doubly-linked list that holds the element to remove.\r
- *\r
- * @return Pointer to an #IotLink_t representing the removed list head; `NULL`\r
- * if the list is empty. The macro #IotLink_Container may be used to determine\r
- * the address of the link's container.\r
- */\r
-/* @[declare_linear_containers_list_double_removehead] */\r
-static inline IotLink_t * IotListDouble_RemoveHead( IotListDouble_t * const pList )\r
-/* @[declare_linear_containers_list_double_removehead] */\r
-{\r
-    IotLink_t * pHead = NULL;\r
-\r
-    if( IotListDouble_IsEmpty( pList ) == false )\r
-    {\r
-        pHead = pList->pNext;\r
-        IotListDouble_Remove( pHead );\r
-    }\r
-\r
-    return pHead;\r
-}\r
-\r
-/**\r
- * @brief Remove the element at the tail of a doubly-linked list.\r
- *\r
- * @param[in] pList The doubly-linked list that holds the element to remove.\r
- *\r
- * @return Pointer to an #IotLink_t representing the removed list tail; `NULL`\r
- * if the list is empty. The macro #IotLink_Container may be used to determine\r
- * the address of the link's container.\r
- */\r
-/* @[declare_linear_containers_list_double_removetail] */\r
-static inline IotLink_t * IotListDouble_RemoveTail( IotListDouble_t * const pList )\r
-/* @[declare_linear_containers_list_double_removetail] */\r
-{\r
-    IotLink_t * pTail = NULL;\r
-\r
-    if( IotListDouble_IsEmpty( pList ) == false )\r
-    {\r
-        pTail = pList->pPrevious;\r
-        IotListDouble_Remove( pTail );\r
-    }\r
-\r
-    return pTail;\r
-}\r
-\r
-/**\r
- * @brief Remove all elements in a doubly-linked list.\r
- *\r
- * @param[in] pList The list to empty.\r
- * @param[in] freeElement A function to free memory used by each removed list\r
- * element. Optional; pass `NULL` to ignore.\r
- * @param[in] linkOffset Offset in bytes of a link member in its container, used\r
- * to calculate the pointer to pass to `freeElement`. This value should be calculated\r
- * with the C `offsetof` macro. This parameter is ignored if `freeElement` is `NULL`\r
- * or its value is `0`.\r
- */\r
-/* @[declare_linear_containers_list_double_removeall] */\r
-static inline void IotListDouble_RemoveAll( IotListDouble_t * const pList,\r
-                                            void ( *freeElement )( void * ),\r
-                                            size_t linkOffset )\r
-/* @[declare_linear_containers_list_double_removeall] */\r
-{\r
-    /* This function must not be called with a NULL pList parameter. */\r
-    IotContainers_Assert( pList != NULL );\r
-\r
-    /* Get the list head. */\r
-    IotLink_t * pCurrent = pList->pNext;\r
-\r
-    /* Iterate through the list and remove all elements. */\r
-    while( pCurrent != pList )\r
-    {\r
-        /* Save a pointer to the next list element. */\r
-        IotLink_t * pNext = pCurrent->pNext;\r
-\r
-        /* Remove and free the current list element. */\r
-        IotListDouble_Remove( pCurrent );\r
-\r
-        if( freeElement != NULL )\r
-        {\r
-            freeElement( ( ( uint8_t * ) pCurrent ) - linkOffset );\r
-        }\r
-\r
-        /* Move the iterating pointer to the next list element. */\r
-        pCurrent = pNext;\r
-    }\r
-}\r
-\r
-/**\r
- * @brief Search a doubly-linked list for the first matching element.\r
- *\r
- * If a match is found, the matching element is <b>not</b> removed from the list.\r
- * See @ref linear_containers_function_list_double_removefirstmatch for the function\r
- * that searches and removes.\r
- *\r
- * @param[in] pList The doubly-linked list to search.\r
- * @param[in] pStartPoint An element in `pList`. Only elements between this one and\r
- * the list tail are checked. Pass `NULL` to search from the beginning of the list.\r
- * @param[in] isMatch Function to determine if an element matches. Pass `NULL` to\r
- * search using the address `pMatch`, i.e. `element == pMatch`.\r
- * @param[in] pMatch If `isMatch` is `NULL`, each element in the list is compared\r
- * to this address to find a match. Otherwise, it is passed as the second argument\r
- * to `isMatch`.\r
- *\r
- * @return Pointer to an #IotLink_t representing the first matched element; `NULL`\r
- * if no match is found. The macro #IotLink_Container may be used to determine the\r
- * address of the link's container.\r
- */\r
-/* @[declare_linear_containers_list_double_findfirstmatch] */\r
-static inline IotLink_t * IotListDouble_FindFirstMatch( const IotListDouble_t * const pList,\r
-                                                        const IotLink_t * const pStartPoint,\r
-                                                        bool ( *isMatch )( const IotLink_t * const, void * ),\r
-                                                        void * pMatch )\r
-/* @[declare_linear_containers_list_double_findfirstmatch] */\r
-{\r
-    /* The const must be cast away to match this function's return value. Nevertheless,\r
-     * this function will respect the const-ness of pStartPoint. */\r
-    IotLink_t * pCurrent = ( IotLink_t * ) pStartPoint;\r
-\r
-    /* This function must not be called with a NULL pList parameter. */\r
-    IotContainers_Assert( pList != NULL );\r
-\r
-    /* Search starting from list head if no start point is given. */\r
-    if( pStartPoint == NULL )\r
-    {\r
-        pCurrent = pList->pNext;\r
-    }\r
-\r
-    /* Iterate through the list to search for matches. */\r
-    while( pCurrent != pList )\r
-    {\r
-        /* Call isMatch if provided. Otherwise, compare pointers. */\r
-        if( isMatch != NULL )\r
-        {\r
-            if( isMatch( pCurrent, pMatch ) == true )\r
-            {\r
-                return pCurrent;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            if( pCurrent == pMatch )\r
-            {\r
-                return pCurrent;\r
-            }\r
-        }\r
-\r
-        pCurrent = pCurrent->pNext;\r
-    }\r
-\r
-    /* No match found, return NULL. */\r
-    return NULL;\r
-}\r
-\r
-/**\r
- * @brief Search a doubly-linked list for the first matching element and remove\r
- * it.\r
- *\r
- * An #IotLink_t may be passed as `pList` to start searching after the head of a\r
- * doubly-linked list.\r
- *\r
- * @param[in] pList The doubly-linked list to search.\r
- * @param[in] pStartPoint An element in `pList`. Only elements between this one and\r
- * the list tail are checked. Pass `NULL` to search from the beginning of the list.\r
- * @param[in] isMatch Function to determine if an element matches. Pass `NULL` to\r
- * search using the address `pMatch`, i.e. `element == pMatch`.\r
- * @param[in] pMatch If `isMatch` is `NULL`, each element in the list is compared\r
- * to this address to find a match. Otherwise, it is passed as the second argument\r
- * to `isMatch`.\r
- *\r
- * @return Pointer to an #IotLink_t representing the matched and removed element;\r
- * `NULL` if no match is found. The macro #IotLink_Container may be used to determine\r
- * the address of the link's container.\r
- */\r
-/* @[declare_linear_containers_list_double_removefirstmatch] */\r
-static inline IotLink_t * IotListDouble_RemoveFirstMatch( IotListDouble_t * const pList,\r
-                                                          const IotLink_t * const pStartPoint,\r
-                                                          bool ( *isMatch )( const IotLink_t *, void * ),\r
-                                                          void * pMatch )\r
-/* @[declare_linear_containers_list_double_removefirstmatch] */\r
-{\r
-    IotLink_t * pMatchedElement = IotListDouble_FindFirstMatch( pList,\r
-                                                                pStartPoint,\r
-                                                                isMatch,\r
-                                                                pMatch );\r
-\r
-    if( pMatchedElement != NULL )\r
-    {\r
-        IotListDouble_Remove( pMatchedElement );\r
-    }\r
-\r
-    return pMatchedElement;\r
-}\r
-\r
-/**\r
- * @brief Remove all matching elements from a doubly-linked list.\r
- *\r
- * @param[in] pList The doubly-linked list to search.\r
- * @param[in] isMatch Function to determine if an element matches. Pass `NULL` to\r
- * search using the address `pMatch`, i.e. `element == pMatch`.\r
- * @param[in] pMatch If `isMatch` is `NULL`, each element in the list is compared\r
- * to this address to find a match. Otherwise, it is passed as the second argument\r
- * to `isMatch`.\r
- * @param[in] freeElement A function to free memory used by each removed list\r
- * element. Optional; pass `NULL` to ignore.\r
- * @param[in] linkOffset Offset in bytes of a link member in its container, used\r
- * to calculate the pointer to pass to `freeElement`. This value should be calculated\r
- * with the C `offsetof` macro. This parameter is ignored if `freeElement` is `NULL`\r
- * or its value is `0`.\r
- */\r
-/* @[declare_linear_containers_list_double_removeallmatches] */\r
-static inline void IotListDouble_RemoveAllMatches( IotListDouble_t * const pList,\r
-                                                   bool ( *isMatch )( const IotLink_t *, void * ),\r
-                                                   void * pMatch,\r
-                                                   void ( *freeElement )( void * ),\r
-                                                   size_t linkOffset )\r
-/* @[declare_linear_containers_list_double_removeallmatches] */\r
-{\r
-    IotLink_t * pMatchedElement = NULL, * pNextElement = NULL;\r
-\r
-    /* Search the list for all matching elements. */\r
-    do\r
-    {\r
-        pMatchedElement = IotListDouble_FindFirstMatch( pList,\r
-                                                        pMatchedElement,\r
-                                                        isMatch,\r
-                                                        pMatch );\r
-\r
-        if( pMatchedElement != NULL )\r
-        {\r
-            /* Save pointer to next element. */\r
-            pNextElement = pMatchedElement->pNext;\r
-\r
-            /* Match found; remove and free. */\r
-            IotListDouble_Remove( pMatchedElement );\r
-\r
-            if( freeElement != NULL )\r
-            {\r
-                freeElement( ( ( uint8_t * ) pMatchedElement ) - linkOffset );\r
-            }\r
-\r
-            /* Continue search from next element. */\r
-            pMatchedElement = pNextElement;\r
-        }\r
-    } while( pMatchedElement != NULL );\r
-}\r
-\r
-/**\r
- * @brief Create a new queue.\r
- *\r
- * This function initializes a new double-ended queue. It must be called on an uninitialized\r
- * #IotDeQueue_t before calling any other queue function. This function must not be\r
- * called on an already-initialized #IotDeQueue_t.\r
- *\r
- * This function will not fail.\r
- *\r
- * @param[in] pQueue Pointer to the memory that will hold the new queue.\r
- */\r
-/* @[declare_linear_containers_queue_create] */\r
-static inline void IotDeQueue_Create( IotDeQueue_t * const pQueue )\r
-/* @[declare_linear_containers_queue_create] */\r
-{\r
-    IotListDouble_Create( pQueue );\r
-}\r
-\r
-/**\r
- * @brief Return the number of elements contained in an #IotDeQueue_t.\r
- *\r
- * @param[in] pQueue The queue with the elements to count.\r
- *\r
- * @return The number of items elements in the queue.\r
- */\r
-/* @[declare_linear_containers_queue_count] */\r
-static inline size_t IotDeQueue_Count( const IotDeQueue_t * const pQueue )\r
-/* @[declare_linear_containers_queue_count] */\r
-{\r
-    return IotListDouble_Count( pQueue );\r
-}\r
-\r
-/**\r
- * @brief Check if a queue is empty.\r
- *\r
- * @param[in] pQueue The queue to check.\r
- *\r
- * @return `true` if the queue is empty; `false` otherwise.\r
- *\r
- */\r
-/* @[declare_linear_containers_queue_isempty] */\r
-static inline bool IotDeQueue_IsEmpty( const IotDeQueue_t * const pQueue )\r
-/* @[declare_linear_containers_queue_isempty] */\r
-{\r
-    return IotListDouble_IsEmpty( pQueue );\r
-}\r
-\r
-/**\r
- * @brief Return an #IotLink_t representing the element at the front of the queue\r
- * without removing it.\r
- *\r
- * @param[in] pQueue The queue to peek.\r
- *\r
- * @return Pointer to an #IotLink_t representing the element at the head of the\r
- * queue; `NULL` if the queue is empty. The macro #IotLink_Container may be used\r
- * to determine the address of the link's container.\r
- */\r
-/* @[declare_linear_containers_queue_peekhead] */\r
-static inline IotLink_t * IotDeQueue_PeekHead( const IotDeQueue_t * const pQueue )\r
-/* @[declare_linear_containers_queue_peekhead] */\r
-{\r
-    return IotListDouble_PeekHead( pQueue );\r
-}\r
-\r
-/**\r
- * @brief Return an #IotLink_t representing the element at the back of the queue\r
- * without removing it.\r
- *\r
- * @param[in] pQueue The queue to peek.\r
- *\r
- * @return Pointer to an #IotLink_t representing the element at the head of the\r
- * queue; `NULL` if the queue is empty. The macro #IotLink_Container may be used\r
- * to determine the address of the link's container.\r
- */\r
-/* @[declare_linear_containers_queue_peektail] */\r
-static inline IotLink_t * IotDeQueue_PeekTail( const IotDeQueue_t * const pQueue )\r
-/* @[declare_linear_containers_queue_peektail] */\r
-{\r
-    return IotListDouble_PeekTail( pQueue );\r
-}\r
-\r
-/**\r
- * @brief Add an element at the head of the queue.\r
- *\r
- * @param[in] pQueue The queue that will hold the new element.\r
- * @param[in] pLink Pointer to the new element's link member.\r
- */\r
-/* @[declare_linear_containers_queue_enqueuehead] */\r
-static inline void IotDeQueue_EnqueueHead( IotDeQueue_t * const pQueue,\r
-                                     IotLink_t * const pLink )\r
-/* @[declare_linear_containers_queue_enqueuehead] */\r
-{\r
-    IotListDouble_InsertHead( pQueue, pLink );\r
-}\r
-\r
-/**\r
- * @brief Remove an element at the head of the queue.\r
- *\r
- * @param[in] pQueue The queue that holds the element to remove.\r
- *\r
- * @return Pointer to an #IotLink_t representing the removed queue element; `NULL`\r
- * if the queue is empty. The macro #IotLink_Container may be used to determine\r
- * the address of the link's container.\r
- */\r
-/* @[declare_linear_containers_queue_dequeuehead] */\r
-static inline IotLink_t * IotDeQueue_DequeueHead( IotDeQueue_t * const pQueue )\r
-/* @[declare_linear_containers_queue_dequeuehead] */\r
-{\r
-    return IotListDouble_RemoveHead( pQueue );\r
-}\r
-\r
-/**\r
- * @brief Add an element at the tail of the queue.\r
- *\r
- * @param[in] pQueue The queue that will hold the new element.\r
- * @param[in] pLink Pointer to the new element's link member.\r
- */\r
-/* @[declare_linear_containers_queue_enqueuetail] */\r
-static inline void IotDeQueue_EnqueueTail( IotDeQueue_t * const pQueue,\r
-                                     IotLink_t * const pLink )\r
-/* @[declare_linear_containers_queue_enqueuetail] */\r
-{\r
-    IotListDouble_InsertTail( pQueue, pLink );\r
-}\r
-\r
-/**\r
- * @brief Remove an element at the tail of the queue.\r
- *\r
- * @param[in] pQueue The queue that holds the element to remove.\r
- *\r
- * @return Pointer to an #IotLink_t representing the removed queue element; `NULL`\r
- * if the queue is empty. The macro #IotLink_Container may be used to determine\r
- * the address of the link's container.\r
- */\r
-/* @[declare_linear_containers_queue_dequeuetail] */\r
-static inline IotLink_t * IotDeQueue_DequeueTail( IotDeQueue_t * const pQueue )\r
-/* @[declare_linear_containers_queue_dequeuetail] */\r
-{\r
-    return IotListDouble_RemoveTail( pQueue );\r
-}\r
-\r
-/**\r
- * @brief Remove a single element from a queue.\r
- *\r
- * @param[in] pLink The element to remove.\r
- */\r
-/* @[declare_linear_containers_queue_remove] */\r
-static inline void IotDeQueue_Remove( IotLink_t * const pLink )\r
-/* @[declare_linear_containers_queue_remove] */\r
-{\r
-    IotListDouble_Remove( pLink );\r
-}\r
-\r
-/**\r
- * @brief Remove all elements in a queue.\r
- *\r
- * @param[in] pQueue The queue to empty.\r
- * @param[in] freeElement A function to free memory used by each removed queue\r
- * element. Optional; pass `NULL` to ignore.\r
- * @param[in] linkOffset Offset in bytes of a link member in its container, used\r
- * to calculate the pointer to pass to `freeElement`. This value should be calculated\r
- * with the C `offsetof` macro. This parameter is ignored if `freeElement` is `NULL`\r
- * or its value is `0`.\r
- */\r
-/* @[declare_linear_containers_queue_removeall] */\r
-static inline void IotDeQueue_RemoveAll( IotDeQueue_t * const pQueue,\r
-                                       void ( * freeElement )( void * ),\r
-                                       size_t linkOffset )\r
-/* @[declare_linear_containers_queue_removeall] */\r
-{\r
-    IotListDouble_RemoveAll( pQueue, freeElement, linkOffset );\r
-}\r
-\r
-/**\r
- * @brief Remove all matching elements from a queue.\r
- *\r
- * @param[in] pQueue The queue to search.\r
- * @param[in] isMatch Function to determine if an element matches. Pass `NULL` to\r
- * search using the address `pMatch`, i.e. `element == pMatch`.\r
- * @param[in] pMatch If `isMatch` is `NULL`, each element in the queue is compared\r
- * to this address to find a match. Otherwise, it is passed as the second argument\r
- * to `isMatch`.\r
- * @param[in] freeElement A function to free memory used by each removed queue\r
- * element. Optional; pass `NULL` to ignore.\r
- * @param[in] linkOffset Offset in bytes of a link member in its container, used\r
- * to calculate the pointer to pass to `freeElement`. This value should be calculated\r
- * with the C `offsetof` macro. This parameter is ignored if `freeElement` is `NULL`\r
- * or its value is `0`.\r
- */\r
-/* @[declare_linear_containers_queue_removeallmatches] */\r
-static inline void IotDeQueue_RemoveAllMatches( IotDeQueue_t * const pQueue,\r
-                                              bool ( * isMatch )( const IotLink_t *, void * ),\r
-                                              void * pMatch,\r
-                                              void ( * freeElement )( void * ),\r
-                                              size_t linkOffset )\r
-/* @[declare_linear_containers_queue_removeallmatches] */\r
-{\r
-    IotListDouble_RemoveAllMatches( pQueue, isMatch, pMatch, freeElement, linkOffset );\r
-}\r
-\r
-#endif /* IOT_LINEAR_CONTAINERS_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/iot_logging_setup.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/iot_logging_setup.h
deleted file mode 100644 (file)
index ec3d6d1..0000000
+++ /dev/null
@@ -1,223 +0,0 @@
-/*\r
- * Amazon FreeRTOS Common V1.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_logging_setup.h\r
- * @brief Defines the logging macro #IotLog.\r
- */\r
-\r
-#ifndef IOT_LOGGING_SETUP_H_\r
-#define IOT_LOGGING_SETUP_H_\r
-\r
-/* The config header is always included first. */\r
-#include "iot_config.h"\r
-\r
-/* Logging include. Because it's included here, iot_logging.h never needs\r
- * to be included in source. */\r
-#include "private/iot_logging.h"\r
-\r
-/**\r
- * @functionpage{IotLog,logging,log}\r
- * @functionpage{IotLog_PrintBuffer,logging,printbuffer}\r
- */\r
-\r
-/**\r
- * @def IotLog( messageLevel, pLogConfig, ... )\r
- * @brief Logging function for a specific library. In most cases, this is the\r
- * logging function to call.\r
- *\r
- * This function prints a single log message. It is available when @ref\r
- * LIBRARY_LOG_LEVEL is not #IOT_LOG_NONE. Log messages automatically\r
- * include the [log level](@ref logging_constants_levels), [library name]\r
- * (@ref LIBRARY_LOG_NAME), and time. An optional @ref IotLogConfig_t may\r
- * be passed to this function to hide information for a single log message.\r
- *\r
- * The logging library must be set up before this function may be called. See\r
- * @ref logging_setup_use for more information.\r
- *\r
- * This logging function also has the following abbreviated forms that can be used\r
- * when an #IotLogConfig_t isn't needed.\r
- *\r
- * Name         | Equivalent to\r
- * ----         | -------------\r
- * #IotLogError | @code{c} IotLog( IOT_LOG_ERROR, NULL, ... ) @endcode\r
- * #IotLogWarn  | @code{c} IotLog( IOT_LOG_WARN, NULL, ... ) @endcode\r
- * #IotLogInfo  | @code{c} IotLog( IOT_LOG_INFO, NULL, ... ) @endcode\r
- * #IotLogDebug | @code{c} IotLog( IOT_LOG_DEBUG, NULL, ... ) @endcode\r
- *\r
- * @param[in] messageLevel Log level of this message. Must be one of the\r
- * @ref logging_constants_levels.\r
- * @param[in] pLogConfig Pointer to an #IotLogConfig_t. Optional; pass `NULL`\r
- * to ignore.\r
- * @param[in] ... Message and format specification.\r
- *\r
- * @return No return value. On errors, it prints nothing.\r
- *\r
- * @note This function may be implemented as a macro.\r
- * @see @ref logging_function_generic for the generic (not library-specific)\r
- * logging function.\r
- */\r
-\r
-/**\r
- * @def IotLog_PrintBuffer( pHeader, pBuffer, bufferSize )\r
- * @brief Log the contents of buffer as bytes. Only available when @ref\r
- * LIBRARY_LOG_LEVEL is #IOT_LOG_DEBUG.\r
- *\r
- * This function prints the bytes located at a given memory address. It is\r
- * intended for debugging only, and is therefore only available when @ref\r
- * LIBRARY_LOG_LEVEL is #IOT_LOG_DEBUG.\r
- *\r
- * Log messages printed by this function <b>always</b> include the [log level]\r
- * (@ref logging_constants_levels), [library name](@ref LIBRARY_LOG_NAME),\r
- * and time.  In addition, this function may print an optional header `pHeader`\r
- * before it prints the contents of the buffer. This function does not have an\r
- * #IotLogConfig_t parameter.\r
- *\r
- * The logging library must be set up before this function may be called. See\r
- * @ref logging_setup_use for more information.\r
- *\r
- * @param[in] pHeader A message to log before the buffer. Optional; pass `NULL`\r
- * to ignore.\r
- * @param[in] pBuffer Pointer to start of buffer.\r
- * @param[in] bufferSize Size of `pBuffer`.\r
- *\r
- * @return No return value. On errors, it prints nothing.\r
- *\r
- * @note This function may be implemented as a macro.\r
- * @note To conserve memory, @ref logging_function_genericprintbuffer (the underlying\r
- * implementation) only allocates enough memory for a single line of output. Therefore,\r
- * in multithreaded systems, its output may appear "fragmented" if other threads are\r
- * logging simultaneously.\r
- * @see @ref logging_function_genericprintbuffer for the generic (not library-specific)\r
- * buffer logging function.\r
- *\r
- * <b>Example</b>\r
- * @code{c}\r
- * const uint8_t pBuffer[] = { 0x00, 0x01, 0x02, 0x03 };\r
- *\r
- * IotLog_PrintBuffer( "This buffer contains:",\r
- *                     pBuffer,\r
- *                     4 );\r
- * @endcode\r
- * The code above prints something like the following:\r
- * @code{c}\r
- * [DEBUG][LIB_NAME][2018-01-01 12:00:00] This buffer contains:\r
- * 00 01 02 03\r
- * @endcode\r
- */\r
-\r
-/**\r
- * @def IotLogError( ...  )\r
- * @brief Abbreviated logging macro for level #IOT_LOG_ERROR.\r
- *\r
- * Equivalent to:\r
- * @code{c}\r
- * IotLog( IOT_LOG_ERROR, NULL, ... )\r
- * @endcode\r
- */\r
-\r
-/**\r
- * @def IotLogWarn( ...  )\r
- * @brief Abbreviated logging macro for level #IOT_LOG_WARN.\r
- *\r
- * Equivalent to:\r
- * @code{c}\r
- * IotLog( IOT_LOG_WARN, NULL, ... )\r
- * @endcode\r
- */\r
-\r
-/**\r
- * @def IotLogInfo( ...  )\r
- * @brief Abbreviated logging macro for level #IOT_LOG_INFO.\r
- *\r
- * Equivalent to:\r
- * @code{c}\r
- * IotLog( IOT_LOG_INFO, NULL, ... )\r
- * @endcode\r
- */\r
-\r
-/**\r
- * @def IotLogDebug( ...  )\r
- * @brief Abbreviated logging macro for level #IOT_LOG_DEBUG.\r
- *\r
- * Equivalent to:\r
- * @code{c}\r
- * IotLog( IOT_LOG_DEBUG, NULL, ... )\r
- * @endcode\r
- */\r
-\r
-/* Check that LIBRARY_LOG_LEVEL is defined and has a valid value. */\r
-#if !defined( LIBRARY_LOG_LEVEL ) ||            \\r
-    ( LIBRARY_LOG_LEVEL != IOT_LOG_NONE &&  \\r
-      LIBRARY_LOG_LEVEL != IOT_LOG_ERROR && \\r
-      LIBRARY_LOG_LEVEL != IOT_LOG_WARN &&  \\r
-      LIBRARY_LOG_LEVEL != IOT_LOG_INFO &&  \\r
-      LIBRARY_LOG_LEVEL != IOT_LOG_DEBUG )\r
-    #error "Please define LIBRARY_LOG_LEVEL as either IOT_LOG_NONE, IOT_LOG_ERROR, IOT_LOG_WARN, IOT_LOG_INFO, or IOT_LOG_DEBUG."\r
-/* Check that LIBRARY_LOG_NAME is defined and has a valid value. */\r
-#elif !defined( LIBRARY_LOG_NAME )\r
-    #error "Please define LIBRARY_LOG_NAME."\r
-#else\r
-    /* Define IotLog if the log level is greater than "none". */\r
-    #if LIBRARY_LOG_LEVEL > IOT_LOG_NONE\r
-        #define IotLog( messageLevel, pLogConfig, ... )   \\r
-                IotLog_Generic( LIBRARY_LOG_LEVEL,        \\r
-                                LIBRARY_LOG_NAME,        \\r
-                                messageLevel,             \\r
-                                pLogConfig,               \\r
-                                __VA_ARGS__ )\r
-\r
-        /* Define the abbreviated logging macros. */\r
-        #define IotLogError( ...  )    IotLog( IOT_LOG_ERROR, NULL, __VA_ARGS__ )\r
-        #define IotLogWarn( ... )      IotLog( IOT_LOG_WARN, NULL, __VA_ARGS__ )\r
-        #define IotLogInfo( ... )      IotLog( IOT_LOG_INFO, NULL, __VA_ARGS__ )\r
-        #define IotLogDebug( ... )     IotLog( IOT_LOG_DEBUG, NULL, __VA_ARGS__ )\r
-\r
-        /* If log level is DEBUG, enable the function to print buffers. */\r
-        #if LIBRARY_LOG_LEVEL >= IOT_LOG_DEBUG\r
-        #define IotLog_PrintBuffer( pHeader, pBuffer, bufferSize )    \\r
-                IotLog_GenericPrintBuffer( LIBRARY_LOG_NAME,         \\r
-                                           pHeader,                   \\r
-                                           pBuffer,                   \\r
-                                           bufferSize )\r
-        #else\r
-        #define IotLog_PrintBuffer( pHeader, pBuffer, bufferSize )\r
-        #endif\r
-    /* Remove references to IotLog from the source code if logging is disabled. */\r
-    #else\r
-        /* @[declare_logging_log] */\r
-        #define IotLog( messageLevel, pLogConfig, ... )\r
-        /* @[declare_logging_log] */\r
-        /* @[declare_logging_printbuffer] */\r
-        #define IotLog_PrintBuffer( pHeader, pBuffer, bufferSize )\r
-        /* @[declare_logging_printbuffer] */\r
-        #define IotLogError( ...  )\r
-        #define IotLogWarn( ... )\r
-        #define IotLogInfo( ... )\r
-        #define IotLogDebug( ... )\r
-    #endif\r
-#endif\r
-\r
-#endif /* ifndef IOT_LOGGING_SETUP_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/iot_taskpool.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/iot_taskpool.h
deleted file mode 100644 (file)
index a91ccf1..0000000
+++ /dev/null
@@ -1,558 +0,0 @@
-/*\r
- * Amazon FreeRTOS Common V1.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_taskpool.h\r
- * @brief User-facing functions of the task pool library.\r
- */\r
-\r
-#ifndef IOT_TASKPOOL_H_\r
-#define IOT_TASKPOOL_H_\r
-\r
-/* The config header is always included first. */\r
-#include "iot_config.h"\r
-\r
-/* Standard includes. */\r
-#include <stdbool.h>\r
-#include <stdint.h>\r
-#include <stddef.h>\r
-\r
-/* Task pool types. */\r
-#include "types/iot_taskpool_types.h"\r
-\r
-/*------------------------- Task Pool library functions --------------------------*/\r
-\r
-/**\r
- * @functionspage{taskpool,task pool library}\r
- * - @functionname{taskpool_function_createsystemtaskpool}\r
- * - @functionname{taskpool_function_getsystemtaskpool}\r
- * - @functionname{taskpool_function_create}\r
- * - @functionname{taskpool_function_destroy}\r
- * - @functionname{taskpool_function_setmaxthreads}\r
- * - @functionname{taskpool_function_createjob}\r
- * - @functionname{taskpool_function_createrecyclablejob}\r
- * - @functionname{taskpool_function_destroyrecyclablejob}\r
- * - @functionname{taskpool_function_recyclejob}\r
- * - @functionname{taskpool_function_schedule}\r
- * - @functionname{taskpool_function_scheduledeferred}\r
- * - @functionname{taskpool_function_getstatus}\r
- * - @functionname{taskpool_function_trycancel}\r
- * - @functionname{taskpool_function_getjobstoragefromhandle}\r
- * - @functionname{taskpool_function_strerror}\r
- */\r
-\r
-/**\r
- * @functionpage{IotTaskPool_CreateSystemTaskPool,taskpool,createsystemtaskpool}\r
- * @functionpage{IotTaskPool_GetSystemTaskPool,taskpool,getsystemtaskpool}\r
- * @functionpage{IotTaskPool_Create,taskpool,create}\r
- * @functionpage{IotTaskPool_Destroy,taskpool,destroy}\r
- * @functionpage{IotTaskPool_SetMaxThreads,taskpool,setmaxthreads}\r
- * @functionpage{IotTaskPool_CreateJob,taskpool,createjob}\r
- * @functionpage{IotTaskPool_CreateRecyclableJob,taskpool,createrecyclablejob}\r
- * @functionpage{IotTaskPool_DestroyRecyclableJob,taskpool,destroyrecyclablejob}\r
- * @functionpage{IotTaskPool_RecycleJob,taskpool,recyclejob}\r
- * @functionpage{IotTaskPool_Schedule,taskpool,schedule}\r
- * @functionpage{IotTaskPool_ScheduleDeferred,taskpool,scheduledeferred}\r
- * @functionpage{IotTaskPool_GetStatus,taskpool,getstatus}\r
- * @functionpage{IotTaskPool_TryCancel,taskpool,trycancel}\r
- * @functionpage{IotTaskPool_GetJobStorageFromHandle,taskpool,getjobstoragefromhandle}\r
- * @functionpage{IotTaskPool_strerror,taskpool,strerror}\r
- */\r
-\r
-/**\r
- * @brief Creates the one single instance of the system task pool.\r
- *\r
- * This function should be called once by the application to initialize the one single instance of the system task pool.\r
- * An application should initialize the system task pool early in the boot sequence, before initializing any other library\r
- * and before posting any jobs. Early initialization it typically easy to accomplish by creating the system task pool\r
- * before starting the scheduler.\r
- *\r
- * This function does not allocate memory to hold the task pool data structures and state, but it\r
- * may allocate memory to hold the dependent entities and data structures, e.g. the threads of the task\r
- * pool. The system task pool handle is recoverable for later use by calling @ref IotTaskPool_GetSystemTaskPool or\r
- * the shortcut @ref IOT_SYSTEM_TASKPOOL.\r
- *\r
- * @param[in] pInfo A pointer to the task pool initialization data.\r
- *\r
- * @return One of the following:\r
- * - #IOT_TASKPOOL_SUCCESS\r
- * - #IOT_TASKPOOL_BAD_PARAMETER\r
- * - #IOT_TASKPOOL_NO_MEMORY\r
- *\r
- * @warning This function should be called only once. Calling this function more that once will result in\r
- * undefined behavior.\r
- *\r
- */\r
-/* @[declare_taskpool_createsystemtaskpool] */\r
-IotTaskPoolError_t IotTaskPool_CreateSystemTaskPool( const IotTaskPoolInfo_t * const pInfo );\r
-/* @[declare_taskpool_createsystemtaskpool] */\r
-\r
-/**\r
- * @brief Retrieves the one and only instance of a system task pool\r
- *\r
- * This function retrieves the system task pool created with @ref IotTaskPool_CreateSystemTaskPool, and it is functionally\r
- * equivalent to using the shortcut @ref IOT_SYSTEM_TASKPOOL.\r
- *\r
- * @return The system task pool handle.\r
- *\r
- * @warning This function should be called after creating the system task pool with @ref IotTaskPool_CreateSystemTaskPool.\r
- * Calling this function before creating the system task pool may return a pointer to an uninitialized task pool, NULL, or otherwise\r
- * fail with undefined behaviour.\r
- *\r
- */\r
-/* @[declare_taskpool_getsystemtaskpool] */\r
-IotTaskPool_t IotTaskPool_GetSystemTaskPool( void );\r
-/* @[declare_taskpool_getsystemtaskpool] */\r
-\r
-/**\r
- * @brief Creates one instance of a task pool.\r
- *\r
- * This function should be called by the user to initialize one instance of a task\r
- * pool. The task pool instance will be created around the storage pointed to by the `pTaskPool`\r
- * parameter. This function will create the minimum number of threads requested by the user\r
- * through an instance of the #IotTaskPoolInfo_t type specified with the `pInfo` parameter.\r
- * This function does not allocate memory to hold the task pool data structures and state, but it\r
- * may allocates memory to hold the dependent data structures, e.g. the threads of the task\r
- * pool.\r
- *\r
- * @param[in] pInfo A pointer to the task pool initialization data.\r
- * @param[out] pTaskPool A pointer to the task pool handle to be used after initialization.\r
- * The pointer `pTaskPool` will hold a valid handle only if (@ref IotTaskPool_Create)\r
- * completes successfully.\r
- *\r
- * @return One of the following:\r
- * - #IOT_TASKPOOL_SUCCESS\r
- * - #IOT_TASKPOOL_BAD_PARAMETER\r
- * - #IOT_TASKPOOL_NO_MEMORY\r
- *\r
- */\r
-/* @[declare_taskpool_create] */\r
-IotTaskPoolError_t IotTaskPool_Create( const IotTaskPoolInfo_t * const pInfo,\r
-                                       IotTaskPool_t * const pTaskPool );\r
-/* @[declare_taskpool_create] */\r
-\r
-/**\r
- * @brief Destroys a task pool instance and collects all memory associated with a task pool and its\r
- * satellite data structures.\r
- *\r
- * This function should be called to destroy one instance of a task pool previously created with a call\r
- * to @ref IotTaskPool_Create or @ref IotTaskPool_CreateSystemTaskPool.\r
- * Calling this fuction release all underlying resources. After calling this function, any job scheduled but not yet executed\r
- * will be canceled and destroyed.\r
- * The `taskPool` instance will no longer be valid after this function returns.\r
- *\r
- * @param[in] taskPool A handle to the task pool, e.g. as returned by a call to @ref IotTaskPool_Create or\r
- * @ref IotTaskPool_CreateSystemTaskPool. The `taskPool` instance will no longer be valid after this function returns.\r
- *\r
- * @return One of the following:\r
- * - #IOT_TASKPOOL_SUCCESS\r
- * - #IOT_TASKPOOL_BAD_PARAMETER\r
- *\r
- */\r
-/* @[declare_taskpool_destroy] */\r
-IotTaskPoolError_t IotTaskPool_Destroy( IotTaskPool_t taskPool );\r
-/* @[declare_taskpool_destroy] */\r
-\r
-/**\r
- * @brief Sets the maximum number of threads for one instance of a task pool.\r
- *\r
- * This function sets the maximum number of threads for the task pool\r
- * pointed to by `taskPool`.\r
- *\r
- * If the number of currently active threads in the task pool is greater than `maxThreads`, this\r
- * function causes the task pool to shrink the number of active threads.\r
- *\r
- * @param[in] taskPool A handle to the task pool that must have been previously initialized with\r
- * a call to @ref IotTaskPool_Create or @ref IotTaskPool_CreateSystemTaskPool.\r
- * @param[in] maxThreads The maximum number of threads for the task pool.\r
- *\r
- * @return One of the following:\r
- * - #IOT_TASKPOOL_SUCCESS\r
- * - #IOT_TASKPOOL_BAD_PARAMETER\r
- * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS\r
- *\r
- */\r
-/* @[declare_taskpool_setmaxthreads] */\r
-IotTaskPoolError_t IotTaskPool_SetMaxThreads( IotTaskPool_t taskPool,\r
-                                              uint32_t maxThreads );\r
-/* @[declare_taskpool_setmaxthreads] */\r
-\r
-/**\r
- * @brief Creates a job for the task pool around a user-provided storage.\r
- *\r
- * This function may allocate memory to hold the state for a job.\r
- *\r
- * @param[in] userCallback A user-specified callback for the job.\r
- * @param[in] pUserContext A user-specified context for the callback.\r
- * @param[in] pJobStorage The storage for the job data structure.\r
- * @param[out] pJob A pointer to an instance of @ref IotTaskPoolJob_t that will be initialized when this\r
- * function returns successfully. This handle can be used to inspect the job status with\r
- * @ref IotTaskPool_GetStatus or cancel the job with @ref IotTaskPool_TryCancel, etc....\r
- *\r
- * @return One of the following:\r
- * - #IOT_TASKPOOL_SUCCESS\r
- * - #IOT_TASKPOOL_BAD_PARAMETER\r
- *\r
- *\r
- */\r
-/* @[declare_taskpool_createjob] */\r
-IotTaskPoolError_t IotTaskPool_CreateJob( IotTaskPoolRoutine_t userCallback,\r
-                                          void * pUserContext,\r
-                                          IotTaskPoolJobStorage_t * const pJobStorage,\r
-                                          IotTaskPoolJob_t * const pJob );\r
-/* @[declare_taskpool_createjob] */\r
-\r
-/**\r
- * brief Creates a job for the task pool by allocating the job dynamically.\r
- *\r
- * A recyclable job does not need to be allocated twice, but it can rather be reused through\r
- * subsequent calls to @ref IotTaskPool_CreateRecyclableJob.\r
- *\r
- * @param[in] taskPool A handle to the task pool for which to create a recyclable job.\r
- * @param[in] userCallback A user-specified callback for the job.\r
- * @param[in] pUserContext A user-specified context for the callback.\r
- * @param[out] pJob A pointer to an instance of @ref IotTaskPoolJob_t that will be initialized when this\r
- * function returns successfully. This handle can be used to inspect the job status with\r
- * @ref IotTaskPool_GetStatus or cancel the job with @ref IotTaskPool_TryCancel, etc....\r
- *\r
- * @return One of the following:\r
- * - #IOT_TASKPOOL_SUCCESS\r
- * - #IOT_TASKPOOL_BAD_PARAMETER\r
- * - #IOT_TASKPOOL_NO_MEMORY\r
- * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS\r
- *\r
- * @note This function will not allocate memory. //_RB_ Incorrect comment.\r
- *\r
- * @warning A recyclable job should be recycled with a call to @ref IotTaskPool_RecycleJob rather than destroyed.\r
- *\r
- */\r
-/* @[declare_taskpool_createrecyclablejob] */\r
-IotTaskPoolError_t IotTaskPool_CreateRecyclableJob( IotTaskPool_t taskPool,\r
-                                                    IotTaskPoolRoutine_t userCallback,\r
-                                                    void * pUserContext,\r
-                                                    IotTaskPoolJob_t * const pJob );\r
-/* @[declare_taskpool_createrecyclablejob] */\r
-\r
-/**\r
- * @brief This function un-initializes a job.\r
- *\r
- * This function will destroy a job created with @ref IotTaskPool_CreateRecyclableJob.\r
- * A job should not be destroyed twice. A job that was previously scheduled but has not completed yet should not be destroyed,\r
- * but rather the application should attempt to cancel it first by calling @ref IotTaskPool_TryCancel.\r
- * An attempt to destroy a job that was scheduled but not yet executed or canceled, may result in a\r
- * @ref IOT_TASKPOOL_ILLEGAL_OPERATION error.\r
- *\r
- * @param[in] taskPool A handle to the task pool, e.g. as returned by a call to @ref IotTaskPool_Create or @ref IotTaskPool_CreateSystemTaskPool.\r
- * @param[in] job A handle to a job that was create with a call to @ref IotTaskPool_CreateJob.\r
- *\r
- * @return One of the following:\r
- * - #IOT_TASKPOOL_SUCCESS\r
- * - #IOT_TASKPOOL_BAD_PARAMETER\r
- * - #IOT_TASKPOOL_ILLEGAL_OPERATION\r
- * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS\r
- *\r
- * @warning The task pool will try and prevent destroying jobs that are currently queued for execution, but does\r
- * not enforce strict ordering of operations. It is up to the user to make sure @ref IotTaskPool_DestroyRecyclableJob is not called\r
- * our of order.\r
- *\r
- * @warning Calling this function on job that was not previously created with @ref IotTaskPool_CreateRecyclableJob\r
- * will result in a @ref IOT_TASKPOOL_ILLEGAL_OPERATION error.\r
- *\r
- */\r
-/* @[declare_taskpool_destroyrecyclablejob] */\r
-IotTaskPoolError_t IotTaskPool_DestroyRecyclableJob( IotTaskPool_t taskPool,\r
-                                                     IotTaskPoolJob_t job );\r
-/* @[declare_taskpool_destroyrecyclablejob] */\r
-\r
-/**\r
- * @brief Recycles a job into the task pool job cache.\r
- *\r
- * This function will try and recycle the job into the task pool cache. If the cache is full,\r
- * the job memory is destroyed as if the user called @ref IotTaskPool_DestroyRecyclableJob. The job should be recycled into\r
- * the task pool instance from where it was allocated.\r
- * Failure to do so will yield undefined results. A job should not be recycled twice. A job\r
- * that was previously scheduled but not completed or canceled cannot be safely recycled. An attempt to do so will result\r
- * in an @ref IOT_TASKPOOL_ILLEGAL_OPERATION error.\r
- *\r
- * @param[in] taskPool A handle to the task pool, e.g. as returned by a call to @ref IotTaskPool_Create.\r
- * @param[out] job A pointer to a job that was create with a call to @ref IotTaskPool_CreateJob.\r
- *\r
- * @return One of the following:\r
- * - #IOT_TASKPOOL_SUCCESS\r
- * - #IOT_TASKPOOL_BAD_PARAMETER\r
- * - #IOT_TASKPOOL_ILLEGAL_OPERATION\r
- * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS\r
- *\r
- * @warning The `taskPool` used in this function should be the same\r
- * used to create the job pointed to by `job`, or the results will be undefined.\r
- *\r
- * @warning Attempting to call this function on a statically allocated job will result in @ref IOT_TASKPOOL_ILLEGAL_OPERATION\r
- * error.\r
- *\r
- * @warning This function should be used to recycle a job in the task pool cache when after the job executed.\r
- * Failing to call either this function or @ref IotTaskPool_DestroyRecyclableJob will result is a memory leak. Statically\r
- * allocated jobs do not need to be recycled or destroyed.\r
- *\r
- */\r
-/* @[declare_taskpool_recyclejob] */\r
-IotTaskPoolError_t IotTaskPool_RecycleJob( IotTaskPool_t taskPool,\r
-                                           IotTaskPoolJob_t job );\r
-/* @[declare_taskpool_recyclejob] */\r
-\r
-/**\r
- * @brief This function schedules a job created with @ref IotTaskPool_CreateJob or @ref IotTaskPool_CreateRecyclableJob\r
- * against the task pool pointed to by `taskPool`.\r
- *\r
- * See @ref taskpool_design for a description of the jobs lifetime and interaction with the threads used in the task pool\r
- * library.\r
- *\r
- * @param[in] taskPool A handle to the task pool that must have been previously initialized with.\r
- * a call to @ref IotTaskPool_Create.\r
- * @param[in] job A job to schedule for execution. This must be first initialized with a call to @ref IotTaskPool_CreateJob.\r
- * @param[in] flags Flags to be passed by the user, e.g. to identify the job as high priority by specifying #IOT_TASKPOOL_JOB_HIGH_PRIORITY.\r
- *\r
- * @return One of the following:\r
- * - #IOT_TASKPOOL_SUCCESS\r
- * - #IOT_TASKPOOL_BAD_PARAMETER\r
- * - #IOT_TASKPOOL_ILLEGAL_OPERATION\r
- * - #IOT_TASKPOOL_NO_MEMORY\r
- * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS\r
- *\r
- *\r
- * @note This function will not allocate memory, so it is guaranteed to succeed if the paramters are correct and the task pool\r
- * was correctly initialized, and not yet destroyed.\r
- *\r
- * @warning The `taskPool` used in this function should be the same used to create the job pointed to by `job`, or the\r
- * results will be undefined.\r
- *\r
- * <b>Example</b>\r
- * @code{c}\r
- * // An example of a user context to pass to a callback through a task pool thread.\r
- * typedef struct JobUserContext\r
- * {\r
- *     uint32_t counter;\r
- * } JobUserContext_t;\r
- *\r
- * // An example of a user callback to invoke through a task pool thread.\r
- * static void ExecutionCb( IotTaskPool_t taskPool, IotTaskPoolJob_t job, void * context )\r
- * {\r
- *     ( void )taskPool;\r
- *     ( void )job;\r
- *\r
- *     JobUserContext_t * pUserContext = ( JobUserContext_t * )context;\r
- *\r
- *     pUserContext->counter++;\r
- * }\r
- *\r
- * void TaskPoolExample( )\r
- * {\r
- *     JobUserContext_t userContext = { 0 };\r
- *     IotTaskPoolJob_t job;\r
- *     IotTaskPool_t taskPool;\r
- *\r
- *     // Configure the task pool to hold at least two threads and three at the maximum.\r
- *     // Provide proper stack size and priority per the application needs.\r
- *\r
- *     const IotTaskPoolInfo_t tpInfo = { .minThreads = 2, .maxThreads = 3, .stackSize = 512, .priority = 0 };\r
- *\r
- *     // Create a task pool.\r
- *     IotTaskPool_Create( &tpInfo, &taskPool );\r
- *\r
- *     // Statically allocate one job, schedule it.\r
- *     IotTaskPool_CreateJob( &ExecutionCb, &userContext, &job );\r
- *\r
- *     IotTaskPoolError_t errorSchedule = IotTaskPool_Schedule( taskPool, &job, 0 );\r
- *\r
- *     switch ( errorSchedule )\r
- *     {\r
- *     case IOT_TASKPOOL_SUCCESS:\r
- *         break;\r
- *     case IOT_TASKPOOL_BAD_PARAMETER:          // Invalid parameters, such as a NULL handle, can trigger this error.\r
- *     case IOT_TASKPOOL_ILLEGAL_OPERATION:      // Scheduling a job that was previously scheduled or destroyed could trigger this error.\r
- *     case IOT_TASKPOOL_NO_MEMORY:              // Scheduling a with flag #IOT_TASKPOOL_JOB_HIGH_PRIORITY could trigger this error.\r
- *     case IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS:   // Scheduling a job after trying to destroy the task pool could trigger this error.\r
- *         // ASSERT\r
- *         break;\r
- *     default:\r
- *         // ASSERT\r
- *     }\r
- *\r
- *     //\r
- *     // ... Perform other operations ...\r
- *     //\r
- *\r
- *     IotTaskPool_Destroy( taskPool );\r
- * }\r
- * @endcode\r
- */\r
-/* @[declare_taskpool_schedule] */\r
-IotTaskPoolError_t IotTaskPool_Schedule( IotTaskPool_t taskPool,\r
-                                         IotTaskPoolJob_t job,\r
-                                         uint32_t flags );\r
-/* @[declare_taskpool_schedule] */\r
-\r
-/**\r
- * @brief This function schedules a job created with @ref IotTaskPool_CreateJob against the task pool\r
- * pointed to by `taskPool` to be executed after a user-defined time interval.\r
- *\r
- * See @ref taskpool_design for a description of the jobs lifetime and interaction with the threads used in the task pool\r
- * library.\r
- *\r
- * @param[in] taskPool A handle to the task pool that must have been previously initialized with.\r
- * a call to @ref IotTaskPool_Create.\r
- * @param[in] job A job to schedule for execution. This must be first initialized with a call to @ref IotTaskPool_CreateJob.\r
- * @param[in] timeMs The time in milliseconds to wait before scheduling the job.\r
- *\r
- * @return One of the following:\r
- * - #IOT_TASKPOOL_SUCCESS\r
- * - #IOT_TASKPOOL_BAD_PARAMETER\r
- * - #IOT_TASKPOOL_ILLEGAL_OPERATION\r
- * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS\r
- *\r
- *\r
- * @note This function will not allocate memory.\r
- *\r
- * @warning The `taskPool` used in this function should be the same\r
- * used to create the job pointed to by `job`, or the results will be undefined.\r
- *\r
- */\r
-/* @[declare_taskpool_scheduledeferred] */\r
-IotTaskPoolError_t IotTaskPool_ScheduleDeferred( IotTaskPool_t taskPool,\r
-                                                 IotTaskPoolJob_t job,\r
-                                                 uint32_t timeMs );\r
-/* @[declare_taskpool_scheduledeferred] */\r
-\r
-/**\r
- * @brief This function retrieves the current status of a job.\r
- *\r
- * @param[in] taskPool A handle to the task pool that must have been previously initialized with\r
- * a call to @ref IotTaskPool_Create or @ref IotTaskPool_CreateSystemTaskPool.\r
- * @param[in] job The job to cancel.\r
- * @param[out] pStatus The status of the job at the time of cancellation.\r
- *\r
- * @return One of the following:\r
- * - #IOT_TASKPOOL_SUCCESS\r
- * - #IOT_TASKPOOL_BAD_PARAMETER\r
- * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS\r
- *\r
- * @warning This function is not thread safe and the job status returned in `pStatus` may be invalid by the time\r
- * the calling thread has a chance to inspect it.\r
- */\r
-/* @[declare_taskpool_getstatus] */\r
-IotTaskPoolError_t IotTaskPool_GetStatus( IotTaskPool_t taskPool,\r
-                                          IotTaskPoolJob_t job,\r
-                                          IotTaskPoolJobStatus_t * const pStatus );\r
-/* @[declare_taskpool_getstatus] */\r
-\r
-/**\r
- * @brief This function tries to cancel a job that was previously scheduled with @ref IotTaskPool_Schedule.\r
- *\r
- * A job can be canceled only if it is not yet executing, i.e. if its status is\r
- * @ref IOT_TASKPOOL_STATUS_READY or @ref IOT_TASKPOOL_STATUS_SCHEDULED. Calling\r
- * @ref IotTaskPool_TryCancel on a job whose status is @ref IOT_TASKPOOL_STATUS_COMPLETED,\r
- * or #IOT_TASKPOOL_STATUS_CANCELED will yield a #IOT_TASKPOOL_CANCEL_FAILED return result.\r
- *\r
- * @param[in] taskPool A handle to the task pool that must have been previously initialized with\r
- * a call to @ref IotTaskPool_Create.\r
- * @param[in] job The job to cancel.\r
- * @param[out] pStatus The status of the job at the time of cancellation.\r
- *\r
- * @return One of the following:\r
- * - #IOT_TASKPOOL_SUCCESS\r
- * - #IOT_TASKPOOL_BAD_PARAMETER\r
- * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS\r
- * - #IOT_TASKPOOL_CANCEL_FAILED\r
- *\r
- * @warning The `taskPool` used in this function should be the same\r
- * used to create the job pointed to by `job`, or the results will be undefined.\r
- *\r
- */\r
-/* @[declare_taskpool_trycancel] */\r
-IotTaskPoolError_t IotTaskPool_TryCancel( IotTaskPool_t taskPool,\r
-                                          IotTaskPoolJob_t job,\r
-                                          IotTaskPoolJobStatus_t * const pStatus );\r
-/* @[declare_taskpool_trycancel] */\r
-\r
-/**\r
- * @brief Returns a pointer to the job storage from an instance of a job handle\r
- * of type @ref IotTaskPoolJob_t. This function is guaranteed to succeed for a\r
- * valid job handle.\r
- *\r
- * @param[in] job The job handle.\r
- *\r
- * @return A pointer to the storage associated with the job handle `job`.\r
- *\r
- * @warning If the `job` handle used is invalid, the results will be undefined.\r
- */\r
-/* @[declare_taskpool_getjobstoragefromhandle] */\r
-IotTaskPoolJobStorage_t * IotTaskPool_GetJobStorageFromHandle( IotTaskPoolJob_t job );\r
-/* @[declare_taskpool_getjobstoragefromhandle] */\r
-\r
-/**\r
- * @brief Returns a string that describes an @ref IotTaskPoolError_t.\r
- *\r
- * Like the POSIX's `strerror`, this function returns a string describing a\r
- * return code. In this case, the return code is a task pool library error code,\r
- * `status`.\r
- *\r
- * The string returned by this function <b>MUST</b> be treated as read-only: any\r
- * attempt to modify its contents may result in a crash. Therefore, this function\r
- * is limited to usage in logging.\r
- *\r
- * @param[in] status The status to describe.\r
- *\r
- * @return A read-only string that describes `status`.\r
- *\r
- * @warning The string returned by this function must never be modified.\r
- */\r
-/* @[declare_taskpool_strerror] */\r
-const char * IotTaskPool_strerror( IotTaskPoolError_t status );\r
-/* @[declare_taskpool_strerror] */\r
-\r
-/**\r
- * @brief The maximum number of task pools to be created when using\r
- * a memory pool.\r
- */\r
-#ifndef IOT_TASKPOOLS\r
-#define IOT_TASKPOOLS                          ( 4 )\r
-#endif\r
-\r
-/**\r
- * @brief The maximum number of jobs to cache.\r
- */\r
-#ifndef IOT_TASKPOOL_JOBS_RECYCLE_LIMIT\r
-    #define IOT_TASKPOOL_JOBS_RECYCLE_LIMIT    ( 8UL )\r
-#endif\r
-\r
-/**\r
- * @brief The maximum timeout in milliseconds to wait for a job to be scheduled before waking up a worker thread.\r
- * A worker thread that wakes up as a result of a timeout may exit to allow the task pool to fold back to its\r
- * minimum number of threads.\r
- */\r
-#ifndef IOT_TASKPOOL_JOB_WAIT_TIMEOUT_MS\r
-    #define IOT_TASKPOOL_JOB_WAIT_TIMEOUT_MS    ( 60 * 1000UL )\r
-#endif\r
-\r
-#endif /* ifndef IOT_TASKPOOL_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/private/iot_error.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/private/iot_error.h
deleted file mode 100644 (file)
index 8050390..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*\r
- * Amazon FreeRTOS Common V1.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_error.h\r
- * @brief Provides macros for error checking and function cleanup.\r
- *\r
- * The macros in this file are generic. They may be customized by each library\r
- * by setting the library prefix.\r
- */\r
-\r
-#ifndef IOT_ERROR_H_\r
-#define IOT_ERROR_H_\r
-\r
-/* The config header is always included first. */\r
-#include "iot_config.h"\r
-\r
-/**\r
- * @brief Declare the status variable and an initial value.\r
- *\r
- * This macro should be at the beginning of any functions that use cleanup sections.\r
- *\r
- * @param[in] statusType The type of the status variable for this function.\r
- * @param[in] initialValue The initial value to assign to the status variable.\r
- */\r
-#define IOT_FUNCTION_ENTRY( statusType, initialValue )    statusType status = initialValue\r
-\r
-/**\r
- * @brief Declares the label that begins a cleanup section.\r
- *\r
- * This macro should be placed at the end of a function and followed by\r
- * #IOT_FUNCTION_CLEANUP_END.\r
- */\r
-#define IOT_FUNCTION_CLEANUP_BEGIN()                      iotCleanup:\r
-\r
-/**\r
- * @brief Declares the end of a cleanup section.\r
- *\r
- * This macro should be placed at the end of a function and preceded by\r
- * #IOT_FUNCTION_CLEANUP_BEGIN.\r
- */\r
-#define IOT_FUNCTION_CLEANUP_END()                        return status\r
-\r
-/**\r
- * @brief Declares an empty cleanup section.\r
- *\r
- * This macro should be placed at the end of a function to exit on error if no\r
- * cleanup is required.\r
- */\r
-#define IOT_FUNCTION_EXIT_NO_CLEANUP()                    IOT_FUNCTION_CLEANUP_BEGIN(); IOT_FUNCTION_CLEANUP_END()\r
-\r
-/**\r
- * @brief Jump to the cleanup section.\r
- */\r
-#define IOT_GOTO_CLEANUP()                                goto iotCleanup\r
-\r
-/**\r
- * @brief Assign a value to the status variable and jump to the cleanup section.\r
- *\r
- * @param[in] statusValue The value to assign to the status variable.\r
- */\r
-#define IOT_SET_AND_GOTO_CLEANUP( statusValue )           { status = ( statusValue ); IOT_GOTO_CLEANUP(); }\r
-\r
-/**\r
- * @brief Jump to the cleanup section if a condition is `false`.\r
- *\r
- * This macro may be used in place of `assert` to exit a function is a condition\r
- * is `false`.\r
- *\r
- * @param[in] condition The condition to check.\r
- */\r
-#define IOT_GOTO_CLEANUP_IF_FALSE( condition )            { if( ( condition ) == false ) { IOT_GOTO_CLEANUP(); } }\r
-\r
-/**\r
- * @brief Assign a value to the status variable and jump to the cleanup section\r
- * if a condition is `false`.\r
- *\r
- * @param[in] statusValue The value to assign to the status variable.\r
- * @param[in] condition The condition to check.\r
- */\r
-#define IOT_SET_AND_GOTO_CLEANUP_IF_FALSE( statusValue, condition ) \\r
-    if( ( condition ) == false )                                    \\r
-        IOT_SET_AND_GOTO_CLEANUP( statusValue )\r
-\r
-/**\r
- * @brief Check a condition; if `false`, assign the "Bad parameter" status value\r
- * and jump to the cleanup section.\r
- *\r
- * @param[in] libraryPrefix The library prefix of the status variable.\r
- * @param[in] condition The condition to check.\r
- */\r
-#define IOT_VALIDATE_PARAMETER( libraryPrefix, condition ) \\r
-    IOT_SET_AND_GOTO_CLEANUP_IF_FALSE( libraryPrefix ## _BAD_PARAMETER, condition )\r
-\r
-#endif /* ifndef IOT_ERROR_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/private/iot_lib_init.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/private/iot_lib_init.h
deleted file mode 100644 (file)
index 2930d74..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*\r
- * Amazon FreeRTOS Common V1.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
-#ifndef _AWS_LIB_INIT_H_\r
-#define _AWS_LIB_INIT_H_\r
-\r
-#include "FreeRTOS.h"\r
-\r
-#define lib_initDECLARE_LIB_INIT( f )    extern BaseType_t f( void )\r
-\r
-#endif /* _AWS_LIB_INIT_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/private/iot_logging.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/private/iot_logging.h
deleted file mode 100644 (file)
index 377dd69..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-/*\r
- * Amazon FreeRTOS Common V1.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_logging.h\r
- * @brief Generic logging function header file.\r
- *\r
- * Declares the generic logging function and the log levels. This file never\r
- * needs to be included in source code. The header iot_logging_setup.h should\r
- * be included instead.\r
- *\r
- * @see iot_logging_setup.h\r
- */\r
-\r
-#ifndef IOT_LOGGING_H_\r
-#define IOT_LOGGING_H_\r
-\r
-/* The config header is always included first. */\r
-#include "iot_config.h"\r
-\r
-/* Standard includes. */\r
-#include <stdbool.h>\r
-#include <stddef.h>\r
-#include <stdint.h>\r
-\r
-/**\r
- * @constantspage{logging,logging library}\r
- *\r
- * @section logging_constants_levels Log levels\r
- * @brief Log levels for the libraries in this SDK.\r
- *\r
- * Each library should specify a log level by setting @ref LIBRARY_LOG_LEVEL.\r
- * All log messages with a level at or below the specified level will be printed\r
- * for that library.\r
- *\r
- * Currently, there are 4 log levels. In the order of lowest to highest, they are:\r
- * - #IOT_LOG_NONE <br>\r
- *   @copybrief IOT_LOG_NONE\r
- * - #IOT_LOG_ERROR <br>\r
- *   @copybrief IOT_LOG_ERROR\r
- * - #IOT_LOG_WARN <br>\r
- *   @copybrief IOT_LOG_WARN\r
- * - #IOT_LOG_INFO <br>\r
- *   @copybrief IOT_LOG_INFO\r
- * - #IOT_LOG_DEBUG <br>\r
- *   @copybrief IOT_LOG_DEBUG\r
- */\r
-\r
-/**\r
- * @brief No log messages.\r
- *\r
- * Log messages with this level will be silently discarded. When @ref\r
- * LIBRARY_LOG_LEVEL is #IOT_LOG_NONE, logging is disabled and no [logging functions]\r
- * (@ref logging_functions) can be called.\r
- */\r
-#define IOT_LOG_NONE     0\r
-\r
-/**\r
- * @brief Only critical, unrecoverable errors.\r
- *\r
- * Log messages with this level will be printed when a library encounters an\r
- * error from which it cannot easily recover.\r
- */\r
-#define IOT_LOG_ERROR    1\r
-\r
-/**\r
- * @brief Message about an abnormal but recoverable event.\r
- *\r
- * Log messages with this level will be printed when a library encounters an\r
- * abnormal event that may be indicative of an error. Libraries should continue\r
- * execution after logging a warning.\r
- */\r
-#define IOT_LOG_WARN     2\r
-\r
-/**\r
- * @brief A helpful, informational message.\r
- *\r
- * Log messages with this level may indicate the normal status of a library\r
- * function. They should be used to track how far a program has executed.\r
- */\r
-#define IOT_LOG_INFO     3\r
-\r
-/**\r
- * @brief Detailed and excessive debug information.\r
- *\r
- * Log messages with this level are intended for developers. They may contain\r
- * excessive information such as internal variables, buffers, or other specific\r
- * information.\r
- */\r
-#define IOT_LOG_DEBUG    4\r
-\r
-/**\r
- * @paramstructs{logging,logging}\r
- */\r
-\r
-/**\r
- * @ingroup logging_datatypes_paramstructs\r
- * @brief Log message configuration struct.\r
- *\r
- * @paramfor @ref logging_function_log, @ref logging_function_generic\r
- *\r
- * By default, log messages print the library name, log level, and a timestring.\r
- * This struct can be passed to @ref logging_function_generic to disable one of\r
- * the above components in the log message.\r
- *\r
- * <b>Example:</b>\r
- *\r
- * @code{c}\r
- * IotLog_Generic( IOT_LOG_DEBUG, "SAMPLE", IOT_LOG_DEBUG, NULL, "Hello world!" );\r
- * @endcode\r
- * The code above prints the following message:\r
- * @code\r
- * [DEBUG][SAMPLE][2018-01-01 12:00:00] Hello world!\r
- * @endcode\r
- *\r
- * The timestring can be disabled as follows:\r
- * @code\r
- * IotLogConfig_t logConfig = { .hideLogLevel = false, .hideLibraryName = false, .hideTimestring = true};\r
- * IotLog_Generic( IOT_LOG_DEBUG, "SAMPLE", IOT_LOG_DEBUG, &logConfig, "Hello world!" );\r
- * @endcode\r
- * The resulting log message will be:\r
- * @code\r
- * [DEBUG][SAMPLE] Hello world!\r
- * @endcode\r
- */\r
-typedef struct IotLogConfig\r
-{\r
-    bool hideLogLevel;    /**< @brief Don't print the log level string for this message. */\r
-    bool hideLibraryName; /**< @brief Don't print the library name for this message. */\r
-    bool hideTimestring;  /**< @brief Don't print the timestring for this message. */\r
-} IotLogConfig_t;\r
-\r
-/**\r
- * @functionspage{logging,logging library}\r
- *\r
- * - @functionname{logging_function_log}\r
- * - @functionname{logging_function_printbuffer}\r
- * - @functionname{logging_function_generic}\r
- * - @functionname{logging_function_genericprintbuffer}\r
- */\r
-\r
-/**\r
- * @functionpage{IotLog_Generic,logging,generic}\r
- * @functionpage{IotLog_PrintBuffer,logging,genericprintbuffer}\r
- */\r
-\r
-/**\r
- * @brief Generic logging function that prints a single message.\r
- *\r
- * This function is the generic logging function shared across all libraries.\r
- * The library-specific logging function @ref logging_function_log is implemented\r
- * using this function. Like @ref logging_function_log, this function is only\r
- * available when @ref LIBRARY_LOG_LEVEL is #IOT_LOG_NONE.\r
- *\r
- * In most cases, the library-specific logging function @ref logging_function_log\r
- * should be called instead of this function.\r
- *\r
- * @param[in] libraryLogSetting The log level setting of the library, used to\r
- * determine if the log message should be printed. Must be one of the @ref\r
- * logging_constants_levels.\r
- * @param[in] pLibraryName The library name to print. See @ref LIBRARY_LOG_NAME.\r
- * @param[in] messageLevel The log level of the this message. See @ref LIBRARY_LOG_LEVEL.\r
- * @param[in] pLogConfig Pointer to a #IotLogConfig_t. Optional; pass `NULL` to ignore.\r
- * @param[in] pFormat Format string for the log message.\r
- * @param[in] ... Arguments for format specification.\r
- *\r
- * @return No return value. On errors, it prints nothing.\r
- */\r
-/* @[declare_logging_generic] */\r
-void IotLog_Generic( int libraryLogSetting,\r
-                     const char * const pLibraryName,\r
-                     int messageLevel,\r
-                     const IotLogConfig_t * const pLogConfig,\r
-                     const char * const pFormat,\r
-                     ... );\r
-/* @[declare_logging_generic] */\r
-\r
-/**\r
- * @brief Generic function to log the contents of a buffer as bytes.\r
- *\r
- * This function is the generic buffer logging function shared across all libraries.\r
- * The library-specific buffer logging function @ref logging_function_printbuffer is\r
- * implemented using this function. Like @ref logging_function_printbuffer, this\r
- * function is only available when @ref LIBRARY_LOG_LEVEL is #IOT_LOG_DEBUG.\r
- *\r
- * In most cases, the library-specific buffer logging function @ref\r
- * logging_function_printbuffer should be called instead of this function.\r
- *\r
- * @param[in] pLibraryName The library name to print with the log. See @ref LIBRARY_LOG_NAME.\r
- * @param[in] pHeader A message to print before printing the buffer.\r
- * @param[in] pBuffer The buffer to print.\r
- * @param[in] bufferSize The number of bytes in `pBuffer` to print.\r
- *\r
- * @return No return value. On errors, it prints nothing.\r
- *\r
- * @note To conserve memory, this function only allocates enough memory for a\r
- * single line of output. Therefore, in multithreaded systems, its output may\r
- * appear "fragmented" if other threads are logging simultaneously.\r
- */\r
-/* @[declare_logging_genericprintbuffer] */\r
-void IotLog_GenericPrintBuffer( const char * const pLibraryName,\r
-                                const char * const pHeader,\r
-                                const uint8_t * const pBuffer,\r
-                                size_t bufferSize );\r
-/* @[declare_logging_genericprintbuffer] */\r
-\r
-#endif /* ifndef IOT_LOGGING_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/private/iot_static_memory.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/private/iot_static_memory.h
deleted file mode 100644 (file)
index 76fe2b3..0000000
+++ /dev/null
@@ -1,250 +0,0 @@
-/*\r
- * Amazon FreeRTOS Common V1.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_static_memory.h\r
- * @brief Common functions for managing static buffers. Only used when\r
- * @ref IOT_STATIC_MEMORY_ONLY is `1`.\r
- */\r
-\r
-/* The config header is always included first. */\r
-#include "iot_config.h"\r
-\r
-/* The functions in this file should only exist in static memory only mode, hence\r
- * the check for IOT_STATIC_MEMORY_ONLY in the double inclusion guard. */\r
-#if !defined( IOT_STATIC_MEMORY_H_ ) && ( IOT_STATIC_MEMORY_ONLY == 1 )\r
-#define IOT_STATIC_MEMORY_H_\r
-\r
-/* Standard includes. */\r
-#include <stdbool.h>\r
-#include <stddef.h>\r
-#include <stdint.h>\r
-\r
-/**\r
- * @functionspage{static_memory,static memory component}\r
- * - @functionname{static_memory_function_init}\r
- * - @functionname{static_memory_function_cleanup}\r
- * - @functionname{static_memory_function_findfree}\r
- * - @functionname{static_memory_function_returninuse}\r
- * - @functionname{static_memory_function_messagebuffersize}\r
- * - @functionname{static_memory_function_mallocmessagebuffer}\r
- * - @functionname{static_memory_function_freemessagebuffer}\r
- */\r
-\r
-/*----------------------- Initialization and cleanup ------------------------*/\r
-\r
-/**\r
- * @functionpage{IotStaticMemory_Init,static_memory,init}\r
- * @functionpage{IotStaticMemory_Cleanup,static_memory,cleanup}\r
- */\r
-\r
-/**\r
- * @brief One-time initialization function for static memory.\r
- *\r
- * This function performs internal setup of static memory. <b>It must be called\r
- * once (and only once) before calling any other static memory function.</b>\r
- * Calling this function more than once without first calling\r
- * @ref static_memory_function_cleanup may result in a crash.\r
- *\r
- * @return `true` if initialization succeeded; `false` otherwise.\r
- *\r
- * @attention This function is called by `IotSdk_Init` and does not need to be\r
- * called by itself.\r
- *\r
- * @warning No thread-safety guarantees are provided for this function.\r
- *\r
- * @see static_memory_function_cleanup\r
- */\r
-/* @[declare_static_memory_init] */\r
-bool IotStaticMemory_Init( void );\r
-/* @[declare_static_memory_init] */\r
-\r
-/**\r
- * @brief One-time deinitialization function for static memory.\r
- *\r
- * This function frees resources taken in @ref static_memory_function_init.\r
- * It should be called after to clean up static memory. After this function\r
- * returns, @ref static_memory_function_init must be called again before\r
- * calling any other static memory function.\r
- *\r
- * @attention This function is called by `IotSdk_Cleanup` and does not need\r
- * to be called by itself.\r
- *\r
- * @warning No thread-safety guarantees are provided for this function.\r
- *\r
- * @see static_memory_function_init\r
- */\r
-/* @[declare_static_memory_cleanup] */\r
-void IotStaticMemory_Cleanup( void );\r
-/* @[declare_static_memory_cleanup] */\r
-\r
-/*------------------------- Buffer allocation and free ----------------------*/\r
-\r
-/**\r
- * @functionpage{IotStaticMemory_FindFree,static_memory,findfree}\r
- * @functionpage{IotStaticMemory_ReturnInUse,static_memory,returninuse}\r
- */\r
-\r
-/**\r
- * @brief Find a free buffer using the "in-use" flags.\r
- *\r
- * If a free buffer is found, this function marks the buffer in-use. This function\r
- * is common to the static memory implementation.\r
- *\r
- * @param[in] pInUse The "in-use" flags to search.\r
- * @param[in] limit How many flags to check, i.e. the size of `pInUse`.\r
- *\r
- * @return The index of a free buffer; `-1` if no free buffers are available.\r
- *\r
- * <b>Example</b>:\r
- * @code{c}\r
- * // To use this function, first declare two arrays. One provides the statically-allocated\r
- * // objects, the other provides flags to determine which objects are in-use.\r
- * #define NUMBER_OF_OBJECTS    ...\r
- * #define OBJECT_SIZE          ...\r
- * static bool _pInUseObjects[ NUMBER_OF_OBJECTS ] = { 0 };\r
- * static uint8_t _pObjects[ NUMBER_OF_OBJECTS ][ OBJECT_SIZE ] = { { 0 } }; // Placeholder for objects.\r
- *\r
- * // The function to statically allocate objects. Must have the same signature\r
- * // as malloc().\r
- * void * Iot_MallocObject( size_t size )\r
- * {\r
- *     int32_t freeIndex = -1;\r
- *     void * pNewObject = NULL;\r
- *\r
- *     // Check that sizes match. \r
- *     if( size != OBJECT_SIZE )\r
- *     {\r
- *         // Get the index of a free object.\r
- *         freeIndex = IotStaticMemory_FindFree( _pInUseMessageBuffers,\r
- *                                               IOT_MESSAGE_BUFFERS );\r
- *\r
- *         if( freeIndex != -1 )\r
- *         {\r
- *             pNewBuffer = &( _pMessageBuffers[ freeIndex ][ 0 ] );\r
- *         }\r
- *     }\r
- *\r
- *     return pNewBuffer;\r
- * }\r
- * @endcode\r
- */\r
-/* @[declare_static_memory_findfree] */\r
-int32_t IotStaticMemory_FindFree( bool * pInUse,\r
-                                  size_t limit );\r
-/* @[declare_static_memory_findfree] */\r
-\r
-/**\r
- * @brief Return an "in-use" buffer.\r
- *\r
- * This function is common to the static memory implementation.\r
- *\r
- * @param[in] ptr Pointer to the buffer to return.\r
- * @param[in] pPool The pool of buffers that the in-use buffer was allocated from.\r
- * @param[in] pInUse The "in-use" flags for pPool.\r
- * @param[in] limit How many buffers (and flags) to check while searching for ptr.\r
- * @param[in] elementSize The size of a single element in pPool.\r
- *\r
- * <b>Example</b>:\r
- * @code{c}\r
- * // To use this function, first declare two arrays. One provides the statically-allocated\r
- * // objects, the other provides flags to determine which objects are in-use.\r
- * #define NUMBER_OF_OBJECTS    ...\r
- * #define OBJECT_SIZE          ...\r
- * static bool _pInUseObjects[ NUMBER_OF_OBJECTS ] = { 0 };\r
- * static uint8_t _pObjects[ NUMBER_OF_OBJECTS ][ OBJECT_SIZE ] = { { 0 } }; // Placeholder for objects.\r
- *\r
- * // The function to free statically-allocated objects. Must have the same signature\r
- * // as free().\r
- * void Iot_FreeObject( void * ptr )\r
- * {\r
- *     IotStaticMemory_ReturnInUse( ptr,\r
- *                                 _pObjects,\r
- *                                 _pInUseObjects,\r
- *                                 NUMBER_OF_OBJECTS,\r
- *                                 OBJECT_SIZE );\r
- * }\r
- * @endcode\r
- */\r
-/* @[declare_static_memory_returninuse] */\r
-void IotStaticMemory_ReturnInUse( void * ptr,\r
-                                  void * pPool,\r
-                                  bool * pInUse,\r
-                                  size_t limit,\r
-                                  size_t elementSize );\r
-/* @[declare_static_memory_returninuse] */\r
-\r
-/*------------------------ Message buffer management ------------------------*/\r
-\r
-/**\r
- * @functionpage{Iot_MessageBufferSize,static_memory,messagebuffersize}\r
- * @functionpage{Iot_MallocMessageBuffer,static_memory,mallocmessagebuffer}\r
- * @functionpage{Iot_FreeMessageBuffer,static_memory,freemessagebuffer}\r
- */\r
-\r
-/**\r
- * @brief Get the fixed size of a message buffer.\r
- *\r
- * The size of the message buffers are known at compile time, but it is a [constant]\r
- * (@ref IOT_MESSAGE_BUFFER_SIZE) that may not be visible to all source files.\r
- * This function allows other source files to know the size of a message buffer.\r
- *\r
- * @return The size, in bytes, of a single message buffer.\r
- */\r
-/* @[declare_static_memory_messagebuffersize] */\r
-size_t Iot_MessageBufferSize( void );\r
-/* @[declare_static_memory_messagebuffersize] */\r
-\r
-/**\r
- * @brief Get an empty message buffer.\r
- *\r
- * This function is the analog of [malloc]\r
- * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html)\r
- * for message buffers.\r
- *\r
- * @param[in] size Requested size for a message buffer.\r
- *\r
- * @return Pointer to the start of a message buffer. If the `size` argument is larger\r
- * than the [fixed size of a message buffer](@ref IOT_MESSAGE_BUFFER_SIZE)\r
- * or no message buffers are available, `NULL` is returned.\r
- */\r
-/* @[declare_static_memory_mallocmessagebuffer] */\r
-void * Iot_MallocMessageBuffer( size_t size );\r
-/* @[declare_static_memory_mallocmessagebuffer] */\r
-\r
-/**\r
- * @brief Free an in-use message buffer.\r
- *\r
- * This function is the analog of [free]\r
- * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html)\r
- * for message buffers.\r
- *\r
- * @param[in] ptr Pointer to the message buffer to free.\r
- */\r
-/* @[declare_static_memory_freemessagebuffer] */\r
-void Iot_FreeMessageBuffer( void * ptr );\r
-/* @[declare_static_memory_freemessagebuffer] */\r
\r
-#endif /* if !defined( IOT_STATIC_MEMORY_H_ ) && ( IOT_STATIC_MEMORY_ONLY == 1 ) */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/private/iot_taskpool_internal.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/private/iot_taskpool_internal.h
deleted file mode 100644 (file)
index 3779ff9..0000000
+++ /dev/null
@@ -1,293 +0,0 @@
-/*\r
- * Amazon FreeRTOS Common V1.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_taskpool_internal.h\r
- * @brief Internal header of task pool library. This header should not be included in\r
- * typical application code.\r
- */\r
-\r
-#ifndef IOT_TASKPOOL_INTERNAL_H_\r
-#define IOT_TASKPOOL_INTERNAL_H_\r
-\r
-/* The config header is always included first. */\r
-#include "iot_config.h"\r
-\r
-/* Task pool include. */\r
-#include "private/iot_error.h"\r
-#include "iot_taskpool.h"\r
-\r
-/* FreeRTOS includes. */\r
-#include "FreeRTOS.h"\r
-#include "semphr.h"\r
-#include "timers.h"\r
-\r
-/* Establish a few convenience macros to handle errors in a standard way. */\r
-\r
-/**\r
- * @brief Every public API return an enumeration value with an undelying value of 0 in case of success.\r
- */\r
-#define TASKPOOL_SUCCEEDED( x )               ( ( x ) == IOT_TASKPOOL_SUCCESS )\r
-\r
-/**\r
- * @brief Every public API returns an enumeration value with an undelying value different than 0 in case of success.\r
- */\r
-#define TASKPOOL_FAILED( x )                  ( ( x ) != IOT_TASKPOOL_SUCCESS )\r
-\r
-/**\r
- * @brief Jump to the cleanup area.\r
- */\r
-#define TASKPOOL_GOTO_CLEANUP()               IOT_GOTO_CLEANUP()\r
-\r
-/**\r
- * @brief Declare the storage for the error status variable.\r
- */\r
-#define  TASKPOOL_FUNCTION_ENTRY( result )    IOT_FUNCTION_ENTRY( IotTaskPoolError_t, result )\r
-\r
-/**\r
- * @brief Check error and leave in case of failure.\r
- */\r
-#define TASKPOOL_ON_ERROR_GOTO_CLEANUP( expr )                           \\r
-    { if( TASKPOOL_FAILED( status = ( expr ) ) ) { IOT_GOTO_CLEANUP(); } \\r
-    }\r
-\r
-/**\r
- * @brief Exit if an argument is NULL.\r
- */\r
-#define TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( ptr )      IOT_VALIDATE_PARAMETER( IOT_TASKPOOL, ( ptr != NULL ) )\r
-\r
-/**\r
- * @brief Exit if an argument is NULL.\r
- */\r
-#define TASKPOOL_ON_ARG_ERROR_GOTO_CLEANUP( expr )    IOT_VALIDATE_PARAMETER( IOT_TASKPOOL, ( ( expr ) == false ) )\r
-\r
-/**\r
- * @brief Set error and leave.\r
- */\r
-#define TASKPOOL_SET_AND_GOTO_CLEANUP( expr )         IOT_SET_AND_GOTO_CLEANUP( expr )\r
-\r
-/**\r
- * @brief Initialize error and declare start of cleanup area.\r
- */\r
-#define TASKPOOL_FUNCTION_CLEANUP()                   IOT_FUNCTION_CLEANUP_BEGIN()\r
-\r
-/**\r
- * @brief Initialize error and declare end of cleanup area.\r
- */\r
-#define TASKPOOL_FUNCTION_CLEANUP_END()               IOT_FUNCTION_CLEANUP_END()\r
-\r
-/**\r
- * @brief Create an empty cleanup area.\r
- */\r
-#define TASKPOOL_NO_FUNCTION_CLEANUP()                IOT_FUNCTION_EXIT_NO_CLEANUP()\r
-\r
-/**\r
- * @brief Does not create a cleanup area.\r
- */\r
-#define TASKPOOL_NO_FUNCTION_CLEANUP_NOLABEL()        return status\r
-\r
-/**\r
- * @def IotTaskPool_Assert( expression )\r
- * @brief Assertion macro for the Task pool library.\r
- *\r
- * Set @ref IOT_TASKPOOL_ENABLE_ASSERTS to `1` to enable assertions in the Task pool\r
- * library.\r
- *\r
- * @param[in] expression Expression to be evaluated.\r
- */\r
-#if IOT_TASKPOOL_ENABLE_ASSERTS == 1\r
-    #ifndef IotTaskPool_Assert\r
-        #include <assert.h>\r
-        #define IotTaskPool_Assert( expression )    assert( expression )\r
-    #endif\r
-#else\r
-    #define IotTaskPool_Assert( expression )\r
-#endif\r
-\r
-/* Configure logs for TASKPOOL functions. */\r
-#ifdef IOT_LOG_LEVEL_TASKPOOL\r
-    #define LIBRARY_LOG_LEVEL        IOT_LOG_LEVEL_TASKPOOL\r
-#else\r
-    #ifdef IOT_LOG_LEVEL_GLOBAL\r
-        #define LIBRARY_LOG_LEVEL    IOT_LOG_LEVEL_GLOBAL\r
-    #else\r
-        #define LIBRARY_LOG_LEVEL    IOT_LOG_NONE\r
-    #endif\r
-#endif\r
-\r
-#define LIBRARY_LOG_NAME    ( "TASKPOOL" )\r
-#include "iot_logging_setup.h"\r
-\r
-/*\r
- * Provide default values for undefined memory allocation functions based on\r
- * the usage of dynamic memory allocation.\r
- */\r
-#if IOT_STATIC_MEMORY_ONLY == 1\r
-    #include "private/iot_static_memory.h"\r
-\r
-/**\r
- * @brief Allocate an #_taskPool_t. This function should have the\r
- * same signature as [malloc].\r
- */\r
-    void * IotTaskPool_MallocTaskPool( size_t size );\r
-\r
-/**\r
- * @brief Free an #_taskPool_t. This function should have the\r
- * same signature as [malloc].\r
- */\r
-    void IotTaskPool_FreeTaskPool( void * ptr );\r
-\r
-/**\r
- * @brief Allocate an #IotTaskPoolJob_t. This function should have the\r
- * same signature as [malloc].\r
- */\r
-    void * IotTaskPool_MallocJob( size_t size );\r
-\r
-/**\r
- * @brief Free an #IotTaskPoolJob_t. This function should have the same\r
- * same signature as [malloc].\r
- * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html).\r
- */\r
-    void IotTaskPool_FreeJob( void * ptr );\r
-\r
-/**\r
- * @brief Allocate an #_taskPoolTimerEvent_t. This function should have the\r
- * same signature as [malloc].\r
- */\r
-    void * IotTaskPool_MallocTimerEvent( size_t size );\r
-\r
-/**\r
- * @brief Free an #_taskPoolTimerEvent_t. This function should have the\r
- * same signature as[ free ].\r
- */\r
-    void IotTaskPool_FreeTimerEvent( void * ptr );\r
-\r
-#else /* if IOT_STATIC_MEMORY_ONLY == 1 */\r
-    #include <stdlib.h>\r
-\r
-    #ifndef IotTaskPool_MallocTaskPool\r
-        #define IotTaskPool_MallocTaskPool    malloc\r
-    #endif\r
-\r
-    #ifndef IotTaskPool_FreeTaskPool\r
-        #define IotTaskPool_FreeTaskPool    free\r
-    #endif\r
-\r
-    #ifndef IotTaskPool_MallocJob\r
-        #define IotTaskPool_MallocJob    malloc\r
-    #endif\r
-\r
-    #ifndef IotTaskPool_FreeJob\r
-        #define IotTaskPool_FreeJob    free\r
-    #endif\r
-\r
-    #ifndef IotTaskPool_MallocTimerEvent\r
-        #define IotTaskPool_MallocTimerEvent    malloc\r
-    #endif\r
-\r
-    #ifndef IotTaskPool_FreeTimerEvent\r
-        #define IotTaskPool_FreeTimerEvent    free\r
-    #endif\r
-\r
-#endif /* if IOT_STATIC_MEMORY_ONLY == 1 */\r
-\r
-/* ---------------------------------------------------------------------------------------------- */\r
-\r
-/**\r
- * @cond DOXYGEN_IGNORE\r
- * Doxygen should ignore this section.\r
- *\r
- * A macros to manage task pool memory allocation.\r
- */\r
-#define IOT_TASK_POOL_INTERNAL_STATIC    ( ( uint32_t ) 0x00000001 )      /* Flag to mark a job as user-allocated. */\r
-/** @endcond */\r
-\r
-/**\r
- * @brief Task pool jobs cache.\r
- *\r
- * @warning This is a system-level data type that should not be modified or used directly in any application.\r
- * @warning This is a system-level data type that can and will change across different versions of the platform, with no regards for backward compatibility.\r
- *\r
- */\r
-typedef struct _taskPoolCache\r
-{\r
-    IotListDouble_t freeList; /**< @brief A list ot hold cached jobs. */\r
-\r
-    uint32_t freeCount;       /**< @brief A counter to track the number of jobs in the cache. */\r
-} _taskPoolCache_t;\r
-\r
-/**\r
- * @brief The task pool data structure keeps track of the internal state and the signals for the dispatcher threads.\r
- * The task pool is a thread safe data structure.\r
- *\r
- * @warning This is a system-level data type that should not be modified or used directly in any application.\r
- * @warning This is a system-level data type that can and will change across different versions of the platform, with no regards for backward compatibility.\r
- *\r
- */\r
-typedef struct _taskPool\r
-{\r
-    IotDeQueue_t dispatchQueue;              /**< @brief The queue for the jobs waiting to be executed. */\r
-    IotListDouble_t timerEventsList;         /**< @brief The timeouts queue for all deferred jobs waiting to be executed. */\r
-    _taskPoolCache_t jobsCache;              /**< @brief A cache to re-use jobs in order to limit memory allocations. */\r
-    uint32_t activeThreads;                  /**< @brief The number of threads in the task pool at any given time. */\r
-    int32_t priority;                        /**< @brief The priority for all task pool threads. */\r
-    SemaphoreHandle_t dispatchSignal;        /**< @brief The synchronization object on which threads are waiting for incoming jobs. */\r
-    StaticSemaphore_t dispatchSignalBuffer;  /**< @brief The semaphore buffer. */\r
-    StaticSemaphore_t startStopSignalBuffer; /**< @brief The semaphore buffer. */\r
-    TimerHandle_t timer;                     /**< @brief The timer for deferred jobs. */\r
-    StaticTimer_t timerBuffer;               /**< @brief The timer buffer. */\r
-    bool running;                            /**< @brief A flag to track whether the task pool is operational or should shut down. */\r
-} _taskPool_t;\r
-\r
-/**\r
- * @brief The job data structure keeps track of the user callback and context, as well as the status of the job.\r
- *\r
- * @warning This is a system-level data type that should not be modified or used directly in any application.\r
- * @warning This is a system-level data type that can and will change across different versions of the platform, with no regards for backward compatibility.\r
- *\r
- */\r
-typedef struct _taskPoolJob\r
-{\r
-    IotLink_t link;                    /**< @brief The link to insert the job in the dispatch queue. */\r
-    IotTaskPoolRoutine_t userCallback; /**< @brief The user provided callback. */\r
-    void * pUserContext;               /**< @brief The user provided context. */\r
-    uint32_t flags;                    /**< @brief Internal flags. */\r
-    IotTaskPoolJobStatus_t status;     /**< @brief The status for the job. */\r
-} _taskPoolJob_t;\r
-\r
-/**\r
- * @brief Represents an operation that is subject to a timer.\r
- *\r
- * These events are queued per MQTT connection. They are sorted by their\r
- * expiration time.\r
- */\r
-typedef struct _taskPoolTimerEvent\r
-{\r
-    IotLink_t link;            /**< @brief List link member. */\r
-    TickType_t expirationTime; /**< @brief When this event should be processed. */\r
-    IotTaskPoolJob_t job;      /**< @brief The task pool job associated with this event. */\r
-} _taskPoolTimerEvent_t;\r
-\r
-#endif /* ifndef IOT_TASKPOOL_INTERNAL_H_ */
\ No newline at end of file
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/types/iot_taskpool_types.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/types/iot_taskpool_types.h
deleted file mode 100644 (file)
index ce80167..0000000
+++ /dev/null
@@ -1,362 +0,0 @@
-/*\r
- * Amazon FreeRTOS Common V1.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_taskpool_types.h\r
- * @brief Types of the task pool.\r
- */\r
-\r
-#ifndef IOT_TASKPOOL_TYPES_H_\r
-#define IOT_TASKPOOL_TYPES_H_\r
-\r
-/* The config header is always included first. */\r
-#include "iot_config.h"\r
-\r
-/* Standard includes. */\r
-#include <stdbool.h>\r
-#include <stdint.h>\r
-\r
-/* Platform types includes. */\r
-#include "types/iot_platform_types.h"\r
-\r
-/* Linear containers (lists and queues) include. */\r
-#include "iot_linear_containers.h"\r
-\r
-/*-------------------------- Task pool enumerated types --------------------------*/\r
-\r
-/**\r
- * @ingroup taskpool_datatypes_enums\r
- * @brief Return codes of [task pool functions](@ref taskpool_functions).\r
- */\r
-typedef enum IotTaskPoolError\r
-{\r
-    /**\r
-     * @brief Task pool operation completed successfully.\r
-     *\r
-     * Functions that may return this value:\r
-     * - @ref taskpool_function_createsystemtaskpool\r
-     * - @ref taskpool_function_create\r
-     * - @ref taskpool_function_destroy\r
-     * - @ref taskpool_function_setmaxthreads\r
-     * - @ref taskpool_function_createjob\r
-     * - @ref taskpool_function_createrecyclablejob\r
-     * - @ref taskpool_function_destroyrecyclablejob\r
-     * - @ref taskpool_function_recyclejob\r
-     * - @ref taskpool_function_schedule\r
-     * - @ref taskpool_function_scheduledeferred\r
-     * - @ref taskpool_function_getstatus\r
-     * - @ref taskpool_function_trycancel\r
-     *\r
-     */\r
-    IOT_TASKPOOL_SUCCESS = 0,\r
-\r
-    /**\r
-     * @brief Task pool operation failed because at least one parameter is invalid.\r
-     *\r
-     * Functions that may return this value:\r
-     * - @ref taskpool_function_createsystemtaskpool\r
-     * - @ref taskpool_function_create\r
-     * - @ref taskpool_function_destroy\r
-     * - @ref taskpool_function_setmaxthreads\r
-     * - @ref taskpool_function_createjob\r
-     * - @ref taskpool_function_createrecyclablejob\r
-     * - @ref taskpool_function_destroyrecyclablejob\r
-     * - @ref taskpool_function_recyclejob\r
-     * - @ref taskpool_function_schedule\r
-     * - @ref taskpool_function_scheduledeferred\r
-     * - @ref taskpool_function_getstatus\r
-     * - @ref taskpool_function_trycancel\r
-     *\r
-     */\r
-    IOT_TASKPOOL_BAD_PARAMETER,\r
-\r
-    /**\r
-     * @brief Task pool operation failed because it is illegal.\r
-     *\r
-     * Functions that may return this value:\r
-     * - @ref taskpool_function_createjob\r
-     * - @ref taskpool_function_createrecyclablejob\r
-     * - @ref taskpool_function_destroyrecyclablejob\r
-     * - @ref taskpool_function_recyclejob\r
-     * - @ref taskpool_function_schedule\r
-     * - @ref taskpool_function_scheduledeferred\r
-     * - @ref taskpool_function_trycancel\r
-     *\r
-     */\r
-    IOT_TASKPOOL_ILLEGAL_OPERATION,\r
-\r
-    /**\r
-     * @brief Task pool operation failed because allocating memory failed.\r
-     *\r
-     * Functions that may return this value:\r
-     * - @ref taskpool_function_createsystemtaskpool\r
-     * - @ref taskpool_function_create\r
-     * - @ref taskpool_function_setmaxthreads\r
-     * - @ref taskpool_function_createrecyclablejob\r
-     * - @ref taskpool_function_scheduledeferred\r
-     * - @ref taskpool_function_getstatus\r
-     *\r
-     */\r
-    IOT_TASKPOOL_NO_MEMORY,\r
-\r
-    /**\r
-     * @brief Task pool operation failed because of an invalid parameter.\r
-     *\r
-     * Functions that may return this value:\r
-     * - @ref taskpool_function_setmaxthreads\r
-     * - @ref taskpool_function_createrecyclablejob\r
-     * - @ref taskpool_function_destroyrecyclablejob\r
-     * - @ref taskpool_function_recyclejob\r
-     * - @ref taskpool_function_schedule\r
-     * - @ref taskpool_function_scheduledeferred\r
-     * - @ref taskpool_function_getstatus\r
-     * - @ref taskpool_function_trycancel\r
-     *\r
-     */\r
-    IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS,\r
-\r
-    /**\r
-     * @brief Task pool cancellation failed.\r
-     *\r
-     * Functions that may return this value:\r
-     * - @ref taskpool_function_trycancel\r
-     *\r
-     */\r
-    IOT_TASKPOOL_CANCEL_FAILED,\r
-} IotTaskPoolError_t;\r
-\r
-/**\r
- * @enums{taskpool,Task pool library}\r
- */\r
-\r
-/**\r
- * @ingroup taskpool_datatypes_enums\r
- * @brief Status codes of [task pool Job](@ref IotTaskPoolJob_t).\r
- *\r
- */\r
-typedef enum IotTaskPoolJobStatus\r
-{\r
-    /**\r
-     * @brief Job is ready to be scheduled.\r
-     *\r
-     */\r
-    IOT_TASKPOOL_STATUS_READY = 0,\r
-\r
-    /**\r
-     * @brief Job has been queued for execution.\r
-     *\r
-     */\r
-    IOT_TASKPOOL_STATUS_SCHEDULED,\r
-\r
-    /**\r
-     * @brief Job has been scheduled for deferred execution.\r
-     *\r
-     */\r
-    IOT_TASKPOOL_STATUS_DEFERRED,\r
-\r
-    /**\r
-     * @brief Job is executing.\r
-     *\r
-     */\r
-    IOT_TASKPOOL_STATUS_COMPLETED,\r
-\r
-    /**\r
-     * @brief Job has been canceled before executing.\r
-     *\r
-     */\r
-    IOT_TASKPOOL_STATUS_CANCELED,\r
-\r
-    /**\r
-     * @brief Job status is undefined.\r
-     *\r
-     */\r
-    IOT_TASKPOOL_STATUS_UNDEFINED,\r
-} IotTaskPoolJobStatus_t;\r
-\r
-/*------------------------- Task pool types and handles --------------------------*/\r
-\r
-/**\r
- * @ingroup taskpool_datatypes_handles\r
- * @brief Opaque handle of a Task Pool instance.\r
- *\r
- * This type identifies a Task Pool instance, which is valid after a successful call\r
- * to @ref taskpool_function_createsystemtaskpool or @ref taskpool_function_create. A\r
- *  variable of this type is passed as the first\r
- * argument to [Task Pool library functions](@ref taskpool_functions) to identify which\r
- * task pool that function acts on.\r
- *\r
- * A call to @ref taskpool_function_destroy makes a task pool handle invalid. Once\r
- * @ref taskpool_function_destroy returns, the task handle should no longer\r
- * be used.\r
- *\r
- * @initializer{IotTaskPool_t,IOT_TASKPOOL_INITIALIZER}\r
- */\r
-typedef struct _taskPool * IotTaskPool_t;\r
-\r
-/**\r
- * @ingroup taskpool_datatypes_structs\r
- * @brief The job storage data structure provides the storage for a statically allocated Task Pool Job instance.\r
- *\r
- * @warning This is a system-level data type that should not be modified or used directly in any application.\r
- * @warning This is a system-level data type that can and will change across different versions of the platform, with no regards for backward compatibility.\r
- *\r
- */\r
-typedef struct IotTaskPoolJobStorage\r
-{\r
-    IotLink_t link;                 /**< @brief Placeholder. */\r
-    void * dummy2;                  /**< @brief Placeholder. */\r
-    void * dummy3;                  /**< @brief Placeholder. */\r
-    uint32_t dummy4;                /**< @brief Placeholder. */\r
-    IotTaskPoolJobStatus_t status;  /**< @brief Placeholder. */\r
-} IotTaskPoolJobStorage_t;\r
-\r
-/**\r
- * @ingroup taskpool_datatypes_handles\r
- * @brief Opaque handle of a Task Pool Job.\r
- *\r
- * This type identifies a Task Pool Job instance, which is valid after a successful call\r
- * to @ref taskpool_function_createjob or @ref taskpool_function_createrecyclablejob.\r
- *\r
- * A call to @ref taskpool_function_recyclejob or @ref taskpool_function_destroyrecyclablejob makes a\r
- * task pool job handle invalid. Once @ref taskpool_function_recyclejob or\r
- * @ref taskpool_function_destroyrecyclablejob returns, the task job handle should no longer be used.\r
- *\r
- * @initializer{IotTaskPoolJob_t,IOT_TASKPOOL_JOB_INITIALIZER}\r
- *\r
- */\r
-typedef struct _taskPoolJob * IotTaskPoolJob_t;\r
-\r
-/*------------------------- Task pool parameter structs --------------------------*/\r
-\r
-/**\r
- * @ingroup taskpool_datatypes_functionpointers\r
- * @brief Callback type for a user callback.\r
- *\r
- * This type identifies the user callback signature to execute a task pool job. This callback will be invoked\r
- * by the task pool threads with the `pUserContext` parameter, as specified by the user when\r
- * calling @ref IotTaskPool_Schedule.\r
- *\r
- */\r
-typedef void ( * IotTaskPoolRoutine_t )( IotTaskPool_t pTaskPool,\r
-                                         IotTaskPoolJob_t pJob,\r
-                                         void * pUserContext );\r
-\r
-/**\r
- * @ingroup taskpool_datatypes_paramstructs\r
- * @brief Initialization information to create one task pool instance.\r
- *\r
- * @paramfor  @ref taskpool_function_createsystemtaskpool @ref taskpool_function_create.\r
- *\r
- * Passed as an argument to @ref taskpool_function_create.\r
- *\r
- * @initializer{IotTaskPoolInfo_t,IOT_TASKPOOL_INFO_INITIALIZER}\r
- */\r
-typedef struct IotTaskPoolInfo\r
-{\r
-    /**\r
-     * @brief Specifies the operating parameters for a task pool.\r
-     *\r
-     * @attention #IotTaskPoolInfo_t.minThreads <b>MUST</b> be at least 1.\r
-     * #IotTaskPoolInfo_t.maxThreads <b>MUST</b> be greater or equal to #IotTaskPoolInfo_t.minThreads.\r
-     * If the minimum number of threads is same as the maximum, then the task pool will not try and grow the\r
-     * number of worker threads at run time.\r
-     */\r
-\r
-    uint32_t minThreads; /**< @brief Minimum number of threads in a task pool. These threads will be created when the task pool is first created with @ref taskpool_function_create. */\r
-    uint32_t maxThreads; /**< @brief Maximum number of threads in a task pool. A task pool may try and grow the number of active threads up to #IotTaskPoolInfo_t.maxThreads. */\r
-    uint32_t stackSize;  /**< @brief Stack size for every task pool thread. The stack size for each thread is fixed after the task pool is created and cannot be changed. */\r
-    int32_t priority;    /**< @brief priority for every task pool thread. The priority for each thread is fixed after the task pool is created and cannot be changed. */\r
-} IotTaskPoolInfo_t;\r
-\r
-/*------------------------- TASKPOOL defined constants --------------------------*/\r
-\r
-/**\r
- * @constantspage{taskpool,task pool library}\r
- *\r
- * @section taskpool_constants_initializers Task pool Initializers\r
- * @brief Provides default values for initializing the data types of the task pool library.\r
- *\r
- * @snippet this define_taskpool_initializers\r
- *\r
- * All user-facing data types of the task pool library can be initialized using\r
- * one of the following.\r
- *\r
- * @warning Failure to initialize a task pool data type with the appropriate initializer\r
- * may result in a runtime error!\r
- * @note The initializers may change at any time in future versions, but their\r
- * names will remain the same.\r
- *\r
- * <b>Example</b>\r
- * @code{c}\r
- *\r
- * IotTaskPool_t * pTaskPool;\r
- *\r
- * const IotTaskPoolInfo_t tpInfo = IOT_TASKPOOL_INFO_INITIALIZER_LARGE;\r
- *\r
- * IotTaskPoolError_t error = IotTaskPool_Create( &tpInfo, &pTaskPool );\r
- *\r
- * // Use the task pool\r
- * // ...\r
- *\r
- * @endcode\r
- *\r
- */\r
-/* @[define_taskpool_initializers] */\r
-/** @brief Initializer for a small #IotTaskPoolInfo_t. */\r
-#define IOT_TASKPOOL_INFO_INITIALIZER_SMALL     { .minThreads = 1, .maxThreads = 1, .stackSize = IOT_THREAD_DEFAULT_STACK_SIZE, .priority = IOT_THREAD_DEFAULT_PRIORITY }\r
-/** @brief Initializer for a medium #IotTaskPoolInfo_t. */\r
-#define IOT_TASKPOOL_INFO_INITIALIZER_MEDIUM    { .minThreads = 1, .maxThreads = 2, .stackSize = IOT_THREAD_DEFAULT_STACK_SIZE, .priority = IOT_THREAD_DEFAULT_PRIORITY }\r
-/** @brief Initializer for a large #IotTaskPoolInfo_t. */\r
-#define IOT_TASKPOOL_INFO_INITIALIZER_LARGE     { .minThreads = 2, .maxThreads = 3, .stackSize = IOT_THREAD_DEFAULT_STACK_SIZE, .priority = IOT_THREAD_DEFAULT_PRIORITY }\r
-/** @brief Initializer for a very large #IotTaskPoolInfo_t. */\r
-#define IOT_TASKPOOL_INFO_INITIALIZER_XLARGE    { .minThreads = 2, .maxThreads = 4, .stackSize = IOT_THREAD_DEFAULT_STACK_SIZE, .priority = IOT_THREAD_DEFAULT_PRIORITY }\r
-/** @brief Initializer for a typical #IotTaskPoolInfo_t. */\r
-#define IOT_TASKPOOL_INFO_INITIALIZER           IOT_TASKPOOL_INFO_INITIALIZER_MEDIUM\r
-/** @brief Initializer for a #IotTaskPool_t. */\r
-#define IOT_TASKPOOL_INITIALIZER                NULL\r
-/** @brief Initializer for a #IotTaskPoolJobStorage_t. */\r
-#define IOT_TASKPOOL_JOB_STORAGE_INITIALIZER    { { NULL, NULL }, NULL, NULL, 0, IOT_TASKPOOL_STATUS_UNDEFINED }\r
-/** @brief Initializer for a #IotTaskPoolJob_t. */\r
-#define IOT_TASKPOOL_JOB_INITIALIZER            NULL\r
-/* @[define_taskpool_initializers] */\r
-\r
-/**\r
- * @brief Flag for scheduling a job to execute immediately, even if the maximum number of threads in the\r
- * task pool was reached already.\r
- *\r
- * @warning This flag may cause the task pool to create a worker to serve the job immediately, and\r
- * therefore using this flag may incur in additional memory usage and potentially fail scheduling the job.\r
- */\r
-#define IOT_TASKPOOL_JOB_HIGH_PRIORITY    ( ( uint32_t ) 0x00000001 )\r
-\r
-/**\r
- * @brief Allows the use of the handle to the system task pool.\r
- *\r
- * @warning The task pool handle is not valid unless @ref IotTaskPool_CreateSystemTaskPool is\r
- * called before the handle is used.\r
- */\r
-#define IOT_SYSTEM_TASKPOOL               ( IotTaskPool_GetSystemTaskPool() )\r
-\r
-#endif /* ifndef IOT_TASKPOOL_TYPES_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/logging/iot_logging.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/logging/iot_logging.c
deleted file mode 100644 (file)
index aac8d31..0000000
+++ /dev/null
@@ -1,454 +0,0 @@
-/*\r
- * Amazon FreeRTOS Common V1.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_logging.c\r
- * @brief Implementation of logging functions from iot_logging.h\r
- */\r
-\r
-/* The config header is always included first. */\r
-#include "iot_config.h"\r
-\r
-/* Standard includes. */\r
-#include <stdarg.h>\r
-#include <stdio.h>\r
-#include <string.h>\r
-\r
-/* Platform clock include. */\r
-#include "platform/iot_clock.h"\r
-\r
-/* Logging includes. */\r
-#include "private/iot_logging.h"\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/* This implementation assumes the following values for the log level constants.\r
- * Ensure that the values have not been modified. */\r
-#if IOT_LOG_NONE != 0\r
-    #error "IOT_LOG_NONE must be 0."\r
-#endif\r
-#if IOT_LOG_ERROR != 1\r
-    #error "IOT_LOG_ERROR must be 1."\r
-#endif\r
-#if IOT_LOG_WARN != 2\r
-    #error "IOT_LOG_WARN must be 2."\r
-#endif\r
-#if IOT_LOG_INFO != 3\r
-    #error "IOT_LOG_INFO must be 3."\r
-#endif\r
-#if IOT_LOG_DEBUG != 4\r
-    #error "IOT_LOG_DEBUG must be 4."\r
-#endif\r
-\r
-/**\r
- * @def IotLogging_Puts( message )\r
- * @brief Function the logging library uses to print a line.\r
- *\r
- * This function can be set by using a define. By default, the standard library\r
- * [puts](http://pubs.opengroup.org/onlinepubs/9699919799/functions/puts.html)\r
- * function is used.\r
- */\r
-#ifndef IotLogging_Puts\r
-    #define IotLogging_Puts    puts\r
-#endif\r
-\r
-/*\r
- * Provide default values for undefined memory allocation functions based on\r
- * the usage of dynamic memory allocation.\r
- */\r
-#if IOT_STATIC_MEMORY_ONLY == 1\r
-    /* Static memory allocation header. */\r
-    #include "private/iot_static_memory.h"\r
-\r
-/**\r
- * @brief Allocate a new logging buffer. This function must have the same\r
- * signature as [malloc](http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html).\r
- */\r
-    #ifndef IotLogging_Malloc\r
-        #define IotLogging_Malloc    Iot_MallocMessageBuffer\r
-    #endif\r
-\r
-/**\r
- * @brief Free a logging buffer. This function must have the same signature\r
- * as [free](http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
- */\r
-    #ifndef IotLogging_Free\r
-        #define IotLogging_Free    Iot_FreeMessageBuffer\r
-    #endif\r
-\r
-/**\r
- * @brief Get the size of a logging buffer. Statically-allocated buffers\r
- * should all have the same size.\r
- */\r
-    #ifndef IotLogging_StaticBufferSize\r
-        #define IotLogging_StaticBufferSize    Iot_MessageBufferSize\r
-    #endif\r
-#else /* if IOT_STATIC_MEMORY_ONLY == 1 */\r
-    #ifndef IotLogging_Malloc\r
-        #include <stdlib.h>\r
-        #define IotLogging_Malloc    malloc\r
-    #endif\r
-\r
-    #ifndef IotLogging_Free\r
-        #include <stdlib.h>\r
-        #define IotLogging_Free    free\r
-    #endif\r
-#endif /* if IOT_STATIC_MEMORY_ONLY == 1 */\r
-\r
-/**\r
- * @brief A guess of the maximum length of a timestring.\r
- *\r
- * There's no way for this logging library to know the length of a timestring\r
- * before it's generated. Therefore, the logging library will assume a maximum\r
- * length of any timestring it may get. This value should be generous enough\r
- * to accommodate the vast majority of timestrings.\r
- *\r
- * @see @ref platform_clock_function_gettimestring\r
- */\r
-#define MAX_TIMESTRING_LENGTH    ( 64 )\r
-\r
-/**\r
- * @brief The longest string in #_pLogLevelStrings (below), plus 3 to accommodate\r
- * `[]` and a null-terminator.\r
- */\r
-#define MAX_LOG_LEVEL_LENGTH     ( 8 )\r
-\r
-/**\r
- * @brief How many bytes @ref logging_function_genericprintbuffer should output on\r
- * each line.\r
- */\r
-#define BYTES_PER_LINE           ( 16 )\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/**\r
- * @brief Lookup table for log levels.\r
- *\r
- * Converts one of the @ref logging_constants_levels to a string.\r
- */\r
-static const char * const _pLogLevelStrings[ 5 ] =\r
-{\r
-    "",      /* IOT_LOG_NONE */\r
-    "ERROR", /* IOT_LOG_ERROR */\r
-    "WARN ", /* IOT_LOG_WARN */\r
-    "INFO ", /* IOT_LOG_INFO */\r
-    "DEBUG"  /* IOT_LOG_DEBUG */\r
-};\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-#if !defined( IOT_STATIC_MEMORY_ONLY ) || ( IOT_STATIC_MEMORY_ONLY == 0 )\r
-    static bool _reallocLoggingBuffer( void ** pOldBuffer,\r
-                                       size_t newSize,\r
-                                       size_t oldSize )\r
-    {\r
-        bool status = false;\r
-\r
-        /* Allocate a new, larger buffer. */\r
-        void * pNewBuffer = IotLogging_Malloc( newSize );\r
-\r
-        /* Ensure that memory allocation succeeded. */\r
-        if( pNewBuffer != NULL )\r
-        {\r
-            /* Copy the data from the old buffer to the new buffer. */\r
-            ( void ) memcpy( pNewBuffer, *pOldBuffer, oldSize );\r
-\r
-            /* Free the old buffer and update the pointer. */\r
-            IotLogging_Free( *pOldBuffer );\r
-            *pOldBuffer = pNewBuffer;\r
-\r
-            status = true;\r
-        }\r
-\r
-        return status;\r
-    }\r
-#endif /* if !defined( IOT_STATIC_MEMORY_ONLY ) || ( IOT_STATIC_MEMORY_ONLY == 0 ) */\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void IotLog_Generic( int libraryLogSetting,\r
-                     const char * const pLibraryName,\r
-                     int messageLevel,\r
-                     const IotLogConfig_t * const pLogConfig,\r
-                     const char * const pFormat,\r
-                     ... )\r
-{\r
-    int requiredMessageSize = 0;\r
-    size_t bufferSize = 0,\r
-           bufferPosition = 0, timestringLength = 0;\r
-    char * pLoggingBuffer = NULL;\r
-    va_list args;\r
-\r
-    /* If the library's log level setting is lower than the message level,\r
-     * return without doing anything. */\r
-    if( ( messageLevel == 0 ) || ( messageLevel > libraryLogSetting ) )\r
-    {\r
-        return;\r
-    }\r
-\r
-    if( ( pLogConfig == NULL ) || ( pLogConfig->hideLogLevel == false ) )\r
-    {\r
-        /* Add length of log level if requested. */\r
-        bufferSize += MAX_LOG_LEVEL_LENGTH;\r
-    }\r
-\r
-    /* Estimate the amount of buffer needed for this log message. */\r
-    if( ( pLogConfig == NULL ) || ( pLogConfig->hideLibraryName == false ) )\r
-    {\r
-        /* Add size of library name if requested. Add 2 to accommodate "[]". */\r
-        bufferSize += strlen( pLibraryName ) + 2;\r
-    }\r
-\r
-    if( ( pLogConfig == NULL ) || ( pLogConfig->hideTimestring == false ) )\r
-    {\r
-        /* Add length of timestring if requested. */\r
-        bufferSize += MAX_TIMESTRING_LENGTH;\r
-    }\r
-\r
-    /* Add 64 as an initial (arbitrary) guess for the length of the message. */\r
-    bufferSize += 64;\r
-\r
-    /* In static memory mode, check that the log message will fit in the a\r
-     * static buffer. */\r
-    #if IOT_STATIC_MEMORY_ONLY == 1\r
-        if( bufferSize >= IotLogging_StaticBufferSize() )\r
-        {\r
-            /* If the static buffers are likely too small to fit the log message,\r
-             * return. */\r
-            return;\r
-        }\r
-\r
-        /* Otherwise, update the buffer size to the size of a static buffer. */\r
-        bufferSize = IotLogging_StaticBufferSize();\r
-    #endif\r
-\r
-    /* Allocate memory for the logging buffer. */\r
-    pLoggingBuffer = ( char * ) IotLogging_Malloc( bufferSize );\r
-\r
-    if( pLoggingBuffer == NULL )\r
-    {\r
-        return;\r
-    }\r
-\r
-    /* Print the message log level if requested. */\r
-    if( ( pLogConfig == NULL ) || ( pLogConfig->hideLogLevel == false ) )\r
-    {\r
-        /* Ensure that message level is valid. */\r
-        if( ( messageLevel >= IOT_LOG_NONE ) && ( messageLevel <= IOT_LOG_DEBUG ) )\r
-        {\r
-            /* Add the log level string to the logging buffer. */\r
-            requiredMessageSize = snprintf( pLoggingBuffer + bufferPosition,\r
-                                            bufferSize - bufferPosition,\r
-                                            "[%s]",\r
-                                            _pLogLevelStrings[ messageLevel ] );\r
-\r
-            /* Check for encoding errors. */\r
-            if( requiredMessageSize <= 0 )\r
-            {\r
-                IotLogging_Free( pLoggingBuffer );\r
-\r
-                return;\r
-            }\r
-\r
-            /* Update the buffer position. */\r
-            bufferPosition += ( size_t ) requiredMessageSize;\r
-        }\r
-    }\r
-\r
-    /* Print the library name if requested. */\r
-    if( ( pLogConfig == NULL ) || ( pLogConfig->hideLibraryName == false ) )\r
-    {\r
-        /* Add the library name to the logging buffer. */\r
-        requiredMessageSize = snprintf( pLoggingBuffer + bufferPosition,\r
-                                        bufferSize - bufferPosition,\r
-                                        "[%s]",\r
-                                        pLibraryName );\r
-\r
-        /* Check for encoding errors. */\r
-        if( requiredMessageSize <= 0 )\r
-        {\r
-            IotLogging_Free( pLoggingBuffer );\r
-\r
-            return;\r
-        }\r
-\r
-        /* Update the buffer position. */\r
-        bufferPosition += ( size_t ) requiredMessageSize;\r
-    }\r
-\r
-    /* Print the timestring if requested. */\r
-    if( ( pLogConfig == NULL ) || ( pLogConfig->hideTimestring == false ) )\r
-    {\r
-        /* Add the opening '[' enclosing the timestring. */\r
-        pLoggingBuffer[ bufferPosition ] = '[';\r
-        bufferPosition++;\r
-\r
-        /* Generate the timestring and add it to the buffer. */\r
-        if( IotClock_GetTimestring( pLoggingBuffer + bufferPosition,\r
-                                    bufferSize - bufferPosition,\r
-                                    &timestringLength ) == true )\r
-        {\r
-            /* If the timestring was successfully generated, add the closing "]". */\r
-            bufferPosition += timestringLength;\r
-            pLoggingBuffer[ bufferPosition ] = ']';\r
-            bufferPosition++;\r
-        }\r
-        else\r
-        {\r
-            /* Sufficient memory for a timestring should have been allocated. A timestring\r
-             * probably failed to generate due to a clock read error; remove the opening '['\r
-             * from the logging buffer. */\r
-            bufferPosition--;\r
-            pLoggingBuffer[ bufferPosition ] = '\0';\r
-        }\r
-    }\r
-\r
-    /* Add a padding space between the last closing ']' and the message, unless\r
-     * the logging buffer is empty. */\r
-    if( bufferPosition > 0 )\r
-    {\r
-        pLoggingBuffer[ bufferPosition ] = ' ';\r
-        bufferPosition++;\r
-    }\r
-\r
-    va_start( args, pFormat );\r
-\r
-    /* Add the log message to the logging buffer. */\r
-    requiredMessageSize = vsnprintf( pLoggingBuffer + bufferPosition,\r
-                                     bufferSize - bufferPosition,\r
-                                     pFormat,\r
-                                     args );\r
-\r
-    va_end( args );\r
-\r
-    /* If the logging buffer was too small to fit the log message, reallocate\r
-     * a larger logging buffer. */\r
-    if( ( size_t ) requiredMessageSize >= bufferSize - bufferPosition )\r
-    {\r
-        #if IOT_STATIC_MEMORY_ONLY == 1\r
-\r
-            /* There's no point trying to allocate a larger static buffer. Return\r
-             * immediately. */\r
-            IotLogging_Free( pLoggingBuffer );\r
-\r
-            return;\r
-        #else\r
-            if( _reallocLoggingBuffer( ( void ** ) &pLoggingBuffer,\r
-                                       ( size_t ) requiredMessageSize + bufferPosition + 1,\r
-                                       bufferSize ) == false )\r
-            {\r
-                /* If buffer reallocation failed, return. */\r
-                IotLogging_Free( pLoggingBuffer );\r
-\r
-                return;\r
-            }\r
-\r
-            /* Reallocation successful, update buffer size. */\r
-            bufferSize = ( size_t ) requiredMessageSize + bufferPosition + 1;\r
-\r
-            /* Add the log message to the buffer. Now that the buffer has been\r
-             * reallocated, this should succeed. */\r
-            va_start( args, pFormat );\r
-            requiredMessageSize = vsnprintf( pLoggingBuffer + bufferPosition,\r
-                                             bufferSize - bufferPosition,\r
-                                             pFormat,\r
-                                             args );\r
-            va_end( args );\r
-        #endif /* if IOT_STATIC_MEMORY_ONLY == 1 */\r
-    }\r
-\r
-    /* Check for encoding errors. */\r
-    if( requiredMessageSize <= 0 )\r
-    {\r
-        IotLogging_Free( pLoggingBuffer );\r
-\r
-        return;\r
-    }\r
-\r
-    /* Print the logging buffer to stdout. */\r
-    IotLogging_Puts( pLoggingBuffer );\r
-\r
-    /* Free the logging buffer. */\r
-    IotLogging_Free( pLoggingBuffer );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void IotLog_GenericPrintBuffer( const char * const pLibraryName,\r
-                                const char * const pHeader,\r
-                                const uint8_t * const pBuffer,\r
-                                size_t bufferSize )\r
-{\r
-    size_t i = 0, offset = 0;\r
-\r
-    /* Allocate memory to hold each line of the log message. Since each byte\r
-     * of pBuffer is printed in 4 characters (2 digits, a space, and a null-\r
-     * terminator), the size of each line is 4 * BYTES_PER_LINE. */\r
-    char * pMessageBuffer = IotLogging_Malloc( 4 * BYTES_PER_LINE );\r
-\r
-    /* Exit if no memory is available. */\r
-    if( pMessageBuffer == NULL )\r
-    {\r
-        return;\r
-    }\r
-\r
-    /* Print pHeader before printing pBuffer. */\r
-    if( pHeader != NULL )\r
-    {\r
-        IotLog_Generic( IOT_LOG_DEBUG,\r
-                        pLibraryName,\r
-                        IOT_LOG_DEBUG,\r
-                        NULL,\r
-                        pHeader );\r
-    }\r
-\r
-    /* Print each byte in pBuffer. */\r
-    for( i = 0; i < bufferSize; i++ )\r
-    {\r
-        /* Print a line if BYTES_PER_LINE is reached. But don't print a line\r
-         * at the beginning (when i=0). */\r
-        if( ( i % BYTES_PER_LINE == 0 ) && ( i != 0 ) )\r
-        {\r
-            IotLogging_Puts( pMessageBuffer );\r
-\r
-            /* Reset offset so that pMessageBuffer is filled from the beginning. */\r
-            offset = 0;\r
-        }\r
-\r
-        /* Print a single byte into pMessageBuffer. */\r
-        ( void ) snprintf( pMessageBuffer + offset, 4, "%02x ", pBuffer[ i ] );\r
-\r
-        /* Move the offset where the next character is printed. */\r
-        offset += 3;\r
-    }\r
-\r
-    /* Print the final line of bytes. This line isn't printed by the for-loop above. */\r
-    IotLogging_Puts( pMessageBuffer );\r
-\r
-    /* Free memory used by this function. */\r
-    IotLogging_Free( pMessageBuffer );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/logging/iot_logging_task_dynamic_buffers.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/logging/iot_logging_task_dynamic_buffers.c
deleted file mode 100644 (file)
index ac08e22..0000000
+++ /dev/null
@@ -1,250 +0,0 @@
-/*\r
- * Amazon FreeRTOS Common V1.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
-/* FreeRTOS includes. */\r
-#include "FreeRTOS.h"\r
-#include "task.h"\r
-#include "queue.h"\r
-\r
-/* Logging includes. */\r
-#include "iot_logging_task.h"\r
-\r
-/* Standard includes. */\r
-#include <stdio.h>\r
-#include <stdarg.h>\r
-#include <string.h>\r
-\r
-/* Sanity check all the definitions required by this file are set. */\r
-#ifndef configPRINT_STRING\r
-    #error configPRINT_STRING( x ) must be defined in FreeRTOSConfig.h to use this logging file.  Set configPRINT_STRING( x ) to a function that outputs a string, where X is the string.  For example, #define configPRINT_STRING( x ) MyUARTWriteString( X )\r
-#endif\r
-\r
-#ifndef configLOGGING_MAX_MESSAGE_LENGTH\r
-    #error configLOGGING_MAX_MESSAGE_LENGTH must be defined in FreeRTOSConfig.h to use this logging file.  configLOGGING_MAX_MESSAGE_LENGTH sets the size of the buffer into which formatted text is written, so also sets the maximum log message length.\r
-#endif\r
-\r
-#ifndef configLOGGING_INCLUDE_TIME_AND_TASK_NAME\r
-    #error configLOGGING_INCLUDE_TIME_AND_TASK_NAME must be defined in FreeRTOSConfig.h to use this logging file.  Set configLOGGING_INCLUDE_TIME_AND_TASK_NAME to 1 to prepend a time stamp, message number and the name of the calling task to each logged message.  Otherwise set to 0.\r
-#endif\r
-\r
-/* A block time of 0 just means don't block. */\r
-#define loggingDONT_BLOCK    0\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/*\r
- * The task that actually performs the print output.  Using a separate task\r
- * enables the use of slow output, such as as a UART, without the task that is\r
- * outputting the log message having to wait for the message to be completely\r
- * written.  Using a separate task also serializes access to the output port.\r
- *\r
- * The structure of this task is very simple; it blocks on a queue to wait for\r
- * a pointer to a string, sending any received strings to a macro that performs\r
- * the actual output.  The macro is port specific, so implemented outside of\r
- * this file.  This version uses dynamic memory, so the buffer that contained\r
- * the log message is freed after it has been output.\r
- */\r
-static void prvLoggingTask( void * pvParameters );\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/*\r
- * The queue used to pass pointers to log messages from the task that created\r
- * the message to the task that will performs the output.\r
- */\r
-static QueueHandle_t xQueue = NULL;\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-BaseType_t xLoggingTaskInitialize( uint16_t usStackSize,\r
-                                   UBaseType_t uxPriority,\r
-                                   UBaseType_t uxQueueLength )\r
-{\r
-    BaseType_t xReturn = pdFAIL;\r
-\r
-    /* Ensure the logging task has not been created already. */\r
-    if( xQueue == NULL )\r
-    {\r
-        /* Create the queue used to pass pointers to strings to the logging task. */\r
-        xQueue = xQueueCreate( uxQueueLength, sizeof( char ** ) );\r
-\r
-        if( xQueue != NULL )\r
-        {\r
-            if( xTaskCreate( prvLoggingTask, "Logging", usStackSize, NULL, uxPriority, NULL ) == pdPASS )\r
-            {\r
-                xReturn = pdPASS;\r
-            }\r
-            else\r
-            {\r
-                /* Could not create the task, so delete the queue again. */\r
-                vQueueDelete( xQueue );\r
-            }\r
-        }\r
-    }\r
-\r
-    return xReturn;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvLoggingTask( void * pvParameters )\r
-{\r
-    char * pcReceivedString = NULL;\r
-\r
-    for( ; ; )\r
-    {\r
-        /* Block to wait for the next string to print. */\r
-        if( xQueueReceive( xQueue, &pcReceivedString, portMAX_DELAY ) == pdPASS )\r
-        {\r
-            configPRINT_STRING( pcReceivedString );\r
-            vPortFree( ( void * ) pcReceivedString );\r
-        }\r
-    }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-/*!\r
- * \brief Formats a string to be printed and sends it\r
- * to the print queue.\r
- *\r
- * Appends the message number, time (in ticks), and task\r
- * that called vLoggingPrintf to the beginning of each\r
- * print statement.\r
- *\r
- */\r
-void vLoggingPrintf( const char * pcFormat,\r
-                     ... )\r
-{\r
-    size_t xLength = 0;\r
-    int32_t xLength2 = 0;\r
-    va_list args;\r
-    char * pcPrintString = NULL;\r
-\r
-    /* The queue is created by xLoggingTaskInitialize().  Check\r
-     * xLoggingTaskInitialize() has been called. */\r
-    configASSERT( xQueue );\r
-\r
-    /* Allocate a buffer to hold the log message. */\r
-    pcPrintString = pvPortMalloc( configLOGGING_MAX_MESSAGE_LENGTH );\r
-\r
-    if( pcPrintString != NULL )\r
-    {\r
-        /* There are a variable number of parameters. */\r
-        va_start( args, pcFormat );\r
-\r
-        if( strcmp( pcFormat, "\n" ) != 0 )\r
-        {\r
-            #if ( configLOGGING_INCLUDE_TIME_AND_TASK_NAME == 1 )\r
-                {\r
-                    const char * pcTaskName;\r
-                    const char * pcNoTask = "None";\r
-                    static BaseType_t xMessageNumber = 0;\r
-\r
-                    /* Add a time stamp and the name of the calling task to the\r
-                     * start of the log. */\r
-                    if( xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED )\r
-                    {\r
-                        pcTaskName = pcTaskGetName( NULL );\r
-                    }\r
-                    else\r
-                    {\r
-                        pcTaskName = pcNoTask;\r
-                    }\r
-\r
-                    xLength = snprintf( pcPrintString, configLOGGING_MAX_MESSAGE_LENGTH, "%lu %lu [%s] ",\r
-                                        ( unsigned long ) xMessageNumber++,\r
-                                        ( unsigned long ) xTaskGetTickCount(),\r
-                                        pcTaskName );\r
-                }\r
-            #else /* if ( configLOGGING_INCLUDE_TIME_AND_TASK_NAME == 1 ) */\r
-                {\r
-                    xLength = 0;\r
-                }\r
-            #endif /* if ( configLOGGING_INCLUDE_TIME_AND_TASK_NAME == 1 ) */\r
-        }\r
-\r
-        xLength2 = vsnprintf( pcPrintString + xLength, configLOGGING_MAX_MESSAGE_LENGTH - xLength, pcFormat, args );\r
-\r
-        if( xLength2 < 0 )\r
-        {\r
-            /* vsnprintf() failed. Restore the terminating NULL\r
-             * character of the first part. Note that the first\r
-             * part of the buffer may be empty if the value of\r
-             * configLOGGING_INCLUDE_TIME_AND_TASK_NAME is not\r
-             * 1 and as a result, the whole buffer may be empty.\r
-             * That's the reason we have a check for xLength > 0\r
-             * before sending the buffer to the logging task.\r
-             */\r
-            xLength2 = 0;\r
-            pcPrintString[ xLength ] = '\0';\r
-        }\r
-\r
-        xLength += ( size_t ) xLength2;\r
-        va_end( args );\r
-\r
-        /* Only send the buffer to the logging task if it is\r
-         * not empty. */\r
-        if( xLength > 0 )\r
-        {\r
-            /* Send the string to the logging task for IO. */\r
-            if( xQueueSend( xQueue, &pcPrintString, loggingDONT_BLOCK ) != pdPASS )\r
-            {\r
-                /* The buffer was not sent so must be freed again. */\r
-                vPortFree( ( void * ) pcPrintString );\r
-            }\r
-        }\r
-        else\r
-        {\r
-            /* The buffer was not sent, so it must be\r
-             * freed. */\r
-            vPortFree( ( void * ) pcPrintString );\r
-        }\r
-    }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vLoggingPrint( const char * pcMessage )\r
-{\r
-    char * pcPrintString = NULL;\r
-    size_t xLength = 0;\r
-\r
-    /* The queue is created by xLoggingTaskInitialize().  Check\r
-     * xLoggingTaskInitialize() has been called. */\r
-    configASSERT( xQueue );\r
-\r
-    xLength = strlen( pcMessage ) + 1;\r
-    pcPrintString = pvPortMalloc( xLength );\r
-\r
-    if( pcPrintString != NULL )\r
-    {\r
-        strncpy( pcPrintString, pcMessage, xLength );\r
-\r
-        /* Send the string to the logging task for IO. */\r
-        if( xQueueSend( xQueue, &pcPrintString, loggingDONT_BLOCK ) != pdPASS )\r
-        {\r
-            /* The buffer was not sent so must be freed again. */\r
-            vPortFree( ( void * ) pcPrintString );\r
-        }\r
-    }\r
-}\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/taskpool/iot_taskpool.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/taskpool/iot_taskpool.c
deleted file mode 100644 (file)
index 6f90c19..0000000
+++ /dev/null
@@ -1,1185 +0,0 @@
-/*\r
- * Amazon FreeRTOS Common V1.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
- * @file iot_taskpool.c\r
- * @brief Implements the task pool functions in iot_taskpool.h\r
- */\r
-\r
-/* Kernel includes. */\r
-#include "FreeRTOS.h"\r
-#include "semphr.h"\r
-\r
-/* IoT libraries includes. */\r
-#include "iot_config.h"\r
-\r
-/* Standard includes. */\r
-#include <stdbool.h>\r
-#include <stdio.h>\r
-#include <stddef.h>\r
-#include <stdint.h>\r
-#include <string.h>\r
-\r
-#if !defined( configSUPPORT_STATIC_ALLOCATION ) || ( configSUPPORT_STATIC_ALLOCATION != 1 )\r
-    #error configSUPPORT_STATIC_ALLOCATION must be set to 1 in FreeRTOSConfig.h to build this file.\r
-#endif\r
-\r
-/* Task pool internal include. */\r
-#include "private/iot_taskpool_internal.h"\r
-\r
-/**\r
- * @brief Maximum semaphore value for wait operations.\r
- */\r
-#define TASKPOOL_MAX_SEM_VALUE              0xFFFF\r
-\r
-/**\r
- * @brief Reschedule delay in milliseconds for deferred jobs.\r
- */\r
-#define TASKPOOL_JOB_RESCHEDULE_DELAY_MS    ( 10ULL )\r
-\r
-/* ---------------------------------------------------------------------------------- */\r
-\r
-/**\r
- * Doxygen should ignore this section.\r
- *\r
- * @brief The system task pool handle for all libraries to use.\r
- * User application can use the system task pool as well knowing that the usage will be shared with\r
- * the system libraries as well. The system task pool needs to be initialized before any library is used or\r
- * before any code that posts jobs to the task pool runs.\r
- */\r
-static _taskPool_t _IotSystemTaskPool = { .dispatchQueue = IOT_DEQUEUE_INITIALIZER };\r
-\r
-/* -------------- Convenience functions to create/recycle/destroy jobs -------------- */\r
-\r
-/**\r
- * @brief Initializes one instance of a Task pool cache.\r
- *\r
- * @param[in] pCache The pre-allocated instance of the cache to initialize.\r
- */\r
-static void _initJobsCache( _taskPoolCache_t * const pCache );\r
-\r
-/**\r
- * @brief Initialize a job.\r
- *\r
- * @param[in] pJob The job to initialize.\r
- * @param[in] userCallback The user callback for the job.\r
- * @param[in] pUserContext The context tp be passed to the callback.\r
- * @param[in] isStatic A flag to indicate whether the job is statically or synamically allocated.\r
- */\r
-static void _initializeJob( _taskPoolJob_t * const pJob,\r
-                            IotTaskPoolRoutine_t userCallback,\r
-                            void * pUserContext,\r
-                            bool isStatic );\r
-\r
-/**\r
- * @brief Extracts and initializes one instance of a job from the cache or, if there is none available, it allocates and initialized a new one.\r
- *\r
- * @param[in] pCache The instance of the cache to extract the job from.\r
- */\r
-static _taskPoolJob_t * _fetchOrAllocateJob( _taskPoolCache_t * const pCache );\r
-\r
-/**\r
- * Recycles one instance of a job into the cache or, if the cache is full, it destroys it.\r
- *\r
- * @param[in] pCache The instance of the cache to recycle the job into.\r
- * @param[in] pJob The job to recycle.\r
- *\r
- */\r
-static void _recycleJob( _taskPoolCache_t * const pCache,\r
-                         _taskPoolJob_t * const pJob );\r
-\r
-/**\r
- * Destroys one instance of a job.\r
- *\r
- * @param[in] pJob The job to destroy.\r
- *\r
- */\r
-static void _destroyJob( _taskPoolJob_t * const pJob );\r
-\r
-/* -------------- The worker thread procedure for a task pool thread -------------- */\r
-\r
-/**\r
- * The procedure for a task pool worker thread.\r
- *\r
- * @param[in] pUserContext The user context.\r
- *\r
- */\r
-static void _taskPoolWorker( void * pUserContext );\r
-\r
-/* -------------- Convenience functions to handle timer events  -------------- */\r
-\r
-/**\r
- * Comparer for the time list.\r
- *\r
- * param[in] pTimerEventLink1 The link to the first timer event.\r
- * param[in] pTimerEventLink1 The link to the first timer event.\r
- */\r
-static int32_t _timerEventCompare( const IotLink_t * const pTimerEventLink1,\r
-                                   const IotLink_t * const pTimerEventLink2 );\r
-\r
-/**\r
- * Reschedules the timer for handling deferred jobs to the next timeout.\r
- *\r
- * param[in] timer The timer to reschedule.\r
- * param[in] pFirstTimerEvent The timer event that carries the timeout and job inforamtion.\r
- */\r
-static void _rescheduleDeferredJobsTimer( TimerHandle_t const timer,\r
-                                          _taskPoolTimerEvent_t * const pFirstTimerEvent );\r
-\r
-/**\r
- * The task pool timer procedure for scheduling deferred jobs.\r
- *\r
- * param[in] timer The timer to handle.\r
- */\r
-static void _timerCallback( TimerHandle_t xTimer );\r
-\r
-/* -------------- Convenience functions to create/initialize/destroy the task pool -------------- */\r
-\r
-/**\r
- * Parameter validation for a task pool initialization.\r
- *\r
- * @param[in] pInfo The initialization information for the task pool.\r
- *\r
- */\r
-static IotTaskPoolError_t _performTaskPoolParameterValidation( const IotTaskPoolInfo_t * const pInfo );\r
-\r
-/**\r
- * Initializes a pre-allocated instance of a task pool.\r
- *\r
- * @param[in] pTaskPool The pre-allocated instance of the task pool to initialize.\r
- *\r
- */\r
-static void _initTaskPoolControlStructures( _taskPool_t * const pTaskPool );\r
-\r
-/**\r
- * Initializes a pre-allocated instance of a task pool.\r
- *\r
- * @param[in] pInfo The initialization information for the task pool.\r
- * @param[out] pTaskPool A pointer to the task pool data structure to initialize.\r
- *\r
- */\r
-static IotTaskPoolError_t _createTaskPool( const IotTaskPoolInfo_t * const pInfo,\r
-                                           _taskPool_t * const pTaskPool );\r
-\r
-/**\r
- * Destroys one instance of a task pool.\r
- *\r
- * @param[in] pTaskPool The task pool to destroy.\r
- *\r
- */\r
-static void _destroyTaskPool( _taskPool_t * const pTaskPool );\r
-\r
-/**\r
- * Places a job in the dispatch queue.\r
- *\r
- * @param[in] pTaskPool The task pool to scheduel the job with.\r
- * @param[in] pJob The job to schedule.\r
- * @param[in] flags The job flags.\r
- *\r
- */\r
-static IotTaskPoolError_t _scheduleInternal( _taskPool_t * const pTaskPool,\r
-                                             _taskPoolJob_t * const pJob );\r
-/**\r
- * Matches a deferred job in the timer queue with its timer event wrapper.\r
- *\r
- * @param[in] pLink A pointer to the timer event link in the timer queue.\r
- * @param[in] pMatch A pointer to the job to match.\r
- *\r
- */\r
-static bool _matchJobByPointer( const IotLink_t * const pLink,\r
-                                void * pMatch );\r
-\r
-/**\r
- * Tries to cancel a job.\r
- *\r
- * @param[in] pTaskPool The task pool to cancel an operation against.\r
- * @param[in] pJob The job to cancel.\r
- * @param[out] pStatus The status of the job at the time of cancellation.\r
- *\r
- */\r
-static IotTaskPoolError_t _tryCancelInternal( _taskPool_t * const pTaskPool,\r
-                                              _taskPoolJob_t * const pJob,\r
-                                              IotTaskPoolJobStatus_t * const pStatus );\r
-\r
-/* ---------------------------------------------------------------------------------------------- */\r
-\r
-/*\r
- * The full IoT Task Pool Library has many use cases, including Linux\r
- * development. Â Typical FreeRTOS use cases do not require the full\r
- * functionality so optimised version is provided specifically for use with\r
- * FreeRTOS.  Unlike the full version, this optimised version:\r
- *   + Only supports a single task pool (system task pool) at a time.\r
- *   + Does not auto-scale by dynamically adding more tasks if the number of\r
- *   + tasks in the pool becomes exhausted. Â The number of tasks in the pool\r
- *     are fixed at compile time.  See the task pool configuration options for\r
- *     more information.\r
- *   + Cannot be shut down - it exists for the lifetime of the application.\r
- *\r
- * As such this file does not implement the following API functions:\r
- *   + IotTaskPool_GetSystemTaskPool()\r
- *   + IotTaskPool_Create()\r
- *   + IotTaskPool_Destroy()\r
- *   + IotTaskPool_SetMaxThreads()\r
- *\r
- * Users who are interested in the functionality of the full IoT Task Pool\r
- * library can us it in place of this optimised version.\r
- */\r
-\r
-IotTaskPoolError_t IotTaskPool_CreateSystemTaskPool( const IotTaskPoolInfo_t * const pInfo )\r
-{\r
-    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
-\r
-    /* At this time the task pool cannot be created before the scheduler has\r
-    started because the function attempts to block on synchronization\r
-    primitives (although I'm not sure why). */\r
-    configASSERT( xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED );\r
-\r
-    /* Guard against multiple attempts to create the system task pool in case\r
-    this function is called by more than one library initialization routine. */\r
-    if( _IotSystemTaskPool.running == false )\r
-    {\r
-        /* Parameter checking. */\r
-        TASKPOOL_ON_ERROR_GOTO_CLEANUP( _performTaskPoolParameterValidation( pInfo ) );\r
-\r
-        /* Create the system task pool pool. */\r
-        TASKPOOL_SET_AND_GOTO_CLEANUP( _createTaskPool( pInfo, &_IotSystemTaskPool ) );\r
-    }\r
-\r
-    TASKPOOL_NO_FUNCTION_CLEANUP();\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-IotTaskPoolError_t IotTaskPool_CreateJob( IotTaskPoolRoutine_t userCallback,\r
-                                          void * pUserContext,\r
-                                          IotTaskPoolJobStorage_t * const pJobStorage,\r
-                                          IotTaskPoolJob_t * const ppJob )\r
-{\r
-    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
-\r
-    /* Parameter checking. */\r
-    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( userCallback );\r
-    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pJobStorage );\r
-    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( ppJob );\r
-\r
-    /* Build a job around the user-provided storage. */\r
-    _initializeJob( ( _taskPoolJob_t * ) pJobStorage, userCallback, pUserContext, true );\r
-\r
-    *ppJob = ( IotTaskPoolJob_t ) pJobStorage;\r
-\r
-    TASKPOOL_NO_FUNCTION_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotTaskPoolError_t IotTaskPool_CreateRecyclableJob( IotTaskPool_t taskPoolHandle,\r
-                                                    IotTaskPoolRoutine_t userCallback,\r
-                                                    void * pUserContext,\r
-                                                    IotTaskPoolJob_t * const ppJob )\r
-{\r
-    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
-\r
-    _taskPool_t * const pTaskPool = &_IotSystemTaskPool;\r
-    _taskPoolJob_t * pTempJob = NULL;\r
-\r
-    /* This lean version of the task pool only supports the task pool created\r
-    by this library (the system task pool).  NULL means use the system task\r
-    pool - no other values are allowed.  Use the full implementation of this\r
-    library if you want multiple task pools (there is more than one task in\r
-    each pool. */\r
-    configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) );\r
-\r
-    /* Avoid compiler warnings about unused parameters if configASSERT() is not\r
-    defined. */\r
-    ( void ) taskPoolHandle;\r
-\r
-    /* Parameter checking. */\r
-    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( userCallback );\r
-    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( ppJob );\r
-\r
-    taskENTER_CRITICAL();\r
-    {\r
-        /* Bail out early if this task pool is shutting down. */\r
-        pTempJob = _fetchOrAllocateJob( &pTaskPool->jobsCache );\r
-    }\r
-    taskEXIT_CRITICAL();\r
-\r
-    if( pTempJob == NULL )\r
-    {\r
-        IotLogInfo( "Failed to allocate a job." );\r
-\r
-        TASKPOOL_SET_AND_GOTO_CLEANUP( IOT_TASKPOOL_NO_MEMORY );\r
-    }\r
-\r
-    _initializeJob( pTempJob, userCallback, pUserContext, false );\r
-\r
-    *ppJob = pTempJob;\r
-\r
-    TASKPOOL_NO_FUNCTION_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotTaskPoolError_t IotTaskPool_DestroyRecyclableJob( IotTaskPool_t taskPoolHandle,\r
-                                                     IotTaskPoolJob_t pJobHandle )\r
-{\r
-    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
-\r
-    _taskPoolJob_t * pJob = ( _taskPoolJob_t * ) pJobHandle;\r
-\r
-    /* This lean version of the task pool only supports the task pool created\r
-    by this library (the system task pool).  NULL means use the system task\r
-    pool - no other values are allowed.  Use the full implementation of this\r
-    library if you want multiple task pools (there is more than one task in\r
-    each pool. */\r
-    configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) );\r
-\r
-    /* Avoid compiler warnings about unused parameters if configASSERT() is not\r
-    defined. */\r
-    ( void ) taskPoolHandle;\r
-\r
-    /* Parameter checking. */\r
-    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pJobHandle );\r
-\r
-    IotTaskPool_Assert( IotLink_IsLinked( &pJob->link ) == false );\r
-\r
-    _destroyJob( pJob );\r
-\r
-    TASKPOOL_NO_FUNCTION_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotTaskPoolError_t IotTaskPool_RecycleJob( IotTaskPool_t taskPoolHandle,\r
-                                           IotTaskPoolJob_t pJob )\r
-{\r
-    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
-\r
-    _taskPool_t * pTaskPool = ( _taskPool_t * ) &_IotSystemTaskPool;\r
-\r
-    /* This lean version of the task pool only supports the task pool created\r
-    by this library (the system task pool).  NULL means use the system task\r
-    pool - no other values are allowed.  Use the full implementation of this\r
-    library if you want multiple task pools (there is more than one task in\r
-    each pool. */\r
-    configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) );\r
-\r
-    /* Ensure unused parameters do not cause compiler warnings in case\r
-    configASSERT() is not defined. */\r
-    ( void ) taskPoolHandle;\r
-\r
-    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pJob );\r
-\r
-    taskENTER_CRITICAL();\r
-    {\r
-        IotTaskPool_Assert( IotLink_IsLinked( &pJob->link ) == false );\r
-\r
-        _recycleJob( &pTaskPool->jobsCache, pJob );\r
-    }\r
-    taskEXIT_CRITICAL();\r
-\r
-    TASKPOOL_NO_FUNCTION_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotTaskPoolError_t IotTaskPool_Schedule( IotTaskPool_t taskPoolHandle,\r
-                                         IotTaskPoolJob_t pJob,\r
-                                         uint32_t flags )\r
-{\r
-    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
-\r
-    _taskPool_t * const pTaskPool = &_IotSystemTaskPool;\r
-\r
-    /* Task pool must have been created. */\r
-    configASSERT( pTaskPool->running != false );\r
-\r
-    /* This lean version of the task pool only supports the task pool created\r
-    by this library (the system task pool).  NULL means use the system task\r
-    pool - no other values are allowed.  Use the full implementation of this\r
-    library if you want multiple task pools (there is more than one task in\r
-    each pool. */\r
-    configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) );\r
-\r
-    /* Avoid compiler warnings about unused parameters if configASSERT() is not\r
-    defined. */\r
-    ( void ) taskPoolHandle;\r
-\r
-    /* Parameter checking. */\r
-    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pJob );\r
-    TASKPOOL_ON_ARG_ERROR_GOTO_CLEANUP( ( flags != 0UL ) && ( flags != IOT_TASKPOOL_JOB_HIGH_PRIORITY ) );\r
-\r
-    taskENTER_CRITICAL(); //_RB_ Critical section is too long - does the whole thing need to be protected?\r
-    {\r
-        _scheduleInternal( pTaskPool, pJob );\r
-    }\r
-    taskEXIT_CRITICAL();\r
-\r
-    TASKPOOL_NO_FUNCTION_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotTaskPoolError_t IotTaskPool_ScheduleDeferred( IotTaskPool_t taskPoolHandle,\r
-                                                 IotTaskPoolJob_t job,\r
-                                                 uint32_t timeMs )\r
-{\r
-    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
-\r
-    _taskPool_t * pTaskPool = &_IotSystemTaskPool;\r
-\r
-    /* This lean version of the task pool only supports the task pool created\r
-    by this library (the system task pool).  NULL means use the system task\r
-    pool - no other values are allowed.  Use the full implementation of this\r
-    library if you want multiple task pools (there is more than one task in\r
-    each pool. */\r
-    configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) );\r
-\r
-    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( job );\r
-\r
-    if( timeMs == 0UL )\r
-    {\r
-        TASKPOOL_SET_AND_GOTO_CLEANUP( IotTaskPool_Schedule( pTaskPool, job, 0 ) );\r
-    }\r
-\r
-    taskENTER_CRITICAL();\r
-    {\r
-        _taskPoolTimerEvent_t * pTimerEvent = IotTaskPool_MallocTimerEvent( sizeof( _taskPoolTimerEvent_t ) );\r
-\r
-        if( pTimerEvent == NULL )\r
-        {\r
-            taskEXIT_CRITICAL();\r
-\r
-            TASKPOOL_SET_AND_GOTO_CLEANUP( IOT_TASKPOOL_NO_MEMORY );\r
-        }\r
-\r
-        IotLink_t * pTimerEventLink;\r
-\r
-        TickType_t now = xTaskGetTickCount();\r
-\r
-        pTimerEvent->link.pNext = NULL;\r
-        pTimerEvent->link.pPrevious = NULL;\r
-        pTimerEvent->expirationTime = now + pdMS_TO_TICKS( timeMs );\r
-        pTimerEvent->job = job; //_RB_ Think up to here can be outside the critical section.\r
-\r
-        /* Append the timer event to the timer list. */\r
-        IotListDouble_InsertSorted( &pTaskPool->timerEventsList, &pTimerEvent->link, _timerEventCompare );\r
-\r
-        /* Update the job status to 'scheduled'. */\r
-        job->status = IOT_TASKPOOL_STATUS_DEFERRED;\r
-\r
-        /* Peek the first event in the timer event list. There must be at least one,\r
-         * since we just inserted it. */\r
-        pTimerEventLink = IotListDouble_PeekHead( &pTaskPool->timerEventsList );\r
-        IotTaskPool_Assert( pTimerEventLink != NULL );\r
-\r
-        /* If the event we inserted is at the front of the queue, then\r
-         * we need to reschedule the underlying timer. */\r
-        if( pTimerEventLink == &pTimerEvent->link )\r
-        {\r
-            pTimerEvent = IotLink_Container( _taskPoolTimerEvent_t, pTimerEventLink, link );\r
-\r
-            _rescheduleDeferredJobsTimer( pTaskPool->timer, pTimerEvent );\r
-        }\r
-    }\r
-    taskEXIT_CRITICAL();\r
-\r
-    TASKPOOL_NO_FUNCTION_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotTaskPoolError_t IotTaskPool_GetStatus( IotTaskPool_t taskPoolHandle,\r
-                                          IotTaskPoolJob_t job,\r
-                                          IotTaskPoolJobStatus_t * const pStatus )\r
-{\r
-    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
-\r
-    /* This lean version of the task pool only supports the task pool created\r
-    by this library (the system task pool).  NULL means use the system task\r
-    pool - no other values are allowed.  Use the full implementation of this\r
-    library if you want multiple task pools (there is more than one task in\r
-    each pool. */\r
-    configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) );\r
-    ( void ) taskPoolHandle;\r
-\r
-    /* Parameter checking. */\r
-    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( job );\r
-    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pStatus );\r
-    *pStatus = IOT_TASKPOOL_STATUS_UNDEFINED;\r
-\r
-    taskENTER_CRITICAL();\r
-    {\r
-        *pStatus = job->status;\r
-    }\r
-    taskEXIT_CRITICAL();\r
-\r
-    TASKPOOL_NO_FUNCTION_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotTaskPoolError_t IotTaskPool_TryCancel( IotTaskPool_t taskPoolHandle,\r
-                                          IotTaskPoolJob_t job,\r
-                                          IotTaskPoolJobStatus_t * const pStatus )\r
-{\r
-    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
-\r
-    _taskPool_t * const pTaskPool = &_IotSystemTaskPool;\r
-\r
-    /* This lean version of the task pool only supports the task pool created\r
-    by this library (the system task pool).  NULL means use the system task\r
-    pool - no other values are allowed.  Use the full implementation of this\r
-    library if you want multiple task pools (there is more than one task in\r
-    each pool. */\r
-    configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) );\r
-    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( job );\r
-\r
-    if( pStatus != NULL )\r
-    {\r
-        *pStatus = IOT_TASKPOOL_STATUS_UNDEFINED;\r
-    }\r
-\r
-    taskENTER_CRITICAL();\r
-    {\r
-        status = _tryCancelInternal( pTaskPool, job, pStatus );\r
-    }\r
-    taskEXIT_CRITICAL();\r
-\r
-    TASKPOOL_NO_FUNCTION_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotTaskPoolJobStorage_t * IotTaskPool_GetJobStorageFromHandle( IotTaskPoolJob_t pJob )\r
-{\r
-    return ( IotTaskPoolJobStorage_t * ) pJob;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-const char * IotTaskPool_strerror( IotTaskPoolError_t status )\r
-{\r
-    const char * pMessage = NULL;\r
-\r
-    switch( status )\r
-    {\r
-        case IOT_TASKPOOL_SUCCESS:\r
-            pMessage = "SUCCESS";\r
-            break;\r
-\r
-        case IOT_TASKPOOL_BAD_PARAMETER:\r
-            pMessage = "BAD PARAMETER";\r
-            break;\r
-\r
-        case IOT_TASKPOOL_ILLEGAL_OPERATION:\r
-            pMessage = "ILLEGAL OPERATION";\r
-            break;\r
-\r
-        case IOT_TASKPOOL_NO_MEMORY:\r
-            pMessage = "NO MEMORY";\r
-            break;\r
-\r
-        case IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS:\r
-            pMessage = "SHUTDOWN IN PROGRESS";\r
-            break;\r
-\r
-        case IOT_TASKPOOL_CANCEL_FAILED:\r
-            pMessage = "CANCEL FAILED";\r
-            break;\r
-\r
-        default:\r
-            pMessage = "INVALID STATUS";\r
-            break;\r
-    }\r
-\r
-    return pMessage;\r
-}\r
-\r
-/* ---------------------------------------------------------------------------------------------- */\r
-/* ---------------------------------------------------------------------------------------------- */\r
-/* ---------------------------------------------------------------------------------------------- */\r
-\r
-static IotTaskPoolError_t _performTaskPoolParameterValidation( const IotTaskPoolInfo_t * const pInfo )\r
-{\r
-    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
-\r
-    /* Check input values for consistency. */\r
-    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pInfo );\r
-    TASKPOOL_ON_ARG_ERROR_GOTO_CLEANUP( pInfo->minThreads > pInfo->maxThreads );\r
-    TASKPOOL_ON_ARG_ERROR_GOTO_CLEANUP( pInfo->minThreads < 1UL );\r
-    TASKPOOL_ON_ARG_ERROR_GOTO_CLEANUP( pInfo->maxThreads < 1UL );\r
-\r
-    TASKPOOL_NO_FUNCTION_CLEANUP();\r
-}\r
-\r
-static void _initTaskPoolControlStructures( _taskPool_t * const pTaskPool )\r
-{\r
-    /* Initialize a job data structures that require no de-initialization.\r
-     * All other data structures carry a value of 'NULL' before initailization.\r
-     */\r
-    IotDeQueue_Create( &pTaskPool->dispatchQueue );\r
-    IotListDouble_Create( &pTaskPool->timerEventsList );\r
-\r
-    _initJobsCache( &pTaskPool->jobsCache );\r
-\r
-    /* Initialize the semaphore for waiting for incoming work.  Cannot fail as\r
-    statically allocated. */\r
-    pTaskPool->dispatchSignal = xSemaphoreCreateCountingStatic( TASKPOOL_MAX_SEM_VALUE, 0, &pTaskPool->dispatchSignalBuffer );\r
-}\r
-\r
-static IotTaskPoolError_t _createTaskPool( const IotTaskPoolInfo_t * const pInfo,\r
-                                           _taskPool_t * const pTaskPool )\r
-{\r
-    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
-\r
-    /* Static TCB structures and arrays to be used by statically allocated\r
-    worker tasks. */\r
-    static StaticTask_t workerTaskTCBs[ IOT_TASKPOOL_NUMBER_OF_WORKERS ];\r
-    static StackType_t workerTaskStacks[ IOT_TASKPOOL_NUMBER_OF_WORKERS ][ IOT_TASKPOOL_WORKER_STACK_SIZE_BYTES / sizeof( portSTACK_TYPE ) ];\r
-\r
-       /* Static structure to hold te software timer. */\r
-       static StaticTimer_t staticTimer;\r
-\r
-    uint32_t threadsCreated = 0; /* Although initialised before use removing the initialiser here results in compiler warnings. */\r
-    char taskName[ 10 ];\r
-\r
-    /* Check input values for consistency. */\r
-    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pTaskPool );\r
-\r
-    /* Zero out all data structures. */\r
-    memset( ( void * ) pTaskPool, 0x00, sizeof( _taskPool_t ) );\r
-\r
-    /* Initialize all internal data structure prior to creating all threads. */\r
-    _initTaskPoolControlStructures( pTaskPool );\r
-\r
-    /* Create the timer for a new connection. */\r
-    pTaskPool->timer = xTimerCreateStatic( NULL, /* Text name for the timer, only used for debugging. */\r
-                                                  portMAX_DELAY, /* Timer period in ticks. */\r
-                                                  pdFALSE, /* pdFALSE means its a one-shot timer. */\r
-                                                 ( void * ) pTaskPool, /* Parameter passed into callback. */\r
-                                                 _timerCallback, /* Callback that executes when the timer expires. */\r
-                                                 &staticTimer ); /* Static storage for the timer's data structure. */\r
-\r
-    /* The task pool will initialize the minimum number of threads requested by the user upon start.\r
-    Note this tailored version of the task pool does not autoscale, but fixes the number of tasks\r
-    in the pool to the originally specified minimum, and the specified maximum value is ignored. */\r
-    /* Create the minimum number of threads specified by the user, and if one fails shutdown and return error. */\r
-    for( threadsCreated = 0; threadsCreated < pInfo->minThreads; )\r
-    {\r
-        /* Generate a unique name for the task. */\r
-        snprintf( taskName, sizeof( taskName ), "pool%d", ( int ) threadsCreated );\r
-\r
-        xTaskCreateStatic( _taskPoolWorker, /* Function that implements the task. */\r
-                           taskName,       /* Text name for the task, used for debugging only. */\r
-                                      IOT_TASKPOOL_WORKER_STACK_SIZE_BYTES / sizeof( portSTACK_TYPE ), /* xTaskCreate() expects the stack size to be specified in words. */\r
-                           pTaskPool,       /* Parameter passed into the task. */\r
-                           pInfo->priority, /* Priority at which the task starts running. */\r
-                           &( workerTaskStacks[ threadsCreated ][ 0 ] ), /* Pointer to static storage for the task's stack. */\r
-                                                  &( workerTaskTCBs[ threadsCreated ] ) ); /* Pointer to static storage for te task's TCB. */\r
-\r
-               /* Upon successful thread creation, increase the number of active threads. */\r
-        pTaskPool->activeThreads++;\r
-        ++threadsCreated;\r
-    }\r
-       pTaskPool->running = true;\r
-\r
-    TASKPOOL_FUNCTION_CLEANUP();\r
-\r
-    TASKPOOL_FUNCTION_CLEANUP_END();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static void _destroyTaskPool( _taskPool_t * const pTaskPool )\r
-{\r
-    if( pTaskPool->timer != NULL )\r
-    {\r
-        xTimerDelete( pTaskPool->timer, 0 );\r
-    }\r
-}\r
-\r
-/* ---------------------------------------------------------------------------------------------- */\r
-\r
-static void _taskPoolWorker( void * pUserContext )\r
-{\r
-    IotTaskPool_Assert( pUserContext != NULL );\r
-\r
-    IotTaskPoolRoutine_t userCallback = NULL;\r
-\r
-    /* Extract pTaskPool pointer from context. */\r
-    _taskPool_t * pTaskPool = ( _taskPool_t * ) pUserContext;\r
-\r
-    /* OUTER LOOP: it controls the lifetime of the worker thread. */\r
-    for( ;; )\r
-    {\r
-        IotLink_t * pFirst = NULL;\r
-        _taskPoolJob_t * pJob = NULL;\r
-\r
-        /* Wait on incoming notifications... */\r
-        configASSERT( pTaskPool->dispatchSignal );\r
-        xSemaphoreTake( pTaskPool->dispatchSignal, portMAX_DELAY );\r
-\r
-        /* Acquire the lock to check for incoming notifications. */\r
-        taskENTER_CRITICAL();\r
-        {\r
-            /* Dequeue the first job in FIFO order. */\r
-            pFirst = IotDeQueue_DequeueHead( &pTaskPool->dispatchQueue );\r
-\r
-            /* If there is indeed a job, then update status under lock, and release the lock before processing the job. */\r
-            if( pFirst != NULL )\r
-            {\r
-                /* Extract the job from its link. */\r
-                pJob = IotLink_Container( _taskPoolJob_t, pFirst, link );\r
-\r
-                /* Update status to 'executing'. */\r
-                pJob->status = IOT_TASKPOOL_STATUS_COMPLETED; /*_RB_ Should this be 'executing'? */\r
-                userCallback = pJob->userCallback;\r
-            }\r
-        }\r
-        taskEXIT_CRITICAL();\r
-\r
-        /* INNER LOOP: it controls the execution of jobs: the exit condition is the lack of a job to execute. */\r
-        while( pJob != NULL )\r
-        {\r
-            /* Process the job by invoking the associated callback with the user context.\r
-             * This task pool thread will not be available until the user callback returns.\r
-             */\r
-            {\r
-                IotTaskPool_Assert( IotLink_IsLinked( &pJob->link ) == false );\r
-                IotTaskPool_Assert( userCallback != NULL );\r
-\r
-                userCallback( pTaskPool, pJob, pJob->pUserContext );\r
-\r
-                /* This job is finished, clear its pointer. */\r
-                pJob = NULL;\r
-                userCallback = NULL;\r
-            }\r
-\r
-            /* Acquire the lock before updating the job status. */\r
-            taskENTER_CRITICAL();\r
-            {\r
-                /* Try and dequeue the next job in the dispatch queue. */\r
-                IotLink_t * pItem = NULL;\r
-\r
-                /* Dequeue the next job from the dispatch queue. */\r
-                pItem = IotDeQueue_DequeueHead( &pTaskPool->dispatchQueue );\r
-\r
-                /* If there is no job left in the dispatch queue, update the worker status and leave. */\r
-                if( pItem == NULL )\r
-                {\r
-                    taskEXIT_CRITICAL();\r
-\r
-                    /* Abandon the INNER LOOP. Execution will transfer back to the OUTER LOOP condition. */\r
-                    break;\r
-                }\r
-                else\r
-                {\r
-                    pJob = IotLink_Container( _taskPoolJob_t, pItem, link );\r
-\r
-                    userCallback = pJob->userCallback;\r
-                }\r
-\r
-                pJob->status = IOT_TASKPOOL_STATUS_COMPLETED;\r
-            }\r
-            taskEXIT_CRITICAL();\r
-        }\r
-    }\r
-}\r
-\r
-/* ---------------------------------------------------------------------------------------------- */\r
-\r
-static void _initJobsCache( _taskPoolCache_t * const pCache )\r
-{\r
-    IotDeQueue_Create( &pCache->freeList );\r
-\r
-    pCache->freeCount = 0;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static void _initializeJob( _taskPoolJob_t * const pJob,\r
-                            IotTaskPoolRoutine_t userCallback,\r
-                            void * pUserContext,\r
-                            bool isStatic )\r
-{\r
-    pJob->link.pNext = NULL;\r
-    pJob->link.pPrevious = NULL;\r
-    pJob->userCallback = userCallback;\r
-    pJob->pUserContext = pUserContext;\r
-\r
-    if( isStatic )\r
-    {\r
-        pJob->flags = IOT_TASK_POOL_INTERNAL_STATIC;\r
-        pJob->status = IOT_TASKPOOL_STATUS_READY;\r
-    }\r
-    else\r
-    {\r
-        pJob->status = IOT_TASKPOOL_STATUS_READY;\r
-    }\r
-}\r
-\r
-static _taskPoolJob_t * _fetchOrAllocateJob( _taskPoolCache_t * const pCache )\r
-{\r
-    _taskPoolJob_t * pJob = NULL;\r
-    IotLink_t * pLink = IotListDouble_RemoveHead( &( pCache->freeList ) );\r
-\r
-    if( pLink != NULL )\r
-    {\r
-        pJob = IotLink_Container( _taskPoolJob_t, pLink, link );\r
-    }\r
-\r
-    /* If there is no available job in the cache, then allocate one. */\r
-    if( pJob == NULL )\r
-    {\r
-        pJob = ( _taskPoolJob_t * ) IotTaskPool_MallocJob( sizeof( _taskPoolJob_t ) );\r
-\r
-        if( pJob != NULL )\r
-        {\r
-            memset( pJob, 0x00, sizeof( _taskPoolJob_t ) );\r
-        }\r
-        else\r
-        {\r
-            /* Log allocation failure for troubleshooting purposes. */\r
-            IotLogInfo( "Failed to allocate job." );\r
-        }\r
-    }\r
-    /* If there was a job in the cache, then make sure we keep the counters up-to-date. */\r
-    else\r
-    {\r
-        IotTaskPool_Assert( pCache->freeCount > 0 );\r
-\r
-        pCache->freeCount--;\r
-    }\r
-\r
-    return pJob;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static void _recycleJob( _taskPoolCache_t * const pCache,\r
-                         _taskPoolJob_t * const pJob )\r
-{\r
-    /* We should never try and recycling a job that is linked into some queue. */\r
-    IotTaskPool_Assert( IotLink_IsLinked( &pJob->link ) == false );//_RB_ Seems to be duplicate of test before this is called.\r
-\r
-    /* We will recycle the job if there is space in the cache. */\r
-    if( pCache->freeCount < IOT_TASKPOOL_JOBS_RECYCLE_LIMIT )\r
-    {\r
-        /* Destroy user data, for added safety&security. */\r
-        pJob->userCallback = NULL;\r
-        pJob->pUserContext = NULL;\r
-\r
-        /* Reset the status for added debuggability. */\r
-        pJob->status = IOT_TASKPOOL_STATUS_UNDEFINED;\r
-\r
-        IotListDouble_InsertTail( &pCache->freeList, &pJob->link );\r
-\r
-        pCache->freeCount++;\r
-\r
-        IotTaskPool_Assert( pCache->freeCount >= 1 );\r
-    }\r
-    else\r
-    {\r
-        _destroyJob( pJob );\r
-    }\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static void _destroyJob( _taskPoolJob_t * const pJob )\r
-{\r
-    /* Destroy user data, for added safety & security. */\r
-    pJob->userCallback = NULL;\r
-    pJob->pUserContext = NULL;\r
-\r
-    /* Reset the status for added debuggability. */\r
-    pJob->status = IOT_TASKPOOL_STATUS_UNDEFINED;\r
-\r
-    /* Only dispose of dynamically allocated jobs. */\r
-    if( ( pJob->flags & IOT_TASK_POOL_INTERNAL_STATIC ) == 0UL )\r
-    {\r
-        IotTaskPool_FreeJob( pJob );\r
-    }\r
-}\r
-\r
-/* ---------------------------------------------------------------------------------------------- */\r
-\r
-static IotTaskPoolError_t _scheduleInternal( _taskPool_t * const pTaskPool,\r
-                                             _taskPoolJob_t * const pJob )\r
-{\r
-    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
-\r
-    /* Update the job status to 'scheduled'. */\r
-    pJob->status = IOT_TASKPOOL_STATUS_SCHEDULED;\r
-\r
-    /* Append the job to the dispatch queue. */\r
-    IotDeQueue_EnqueueTail( &pTaskPool->dispatchQueue, &pJob->link );\r
-\r
-    /* Signal a worker to pick up the job. */\r
-    xSemaphoreGive( pTaskPool->dispatchSignal );\r
-\r
-    TASKPOOL_NO_FUNCTION_CLEANUP_NOLABEL();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static bool _matchJobByPointer( const IotLink_t * const pLink,\r
-                                void * pMatch )\r
-{\r
-    const _taskPoolJob_t * const pJob = ( _taskPoolJob_t * ) pMatch;\r
-\r
-    const _taskPoolTimerEvent_t * const pTimerEvent = IotLink_Container( _taskPoolTimerEvent_t, pLink, link );\r
-\r
-    if( pJob == pTimerEvent->job )\r
-    {\r
-        return true;\r
-    }\r
-\r
-    return false;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static IotTaskPoolError_t _tryCancelInternal( _taskPool_t * const pTaskPool,\r
-                                              _taskPoolJob_t * const pJob,\r
-                                              IotTaskPoolJobStatus_t * const pStatus )\r
-{\r
-    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
-\r
-    bool cancelable = false;\r
-\r
-    /* We can only cancel jobs that are either 'ready' (waiting to be scheduled). 'deferred', or 'scheduled'. */\r
-\r
-    IotTaskPoolJobStatus_t currentStatus = pJob->status;\r
-\r
-    switch( currentStatus )\r
-    {\r
-        case IOT_TASKPOOL_STATUS_READY:\r
-        case IOT_TASKPOOL_STATUS_DEFERRED:\r
-        case IOT_TASKPOOL_STATUS_SCHEDULED:\r
-        case IOT_TASKPOOL_STATUS_CANCELED:\r
-            cancelable = true;\r
-            break;\r
-\r
-        case IOT_TASKPOOL_STATUS_COMPLETED:\r
-            /* Log message for debug purposes. */\r
-            IotLogWarn( "Attempt to cancel a job that is already executing, or canceled." );\r
-            break;\r
-\r
-        default:\r
-            /* Log message for debug purposes purposes. */\r
-            IotLogError( "Attempt to cancel a job with an undefined state." );\r
-            break;\r
-    }\r
-\r
-    /* Update the returned status to the current status of the job. */\r
-    if( pStatus != NULL )\r
-    {\r
-        *pStatus = currentStatus;\r
-    }\r
-\r
-    if( cancelable == false )\r
-    {\r
-        TASKPOOL_SET_AND_GOTO_CLEANUP( IOT_TASKPOOL_CANCEL_FAILED );\r
-    }\r
-    else\r
-    {\r
-        /* Update the status of the job. */\r
-        pJob->status = IOT_TASKPOOL_STATUS_CANCELED;\r
-\r
-        /* If the job is cancelable and its current status is 'scheduled' then unlink it from the dispatch\r
-         * queue and signal any waiting threads. */\r
-        if( currentStatus == IOT_TASKPOOL_STATUS_SCHEDULED )\r
-        {\r
-            /* A scheduled work items must be in the dispatch queue. */\r
-            IotTaskPool_Assert( IotLink_IsLinked( &pJob->link ) );\r
-\r
-            IotDeQueue_Remove( &pJob->link );\r
-        }\r
-\r
-        /* If the job current status is 'deferred' then the job has to be pending\r
-         * in the timeouts queue. */\r
-        else if( currentStatus == IOT_TASKPOOL_STATUS_DEFERRED )\r
-        {\r
-            /* Find the timer event associated with the current job. There MUST be one, hence assert if not. */\r
-            IotLink_t * pTimerEventLink = IotListDouble_FindFirstMatch( &pTaskPool->timerEventsList, NULL, _matchJobByPointer, pJob );\r
-            IotTaskPool_Assert( pTimerEventLink != NULL );\r
-\r
-            if( pTimerEventLink != NULL )\r
-            {\r
-                bool shouldReschedule = false;\r
-\r
-                /* If the job being canceled was at the head of the timeouts queue, then we need to reschedule the timer\r
-                 * with the next job timeout */\r
-                IotLink_t * pHeadLink = IotListDouble_PeekHead( &pTaskPool->timerEventsList );\r
-\r
-                if( pHeadLink == pTimerEventLink )\r
-                {\r
-                    shouldReschedule = true;\r
-                }\r
-\r
-                /* Remove the timer event associated with the canceled job and free the associated memory. */\r
-                IotListDouble_Remove( pTimerEventLink );\r
-                IotTaskPool_FreeTimerEvent( IotLink_Container( _taskPoolTimerEvent_t, pTimerEventLink, link ) );\r
-\r
-                if( shouldReschedule )\r
-                {\r
-                    IotLink_t * pNextTimerEventLink = IotListDouble_PeekHead( &pTaskPool->timerEventsList );\r
-\r
-                    if( pNextTimerEventLink != NULL )\r
-                    {\r
-                        _rescheduleDeferredJobsTimer( pTaskPool->timer, IotLink_Container( _taskPoolTimerEvent_t, pNextTimerEventLink, link ) );\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        else\r
-        {\r
-            /* A cancelable job status should be either 'scheduled' or 'deferrred'. */\r
-            IotTaskPool_Assert( ( currentStatus == IOT_TASKPOOL_STATUS_READY ) || ( currentStatus == IOT_TASKPOOL_STATUS_CANCELED ) );\r
-        }\r
-    }\r
-\r
-    TASKPOOL_NO_FUNCTION_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static int32_t _timerEventCompare( const IotLink_t * const pTimerEventLink1,\r
-                                   const IotLink_t * const pTimerEventLink2 )\r
-{\r
-    const _taskPoolTimerEvent_t * const pTimerEvent1 = IotLink_Container( _taskPoolTimerEvent_t,\r
-                                                                          pTimerEventLink1,\r
-                                                                          link );\r
-    const _taskPoolTimerEvent_t * const pTimerEvent2 = IotLink_Container( _taskPoolTimerEvent_t,\r
-                                                                          pTimerEventLink2,\r
-                                                                          link );\r
-\r
-    if( pTimerEvent1->expirationTime < pTimerEvent2->expirationTime )\r
-    {\r
-        return -1;\r
-    }\r
-\r
-    if( pTimerEvent1->expirationTime > pTimerEvent2->expirationTime )\r
-    {\r
-        return 1;\r
-    }\r
-\r
-    return 0;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static void _rescheduleDeferredJobsTimer( TimerHandle_t const timer,\r
-                                          _taskPoolTimerEvent_t * const pFirstTimerEvent )\r
-{\r
-    uint64_t delta = 0;\r
-    TickType_t now = xTaskGetTickCount();\r
-\r
-    if( pFirstTimerEvent->expirationTime > now )\r
-    {\r
-        delta = pFirstTimerEvent->expirationTime - now;\r
-    }\r
-\r
-    if( delta < TASKPOOL_JOB_RESCHEDULE_DELAY_MS )\r
-    {\r
-        delta = TASKPOOL_JOB_RESCHEDULE_DELAY_MS; /* The job will be late... */\r
-    }\r
-\r
-    IotTaskPool_Assert( delta > 0 );\r
-\r
-    if( xTimerChangePeriod( timer, ( uint32_t ) delta, portMAX_DELAY ) == pdFAIL )\r
-    {\r
-        IotLogWarn( "Failed to re-arm timer for task pool" );\r
-    }\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static void _timerCallback( TimerHandle_t xTimer )\r
-{\r
-    _taskPool_t * pTaskPool = pvTimerGetTimerID( xTimer );\r
-\r
-    IotTaskPool_Assert( pTaskPool );\r
-\r
-    _taskPoolTimerEvent_t * pTimerEvent = NULL;\r
-\r
-    IotLogDebug( "Timer thread started for task pool %p.", pTaskPool );\r
-\r
-    /* Attempt to lock the timer mutex. Return immediately if the mutex cannot be locked.\r
-     * If this mutex cannot be locked it means that another thread is manipulating the\r
-     * timeouts list, and will reset the timer to fire again, although it will be late.\r
-     */\r
-    taskENTER_CRITICAL(); //_RB_ Critical section is too long.\r
-    {\r
-        /* Dispatch all deferred job whose timer expired, then reset the timer for the next\r
-         * job down the line. */\r
-        for( ; ; )\r
-        {\r
-            /* Peek the first event in the timer event list. */\r
-            IotLink_t * pLink = IotListDouble_PeekHead( &pTaskPool->timerEventsList );\r
-\r
-            /* Check if the timer misfired for any reason.  */\r
-            if( pLink != NULL )\r
-            {\r
-                /* Record the current time. */\r
-                TickType_t now = xTaskGetTickCount();\r
-\r
-                /* Extract the job from its envelope. */\r
-                pTimerEvent = IotLink_Container( _taskPoolTimerEvent_t, pLink, link );\r
-\r
-                /* Check if the first event should be processed now. */\r
-                if( pTimerEvent->expirationTime <= now )\r
-                {\r
-                    /*  Remove the timer event for immediate processing. */\r
-                    IotListDouble_Remove( &( pTimerEvent->link ) );\r
-                }\r
-                else\r
-                {\r
-                    /* The first element in the timer queue shouldn't be processed yet.\r
-                     * Arm the timer for when it should be processed and leave altogether. */\r
-                    _rescheduleDeferredJobsTimer( pTaskPool->timer, pTimerEvent );\r
-\r
-                    break;\r
-                }\r
-            }\r
-            /* If there are no timer events to process, terminate this thread. */\r
-            else\r
-            {\r
-                IotLogDebug( "No further timer events to process. Exiting timer thread." );\r
-\r
-                break;\r
-            }\r
-\r
-            IotLogDebug( "Scheduling job from timer event." );\r
-\r
-            /* Queue the job associated with the received timer event. */\r
-            ( void ) _scheduleInternal( pTaskPool, pTimerEvent->job );\r
-\r
-            /* Free the timer event. */\r
-            IotTaskPool_FreeTimerEvent( pTimerEvent );\r
-        }\r
-    }\r
-    taskEXIT_CRITICAL();\r
-}\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/taskpool/iot_taskpool_static_memory.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/taskpool/iot_taskpool_static_memory.c
deleted file mode 100644 (file)
index 8de4f6e..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/*\r
- * Amazon FreeRTOS Common V1.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_taskpool_static_memory.c\r
- * @brief Implementation of task pool static memory functions.\r
- */\r
-\r
-/* The config header is always included first. */\r
-#include "iot_config.h"\r
-\r
-/* This file should only be compiled if dynamic memory allocation is forbidden. */\r
-#if IOT_STATIC_MEMORY_ONLY == 1\r
-\r
-/* Standard includes. */\r
-#include <stdbool.h>\r
-#include <stddef.h>\r
-#include <string.h>\r
-\r
-/* Static memory include. */\r
-#include "private/iot_static_memory.h"\r
-\r
-/* Task pool internal include. */\r
-#include "private/iot_taskpool_internal.h"\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/* Validate static memory configuration settings. */\r
-#if IOT_TASKPOOL_JOBS_RECYCLE_LIMIT <= 0\r
-    #error "IOT_TASKPOOL_JOBS_RECYCLE_LIMIT cannot be 0 or negative."\r
-#endif\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/*\r
- * Static memory buffers and flags, allocated and zeroed at compile-time.\r
- */\r
-static bool _pInUseTaskPools[ IOT_TASKPOOLS ] = { 0 };                                                /**< @brief Task pools in-use flags. */\r
-static _taskPool_t _pTaskPools[ IOT_TASKPOOLS ] = { { .dispatchQueue = IOT_DEQUEUE_INITIALIZER } };   /**< @brief Task pools. */\r
-\r
-static bool _pInUseTaskPoolJobs[ IOT_TASKPOOL_JOBS_RECYCLE_LIMIT ] = { 0 };                                     /**< @brief Task pool jobs in-use flags. */\r
-static _taskPoolJob_t _pTaskPoolJobs[ IOT_TASKPOOL_JOBS_RECYCLE_LIMIT ] = { { .link = IOT_LINK_INITIALIZER } }; /**< @brief Task pool jobs. */\r
-\r
-static bool _pInUseTaskPoolTimerEvents[ IOT_TASKPOOL_JOBS_RECYCLE_LIMIT ] = { 0 };                              /**< @brief Task pool timer event in-use flags. */\r
-static _taskPoolTimerEvent_t _pTaskPoolTimerEvents[ IOT_TASKPOOL_JOBS_RECYCLE_LIMIT ] = { { .link = { 0 } } };  /**< @brief Task pool timer events. */\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void * IotTaskPool_MallocTaskPool( size_t size )\r
-{\r
-    int freeIndex = -1;\r
-    void * pNewTaskPool = NULL;\r
-\r
-    /* Check size argument. */\r
-    if( size == sizeof( _taskPool_t ) )\r
-    {\r
-        /* Find a free task pool job. */\r
-        freeIndex = IotStaticMemory_FindFree( _pInUseTaskPools, IOT_TASKPOOLS );\r
-\r
-        if( freeIndex != -1 )\r
-        {\r
-            pNewTaskPool = &( _pTaskPools[ freeIndex ] );\r
-        }\r
-    }\r
-\r
-    return pNewTaskPool;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void IotTaskPool_FreeTaskPool( void * ptr )\r
-{\r
-    /* Return the in-use task pool job. */\r
-    IotStaticMemory_ReturnInUse( ptr,\r
-                                 _pTaskPools,\r
-                                 _pInUseTaskPools,\r
-                                 IOT_TASKPOOLS,\r
-                                 sizeof( _taskPool_t ) );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void * IotTaskPool_MallocJob( size_t size )\r
-{\r
-    int32_t freeIndex = -1;\r
-    void * pNewJob = NULL;\r
-\r
-    /* Check size argument. */\r
-    if( size == sizeof( _taskPoolJob_t ) )\r
-    {\r
-        /* Find a free task pool job. */\r
-        freeIndex = IotStaticMemory_FindFree( _pInUseTaskPoolJobs,\r
-                                              IOT_TASKPOOL_JOBS_RECYCLE_LIMIT );\r
-\r
-        if( freeIndex != -1 )\r
-        {\r
-            pNewJob = &( _pTaskPoolJobs[ freeIndex ] );\r
-        }\r
-    }\r
-\r
-    return pNewJob;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void IotTaskPool_FreeJob( void * ptr )\r
-{\r
-    /* Return the in-use task pool job. */\r
-    IotStaticMemory_ReturnInUse( ptr,\r
-                                 _pTaskPoolJobs,\r
-                                 _pInUseTaskPoolJobs,\r
-                                 IOT_TASKPOOL_JOBS_RECYCLE_LIMIT,\r
-                                 sizeof( _taskPoolJob_t ) );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void * IotTaskPool_MallocTimerEvent( size_t size )\r
-{\r
-    int32_t freeIndex = -1;\r
-    void * pNewTimerEvent = NULL;\r
-\r
-    /* Check size argument. */\r
-    if( size == sizeof( _taskPoolTimerEvent_t ) )\r
-    {\r
-        /* Find a free task pool timer event. */\r
-        freeIndex = IotStaticMemory_FindFree( _pInUseTaskPoolTimerEvents,\r
-                                              IOT_TASKPOOL_JOBS_RECYCLE_LIMIT );\r
-\r
-        if( freeIndex != -1 )\r
-        {\r
-            pNewTimerEvent = &( _pTaskPoolTimerEvents[ freeIndex ] );\r
-        }\r
-    }\r
-\r
-    return pNewTimerEvent;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void IotTaskPool_FreeTimerEvent( void * ptr )\r
-{\r
-    /* Return the in-use task pool timer event. */\r
-    IotStaticMemory_ReturnInUse( ptr,\r
-                                 _pTaskPoolTimerEvents,\r
-                                 _pInUseTaskPoolTimerEvents,\r
-                                 IOT_TASKPOOL_JOBS_RECYCLE_LIMIT,\r
-                                 sizeof( _taskPoolTimerEvent_t ) );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-#endif\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/include/iot_mqtt.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/include/iot_mqtt.h
deleted file mode 100644 (file)
index 327784a..0000000
+++ /dev/null
@@ -1,823 +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.h\r
- * @brief User-facing functions of the MQTT 3.1.1 library.\r
- */\r
-\r
-#ifndef IOT_MQTT_H_\r
-#define IOT_MQTT_H_\r
-\r
-/* The config header is always included first. */\r
-#include "iot_config.h"\r
-\r
-/* MQTT types include. */\r
-#include "types/iot_mqtt_types.h"\r
-\r
-/*------------------------- MQTT library functions --------------------------*/\r
-\r
-/**\r
- * @functionspage{mqtt,MQTT library}\r
- * - @functionname{mqtt_function_init}\r
- * - @functionname{mqtt_function_cleanup}\r
- * - @functionname{mqtt_function_receivecallback}\r
- * - @functionname{mqtt_function_connect}\r
- * - @functionname{mqtt_function_disconnect}\r
- * - @functionname{mqtt_function_subscribe}\r
- * - @functionname{mqtt_function_timedsubscribe}\r
- * - @functionname{mqtt_function_unsubscribe}\r
- * - @functionname{mqtt_function_timedunsubscribe}\r
- * - @functionname{mqtt_function_publish}\r
- * - @functionname{mqtt_function_timedpublish}\r
- * - @functionname{mqtt_function_wait}\r
- * - @functionname{mqtt_function_strerror}\r
- * - @functionname{mqtt_function_operationtype}\r
- * - @functionname{mqtt_function_issubscribed}\r
- */\r
-\r
-/**\r
- * @functionpage{IotMqtt_Init,mqtt,init}\r
- * @functionpage{IotMqtt_Cleanup,mqtt,cleanup}\r
- * @functionpage{IotMqtt_ReceiveCallback,mqtt,receivecallback}\r
- * @functionpage{IotMqtt_Connect,mqtt,connect}\r
- * @functionpage{IotMqtt_Disconnect,mqtt,disconnect}\r
- * @functionpage{IotMqtt_Subscribe,mqtt,subscribe}\r
- * @functionpage{IotMqtt_TimedSubscribe,mqtt,timedsubscribe}\r
- * @functionpage{IotMqtt_Unsubscribe,mqtt,unsubscribe}\r
- * @functionpage{IotMqtt_TimedUnsubscribe,mqtt,timedunsubscribe}\r
- * @functionpage{IotMqtt_Publish,mqtt,publish}\r
- * @functionpage{IotMqtt_TimedPublish,mqtt,timedpublish}\r
- * @functionpage{IotMqtt_Wait,mqtt,wait}\r
- * @functionpage{IotMqtt_strerror,mqtt,strerror}\r
- * @functionpage{IotMqtt_OperationType,mqtt,operationtype}\r
- * @functionpage{IotMqtt_IsSubscribed,mqtt,issubscribed}\r
- */\r
-\r
-/**\r
- * @brief One-time initialization function for the MQTT library.\r
- *\r
- * This function performs setup of the MQTT library. <b>It must be called\r
- * once (and only once) before calling any other MQTT function.</b> Calling this\r
- * function more than once without first calling @ref mqtt_function_cleanup\r
- * may result in a crash.\r
- *\r
- * @return One of the following:\r
- * - #IOT_MQTT_SUCCESS\r
- * - #IOT_MQTT_INIT_FAILED\r
- *\r
- * @warning No thread-safety guarantees are provided for this function.\r
- *\r
- * @see @ref mqtt_function_cleanup\r
- */\r
-/* @[declare_mqtt_init] */\r
-IotMqttError_t IotMqtt_Init( void );\r
-/* @[declare_mqtt_init] */\r
-\r
-/**\r
- * @brief One-time deinitialization function for the MQTT library.\r
- *\r
- * This function frees resources taken in @ref mqtt_function_init. It should be\r
- * called after [closing all MQTT connections](@ref mqtt_function_disconnect) to\r
- * clean up the MQTT library. After this function returns, @ref mqtt_function_init\r
- * must be called again before calling any other MQTT function.\r
- *\r
- * @warning No thread-safety guarantees are provided for this function. Do not\r
- * call this function if any MQTT connections are open!\r
- *\r
- * @see @ref mqtt_function_init\r
- */\r
-/* @[declare_mqtt_cleanup] */\r
-void IotMqtt_Cleanup( void );\r
-/* @[declare_mqtt_cleanup] */\r
-\r
-/**\r
- * @brief Network receive callback for the MQTT library.\r
- *\r
- * This function should be called by the system whenever data is available for\r
- * the MQTT library.\r
- *\r
- * @param[in] pNetworkConnection The network connection associated with the MQTT\r
- * connection, passed by the network stack.\r
- * @param[in] pReceiveContext A pointer to the MQTT connection handle for which\r
- * the packet was received.\r
- */\r
-/* @[declare_mqtt_receivecallback] */\r
-void IotMqtt_ReceiveCallback( void * pNetworkConnection,\r
-                              void * pReceiveContext );\r
-/* @[declare_mqtt_receivecallback] */\r
-\r
-/**\r
- * @brief Establish a new MQTT connection.\r
- *\r
- * This function opens a connection between a new MQTT client and an MQTT server\r
- * (also called a <i>broker</i>). MQTT connections are established on top of transport\r
- * layer protocols (such as TCP/IP), and optionally, application layer security\r
- * protocols (such as TLS). The MQTT packet that establishes a connection is called\r
- * the MQTT CONNECT packet. After @ref mqtt_function_init, this function must be\r
- * called before any other MQTT library function.\r
- *\r
- * If [pConnectInfo->cleanSession](@ref IotMqttConnectInfo_t.cleanSession) is `true`,\r
- * this function establishes a clean MQTT session. Subscriptions and unacknowledged\r
- * PUBLISH messages will be discarded when the connection is closed.\r
- *\r
- * If [pConnectInfo->cleanSession](@ref IotMqttConnectInfo_t.cleanSession) is `false`,\r
- * this function establishes (or re-establishes) a persistent MQTT session. The parameters\r
- * [pConnectInfo->pPreviousSubscriptions](@ref IotMqttConnectInfo_t.pPreviousSubscriptions)\r
- * and [pConnectInfo->previousSubscriptionCount](@ref IotMqttConnectInfo_t.previousSubscriptionCount)\r
- * may be used to restore subscriptions present in a re-established persistent session.\r
- * Any restored subscriptions <b>MUST</b> have been present in the persistent session;\r
- * <b>this function does not send an MQTT SUBSCRIBE packet!</b>\r
- *\r
- * This MQTT library is network agnostic, meaning it has no knowledge of the\r
- * underlying network protocol carrying the MQTT packets. It interacts with the\r
- * network through a network abstraction layer, allowing it to be used with many\r
- * different network stacks. The network abstraction layer is established\r
- * per-connection, allowing every #IotMqttConnection_t to use a different network\r
- * stack. The parameter `pNetworkInterface` sets up the network abstraction layer\r
- * for an MQTT connection; see the documentation on #IotMqttNetworkInfo_t for details\r
- * on its members.\r
- *\r
- * The `pConnectInfo` parameter provides the contents of the MQTT CONNECT packet.\r
- * Most members [are defined by the MQTT spec.](@ref IotMqttConnectInfo_t). The\r
- * [pConnectInfo->pWillInfo](@ref IotMqttConnectInfo_t.pWillInfo) member provides\r
- * information on a Last Will and Testament (LWT) message to be published if the\r
- * MQTT connection is closed without [sending a DISCONNECT packet]\r
- * (@ref mqtt_function_disconnect). Unlike other PUBLISH\r
- * messages, a LWT message payload is limited to 65535 bytes in length. Additionally,\r
- * the retry [interval](@ref IotMqttPublishInfo_t.retryMs) and [limit]\r
- * (@ref IotMqttPublishInfo_t.retryLimit) members of #IotMqttPublishInfo_t\r
- * are ignored for LWT messages. The LWT message is optional; `pWillInfo` may be NULL.\r
- *\r
- * Unlike @ref mqtt_function_publish, @ref mqtt_function_subscribe, and\r
- * @ref mqtt_function_unsubscribe, this function is always blocking. Additionally,\r
- * because the MQTT connection acknowledgement packet (CONNACK packet) does not\r
- * contain any information on <i>which</i> CONNECT packet it acknowledges, only one\r
- * CONNECT operation may be in progress at any time. This means that parallel\r
- * threads making calls to @ref mqtt_function_connect will be serialized to send\r
- * their CONNECT packets one-by-one.\r
- *\r
- * @param[in] pNetworkInfo Information on the transport-layer network connection\r
- * to use with the MQTT connection.\r
- * @param[in] pConnectInfo MQTT connection setup parameters.\r
- * @param[in] timeoutMs If the MQTT server does not accept the connection within\r
- * this timeout, this function returns #IOT_MQTT_TIMEOUT.\r
- * @param[out] pMqttConnection Set to a newly-initialized MQTT connection handle\r
- * if this function succeeds.\r
- *\r
- * @return One of the following:\r
- * - #IOT_MQTT_SUCCESS\r
- * - #IOT_MQTT_BAD_PARAMETER\r
- * - #IOT_MQTT_NO_MEMORY\r
- * - #IOT_MQTT_NETWORK_ERROR\r
- * - #IOT_MQTT_SCHEDULING_ERROR\r
- * - #IOT_MQTT_BAD_RESPONSE\r
- * - #IOT_MQTT_TIMEOUT\r
- * - #IOT_MQTT_SERVER_REFUSED\r
- *\r
- * <b>Example</b>\r
- * @code{c}\r
- * // An initialized and connected network connection.\r
- * IotNetworkConnection_t pNetworkConnection;\r
- *\r
- * // Parameters to MQTT connect.\r
- * IotMqttConnection_t mqttConnection = IOT_MQTT_CONNECTION_INITIALIZER;\r
- * IotMqttNetworkInfo_t networkInfo = IOT_MQTT_NETWORK_INFO_INITIALIZER;\r
- * IotMqttConnectInfo_t connectInfo = IOT_MQTT_CONNECT_INFO_INITIALIZER;\r
- * IotMqttPublishInfo_t willInfo = IOT_MQTT_PUBLISH_INFO_INITIALIZER;\r
- *\r
- * // Example network abstraction types.\r
- * IotNetworkServerInfo_t serverInfo = { ... };\r
- * IotNetworkCredentialInfo_t credentialInfo = { ... };\r
- * IotNetworkInterface_t networkInterface = { ... };\r
- *\r
- * // Example using a generic network implementation.\r
- * networkInfo.createNetworkConnection = true;\r
- * networkInfo.pNetworkServerInfo = &serverInfo;\r
- * networkInfo.pNetworkCredentialInfo = &credentialInfo;\r
- * networkInfo.pNetworkInterface = &networkInterface;\r
- *\r
- * // Set the members of the connection info (password and username not used).\r
- * connectInfo.cleanSession = true;\r
- * connectInfo.keepAliveSeconds = 30;\r
- * connectInfo.pClientIdentifier = "uniqueclientidentifier";\r
- * connectInfo.clientIdentifierLength = 22;\r
- *\r
- * // Set the members of the will info (retain and retry not used).\r
- * willInfo.qos = IOT_MQTT_QOS_1;\r
- * willInfo.pTopicName = "will/topic/name";\r
- * willInfo.topicNameLength = 15;\r
- * willInfo.pPayload = "MQTT client unexpectedly disconnected.";\r
- * willInfo.payloadLength = 38;\r
- *\r
- * // Set the pointer to the will info.\r
- * connectInfo.pWillInfo = &willInfo;\r
- *\r
- * // Call CONNECT with a 5 second block time. Should return\r
- * // IOT_MQTT_SUCCESS when successful.\r
- * IotMqttError_t result = IotMqtt_Connect( &networkInfo,\r
- *                                          &connectInfo,\r
- *                                          5000,\r
- *                                          &mqttConnection );\r
- *\r
- * if( result == IOT_MQTT_SUCCESS )\r
- * {\r
- *     // Do something with the MQTT connection...\r
- *\r
- *     // Clean up and close the MQTT connection once it's no longer needed.\r
- *     IotMqtt_Disconnect( mqttConnection, 0 );\r
- * }\r
- * @endcode\r
- */\r
-/* @[declare_mqtt_connect] */\r
-IotMqttError_t IotMqtt_Connect( const IotMqttNetworkInfo_t * pNetworkInfo,\r
-                                const IotMqttConnectInfo_t * pConnectInfo,\r
-                                uint32_t timeoutMs,\r
-                                IotMqttConnection_t * const pMqttConnection );\r
-/* @[declare_mqtt_connect] */\r
-\r
-/**\r
- * @brief Closes an MQTT connection and frees resources.\r
- *\r
- * This function closes an MQTT connection and should only be called once\r
- * the MQTT connection is no longer needed. Its exact behavior depends on the\r
- * `flags` parameter.\r
- *\r
- * Normally, `flags` should be `0`. This gracefully shuts down an MQTT\r
- * connection by sending an MQTT DISCONNECT packet. Any [network close function]\r
- * (@ref IotNetworkInterface_t::close) provided [when the connection was established]\r
- * (@ref mqtt_function_connect) will also be called. Note that because the MQTT server\r
- * will not acknowledge a DISCONNECT packet, the client has no way of knowing if\r
- * the server received the DISCONNECT packet. In the case where the DISCONNECT\r
- * packet is lost in transport, any Last Will and Testament (LWT) message established\r
- * with the connection may be published. However, if the DISCONNECT reaches the\r
- * MQTT server, the LWT message will be discarded and not published.\r
- *\r
- * Should the underlying network connection become unusable, this function should\r
- * be called with `flags` set to #IOT_MQTT_FLAG_CLEANUP_ONLY. In this case, no\r
- * DISCONNECT packet will be sent, though the [network close function](@ref IotNetworkInterface_t::close)\r
- * will still be called. This function will only free the resources used by the MQTT\r
- * connection; it still must be called even if the network is offline to avoid leaking\r
- * resources.\r
- *\r
- * Once this function is called, its parameter `mqttConnection` should no longer\r
- * be used.\r
- *\r
- * @param[in] mqttConnection The MQTT connection to close and clean up.\r
- * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
- */\r
-/* @[declare_mqtt_disconnect] */\r
-void IotMqtt_Disconnect( IotMqttConnection_t mqttConnection,\r
-                         uint32_t flags );\r
-/* @[declare_mqtt_disconnect] */\r
-\r
-/**\r
- * @brief Subscribes to the given array of topic filters and receive an asynchronous\r
- * notification when the subscribe completes.\r
- *\r
- * This function transmits an MQTT SUBSCRIBE packet to the server. A SUBSCRIBE\r
- * packet notifies the server to send any matching PUBLISH messages to this client.\r
- * A single SUBSCRIBE packet may carry more than one topic filter, hence the\r
- * parameters to this function include an array of [subscriptions]\r
- * (@ref IotMqttSubscription_t).\r
- *\r
- * An MQTT subscription has two pieces:\r
- * 1. The subscription topic filter registered with the MQTT server. The MQTT\r
- * SUBSCRIBE packet sent from this client to server notifies the server to send\r
- * messages matching the given topic filters to this client.\r
- * 2. The [callback function](@ref IotMqttCallbackInfo_t.function) that this\r
- * client will invoke when an incoming message is received. The callback function\r
- * notifies applications of an incoming PUBLISH message.\r
- *\r
- * The helper function @ref mqtt_function_issubscribed can be used to check if a\r
- * [callback function](@ref IotMqttCallbackInfo_t.function) is registered for\r
- * a particular topic filter.\r
- *\r
- * To modify an already-registered subscription callback, call this function with\r
- * a new `pSubscriptionList`. Any topic filters in `pSubscriptionList` that already\r
- * have a registered callback will be replaced with the new values in `pSubscriptionList`.\r
- *\r
- * @attention QoS 2 subscriptions are currently unsupported. Only 0 or 1 are valid\r
- * for subscription QoS.\r
- *\r
- * @param[in] mqttConnection The MQTT connection to use for the subscription.\r
- * @param[in] pSubscriptionList Pointer to the first element in the array of\r
- * subscriptions.\r
- * @param[in] subscriptionCount The number of elements in pSubscriptionList.\r
- * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
- * @param[in] pCallbackInfo Asynchronous notification of this function's completion.\r
- * @param[out] pSubscribeOperation Set to a handle by which this operation may be\r
- * referenced after this function returns. This reference is invalidated once\r
- * the subscription operation completes.\r
- *\r
- * @return This function will return #IOT_MQTT_STATUS_PENDING upon success.\r
- * @return Upon completion of the subscription (either through an\r
- * #IotMqttCallbackInfo_t or @ref mqtt_function_wait), the status will be one of:\r
- * - #IOT_MQTT_SUCCESS\r
- * - #IOT_MQTT_NETWORK_ERROR\r
- * - #IOT_MQTT_SCHEDULING_ERROR\r
- * - #IOT_MQTT_BAD_RESPONSE\r
- * - #IOT_MQTT_SERVER_REFUSED\r
- * @return If this function fails before queuing a subscribe operation, it will return\r
- * one of:\r
- * - #IOT_MQTT_BAD_PARAMETER\r
- * - #IOT_MQTT_NO_MEMORY\r
- *\r
- * @see @ref mqtt_function_timedsubscribe for a blocking variant of this function.\r
- * @see @ref mqtt_function_unsubscribe for the function that removes subscriptions.\r
- *\r
- * <b>Example</b>\r
- * @code{c}\r
- * #define NUMBER_OF_SUBSCRIPTIONS ...\r
- *\r
- * // Subscription callback function.\r
- * void subscriptionCallback( void * pArgument, IotMqttCallbackParam_t * pPublish );\r
- *\r
- * // An initialized and connected MQTT connection.\r
- * IotMqttConnection_t mqttConnection;\r
- *\r
- * // Subscription information.\r
- * pSubscriptions[ NUMBER_OF_SUBSCRIPTIONS ] = { IOT_MQTT_SUBSCRIPTION_INITIALIZER };\r
- * IotMqttOperation_t lastOperation = IOT_MQTT_OPERATION_INITIALIZER;\r
- *\r
- * // Set the subscription information.\r
- * for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )\r
- * {\r
- *     pSubscriptions[ i ].qos = IOT_MQTT_QOS_1;\r
- *     pSubscriptions[ i ].pTopicFilter = "some/topic/filter";\r
- *     pSubscriptions[ i ].topicLength = ( uint16_t ) strlen( pSubscriptions[ i ].pTopicFilter );\r
- *     pSubscriptions[ i ].callback.function = subscriptionCallback;\r
- * }\r
- *\r
- * IotMqttError_t result = IotMqtt_Subscribe( mqttConnection,\r
- *                                            pSubscriptions,\r
- *                                            NUMBER_OF_SUBSCRIPTIONS,\r
- *                                            IOT_MQTT_FLAG_WAITABLE,\r
- *                                            NULL,\r
- *                                            &lastOperation );\r
- *\r
- * // Subscribe returns IOT_MQTT_STATUS_PENDING when successful. Wait up to\r
- * // 5 seconds for the operation to complete.\r
- * if( result == IOT_MQTT_STATUS_PENDING )\r
- * {\r
- *     result = IotMqtt_Wait( subscriptionRef, 5000 );\r
- * }\r
- *\r
- * // Check that the subscriptions were successful.\r
- * if( result == IOT_MQTT_SUCCESS )\r
- * {\r
- *     // Wait for messages on the subscription topic filters...\r
- *\r
- *     // Unsubscribe once the subscriptions are no longer needed.\r
- *     result = IotMqtt_Unsubscribe( mqttConnection,\r
- *                                   pSubscriptions,\r
- *                                   NUMBER_OF_SUBSCRIPTIONS,\r
- *                                   IOT_MQTT_FLAG_WAITABLE,\r
- *                                   NULL,\r
- *                                   &lastOperation );\r
- *\r
- *     // UNSUBSCRIBE returns IOT_MQTT_STATUS_PENDING when successful.\r
- *     // Wait up to 5 seconds for the operation to complete.\r
- *     if( result == IOT_MQTT_STATUS_PENDING )\r
- *     {\r
- *         result = IotMqtt_Wait( lastOperation, 5000 );\r
- *     }\r
- * }\r
- * // Check which subscriptions were rejected by the server.\r
- * else if( result == IOT_MQTT_SERVER_REFUSED )\r
- * {\r
- *     for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )\r
- *     {\r
- *         if( IotMqtt_IsSubscribed( mqttConnection,\r
- *                                   pSubscriptions[ i ].pTopicFilter,\r
- *                                   pSubscriptions[ i ].topicFilterLength,\r
- *                                   NULL ) == false )\r
- *         {\r
- *             // This subscription was rejected.\r
- *         }\r
- *     }\r
- * }\r
- * @endcode\r
- */\r
-/* @[declare_mqtt_subscribe] */\r
-IotMqttError_t IotMqtt_Subscribe( IotMqttConnection_t mqttConnection,\r
-                                  const IotMqttSubscription_t * pSubscriptionList,\r
-                                  size_t subscriptionCount,\r
-                                  uint32_t flags,\r
-                                  const IotMqttCallbackInfo_t * pCallbackInfo,\r
-                                  IotMqttOperation_t * pSubscribeOperation );\r
-/* @[declare_mqtt_subscribe] */\r
-\r
-/**\r
- * @brief Subscribes to the given array of topic filters with a timeout.\r
- *\r
- * This function transmits an MQTT SUBSCRIBE packet to the server, then waits for\r
- * a server response to the packet. Internally, this function is a call to @ref\r
- * mqtt_function_subscribe followed by @ref mqtt_function_wait. See @ref\r
- * mqtt_function_subscribe for more information about the MQTT SUBSCRIBE operation.\r
- *\r
- * @attention QoS 2 subscriptions are currently unsupported. Only 0 or 1 are valid\r
- * for subscription QoS.\r
- *\r
- * @param[in] mqttConnection The MQTT connection to use for the subscription.\r
- * @param[in] pSubscriptionList Pointer to the first element in the array of\r
- * subscriptions.\r
- * @param[in] subscriptionCount The number of elements in pSubscriptionList.\r
- * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
- * Currently, flags are ignored by this function; this parameter is for\r
- * future-compatibility.\r
- * @param[in] timeoutMs If the MQTT server does not acknowledge the subscriptions within\r
- * this timeout, this function returns #IOT_MQTT_TIMEOUT.\r
- *\r
- * @return One of the following:\r
- * - #IOT_MQTT_SUCCESS\r
- * - #IOT_MQTT_BAD_PARAMETER\r
- * - #IOT_MQTT_NO_MEMORY\r
- * - #IOT_MQTT_NETWORK_ERROR\r
- * - #IOT_MQTT_SCHEDULING_ERROR\r
- * - #IOT_MQTT_BAD_RESPONSE\r
- * - #IOT_MQTT_TIMEOUT\r
- * - #IOT_MQTT_SERVER_REFUSED\r
- */\r
-/* @[declare_mqtt_timedsubscribe] */\r
-IotMqttError_t IotMqtt_TimedSubscribe( IotMqttConnection_t mqttConnection,\r
-                                       const IotMqttSubscription_t * pSubscriptionList,\r
-                                       size_t subscriptionCount,\r
-                                       uint32_t flags,\r
-                                       uint32_t timeoutMs );\r
-/* @[declare_mqtt_timedsubscribe] */\r
-\r
-/**\r
- * @brief Unsubscribes from the given array of topic filters and receive an asynchronous\r
- * notification when the unsubscribe completes.\r
- *\r
- * This function transmits an MQTT UNSUBSCRIBE packet to the server. An UNSUBSCRIBE\r
- * packet removes registered topic filters from the server. After unsubscribing,\r
- * the server will no longer send messages on these topic filters to the client.\r
- *\r
- * Corresponding [subscription callback functions](@ref IotMqttCallbackInfo_t.function)\r
- * are also removed from the MQTT connection. These subscription callback functions\r
- * will be removed even if the MQTT UNSUBSCRIBE packet fails to send.\r
- *\r
- * @param[in] mqttConnection The MQTT connection used for the subscription.\r
- * @param[in] pSubscriptionList Pointer to the first element in the array of\r
- * subscriptions.\r
- * @param[in] subscriptionCount The number of elements in pSubscriptionList.\r
- * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
- * @param[in] pCallbackInfo Asynchronous notification of this function's completion.\r
- * @param[out] pUnsubscribeOperation Set to a handle by which this operation may be\r
- * referenced after this function returns. This reference is invalidated once\r
- * the unsubscribe operation completes.\r
- *\r
- * @return This function will return #IOT_MQTT_STATUS_PENDING upon success.\r
- * @return Upon completion of the unsubscribe (either through an\r
- * #IotMqttCallbackInfo_t or @ref mqtt_function_wait), the status will be one of:\r
- * - #IOT_MQTT_SUCCESS\r
- * - #IOT_MQTT_NETWORK_ERROR\r
- * - #IOT_MQTT_SCHEDULING_ERROR\r
- * - #IOT_MQTT_BAD_RESPONSE\r
- * @return If this function fails before queuing an unsubscribe operation, it will return\r
- * one of:\r
- * - #IOT_MQTT_BAD_PARAMETER\r
- * - #IOT_MQTT_NO_MEMORY\r
- *\r
- * @see @ref mqtt_function_timedsubscribe for a blocking variant of this function.\r
- * @see @ref mqtt_function_subscribe for the function that adds subscriptions.\r
- */\r
-/* @[declare_mqtt_unsubscribe] */\r
-IotMqttError_t IotMqtt_Unsubscribe( IotMqttConnection_t mqttConnection,\r
-                                    const IotMqttSubscription_t * pSubscriptionList,\r
-                                    size_t subscriptionCount,\r
-                                    uint32_t flags,\r
-                                    const IotMqttCallbackInfo_t * pCallbackInfo,\r
-                                    IotMqttOperation_t * pUnsubscribeOperation );\r
-/* @[declare_mqtt_unsubscribe] */\r
-\r
-/**\r
- * @brief Unsubscribes from a given array of topic filters with a timeout.\r
- *\r
- * This function transmits an MQTT UNSUBSCRIBE packet to the server, then waits\r
- * for a server response to the packet. Internally, this function is a call to\r
- * @ref mqtt_function_unsubscribe followed by @ref mqtt_function_wait. See @ref\r
- * mqtt_function_unsubscribe for more information about the MQTT UNSUBSCRIBE\r
- * operation.\r
- *\r
- * @param[in] mqttConnection The MQTT connection used for the subscription.\r
- * @param[in] pSubscriptionList Pointer to the first element in the array of\r
- * subscriptions.\r
- * @param[in] subscriptionCount The number of elements in pSubscriptionList.\r
- * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
- * Currently, flags are ignored by this function; this parameter is for\r
- * future-compatibility.\r
- * @param[in] timeoutMs If the MQTT server does not acknowledge the UNSUBSCRIBE within\r
- * this timeout, this function returns #IOT_MQTT_TIMEOUT.\r
- *\r
- * @return One of the following:\r
- * - #IOT_MQTT_SUCCESS\r
- * - #IOT_MQTT_BAD_PARAMETER\r
- * - #IOT_MQTT_NO_MEMORY\r
- * - #IOT_MQTT_NETWORK_ERROR\r
- * - #IOT_MQTT_SCHEDULING_ERROR\r
- * - #IOT_MQTT_BAD_RESPONSE\r
- */\r
-/* @[declare_mqtt_timedunsubscribe] */\r
-IotMqttError_t IotMqtt_TimedUnsubscribe( IotMqttConnection_t mqttConnection,\r
-                                         const IotMqttSubscription_t * pSubscriptionList,\r
-                                         size_t subscriptionCount,\r
-                                         uint32_t flags,\r
-                                         uint32_t timeoutMs );\r
-/* @[declare_mqtt_timedunsubscribe] */\r
-\r
-/**\r
- * @brief Publishes a message to the given topic name and receive an asynchronous\r
- * notification when the publish completes.\r
- *\r
- * This function transmits an MQTT PUBLISH packet to the server. A PUBLISH packet\r
- * contains a payload and a topic name. Any clients with a subscription on a\r
- * topic filter matching the PUBLISH topic name will receive a copy of the\r
- * PUBLISH packet from the server.\r
- *\r
- * If a PUBLISH packet fails to reach the server and it is not a QoS 0 message,\r
- * it will be retransmitted. See #IotMqttPublishInfo_t for a description\r
- * of the retransmission strategy.\r
- *\r
- * @attention QoS 2 messages are currently unsupported. Only 0 or 1 are valid\r
- * for message QoS.\r
- *\r
- * @param[in] mqttConnection The MQTT connection to use for the publish.\r
- * @param[in] pPublishInfo MQTT publish parameters.\r
- * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
- * @param[in] pCallbackInfo Asynchronous notification of this function's completion.\r
- * @param[out] pPublishOperation Set to a handle by which this operation may be\r
- * referenced after this function returns. This reference is invalidated once\r
- * the publish operation completes.\r
- *\r
- * @return This function will return #IOT_MQTT_STATUS_PENDING upon success for\r
- * QoS 1 publishes. For a QoS 0 publish it returns #IOT_MQTT_SUCCESS upon\r
- * success.\r
- * @return Upon completion of a QoS 1 publish (either through an\r
- * #IotMqttCallbackInfo_t or @ref mqtt_function_wait), the status will be one of:\r
- * - #IOT_MQTT_SUCCESS\r
- * - #IOT_MQTT_NETWORK_ERROR\r
- * - #IOT_MQTT_SCHEDULING_ERROR\r
- * - #IOT_MQTT_BAD_RESPONSE\r
- * - #IOT_MQTT_RETRY_NO_RESPONSE (if [pPublishInfo->retryMs](@ref IotMqttPublishInfo_t.retryMs)\r
- * and [pPublishInfo->retryLimit](@ref IotMqttPublishInfo_t.retryLimit) were set).\r
- * @return If this function fails before queuing an publish operation (regardless\r
- * of QoS), it will return one of:\r
- * - #IOT_MQTT_BAD_PARAMETER\r
- * - #IOT_MQTT_NO_MEMORY\r
- *\r
- * @note The parameters `pCallbackInfo` and `pPublishOperation` should only be used for QoS\r
- * 1 publishes. For QoS 0, they should both be `NULL`.\r
- *\r
- * @see @ref mqtt_function_timedpublish for a blocking variant of this function.\r
- *\r
- * <b>Example</b>\r
- * @code{c}\r
- * // An initialized and connected MQTT connection.\r
- * IotMqttConnection_t mqttConnection;\r
- *\r
- * // Publish information.\r
- * IotMqttPublishInfo_t publishInfo = IOT_MQTT_PUBLISH_INFO_INITIALIZER;\r
- *\r
- * // Set the publish information. QoS 0 example (retain not used):\r
- * publishInfo.qos = IOT_MQTT_QOS_0;\r
- * publishInfo.pTopicName = "some/topic/name";\r
- * publishInfo.topicNameLength = 15;\r
- * publishInfo.pPayload = "payload";\r
- * publishInfo.payloadLength = 8;\r
- *\r
- * // QoS 0 publish should return IOT_MQTT_SUCCESS upon success.\r
- * IotMqttError_t qos0Result = IotMqtt_Publish( mqttConnection,\r
- *                                              &publishInfo,\r
- *                                              0,\r
- *                                              NULL,\r
- *                                              NULL );\r
- *\r
- * // QoS 1 with retry example (using same topic name and payload as QoS 0 example):\r
- * IotMqttOperation_t qos1Operation = IOT_MQTT_OPERATION_INITIALIZER;\r
- * publishInfo.qos = IOT_MQTT_QOS_1;\r
- * publishInfo.retryMs = 1000; // Retry if no response is received in 1 second.\r
- * publishInfo.retryLimit = 5; // Retry up to 5 times.\r
- *\r
- * // QoS 1 publish should return IOT_MQTT_STATUS_PENDING upon success.\r
- * IotMqttError_t qos1Result = IotMqtt_Publish( mqttConnection,\r
- *                                              &publishInfo,\r
- *                                              IOT_MQTT_FLAG_WAITABLE,\r
- *                                              NULL,\r
- *                                              &qos1Operation );\r
- *\r
- * // Wait up to 5 seconds for the publish to complete.\r
- * if( qos1Result == IOT_MQTT_STATUS_PENDING )\r
- * {\r
- *     qos1Result = IotMqtt_Wait( qos1Operation, 5000 );\r
- * }\r
- * @endcode\r
- */\r
-/* @[declare_mqtt_publish] */\r
-IotMqttError_t IotMqtt_Publish( IotMqttConnection_t mqttConnection,\r
-                                const IotMqttPublishInfo_t * pPublishInfo,\r
-                                uint32_t flags,\r
-                                const IotMqttCallbackInfo_t * pCallbackInfo,\r
-                                IotMqttOperation_t * pPublishOperation );\r
-/* @[declare_mqtt_publish] */\r
-\r
-/**\r
- * @brief Publish a message to the given topic name with a timeout.\r
- *\r
- * This function transmits an MQTT PUBLISH packet to the server, then waits for\r
- * a server response to the packet. Internally, this function is a call to @ref\r
- * mqtt_function_publish followed by @ref mqtt_function_wait. See @ref\r
- * mqtt_function_publish for more information about the MQTT PUBLISH operation.\r
- *\r
- * @attention QoS 2 messages are currently unsupported. Only 0 or 1 are valid\r
- * for message QoS.\r
- *\r
- * @param[in] mqttConnection The MQTT connection to use for the publish.\r
- * @param[in] pPublishInfo MQTT publish parameters.\r
- * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
- * Currently, flags are ignored by this function; this parameter is for\r
- * future-compatibility.\r
- * @param[in] timeoutMs If the MQTT server does not acknowledge a QoS 1 PUBLISH\r
- * within this timeout, this function returns #IOT_MQTT_TIMEOUT. This parameter\r
- * is ignored for QoS 0 PUBLISH messages.\r
- *\r
- * @return One of the following:\r
- * - #IOT_MQTT_SUCCESS\r
- * - #IOT_MQTT_BAD_PARAMETER\r
- * - #IOT_MQTT_NO_MEMORY\r
- * - #IOT_MQTT_NETWORK_ERROR\r
- * - #IOT_MQTT_SCHEDULING_ERROR\r
- * - #IOT_MQTT_BAD_RESPONSE\r
- * - #IOT_MQTT_RETRY_NO_RESPONSE (if [pPublishInfo->retryMs](@ref IotMqttPublishInfo_t.retryMs)\r
- * and [pPublishInfo->retryLimit](@ref IotMqttPublishInfo_t.retryLimit) were set).\r
- */\r
-/* @[declare_mqtt_timedpublish] */\r
-IotMqttError_t IotMqtt_TimedPublish( IotMqttConnection_t mqttConnection,\r
-                                     const IotMqttPublishInfo_t * pPublishInfo,\r
-                                     uint32_t flags,\r
-                                     uint32_t timeoutMs );\r
-/* @[declare_mqtt_timedpublish] */\r
-\r
-/**\r
- * @brief Waits for an operation to complete.\r
- *\r
- * This function blocks to wait for a [subscribe](@ref mqtt_function_subscribe),\r
- * [unsubscribe](@ref mqtt_function_unsubscribe), or [publish]\r
- * (@ref mqtt_function_publish) to complete. These operations are by default\r
- * asynchronous; the function calls queue an operation for processing, and a\r
- * callback is invoked once the operation is complete.\r
- *\r
- * To use this function, the flag #IOT_MQTT_FLAG_WAITABLE must have been\r
- * set in the operation's function call. Additionally, this function must always\r
- * be called with any waitable operation to clean up resources.\r
- *\r
- * Regardless of its return value, this function always clean up resources used\r
- * by the waitable operation. This means `reference` is invalidated as soon as\r
- * this function returns, even if it returns #IOT_MQTT_TIMEOUT or another error.\r
- *\r
- * @param[in] operation Reference to the operation to wait for. The flag\r
- * #IOT_MQTT_FLAG_WAITABLE must have been set for this operation.\r
- * @param[in] timeoutMs How long to wait before returning #IOT_MQTT_TIMEOUT.\r
- *\r
- * @return The return value of this function depends on the MQTT operation associated\r
- * with `reference`. See #IotMqttError_t for possible return values.\r
- *\r
- * <b>Example</b>\r
- * @code{c}\r
- * // Operation reference and timeout.\r
- * IotMqttOperation_t publishOperation = IOT_MQTT_OPERATION_INITIALIZER;\r
- * uint32_t timeoutMs = 5000; // 5 seconds\r
- *\r
- * // MQTT operation to wait for.\r
- * IotMqttError_t result = IotMqtt_Publish( mqttConnection,\r
- *                                          &publishInfo,\r
- *                                          IOT_MQTT_FLAG_WAITABLE,\r
- *                                          NULL,\r
- *                                          &publishOperation );\r
- *\r
- * // Publish should have returned IOT_MQTT_STATUS_PENDING. The call to wait\r
- * // returns once the result of the publish is available or the timeout expires.\r
- * if( result == IOT_MQTT_STATUS_PENDING )\r
- * {\r
- *     result = IotMqtt_Wait( publishOperation, timeoutMs );\r
- *\r
- *     // After the call to wait, the result of the publish is known\r
- *     // (not IOT_MQTT_STATUS_PENDING).\r
- *     assert( result != IOT_MQTT_STATUS_PENDING );\r
- * }\r
- * @endcode\r
- */\r
-/* @[declare_mqtt_wait] */\r
-IotMqttError_t IotMqtt_Wait( IotMqttOperation_t operation,\r
-                             uint32_t timeoutMs );\r
-/* @[declare_mqtt_wait] */\r
-\r
-/*-------------------------- MQTT helper functions --------------------------*/\r
-\r
-/**\r
- * @brief Returns a string that describes an #IotMqttError_t.\r
- *\r
- * Like the POSIX's `strerror`, this function returns a string describing a\r
- * return code. In this case, the return code is an MQTT library error code,\r
- * `status`.\r
- *\r
- * The string returned by this function <b>MUST</b> be treated as read-only: any\r
- * attempt to modify its contents may result in a crash. Therefore, this function\r
- * is limited to usage in logging.\r
- *\r
- * @param[in] status The status to describe.\r
- *\r
- * @return A read-only string that describes `status`.\r
- *\r
- * @warning The string returned by this function must never be modified.\r
- */\r
-/* @[declare_mqtt_strerror] */\r
-const char * IotMqtt_strerror( IotMqttError_t status );\r
-/* @[declare_mqtt_strerror] */\r
-\r
-/**\r
- * @brief Returns a string that describes an #IotMqttOperationType_t.\r
- *\r
- * This function returns a string describing an MQTT operation type, `operation`.\r
- *\r
- * The string returned by this function <b>MUST</b> be treated as read-only: any\r
- * attempt to modify its contents may result in a crash. Therefore, this function\r
- * is limited to usage in logging.\r
- *\r
- * @param[in] operation The operation to describe.\r
- *\r
- * @return A read-only string that describes `operation`.\r
- *\r
- * @warning The string returned by this function must never be modified.\r
- */\r
-/* @[declare_mqtt_operationtype] */\r
-const char * IotMqtt_OperationType( IotMqttOperationType_t operation );\r
-/* @[declare_mqtt_operationtype] */\r
-\r
-/**\r
- * @brief Check if an MQTT connection has a subscription for a topic filter.\r
- *\r
- * This function checks whether an MQTT connection `mqttConnection` has a\r
- * subscription callback registered for a topic filter `pTopicFilter`. If a\r
- * subscription callback is found, its details are copied into the output parameter\r
- * `pCurrentSubscription`. This subscription callback will be invoked for incoming\r
- * PUBLISH messages on `pTopicFilter`.\r
- *\r
- * <b>The check for a matching subscription is only performed client-side</b>;\r
- * therefore, this function should not be relied upon for perfect accuracy. For\r
- * example, this function may return an incorrect result if the MQTT server\r
- * crashes and drops subscriptions without informing the client.\r
- *\r
- * Note that an MQTT connection's subscriptions might change between the time this\r
- * function checks the subscription list and its caller tests the return value.\r
- * This function certainly should not be used concurrently with any pending SUBSCRIBE\r
- * or UNSUBSCRIBE operations.\r
- *\r
- * One suitable use of this function is to check <i>which</i> subscriptions were rejected\r
- * if @ref mqtt_function_subscribe returns #IOT_MQTT_SERVER_REFUSED; that return\r
- * code only means that <i>at least one</i> subscription was rejected.\r
- *\r
- * @param[in] mqttConnection The MQTT connection to check.\r
- * @param[in] pTopicFilter The topic filter to check.\r
- * @param[in] topicFilterLength Length of `pTopicFilter`.\r
- * @param[out] pCurrentSubscription If a subscription is found, its details are\r
- * copied here. This output parameter is only valid if this function returns `true`.\r
- * Pass `NULL` to ignore.\r
- *\r
- * @return `true` if a subscription was found; `false` otherwise.\r
- *\r
- * @note The subscription QoS is not stored by the MQTT library; therefore,\r
- * `pCurrentSubscription->qos` will always be set to #IOT_MQTT_QOS_0.\r
- */\r
-/* @[declare_mqtt_issubscribed] */\r
-bool IotMqtt_IsSubscribed( IotMqttConnection_t mqttConnection,\r
-                           const char * pTopicFilter,\r
-                           uint16_t topicFilterLength,\r
-                           IotMqttSubscription_t * pCurrentSubscription );\r
-/* @[declare_mqtt_issubscribed] */\r
-\r
-#endif /* ifndef IOT_MQTT_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/include/iot_mqtt_agent.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/include/iot_mqtt_agent.h
deleted file mode 100644 (file)
index fbaaeb7..0000000
+++ /dev/null
@@ -1,358 +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_agent.h\r
- * @brief MQTT Agent Interface.\r
- */\r
-\r
-#ifndef _AWS_MQTT_AGENT_H_\r
-#define _AWS_MQTT_AGENT_H_\r
-\r
-/* FreeRTOS includes. */\r
-#include "FreeRTOS.h"\r
-\r
-/* MQTT lib includes. */\r
-#include "iot_mqtt_lib.h"\r
-\r
-/* Library initialization definition include */\r
-#include "iot_lib_init.h"\r
-\r
-/**\r
- * @brief Opaque handle to represent an MQTT client.\r
- *\r
- * The MQTT library is capable of creating multiple MQTT clients, maximum number of which\r
- * is controlled by mqttconfigMAX_BROKERS macro. Each client is identified by an opaque\r
- * handle which is returned by the MQTT_AGENT_Create API call and later used in all\r
- * the subsequent API calls.\r
- */\r
-typedef void * MQTTAgentHandle_t;\r
-\r
-/**\r
- * @brief Return codes.\r
- *\r
- * Each API returns a value of this type.\r
- */\r
-typedef enum\r
-{\r
-    eMQTTAgentSuccess,              /**< The operation was successful. */\r
-    eMQTTAgentFailure,              /**< The operation failed. */\r
-    eMQTTAgentTimeout,              /**< The operation timed out. */\r
-    eMQTTAgentAPICalledFromCallback /**< The MQTT agent APIs must not be called from MQTT callbacks as callbacks run\r
-                                     *   in the context of MQTT agent task and therefore can result in deadlock. This\r
-                                     *   error code is returned if any MQTT agent API is invoked from any callback. */\r
-} MQTTAgentReturnCode_t;\r
-\r
-/**\r
- * @brief Various events reported by the library in the callback.\r
- *\r
- * The user can register an optional callback with the MQTT library to\r
- * get notified of various events including Publish messages received\r
- * from the broker. This enum identifies the event received in the\r
- * callback.\r
- */\r
-typedef enum\r
-{\r
-    eMQTTAgentPublish,   /**< A Publish message was received from the broker. */\r
-    eMQTTAgentDisconnect /**< The connection to the broker got disconnected. */\r
-} MQTTAgentEvent_t;\r
-\r
-/**\r
- * @brief Passed by the library in the callback to inform the user of various events.\r
- *\r
- * If the user has registered a callback to get notified of various events, a pointer\r
- * to this structure is passed in the callback function.\r
- * @see MQTTAgentEvent_t.\r
- */\r
-typedef struct MQTTAgentCallbackParams\r
-{\r
-    MQTTAgentEvent_t xMQTTEvent; /**< Type of the event received. */\r
-    /* This union is here for future support. */\r
-    union\r
-    {\r
-        MQTTPublishData_t xPublishData; /**< Publish data. Meaningful only in case of eMQTTAgentPublish event. */\r
-    } u;\r
-} MQTTAgentCallbackParams_t;\r
-\r
-/**\r
- * @brief Signature of the callback registered by the user to get notified of various events.\r
- *\r
- * The user can register an optional callback to get notified of various events.\r
- *\r
- * @param[in] pvUserData The user data as provided in the connect parameters while connecting.\r
- * @param[in] pxCallbackParams The event and related data.\r
- *\r
- * @return The return value is ignored in all other cases except publish (i.e. eMQTTAgentPublish\r
- * event):\r
- * 1. If pdTRUE is returned - The ownership of the buffer passed in the callback (xBuffer\r
- * in MQTTPublishData_t) lies with the user.\r
- * 2. If pdFALSE is returned - The ownership of the buffer passed in the callback (xBuffer\r
- * in MQTTPublishData_t) remains with the library and it is recycled as soon as\r
- * the callback returns.<br>\r
- * The user should take the ownership of the buffer containing the received message from the\r
- * broker by returning pdTRUE from the callback if the user wants to use the buffer after\r
- * the callback is over. The user should return the buffer whenever done by calling the\r
- * MQTT_AGENT_ReturnBuffer API.\r
- *\r
- * @see MQTTAgentCallbackParams_t.\r
- */\r
-typedef BaseType_t ( * MQTTAgentCallback_t )( void * pvUserData,\r
-                                              const MQTTAgentCallbackParams_t * const pxCallbackParams );\r
-\r
-/**\r
- * @brief Flags for the MQTT agent connect params.\r
- */\r
-#define mqttagentURL_IS_IP_ADDRESS       0x00000001    /**< Set this bit in xFlags if the provided URL is an IP address. */\r
-#define mqttagentREQUIRE_TLS             0x00000002    /**< Set this bit in xFlags to use TLS. */\r
-#define mqttagentUSE_AWS_IOT_ALPN_443    0x00000004    /**< Set this bit in xFlags to use AWS IoT support for MQTT over TLS port 443. */\r
-\r
-/**\r
- * @brief Parameters passed to the MQTT_AGENT_Connect API.\r
- */\r
-typedef struct MQTTAgentConnectParams\r
-{\r
-    const char * pcURL;             /**< The URL of the MQTT broker to connect to. */\r
-    BaseType_t xFlags;              /**< Flags to control the behavior of MQTT connect. */\r
-    BaseType_t xURLIsIPAddress;     /**< Deprecated. Set the mqttagentURL_IS_IP_ADDRESS bit in xFlags instead. */\r
-    uint16_t usPort;                /**< Port number at which MQTT broker is listening. This field is ignored if the mqttagentUSE_AWS_IOT_ALPN_443 flag is set. */\r
-    const uint8_t * pucClientId;    /**< Client Identifier of the MQTT client. It should be unique per broker. */\r
-    uint16_t usClientIdLength;      /**< The length of the client Id. */\r
-    BaseType_t xSecuredConnection;  /**< Deprecated. Set the mqttagentREQUIRE_TLS bit in xFlags instead. */\r
-    void * pvUserData;              /**< User data supplied back as it is in the callback. Can be NULL. */\r
-    MQTTAgentCallback_t pxCallback; /**< Callback used to report various events. In addition to other events, this callback is invoked for the publish\r
-                                     *   messages received on the topics for which the user has not registered any subscription callback. Can be NULL. */\r
-    char * pcCertificate;           /**< Certificate used for secure connection. Can be NULL. If it is NULL, the one specified in the aws_credential_keys.h is used. */\r
-    uint32_t ulCertificateSize;     /**< Size of certificate used for secure connection. */\r
-} MQTTAgentConnectParams_t;\r
-\r
-/**\r
- * @brief Parameters passed to the MQTT_AGENT_Subscribe API.\r
- */\r
-typedef struct MQTTAgentSubscribeParams\r
-{\r
-    const uint8_t * pucTopic;                    /**< The topic to subscribe to. This can be a topic filter containing wild cards as permitted by the MQTT protocol. */\r
-    uint16_t usTopicLength;                      /**< The length of the topic. */\r
-    MQTTQoS_t xQoS;                              /**< Requested Quality of Service. */\r
-    #if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 )\r
-        void * pvPublishCallbackContext;         /**< Passed as it is in the publish callback. Can be NULL. */\r
-        MQTTPublishCallback_t pxPublishCallback; /**< Callback function to be called whenever a publish message is received on this topic or on a topic which matches this\r
-                                                  *   topic filter. If a publish message is received on a topic which matches more than one topic filters, the order in which\r
-                                                  *   the callbacks are invoked is undefined. This can be NULL if the user does not want to register a topic specific callback,\r
-                                                  *   in which case the generic callback ( if registered during connect ) is invoked. */\r
-    #endif /* mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT */\r
-} MQTTAgentSubscribeParams_t;\r
-\r
-/**\r
- * @brief Parameters passed to the MQTT_AGENT_Unsubscribe API.\r
- */\r
-typedef struct MQTTAgentUnsubscribeParams\r
-{\r
-    const uint8_t * pucTopic; /**< The topic to unsubscribe from. */\r
-    uint16_t usTopicLength;   /**< The length of the topic. */\r
-} MQTTAgentUnsubscribeParams_t;\r
-\r
-/**\r
- * @brief Parameters passed to the MQTT_AGENT_Publish API.\r
- */\r
-typedef struct MQTTAgentPublishParams\r
-{\r
-    const uint8_t * pucTopic; /**< The topic string on which the message should be published. */\r
-    uint16_t usTopicLength;   /**< The length of the topic. */\r
-    MQTTQoS_t xQoS;           /**< Quality of Service (qos). */\r
-    const void * pvData;      /**< The data to publish. This data is copied into the MQTT buffers and therefore the user can free the buffer after the MQTT_AGENT_Publish call returns. */\r
-    uint32_t ulDataLength;    /**< Length of the data. */\r
-} MQTTAgentPublishParams_t;\r
-\r
-/**\r
- * @brief MQTT library Init function.\r
- *\r
- * This function does general initialization and setup. It must be called once\r
- * and only once before calling any other function.\r
- *\r
- * @return pdPASS if everything succeeds, pdFAIL otherwise.\r
- */\r
-lib_initDECLARE_LIB_INIT( MQTT_AGENT_Init );\r
-\r
-/**\r
- * @brief Creates a new MQTT client.\r
- *\r
- * The MQTT library is capable of creating multiple MQTT clients, maximum number of which\r
- * is controlled by mqttconfigMAX_BROKERS macro. If mqttconfigMAX_BROKERS clients are already\r
- * in use, this function will fail immediately. Otherwise a new client is setup and the handle\r
- * to the created client is returned in the pxMQTTHandle parameter which should be used in all\r
- * the subsequent API calls. Note that the returned handled is only valid if the return value\r
- * of the API is eMQTTAgentSuccess.\r
- *\r
- * @param[out] pxMQTTHandle Output parameter to return the opaque client handle.\r
- *\r
- * @return eMQTTAgentSuccess if a new client is successfully created, otherwise an error code\r
- * explaining the reason of the failure is returned.\r
- */\r
-MQTTAgentReturnCode_t MQTT_AGENT_Create( MQTTAgentHandle_t * const pxMQTTHandle );\r
-\r
-/**\r
- * @brief Deletes the already created MQTT client.\r
- *\r
- * This function just frees up the internal resources and does not disconnect. The user must\r
- * call MQTT_AGENT_Disconnect API to make sure that the client is disconnected before\r
- * deleting it.\r
- *\r
- * @param[in] xMQTTHandle The opaque handle as returned from MQTT_AGENT_Create.\r
- *\r
- * @return eMQTTAgentSuccess if the client is successfully deleted, otherwise an\r
- * error code explaining the reason of the failure is returned.\r
- */\r
-MQTTAgentReturnCode_t MQTT_AGENT_Delete( MQTTAgentHandle_t xMQTTHandle );\r
-\r
-/**\r
- * @brief Establishes a connection with the MQTT broker.\r
- *\r
- * @note This function alters the calling task's notification state and value. If xTimeoutTicks\r
- * is short the calling task's notification state and value may be updated after MQTT_AGENT_Connect()\r
- * has returned.\r
- *\r
- * @param[in] xMQTTHandle The opaque handle as returned from MQTT_AGENT_Create.\r
- * @param[in] pxConnectParams Connect parameters.\r
- * @param[in] xTimeoutTicks Maximum time in ticks after which the operation should fail. Use pdMS_TO_TICKS\r
- * macro to convert milliseconds to ticks.\r
- *\r
- * @return eMQTTAgentSuccess if the connect operation succeeds, otherwise an error code explaining the\r
- * reason of the failure is returned.\r
- */\r
-MQTTAgentReturnCode_t MQTT_AGENT_Connect( MQTTAgentHandle_t xMQTTHandle,\r
-                                          const MQTTAgentConnectParams_t * const pxConnectParams,\r
-                                          TickType_t xTimeoutTicks );\r
-\r
-/**\r
- * @brief Disconnects the connection with the MQTT broker.\r
- *\r
- * @note This function alters the calling task's notification state and value. If xTimeoutTicks\r
- * is short the calling task's notification state and value may be updated after MQTT_AGENT_Disconnect()\r
- * has returned.\r
- *\r
- * @param[in] xMQTTHandle The opaque handle as returned from MQTT_AGENT_Create.\r
- * @param[in] xTimeoutTicks Maximum time in ticks after which the operation should fail. Use pdMS_TO_TICKS\r
- * macro to convert milliseconds to ticks.\r
- *\r
- * @return eMQTTAgentSuccess if the disconnect operation succeeds, otherwise an error code explaining\r
- * the reason of the failure is returned.\r
- */\r
-MQTTAgentReturnCode_t MQTT_AGENT_Disconnect( MQTTAgentHandle_t xMQTTHandle,\r
-                                             TickType_t xTimeoutTicks );\r
-\r
-/**\r
- * @brief Subscribes to a given topic.\r
- *\r
- * @note This function alters the calling task's notification state and value. If xTimeoutTicks\r
- * is short the calling task's notification state and value may be updated after MQTT_AGENT_Subscribe()\r
- * has returned.\r
- *\r
- * Whenever a publish message is received on a topic, the registered callbacks are invoked\r
- * in the following order:\r
- * * If we have an exact matching entry in the subscription manager, the corresponding\r
- *   callback is invoked.\r
- * * Then the wild card topic filters are checked for match and the corresponding callbacks\r
- *   are invoked for the ones which match the topic.\r
- *\r
- * @note If a publish message is received on a topic which matches more than one topic\r
- * filters, the order in which the registered callbacks are invoked is undefined.\r
- *\r
- * @warning If the user takes the ownership of the MQTT buffer by returning eMQTTTrue from the\r
- * callback, no further callbacks are invoked. The user should make sure not to take the ownership\r
- * of the MQTT buffer if they want all the callbacks to get invoked. For example:\r
- * * Subscriptions: a/b/c, a/b/#, a/b/+\r
- * * Publish message received on topic: a/b/c --> First the callback corresponding to a/b/c\r
- *   subscription is invoked. Then the callbacks for topic filters a/b/# and a/b/+ are invoked\r
- *   in no particular order. If the user decides to take the ownership of the MQTT buffer in\r
- *   any of the callback by returning eMQTTTrue, no further callbacks are invoked.\r
- *\r
- * @param[in] xMQTTHandle The opaque handle as returned from MQTT_AGENT_Create.\r
- * @param[in] pxSubscribeParams Subscribe parameters.\r
- * @param[in] xTimeoutTicks Maximum time in ticks after which the operation should fail. Use pdMS_TO_TICKS\r
- * macro to convert milliseconds to ticks.\r
- *\r
- * @return eMQTTAgentSuccess if the subscribe operation succeeds, otherwise an error code explaining\r
- * the reason of the failure is returned.\r
- */\r
-MQTTAgentReturnCode_t MQTT_AGENT_Subscribe( MQTTAgentHandle_t xMQTTHandle,\r
-                                            const MQTTAgentSubscribeParams_t * const pxSubscribeParams,\r
-                                            TickType_t xTimeoutTicks );\r
-\r
-/**\r
- * @brief Unsubscribes from a given topic.\r
- *\r
- * @note This function alters the calling task's notification state and value. If xTimeoutTicks\r
- * is short the calling task's notification state and value may be updated after MQTT_AGENT_Unsubscribe()\r
- * has returned.\r
- *\r
- * @param[in] xMQTTHandle The opaque handle as returned from MQTT_AGENT_Create.\r
- * @param[in] pxUnsubscribeParams Unsubscribe parameters.\r
- * @param[in] xTimeoutTicks Maximum time in ticks after which the operation should fail. Use pdMS_TO_TICKS\r
- * macro to convert milliseconds to ticks.\r
- *\r
- * @return eMQTTAgentSuccess if the unsubscribe operation succeeds, otherwise an error code explaining\r
- * the reason of the failure is returned.\r
- */\r
-MQTTAgentReturnCode_t MQTT_AGENT_Unsubscribe( MQTTAgentHandle_t xMQTTHandle,\r
-                                              const MQTTAgentUnsubscribeParams_t * const pxUnsubscribeParams,\r
-                                              TickType_t xTimeoutTicks );\r
-\r
-/**\r
- * @brief Publishes a message to a given topic.\r
- *\r
- * @note This function alters the calling task's notification state and value. If xTimeoutTicks\r
- * is short the calling task's notification state and value may be updated after MQTT_AGENT_Publish()\r
- * has returned.\r
- *\r
- * @param[in] xMQTTHandle The opaque handle as returned from MQTT_AGENT_Create.\r
- * @param[in] pxPublishParams Publish parameters.\r
- * @param[in] xTimeoutTicks Maximum time in ticks after which the operation should fail. Use pdMS_TO_TICKS\r
- * macro to convert milliseconds to ticks.\r
- *\r
- * @return eMQTTAgentSuccess if the publish operation succeeds, otherwise an error code explaining\r
- * the reason of the failure is returned.\r
- */\r
-MQTTAgentReturnCode_t MQTT_AGENT_Publish( MQTTAgentHandle_t xMQTTHandle,\r
-                                          const MQTTAgentPublishParams_t * const pxPublishParams,\r
-                                          TickType_t xTimeoutTicks );\r
-\r
-/**\r
- * @brief Returns the buffer provided in the publish callback.\r
- *\r
- * When a publish message is received from the broker, the buffer containing the message\r
- * is returned in the user supplied callback (xBuffer in MQTTPublishData_t) and the user\r
- * can take the ownership by returning pdTRUE from the callback. The user should later\r
- * return the buffer whenever done by calling the MQTT_AGENT_ReturnBuffer API.\r
- *\r
- * @param[in] xMQTTHandle The opaque handle as returned from MQTT_AGENT_Create.\r
- * @param[in] xBufferHandle The buffer to return.\r
- *\r
- * @return eMQTTAgentSuccess if the return buffer operation succeeds, otherwise an error\r
- * code explaining the reason of the failure is returned.\r
- */\r
-MQTTAgentReturnCode_t MQTT_AGENT_ReturnBuffer( MQTTAgentHandle_t xMQTTHandle,\r
-                                               MQTTBufferHandle_t xBufferHandle );\r
-\r
-#endif /* _AWS_MQTT_AGENT_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/include/iot_mqtt_agent_config_defaults.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/include/iot_mqtt_agent_config_defaults.h
deleted file mode 100644 (file)
index 1ac7780..0000000
+++ /dev/null
@@ -1,180 +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_agent_config_defaults.h\r
- * @brief MQTT agent default config options.\r
- *\r
- * Ensures that the config options for MQTT agent are set to sensible\r
- * default values if the user does not provide one.\r
- */\r
-\r
-#ifndef _AWS_MQTT_AGENT_CONFIG_DEFAULTS_H_\r
-#define _AWS_MQTT_AGENT_CONFIG_DEFAULTS_H_\r
-\r
-/* FreeRTOS includes. */\r
-#include "FreeRTOS.h"\r
-#include "task.h"\r
-\r
-/**\r
- * @brief Controls whether or not to report usage metrics to the\r
- * AWS IoT broker.\r
- *\r
- * If mqttconfigENABLE_METRICS is set to 1, a string containing\r
- * metric information will be included in the "username" field of\r
- * the MQTT connect messages.\r
- */\r
-#ifndef mqttconfigENABLE_METRICS\r
-    #define mqttconfigENABLE_METRICS    ( 1 )\r
-#endif\r
-\r
-/**\r
- * @brief The maximum time interval in seconds allowed to elapse between 2 consecutive\r
- * control packets.\r
- */\r
-#ifndef mqttconfigKEEP_ALIVE_INTERVAL_SECONDS\r
-    #define mqttconfigKEEP_ALIVE_INTERVAL_SECONDS    ( 1200 )\r
-#endif\r
-\r
-/**\r
- * @brief Defines the frequency at which the client should send Keep Alive messages.\r
- *\r
- * Even though the maximum time allowed between 2 consecutive control packets\r
- * is defined by the mqttconfigKEEP_ALIVE_INTERVAL_SECONDS macro, the user\r
- * can and should send Keep Alive messages at a slightly faster rate to ensure\r
- * that the connection is not closed by the server because of network delays.\r
- * This macro defines the interval of inactivity after which a keep alive messages\r
- * is sent.\r
- */\r
-#ifndef mqttconfigKEEP_ALIVE_ACTUAL_INTERVAL_TICKS\r
-    #define mqttconfigKEEP_ALIVE_ACTUAL_INTERVAL_TICKS    ( 5000 )\r
-#endif\r
-\r
-/**\r
- * @brief The maximum interval in ticks to wait for PINGRESP.\r
- *\r
- * If PINGRESP is not received within this much time after sending PINGREQ,\r
- * the client assumes that the PINGREQ timed out.\r
- */\r
-#ifndef mqttconfigKEEP_ALIVE_TIMEOUT_TICKS\r
-    #define mqttconfigKEEP_ALIVE_TIMEOUT_TICKS    ( 1000 )\r
-#endif\r
-\r
-/**\r
- * @brief The maximum time in ticks for which the MQTT task is permitted to block.\r
- *\r
- * The MQTT task blocks until the user initiates any action or until it receives\r
- * any data from the broker. This macro controls the maximum time the MQTT task can\r
- * block. It should be set to a small number for the platforms which do not have any\r
- * mechanism to wake up the MQTT task whenever data is received on a connected socket.\r
- * This ensures that the MQTT task keeps waking up frequently and processes the publish\r
- * messages received from the broker, if any.\r
- *\r
- * If the platform's secure_sockets layer supports SOCKETS_SO_WAKEUP_CALLBACK i.e.\r
- * the MQTT task can wake up whenever data is received on a connected socket, this\r
- * value should be set to maximum value:\r
- * #define  #define mqttconfigMQTT_TASK_MAX_BLOCK_TICKS    ( ~( ( uint32_t ) 0 ) )\r
- *\r
- * If the platform's secure_sockets layer does not support SOCKETS_SO_WAKEUP_CALLBACK\r
- * i.e. the MQTT task cannot wake up whenever data is received on a connected socket,\r
- * this value should be set to a small number:\r
- * #define mqttconfigMQTT_TASK_MAX_BLOCK_TICKS             ( 100 )\r
- */\r
-#ifndef mqttconfigMQTT_TASK_MAX_BLOCK_TICKS\r
-    #error "mqttconfigMQTT_TASK_MAX_BLOCK_TICKS must be defined in iot_mqtt_agent_config.h."\r
-#endif\r
-\r
-/**\r
- * @defgroup MQTTTask MQTT task configuration parameters.\r
- */\r
-/** @{ */\r
-#ifndef mqttconfigMQTT_TASK_STACK_DEPTH\r
-    #define mqttconfigMQTT_TASK_STACK_DEPTH    ( configMINIMAL_STACK_SIZE * 4 )\r
-#endif\r
-\r
-#ifndef mqttconfigMQTT_TASK_PRIORITY\r
-    #define mqttconfigMQTT_TASK_PRIORITY    ( tskIDLE_PRIORITY )\r
-#endif\r
-/** @} */\r
-\r
-/**\r
- * @brief Maximum number of MQTT clients that can exist simultaneously.\r
- */\r
-#ifndef mqttconfigMAX_BROKERS\r
-    #define mqttconfigMAX_BROKERS    ( 1 )\r
-#endif\r
-\r
-/**\r
- * @brief Maximum number of parallel operations per client.\r
- */\r
-#ifndef mqttconfigMAX_PARALLEL_OPS\r
-    #define mqttconfigMAX_PARALLEL_OPS    ( 5 )\r
-#endif\r
-\r
-/**\r
- * @brief Time in milliseconds after which the TCP send operation should timeout.\r
- */\r
-#ifndef mqttconfigTCP_SEND_TIMEOUT_MS\r
-    #define mqttconfigTCP_SEND_TIMEOUT_MS    ( 2000 )\r
-#endif\r
-\r
-/**\r
- * @brief Length of the buffer used to receive data.\r
- */\r
-#ifndef mqttconfigRX_BUFFER_SIZE\r
-    #define mqttconfigRX_BUFFER_SIZE    ( 1024 )\r
-#endif\r
-\r
-/**\r
- * @defgroup BufferPoolInterface The functions used by the MQTT client to get and return buffers.\r
- *\r
- * The MQTT client needs buffers for both transmitting and receiving messages.\r
- * Whenever it needs a buffer, it invokes mqttconfigGET_FREE_BUFFER_FXN function to get\r
- * a buffer and after it is done it invokes mqttconfigRETURN_BUFFER_FXN to return the\r
- * buffer. By default, BUFFERPOOL_GetFreeBuffer and BUFFERPOOL_ReturnBuffer functions are\r
- * used to get and return buffers from the central buffer pool. The user can change the\r
- * buffer management functions for MQTT client by defining mqttconfigGET_FREE_BUFFER_FXN\r
- * and mqttconfigRETURN_BUFFER_FXN macros. The user should implement the two functions\r
- * having signatures same as BUFFERPOOL_GetFreeBuffer and BUFFERPOOL_ReturnBuffer and then\r
- * define the macros in BufferPoolConfig.h:\r
- * @code\r
- * uint8_t* UserDefined_GetFreeBuffer( uint32_t *pulBufferLength );\r
- * void UserDefined_ReturnBuffer( uint8_t * const pucBuffer );\r
- *\r
- * #define mqttconfigGET_FREE_BUFFER_FXN       UserDefined_GetFreeBuffer\r
- * #define mqttconfigRETURN_BUFFER_FXN         UserDefined_ReturnBuffer\r
- * @endcode\r
- */\r
-/** @{ */\r
-#ifndef mqttconfigGET_FREE_BUFFER_FXN\r
-    #define mqttconfigGET_FREE_BUFFER_FXN    BUFFERPOOL_GetFreeBuffer\r
-#endif\r
-\r
-#ifndef mqttconfigRETURN_BUFFER_FXN\r
-    #define mqttconfigRETURN_BUFFER_FXN    BUFFERPOOL_ReturnBuffer\r
-#endif\r
-/** @} */\r
-\r
-#endif /* _AWS_MQTT_AGENT_CONFIG_DEFAULTS_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/include/iot_mqtt_config_defaults.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/include/iot_mqtt_config_defaults.h
deleted file mode 100644 (file)
index 08bcd41..0000000
+++ /dev/null
@@ -1,115 +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_config_defaults.h\r
- * @brief MQTT default config options.\r
- *\r
- * Ensures that the config options for MQTT are set to sensible default\r
- * values if the user does not provide one.\r
- */\r
-\r
-#ifndef _AWS_MQTT_CONFIG_DEFAULTS_H_\r
-#define _AWS_MQTT_CONFIG_DEFAULTS_H_\r
-\r
-/**\r
- * @brief Enable subscription management.\r
- *\r
- * Subscription management allows the user to register per subscription\r
- * callback.\r
- */\r
-#ifndef mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT\r
-    #define mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT    ( 1 )\r
-#endif\r
-\r
-/**\r
- * @brief Maximum length of the topic which can be stored in subscription\r
- * manager.\r
- *\r
- * If the user has enabled subscription management (by defining the macro\r
- * mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT to 1), then this macro must be defined\r
- * to accommodate the maximum length topic which the user is going to subscribe.\r
- * The subscribe operation will fail if the user tries to subscribe to a topic\r
- * of length more than the maximum specified here.\r
- */\r
-#ifndef mqttconfigSUBSCRIPTION_MANAGER_MAX_TOPIC_LENGTH\r
-    #define mqttconfigSUBSCRIPTION_MANAGER_MAX_TOPIC_LENGTH    ( 128 )\r
-#endif\r
-\r
-/**\r
- * @brief Maximum number of subscriptions which can be stored in subscription\r
- * manager.\r
- *\r
- * If the user has enabled subscription management (by defining the macro\r
- * mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT to 1), then this macro must be defined\r
- * to the maximum number of topics which the user is going to subscribe\r
- * simultaneously. The subscribe operation will fail is the user tries to\r
- * subscribe to more topics than the maximum specified here.\r
- */\r
-#ifndef mqttconfigSUBSCRIPTION_MANAGER_MAX_SUBSCRIPTIONS\r
-    #define mqttconfigSUBSCRIPTION_MANAGER_MAX_SUBSCRIPTIONS    ( 8 )\r
-#endif\r
-\r
-/**\r
- * @brief Define mqttconfigASSERT to enable asserts.\r
- *\r
- * mqttconfigASSERT should be defined to match the semantics of standard\r
- * C assert() macro i.e. an assertion should trigger if the parameter\r
- * passed is zero. If the standard C assert is available, the user might\r
- * do the following:\r
- * @code\r
- * #define mqttconfigASSERT( x ) assert( x )\r
- * @endcode\r
- *\r
- * Otherwise, a user can choose to implement a function which should be\r
- * called when an assertion triggers and then define the mqttconfigASSERT\r
- * to that function:\r
- * @code\r
- * extern void vAssertCalled( const char *pcFile, uint32_t ulLine );\r
- * #define mqttconfigASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )\r
- * @endcode\r
- */\r
-#ifndef mqttconfigASSERT\r
-    #define mqttconfigASSERT( x )\r
-#endif\r
-\r
-/**\r
- * @brief Define mqttconfigENABLE_DEBUG_LOGS macro to 1 for enabling debug logs.\r
- *\r
- * If you choose to enable debug logs, the following function must be implemented\r
- * which is called to print logs:\r
- * @code\r
- * void vLoggingPrintf( const char *pcFormatString, ... );\r
- * @endcode\r
- */\r
-#if ( mqttconfigENABLE_DEBUG_LOGS == 1 )\r
-    extern void vLoggingPrintf( const char * pcFormatString,\r
-                                ... );\r
-    #define mqttconfigDEBUG_LOG( x )    vLoggingPrintf x\r
-#else\r
-    #define mqttconfigDEBUG_LOG( x )\r
-#endif\r
-\r
-#endif /* _AWS_MQTT_CONFIG_DEFAULTS_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/include/iot_mqtt_lib.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/include/iot_mqtt_lib.h
deleted file mode 100644 (file)
index ae3e263..0000000
+++ /dev/null
@@ -1,113 +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_lib.h\r
- * @brief MQTT Core Library interface.\r
- */\r
-\r
-#ifndef _AWS_MQTT_LIB_H_\r
-#define _AWS_MQTT_LIB_H_\r
-\r
-/* This ifndef enables the core MQTT library to be used without\r
- * providing MQTTConfig.h. All the config values in this case are\r
- * taken from MQTTConfigDefaults.h. */\r
-#ifndef mqttDO_NOT_USE_CUSTOM_CONFIG\r
-    #include "aws_mqtt_config.h"\r
-#endif\r
-#include "iot_mqtt_config_defaults.h"\r
-\r
-#include "iot_doubly_linked_list.h"\r
-\r
- /**\r
-  * @brief Opaque handle to represent an MQTT buffer.\r
-  */\r
-typedef void * MQTTBufferHandle_t;\r
-\r
-/**\r
- * @brief Boolean type.\r
- */\r
-typedef enum\r
-{\r
-    eMQTTFalse = 0, /**< Boolean False. */\r
-    eMQTTTrue = 1   /**< Boolean True. */\r
-} MQTTBool_t;\r
-\r
-/**\r
- * @brief Quality of Service (qos).\r
- */\r
-typedef enum\r
-{\r
-    eMQTTQoS0 = 0, /**< Quality of Service 0 - Fire and Forget. No ACK. */\r
-    eMQTTQoS1 = 1, /**< Quality of Service 1 - Wait till ACK or Timeout. */\r
-    eMQTTQoS2 = 2  /**< Quality of Service 2 - Not supported. */\r
-} MQTTQoS_t;\r
-\r
-/**\r
- * @brief The data sent by the MQTT library in the user supplied callback\r
- * when a publish message from the broker is received.\r
- */\r
-typedef struct MQTTPublishData\r
-{\r
-    MQTTQoS_t xQos;             /**< Quality of Service (qos). */\r
-    const uint8_t * pucTopic;   /**< The topic on which the message is received. */\r
-    uint16_t usTopicLength;     /**< Length of the topic. */\r
-    const void * pvData;        /**< The received message. */\r
-    uint32_t ulDataLength;      /**< Length of the message. */\r
-    MQTTBufferHandle_t xBuffer; /**< The buffer containing the whole MQTT message. Both pcTopic and pvData are pointers to the locations in this buffer. */\r
-} MQTTPublishData_t;\r
-\r
-/**\r
- * @brief Signature of the user supplied topic specific publish callback which gets called\r
- * whenever a publish message is received on the topic this callback is registered for.\r
- *\r
- * The user can choose to register this optional topic specific callback while subscribing to\r
- * a topic. Whenever a publish message is received on the topic, this callback is invoked. If\r
- * the user chooses not to enable subscription management or chooses not to register a topic\r
- * specific callback, the generic callback supplied during Init is invoked.\r
- *\r
- * @param[in] pvPublishCallbackContext The callback context as supplied by the user in the\r
- * subscribe parameters.\r
- * @param[in] pxPublishData The publish data.\r
- *\r
- * @return The return value is interpreted as follows:\r
- * 1. If eMQTTTrue is returned - the ownership of the buffer passed in the callback (xBuffer\r
- * in MQTTPublishData_t) lies with the user.\r
- * 2. If eMQTTFalse is returned - the ownership of the buffer passed in the callback (xBuffer\r
- * in MQTTPublishData_t) remains with the library and it is recycled as soon as the callback\r
- * returns.<br>\r
- * The user should take the ownership of the buffer containing the received message from the\r
- * broker by returning eMQTTTrue from the callback if the user wants to use the buffer after\r
- * the callback is over. The user should return the buffer whenever done by calling the\r
- * MQTT_ReturnBuffer API.\r
- */\r
-#if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 )\r
-\r
-    typedef MQTTBool_t ( * MQTTPublishCallback_t )( void * pvPublishCallbackContext,\r
-                                                    const MQTTPublishData_t * const pxPublishData );\r
-\r
-#endif /* mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT */\r
-\r
-#endif /* _AWS_MQTT_LIB_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/include/types/iot_mqtt_types.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/include/types/iot_mqtt_types.h
deleted file mode 100644 (file)
index c4bea31..0000000
+++ /dev/null
@@ -1,1087 +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_types.h\r
- * @brief Types of the MQTT library.\r
- */\r
-\r
-#ifndef IOT_MQTT_TYPES_H_\r
-#define IOT_MQTT_TYPES_H_\r
-\r
-/* The config header is always included first. */\r
-#include "iot_config.h"\r
-\r
-/* Standard includes. */\r
-#include <stdbool.h>\r
-#include <stdint.h>\r
-#include <stddef.h>\r
-\r
-/* Type includes. */\r
-#include "types/iot_platform_types.h"\r
-#include "types/iot_taskpool_types.h"\r
-\r
-/* Platform network include. */\r
-#include "platform/iot_network.h"\r
-\r
-/*---------------------------- MQTT handle types ----------------------------*/\r
-\r
-/**\r
- * @handles{mqtt,MQTT library}\r
- */\r
-\r
-/**\r
- * @ingroup mqtt_datatypes_handles\r
- * @brief Opaque handle of an MQTT connection.\r
- *\r
- * This type identifies an MQTT connection, which is valid after a successful call\r
- * to @ref mqtt_function_connect. A variable of this type is passed as the first\r
- * argument to [MQTT library functions](@ref mqtt_functions) to identify which\r
- * connection that function acts on.\r
- *\r
- * A call to @ref mqtt_function_disconnect makes a connection handle invalid. Once\r
- * @ref mqtt_function_disconnect returns, the connection handle should no longer\r
- * be used.\r
- *\r
- * @initializer{IotMqttConnection_t,IOT_MQTT_CONNECTION_INITIALIZER}\r
- */\r
-typedef struct _mqttConnection   * IotMqttConnection_t;\r
-\r
-/**\r
- * @ingroup mqtt_datatypes_handles\r
- * @brief Opaque handle that references an in-progress MQTT operation.\r
- *\r
- * Set as an output parameter of @ref mqtt_function_publish, @ref mqtt_function_subscribe,\r
- * and @ref mqtt_function_unsubscribe. These functions queue an MQTT operation; the result\r
- * of the operation is unknown until a response from the MQTT server is received. Therefore,\r
- * this handle serves as a reference to MQTT operations awaiting MQTT server response.\r
- *\r
- * This reference will be valid from the successful return of @ref mqtt_function_publish,\r
- * @ref mqtt_function_subscribe, or @ref mqtt_function_unsubscribe. The reference becomes\r
- * invalid once the [completion callback](@ref IotMqttCallbackInfo_t) is invoked, or\r
- * @ref mqtt_function_wait returns.\r
- *\r
- * @initializer{IotMqttOperation_t,IOT_MQTT_OPERATION_INITIALIZER}\r
- *\r
- * @see @ref mqtt_function_wait and #IOT_MQTT_FLAG_WAITABLE for waiting on a reference.\r
- * #IotMqttCallbackInfo_t and #IotMqttCallbackParam_t for an asynchronous notification\r
- * of completion.\r
- */\r
-typedef struct _mqttOperation    * IotMqttOperation_t;\r
-\r
-/*-------------------------- MQTT enumerated types --------------------------*/\r
-\r
-/**\r
- * @enums{mqtt,MQTT library}\r
- */\r
-\r
-/**\r
- * @ingroup mqtt_datatypes_enums\r
- * @brief Return codes of [MQTT functions](@ref mqtt_functions).\r
- *\r
- * The function @ref mqtt_function_strerror can be used to get a return code's\r
- * description.\r
- */\r
-typedef enum IotMqttError\r
-{\r
-    /**\r
-     * @brief MQTT operation completed successfully.\r
-     *\r
-     * Functions that may return this value:\r
-     * - @ref mqtt_function_connect\r
-     * - @ref mqtt_function_publish with QoS 0 parameter\r
-     * - @ref mqtt_function_wait\r
-     * - @ref mqtt_function_timedsubscribe\r
-     * - @ref mqtt_function_timedunsubscribe\r
-     * - @ref mqtt_function_timedpublish\r
-     *\r
-     * Will also be the value of an operation completion callback's\r
-     * #IotMqttCallbackParam_t.result when successful.\r
-     */\r
-    IOT_MQTT_SUCCESS = 0,\r
-\r
-    /**\r
-     * @brief MQTT operation queued, awaiting result.\r
-     *\r
-     * Functions that may return this value:\r
-     * - @ref mqtt_function_subscribe\r
-     * - @ref mqtt_function_unsubscribe\r
-     * - @ref mqtt_function_publish with QoS 1 parameter\r
-     */\r
-    IOT_MQTT_STATUS_PENDING,\r
-\r
-    /**\r
-     * @brief Initialization failed.\r
-     *\r
-     * Functions that may return this value:\r
-     * - @ref mqtt_function_init\r
-     */\r
-    IOT_MQTT_INIT_FAILED,\r
-\r
-    /**\r
-     * @brief At least one parameter is invalid.\r
-     *\r
-     * Functions that may return this value:\r
-     * - @ref mqtt_function_connect\r
-     * - @ref mqtt_function_subscribe and @ref mqtt_function_timedsubscribe\r
-     * - @ref mqtt_function_unsubscribe and @ref mqtt_function_timedunsubscribe\r
-     * - @ref mqtt_function_publish and @ref mqtt_function_timedpublish\r
-     * - @ref mqtt_function_wait\r
-     */\r
-    IOT_MQTT_BAD_PARAMETER,\r
-\r
-    /**\r
-     * @brief MQTT operation failed because of memory allocation failure.\r
-     *\r
-     * Functions that may return this value:\r
-     * - @ref mqtt_function_connect\r
-     * - @ref mqtt_function_subscribe and @ref mqtt_function_timedsubscribe\r
-     * - @ref mqtt_function_unsubscribe and @ref mqtt_function_timedunsubscribe\r
-     * - @ref mqtt_function_publish and @ref mqtt_function_timedpublish\r
-     */\r
-    IOT_MQTT_NO_MEMORY,\r
-\r
-    /**\r
-     * @brief MQTT operation failed because the network was unusable.\r
-     *\r
-     * This return value may indicate that the network is disconnected.\r
-     *\r
-     * Functions that may return this value:\r
-     * - @ref mqtt_function_connect\r
-     * - @ref mqtt_function_wait\r
-     * - @ref mqtt_function_timedsubscribe\r
-     * - @ref mqtt_function_timedunsubscribe\r
-     * - @ref mqtt_function_timedpublish\r
-     *\r
-     * May also be the value of an operation completion callback's\r
-     * #IotMqttCallbackParam_t.result.\r
-     */\r
-    IOT_MQTT_NETWORK_ERROR,\r
-\r
-    /**\r
-     * @brief MQTT operation could not be scheduled, i.e. enqueued for sending.\r
-     *\r
-     * Functions that may return this value:\r
-     * - @ref mqtt_function_connect\r
-     * - @ref mqtt_function_subscribe and @ref mqtt_function_timedsubscribe\r
-     * - @ref mqtt_function_unsubscribe and @ref mqtt_function_timedunsubscribe\r
-     * - @ref mqtt_function_publish and @ref mqtt_function_timedpublish\r
-     */\r
-    IOT_MQTT_SCHEDULING_ERROR,\r
-\r
-    /**\r
-     * @brief MQTT response packet received from the network is malformed.\r
-     *\r
-     * Functions that may return this value:\r
-     * - @ref mqtt_function_connect\r
-     * - @ref mqtt_function_wait\r
-     * - @ref mqtt_function_timedsubscribe\r
-     * - @ref mqtt_function_timedunsubscribe\r
-     * - @ref mqtt_function_timedpublish\r
-     *\r
-     * May also be the value of an operation completion callback's\r
-     * #IotMqttCallbackParam_t.result.\r
-     *\r
-     * @note If this value is received, the network connection has been closed.\r
-     */\r
-    IOT_MQTT_BAD_RESPONSE,\r
-\r
-    /**\r
-     * @brief A blocking MQTT operation timed out.\r
-     *\r
-     * Functions that may return this value:\r
-     * - @ref mqtt_function_connect\r
-     * - @ref mqtt_function_wait\r
-     * - @ref mqtt_function_timedsubscribe\r
-     * - @ref mqtt_function_timedunsubscribe\r
-     * - @ref mqtt_function_timedpublish\r
-     */\r
-    IOT_MQTT_TIMEOUT,\r
-\r
-    /**\r
-     * @brief A CONNECT or at least one subscription was refused by the server.\r
-     *\r
-     * Functions that may return this value:\r
-     * - @ref mqtt_function_connect\r
-     * - @ref mqtt_function_wait, but only when its #IotMqttOperation_t parameter\r
-     * is associated with a SUBSCRIBE operation.\r
-     * - @ref mqtt_function_timedsubscribe\r
-     *\r
-     * May also be the value of an operation completion callback's\r
-     * #IotMqttCallbackParam_t.result for a SUBSCRIBE.\r
-     *\r
-     * @note If this value is returned and multiple subscriptions were passed to\r
-     * @ref mqtt_function_subscribe (or @ref mqtt_function_timedsubscribe), it's\r
-     * still possible that some of the subscriptions succeeded. This value only\r
-     * signifies that AT LEAST ONE subscription was rejected. The function @ref\r
-     * mqtt_function_issubscribed can be used to determine which subscriptions\r
-     * were accepted or rejected.\r
-     */\r
-    IOT_MQTT_SERVER_REFUSED,\r
-\r
-    /**\r
-     * @brief A QoS 1 PUBLISH received no response and [the retry limit]\r
-     * (#IotMqttPublishInfo_t.retryLimit) was reached.\r
-     *\r
-     * Functions that may return this value:\r
-     * - @ref mqtt_function_wait, but only when its #IotMqttOperation_t parameter\r
-     * is associated with a QoS 1 PUBLISH operation\r
-     * - @ref mqtt_function_timedpublish\r
-     *\r
-     * May also be the value of an operation completion callback's\r
-     * #IotMqttCallbackParam_t.result for a QoS 1 PUBLISH.\r
-     */\r
-    IOT_MQTT_RETRY_NO_RESPONSE\r
-} IotMqttError_t;\r
-\r
-/**\r
- * @ingroup mqtt_datatypes_enums\r
- * @brief Types of MQTT operations.\r
- *\r
- * The function @ref mqtt_function_operationtype can be used to get an operation\r
- * type's description.\r
- */\r
-typedef enum IotMqttOperationType\r
-{\r
-    IOT_MQTT_CONNECT,           /**< Client-to-server CONNECT. */\r
-    IOT_MQTT_PUBLISH_TO_SERVER, /**< Client-to-server PUBLISH. */\r
-    IOT_MQTT_PUBACK,            /**< Client-to-server PUBACK. */\r
-    IOT_MQTT_SUBSCRIBE,         /**< Client-to-server SUBSCRIBE. */\r
-    IOT_MQTT_UNSUBSCRIBE,       /**< Client-to-server UNSUBSCRIBE. */\r
-    IOT_MQTT_PINGREQ,           /**< Client-to-server PINGREQ. */\r
-    IOT_MQTT_DISCONNECT         /**< Client-to-server DISCONNECT. */\r
-} IotMqttOperationType_t;\r
-\r
-/**\r
- * @ingroup mqtt_datatypes_enums\r
- * @brief Quality of service levels for MQTT PUBLISH messages.\r
- *\r
- * All MQTT PUBLISH messages, including Last Will and Testament and messages\r
- * received on subscription filters, have an associated <i>Quality of Service</i>,\r
- * which defines any delivery guarantees for that message.\r
- * - QoS 0 messages will be delivered at most once. This is a "best effort"\r
- * transmission with no retransmissions.\r
- * - QoS 1 messages will be delivered at least once. See #IotMqttPublishInfo_t\r
- * for the retransmission strategy this library uses to redeliver messages\r
- * assumed to be lost.\r
- *\r
- * @attention QoS 2 is not supported by this library and should not be used.\r
- */\r
-typedef enum IotMqttQos\r
-{\r
-    IOT_MQTT_QOS_0 = 0, /**< Delivery at most once. */\r
-    IOT_MQTT_QOS_1 = 1, /**< Delivery at least once. See #IotMqttPublishInfo_t for client-side retry strategy. */\r
-    IOT_MQTT_QOS_2 = 2  /**< Delivery exactly once. Unsupported, but enumerated for completeness. */\r
-} IotMqttQos_t;\r
-\r
-/**\r
- * @ingroup mqtt_datatypes_enums\r
- * @brief The reason that an MQTT connection (and its associated network connection)\r
- * was disconnected.\r
- *\r
- * When an MQTT connection is closed, its associated [disconnect callback]\r
- * (@ref IotMqttNetworkInfo_t::disconnectCallback) will be invoked. This type\r
- * is passed inside of an #IotMqttCallbackParam_t to provide a reason for the\r
- * disconnect.\r
- */\r
-typedef enum IotMqttDisconnectReason\r
-{\r
-    IOT_MQTT_DISCONNECT_CALLED,   /**< @ref mqtt_function_disconnect was invoked. */\r
-    IOT_MQTT_BAD_PACKET_RECEIVED, /**< An invalid packet was received from the network. */\r
-    IOT_MQTT_KEEP_ALIVE_TIMEOUT   /**< Keep-alive response was not received within @ref IOT_MQTT_RESPONSE_WAIT_MS. */\r
-} IotMqttDisconnectReason_t;\r
-\r
-/*------------------------- MQTT parameter structs --------------------------*/\r
-\r
-/**\r
- * @paramstructs{mqtt,MQTT}\r
- */\r
-\r
-/**\r
- * @ingroup mqtt_datatypes_paramstructs\r
- * @brief Information on a PUBLISH message.\r
- *\r
- * @paramfor @ref mqtt_function_connect, @ref mqtt_function_publish\r
- *\r
- * Passed to @ref mqtt_function_publish as the message to publish and @ref\r
- * mqtt_function_connect as the Last Will and Testament (LWT) message.\r
- *\r
- * @initializer{IotMqttPublishInfo_t,IOT_MQTT_PUBLISH_INFO_INITIALIZER}\r
- *\r
- * #IotMqttPublishInfo_t.retryMs and #IotMqttPublishInfo_t.retryLimit are only\r
- * relevant to QoS 1 PUBLISH messages. They are ignored for QoS 0 PUBLISH\r
- * messages and LWT messages. These members control retransmissions of QoS 1\r
- * messages under the following rules:\r
- * - Retransmission is disabled when #IotMqttPublishInfo_t.retryLimit is 0.\r
- * After sending the PUBLISH, the library will wait indefinitely for a PUBACK.\r
- * - If #IotMqttPublishInfo_t.retryLimit is greater than 0, then QoS 1 publishes\r
- * that do not receive a PUBACK within #IotMqttPublishInfo_t.retryMs will be\r
- * retransmitted, up to #IotMqttPublishInfo_t.retryLimit times.\r
- *\r
- * Retransmission follows a truncated exponential backoff strategy. The constant\r
- * @ref IOT_MQTT_RETRY_MS_CEILING controls the maximum time between retransmissions.\r
- *\r
- * After #IotMqttPublishInfo_t.retryLimit retransmissions are sent, the MQTT\r
- * library will wait @ref IOT_MQTT_RESPONSE_WAIT_MS before a final check\r
- * for a PUBACK. If no PUBACK was received within this time, the QoS 1 PUBLISH\r
- * fails with the code #IOT_MQTT_RETRY_NO_RESPONSE.\r
- *\r
- * @note The lengths of the strings in this struct should not include the NULL\r
- * terminator. Strings in this struct do not need to be NULL-terminated.\r
- *\r
- * @note The AWS IoT MQTT server does not support the DUP bit. When\r
- * [using this library with the AWS IoT MQTT server](@ref IotMqttConnectInfo_t.awsIotMqttMode),\r
- * retransmissions will instead be sent with a new packet identifier in the PUBLISH\r
- * packet. This is a nonstandard workaround. Note that this workaround has some\r
- * flaws, including the following:\r
- * - The previous packet identifier is forgotten, so if a PUBACK arrives for that\r
- * packet identifier, it will be ignored. On an exceptionally busy network, this\r
- * may cause excessive retransmissions when too many PUBACKS arrive after the\r
- * PUBLISH packet identifier is changed. However, the exponential backoff\r
- * retransmission strategy should mitigate this problem.\r
- * - Log messages will be printed using the new packet identifier; the old packet\r
- * identifier is not saved.\r
- *\r
- * <b>Example</b>\r
- *\r
- * Consider a situation where\r
- * - @ref IOT_MQTT_RETRY_MS_CEILING is 60000\r
- * - #IotMqttPublishInfo_t.retryMs is 2000\r
- * - #IotMqttPublishInfo_t.retryLimit is 20\r
- *\r
- * A PUBLISH message will be retransmitted at the following times after the initial\r
- * transmission if no PUBACK is received:\r
- * - 2000 ms (2000 ms after previous transmission)\r
- * - 6000 ms (4000 ms after previous transmission)\r
- * - 14000 ms (8000 ms after previous transmission)\r
- * - 30000 ms (16000 ms after previous transmission)\r
- * - 62000 ms (32000 ms after previous transmission)\r
- * - 122000 ms, 182000 ms, 242000 ms... (every 60000 ms until 20 transmissions have been sent)\r
- *\r
- * After the 20th retransmission, the MQTT library will wait\r
- * @ref IOT_MQTT_RESPONSE_WAIT_MS before checking a final time for a PUBACK.\r
- */\r
-typedef struct IotMqttPublishInfo\r
-{\r
-    IotMqttQos_t qos;         /**< @brief QoS of message. Must be 0 or 1. */\r
-    bool retain;              /**< @brief MQTT message retain flag. */\r
-\r
-    const char * pTopicName;  /**< @brief Topic name of PUBLISH. */\r
-    uint16_t topicNameLength; /**< @brief Length of #IotMqttPublishInfo_t.pTopicName. */\r
-\r
-    const void * pPayload;    /**< @brief Payload of PUBLISH. */\r
-    size_t payloadLength;     /**< @brief Length of #IotMqttPublishInfo_t.pPayload. For LWT messages, this is limited to 65535. */\r
-\r
-    uint32_t retryMs;         /**< @brief If no response is received within this time, the message is retransmitted. */\r
-    uint32_t retryLimit;      /**< @brief How many times to attempt retransmission. */\r
-} IotMqttPublishInfo_t;\r
-\r
-/**\r
- * @ingroup mqtt_datatypes_paramstructs\r
- * @brief Parameter to an MQTT callback function.\r
- *\r
- * @paramfor MQTT callback functions\r
- *\r
- * The MQTT library passes this struct to registered callback whenever an\r
- * operation completes, a message is received on a topic filter, or an MQTT\r
- * connection is disconnected.\r
- *\r
- * The members of this struct are different based on the callback trigger. If the\r
- * callback function was triggered for completed operation, the `operation`\r
- * member is valid. Otherwise, if the callback was triggered because of a\r
- * server-to-client PUBLISH, the `message` member is valid. Finally, if the callback\r
- * was triggered because of a disconnect, the `disconnectReason` member is valid.\r
- *\r
- * For an incoming PUBLISH, the `message.pTopicFilter` parameter provides the\r
- * subscription topic filter that matched the topic name in the PUBLISH. Because\r
- * topic filters may use MQTT wildcards, the topic filter may be different from the\r
- * topic name. This pointer must be treated as read-only; the topic filter must not\r
- * be modified. Additionally, the topic filter may go out of scope as soon as the\r
- * callback function returns, so it must be copied if it is needed at a later time.\r
- *\r
- * @attention Any pointers in this callback parameter may be freed as soon as\r
- * the [callback function](@ref IotMqttCallbackInfo_t.function) returns.\r
- * Therefore, data must be copied if it is needed after the callback function\r
- * returns.\r
- * @attention The MQTT library may set strings that are not NULL-terminated.\r
- *\r
- * @see #IotMqttCallbackInfo_t for the signature of a callback function.\r
- */\r
-typedef struct IotMqttCallbackParam\r
-{\r
-    /**\r
-     * @brief The MQTT connection associated with this completed operation,\r
-     * incoming PUBLISH, or disconnect.\r
-     *\r
-     * [MQTT API functions](@ref mqtt_functions) are safe to call from a callback\r
-     * for completed operations or incoming PUBLISH messages. However, blocking\r
-     * function calls (including @ref mqtt_function_wait) are not recommended\r
-     * (though still safe). Do not call any API functions from a disconnect\r
-     * callback.\r
-     */\r
-    IotMqttConnection_t mqttConnection;\r
-\r
-    union\r
-    {\r
-        /* Valid for completed operations. */\r
-        struct\r
-        {\r
-            IotMqttOperationType_t type;  /**< @brief Type of operation that completed. */\r
-            IotMqttOperation_t reference; /**< @brief Reference to the operation that completed. */\r
-            IotMqttError_t result;        /**< @brief Result of operation, e.g. succeeded or failed. */\r
-        } operation;\r
-\r
-        /* Valid for incoming PUBLISH messages. */\r
-        struct\r
-        {\r
-            const char * pTopicFilter;  /**< @brief Topic filter that matched the message. */\r
-            uint16_t topicFilterLength; /**< @brief Length of `pTopicFilter`. */\r
-            IotMqttPublishInfo_t info;  /**< @brief PUBLISH message received from the server. */\r
-        } message;\r
-\r
-        /* Valid when a connection is disconnected. */\r
-        IotMqttDisconnectReason_t disconnectReason; /**< @brief Why the MQTT connection was disconnected. */\r
-    } u; /**< @brief Valid member depends on callback type. */\r
-} IotMqttCallbackParam_t;\r
-\r
-/**\r
- * @ingroup mqtt_datatypes_paramstructs\r
- * @brief Information on a user-provided MQTT callback function.\r
- *\r
- * @paramfor @ref mqtt_function_subscribe, @ref mqtt_function_unsubscribe,\r
- * and @ref mqtt_function_publish. Cannot be used with #IOT_MQTT_FLAG_WAITABLE.\r
- *\r
- * Provides a function to be invoked when an operation completes or when a\r
- * server-to-client PUBLISH is received.\r
- *\r
- * @initializer{IotMqttCallbackInfo_t,IOT_MQTT_CALLBACK_INFO_INITIALIZER}\r
- *\r
- * Below is an example for receiving an asynchronous notification on operation\r
- * completion. See @ref mqtt_function_subscribe for an example of using this struct\r
- * with for incoming PUBLISH messages.\r
- *\r
- * @code{c}\r
- * // Operation completion callback.\r
- * void operationComplete( void * pArgument, IotMqttCallbackParam_t * pOperation );\r
- *\r
- * // Callback information.\r
- * IotMqttCallbackInfo_t callbackInfo = IOT_MQTT_CALLBACK_INFO_INITIALIZER;\r
- * callbackInfo.function = operationComplete;\r
- *\r
- * // Operation to wait for.\r
- * IotMqttError_t result = IotMqtt_Publish( &mqttConnection,\r
- *                                          &publishInfo,\r
- *                                          0,\r
- *                                          &callbackInfo,\r
- *                                          &reference );\r
- *\r
- * // Publish should have returned IOT_MQTT_STATUS_PENDING. Once a response\r
- * // is received, operationComplete is executed with the actual status passed\r
- * // in pOperation.\r
- * @endcode\r
- */\r
-typedef struct IotMqttCallbackInfo\r
-{\r
-    void * pCallbackContext; /**< @brief The first parameter to pass to the callback function to provide context. */\r
-\r
-    /**\r
-     * @brief User-provided callback function signature.\r
-     *\r
-     * @param[in] void * #IotMqttCallbackInfo_t.pCallbackContext\r
-     * @param[in] IotMqttCallbackParam_t * Details on the outcome of the MQTT operation\r
-     * or an incoming MQTT PUBLISH.\r
-     *\r
-     * @see #IotMqttCallbackParam_t for more information on the second parameter.\r
-     */\r
-    void ( * function )( void *,\r
-                         IotMqttCallbackParam_t * );\r
-} IotMqttCallbackInfo_t;\r
-\r
-/**\r
- * @ingroup mqtt_datatypes_paramstructs\r
- * @brief Information on an MQTT subscription.\r
- *\r
- * @paramfor @ref mqtt_function_subscribe, @ref mqtt_function_unsubscribe\r
- *\r
- * An array of these is passed to @ref mqtt_function_subscribe and @ref\r
- * mqtt_function_unsubscribe. However, #IotMqttSubscription_t.callback and\r
- * and #IotMqttSubscription_t.qos are ignored by @ref mqtt_function_unsubscribe.\r
- *\r
- * @initializer{IotMqttSubscription_t,IOT_MQTT_SUBSCRIPTION_INITIALIZER}\r
- *\r
- * @note The lengths of the strings in this struct should not include the NULL\r
- * terminator. Strings in this struct do not need to be NULL-terminated.\r
- * @see #IotMqttCallbackInfo_t for details on setting a callback function.\r
- */\r
-typedef struct IotMqttSubscription\r
-{\r
-    /**\r
-     * @brief QoS of messages delivered on subscription.\r
-     *\r
-     * Must be `0` or `1`. Ignored by @ref mqtt_function_unsubscribe.\r
-     */\r
-    IotMqttQos_t qos;\r
-\r
-    const char * pTopicFilter;  /**< @brief Topic filter of subscription. */\r
-    uint16_t topicFilterLength; /**< @brief Length of #IotMqttSubscription_t.pTopicFilter. */\r
-\r
-    /**\r
-     * @brief Callback to invoke when a message is received.\r
-     *\r
-     * See #IotMqttCallbackInfo_t. Ignored by @ref mqtt_function_unsubscribe.\r
-     */\r
-    IotMqttCallbackInfo_t callback;\r
-} IotMqttSubscription_t;\r
-\r
-/**\r
- * @ingroup mqtt_datatypes_paramstructs\r
- * @brief Information on a new MQTT connection.\r
- *\r
- * @paramfor @ref mqtt_function_connect\r
- *\r
- * Passed as an argument to @ref mqtt_function_connect. Most members of this struct\r
- * correspond to the content of an [MQTT CONNECT packet.]\r
- * (http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/csprd02/mqtt-v3.1.1-csprd02.html#_Toc385349764)\r
- *\r
- * @initializer{IotMqttConnectInfo_t,IOT_MQTT_CONNECT_INFO_INITIALIZER}\r
- *\r
- * @note The lengths of the strings in this struct should not include the NULL\r
- * terminator. Strings in this struct do not need to be NULL-terminated.\r
- */\r
-typedef struct IotMqttConnectInfo\r
-{\r
-    /**\r
-     * @brief Specifies if this MQTT connection is to an AWS IoT MQTT server.\r
-     *\r
-     * The AWS IoT MQTT broker [differs somewhat from the MQTT specification.]\r
-     * (https://docs.aws.amazon.com/iot/latest/developerguide/mqtt.html)\r
-     * When this member is `true`, the MQTT library will accommodate these\r
-     * differences. This setting should be `false` when communicating with a\r
-     * fully-compliant MQTT broker.\r
-     *\r
-     * @attention This setting <b>MUST</b> be `true` when using the AWS IoT MQTT\r
-     * server; it <b>MUST</b> be `false` otherwise.\r
-     * @note Currently, @ref IOT_MQTT_CONNECT_INFO_INITIALIZER sets this\r
-     * this member to `true`.\r
-     */\r
-    bool awsIotMqttMode;\r
-\r
-    /**\r
-     * @brief Whether this connection is a clean session.\r
-     *\r
-     * MQTT servers can maintain and topic filter subscriptions and unacknowledged\r
-     * PUBLISH messages. These form part of an <i>MQTT session</i>, which is identified by\r
-     * the [client identifier](@ref IotMqttConnectInfo_t.pClientIdentifier).\r
-     *\r
-     * Setting this value to `true` establishes a <i>clean session</i>, which causes\r
-     * the MQTT server to discard any previous session data for a client identifier.\r
-     * When the client disconnects, the server discards all session data. If this\r
-     * value is `true`, #IotMqttConnectInfo_t.pPreviousSubscriptions and\r
-     * #IotMqttConnectInfo_t.previousSubscriptionCount are ignored.\r
-     *\r
-     * Setting this value to `false` does one of the following:\r
-     * - If no previous session exists, the MQTT server will create a new\r
-     * <i>persistent session</i>. The server may maintain subscriptions and\r
-     * unacknowledged PUBLISH messages after a client disconnects, to be restored\r
-     * once the same client identifier reconnects.\r
-     * - If a previous session exists, the MQTT server restores all of the session's\r
-     * subscriptions for the client identifier and may immediately transmit any\r
-     * unacknowledged PUBLISH packets to the client.\r
-     *\r
-     * When a client with a persistent session disconnects, the MQTT server\r
-     * continues to maintain all subscriptions and unacknowledged PUBLISH messages.\r
-     * The client must also remember the session subscriptions to restore them\r
-     * upon reconnecting. #IotMqttConnectInfo_t.pPreviousSubscriptions and\r
-     * #IotMqttConnectInfo_t.previousSubscriptionCount are used to restore a\r
-     * previous session's subscriptions client-side.\r
-     */\r
-    bool cleanSession;\r
-\r
-    /**\r
-     * @brief An array of MQTT subscriptions present in a previous session, if any.\r
-     *\r
-     * Pointer to the start of an array of subscriptions present a previous session,\r
-     * if any. These subscriptions will be immediately restored upon reconnecting.\r
-     *\r
-     * This member is ignored if it is `NULL` or #IotMqttConnectInfo_t.cleanSession\r
-     * is `true`. If this member is not `NULL`, #IotMqttConnectInfo_t.previousSubscriptionCount\r
-     * must be nonzero.\r
-     */\r
-    const IotMqttSubscription_t * pPreviousSubscriptions;\r
-\r
-    /**\r
-     * @brief The number of MQTT subscriptions present in a previous session, if any.\r
-     *\r
-     * Number of subscriptions contained in the array\r
-     * #IotMqttConnectInfo_t.pPreviousSubscriptions.\r
-     *\r
-     * This value is ignored if #IotMqttConnectInfo_t.pPreviousSubscriptions\r
-     * is `NULL` or #IotMqttConnectInfo_t.cleanSession is `true`. If\r
-     * #IotMqttConnectInfo_t.pPreviousSubscriptions is not `NULL`, this value\r
-     * must be nonzero.\r
-     */\r
-    size_t previousSubscriptionCount;\r
-\r
-    /**\r
-     * @brief A message to publish if the new MQTT connection is unexpectedly closed.\r
-     *\r
-     * A Last Will and Testament (LWT) message may be published if this connection is\r
-     * closed without sending an MQTT DISCONNECT packet. This pointer should be set to\r
-     * an #IotMqttPublishInfo_t representing any LWT message to publish. If an LWT\r
-     * is not needed, this member must be set to `NULL`.\r
-     *\r
-     * Unlike other PUBLISH messages, an LWT message is limited to 65535 bytes in\r
-     * length. Additionally, [pWillInfo->retryMs](@ref IotMqttPublishInfo_t.retryMs)\r
-     * and [pWillInfo->retryLimit](@ref IotMqttPublishInfo_t.retryLimit) will\r
-     * be ignored.\r
-     */\r
-    const IotMqttPublishInfo_t * pWillInfo;\r
-\r
-    uint16_t keepAliveSeconds;       /**< @brief Period of keep-alive messages. Set to 0 to disable keep-alive. */\r
-\r
-    const char * pClientIdentifier;  /**< @brief MQTT client identifier. */\r
-    uint16_t clientIdentifierLength; /**< @brief Length of #IotMqttConnectInfo_t.pClientIdentifier. */\r
-\r
-    /* These credentials are not used by AWS IoT and may be ignored if\r
-     * awsIotMqttMode is true. */\r
-    const char * pUserName;  /**< @brief Username for MQTT connection. */\r
-    uint16_t userNameLength; /**< @brief Length of #IotMqttConnectInfo_t.pUserName. */\r
-    const char * pPassword;  /**< @brief Password for MQTT connection. */\r
-    uint16_t passwordLength; /**< @brief Length of #IotMqttConnectInfo_t.pPassword. */\r
-} IotMqttConnectInfo_t;\r
-\r
-#if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
-\r
-/**\r
- * @cond DOXYGEN_IGNORE\r
- * Doxygen should ignore this section.\r
- *\r
- * Forward declaration of the internal MQTT packet structure.\r
- */\r
-    struct _mqttPacket;\r
-/** @endcond */\r
-\r
-/**\r
- * @ingroup mqtt_datatypes_paramstructs\r
- * @brief Function pointers for MQTT packet serializer overrides.\r
- *\r
- * These function pointers allow the MQTT serialization and deserialization functions\r
- * to be overridden for an MQTT connection. The compile-time setting\r
- * @ref IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES must be `1` to enable this functionality.\r
- * See the #IotMqttSerializer_t::serialize and #IotMqttSerializer_t::deserialize\r
- * members for a list of functions that can be overridden. In addition, the functions\r
- * for freeing packets and determining the packet type can also be overridden. If\r
- * @ref IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES is `1`, the serializer initialization and\r
- * cleanup functions may be extended. See documentation of\r
- * @ref IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES for more information.\r
- *\r
- * If any function pointers that are `NULL`, then the default implementation of that\r
- * function will be used.\r
- */\r
-    typedef struct IotMqttSerializer\r
-    {\r
-        /**\r
-         * @brief Get the MQTT packet type from a stream of bytes off the network.\r
-         *\r
-         * @param[in] pNetworkConnection Reference to the network connection.\r
-         * @param[in] pNetworkInterface Function pointers used to interact with the\r
-         * network.\r
-         *\r
-         * <b>Default implementation:</b> #_IotMqtt_GetPacketType\r
-         */\r
-        uint8_t ( * getPacketType )( void * /* pNetworkConnection */,\r
-                                     const IotNetworkInterface_t * /* pNetworkInterface */ );\r
-\r
-        /**\r
-         * @brief Get the remaining length from a stream of bytes off the network.\r
-         *\r
-         * @param[in] pNetworkConnection Reference to the network connection.\r
-         * @param[in] pNetworkInterface Function pointers used to interact with the\r
-         * network.\r
-         *\r
-         * <b>Default implementation:</b> #_IotMqtt_GetRemainingLength\r
-         */\r
-        size_t ( * getRemainingLength )( void * pNetworkConnection,\r
-                                         const IotNetworkInterface_t * pNetworkInterface );\r
-\r
-        /**\r
-         * @brief Free a packet generated by the serializer.\r
-         *\r
-         * This function pointer must be set if any other serializer override is set.\r
-         * @param[in] uint8_t* The packet to free.\r
-         *\r
-         * <b>Default implementation:</b> #_IotMqtt_FreePacket\r
-         */\r
-        void ( * freePacket )( uint8_t * /* pPacket */ );\r
-\r
-        struct\r
-        {\r
-            /**\r
-             * @brief CONNECT packet serializer function.\r
-             * @param[in] IotMqttConnectInfo_t* User-provided CONNECT information.\r
-             * @param[out] uint8_t** Where the CONNECT packet is written.\r
-             * @param[out] size_t* Size of the CONNECT packet.\r
-             *\r
-             * <b>Default implementation:</b> #_IotMqtt_SerializeConnect\r
-             */\r
-            IotMqttError_t ( * connect )( const IotMqttConnectInfo_t * /* pConnectInfo */,\r
-                                          uint8_t ** /* pConnectPacket */,\r
-                                          size_t * /* pPacketSize */ );\r
-\r
-            /**\r
-             * @brief PUBLISH packet serializer function.\r
-             * @param[in] IotMqttPublishInfo_t* User-provided PUBLISH information.\r
-             * @param[out] uint8_t** Where the PUBLISH packet is written.\r
-             * @param[out] size_t* Size of the PUBLISH packet.\r
-             * @param[out] uint16_t* The packet identifier generated for this PUBLISH.\r
-             * @param[out] uint8_t** Where the high byte of the packet identifier\r
-             * is written.\r
-             *\r
-             * <b>Default implementation:</b> #_IotMqtt_SerializePublish\r
-             */\r
-            IotMqttError_t ( * publish )( const IotMqttPublishInfo_t * /* pPublishInfo */,\r
-                                          uint8_t ** /* pPublishPacket */,\r
-                                          size_t * /* pPacketSize */,\r
-                                          uint16_t * /* pPacketIdentifier */,\r
-                                          uint8_t ** /* pPacketIdentifierHigh */ );\r
-\r
-            /**\r
-             * @brief Set the `DUP` bit in a QoS `1` PUBLISH packet.\r
-             * @param[in] uint8_t* Pointer to the PUBLISH packet to modify.\r
-             * @param[in] uint8_t* The high byte of any packet identifier to modify.\r
-             * @param[out] uint16_t* New packet identifier (AWS IoT MQTT mode only).\r
-             *\r
-             * <b>Default implementation:</b> #_IotMqtt_PublishSetDup\r
-             */\r
-            void ( *publishSetDup )( uint8_t * /* pPublishPacket */,\r
-                                     uint8_t * /* pPacketIdentifierHigh */,\r
-                                     uint16_t * /* pNewPacketIdentifier */ );\r
-\r
-            /**\r
-             * @brief PUBACK packet serializer function.\r
-             * @param[in] uint16_t The packet identifier to place in PUBACK.\r
-             * @param[out] uint8_t** Where the PUBACK packet is written.\r
-             * @param[out] size_t* Size of the PUBACK packet.\r
-             *\r
-             * <b>Default implementation:</b> #_IotMqtt_SerializePuback\r
-             */\r
-            IotMqttError_t ( * puback )( uint16_t /* packetIdentifier */,\r
-                                         uint8_t ** /* pPubackPacket */,\r
-                                         size_t * /* pPacketSize */ );\r
-\r
-            /**\r
-             * @brief SUBSCRIBE packet serializer function.\r
-             * @param[in] IotMqttSubscription_t* User-provided array of subscriptions.\r
-             * @param[in] size_t Number of elements in the subscription array.\r
-             * @param[out] uint8_t** Where the SUBSCRIBE packet is written.\r
-             * @param[out] size_t* Size of the SUBSCRIBE packet.\r
-             * @param[out] uint16_t* The packet identifier generated for this SUBSCRIBE.\r
-             *\r
-             * <b>Default implementation:</b> #_IotMqtt_SerializeSubscribe\r
-             */\r
-            IotMqttError_t ( * subscribe )( const IotMqttSubscription_t * /* pSubscriptionList */,\r
-                                            size_t /* subscriptionCount */,\r
-                                            uint8_t ** /* pSubscribePacket */,\r
-                                            size_t * /* pPacketSize */,\r
-                                            uint16_t * /* pPacketIdentifier */ );\r
-\r
-            /**\r
-             * @brief UNSUBSCRIBE packet serializer function.\r
-             * @param[in] IotMqttSubscription_t* User-provided array of subscriptions to remove.\r
-             * @param[in] size_t Number of elements in the subscription array.\r
-             * @param[out] uint8_t** Where the UNSUBSCRIBE packet is written.\r
-             * @param[out] size_t* Size of the UNSUBSCRIBE packet.\r
-             * @param[out] uint16_t* The packet identifier generated for this UNSUBSCRIBE.\r
-             *\r
-             * <b>Default implementation:</b> #_IotMqtt_SerializeUnsubscribe\r
-             */\r
-            IotMqttError_t ( * unsubscribe )( const IotMqttSubscription_t * /* pSubscriptionList */,\r
-                                              size_t /* subscriptionCount */,\r
-                                              uint8_t ** /* pUnsubscribePacket */,\r
-                                              size_t * /* pPacketSize */,\r
-                                              uint16_t * /* pPacketIdentifier */ );\r
-\r
-            /**\r
-             * @brief PINGREQ packet serializer function.\r
-             * @param[out] uint8_t** Where the PINGREQ packet is written.\r
-             * @param[out] size_t* Size of the PINGREQ packet.\r
-             *\r
-             * <b>Default implementation:</b> #_IotMqtt_SerializePingreq\r
-             */\r
-            IotMqttError_t ( * pingreq )( uint8_t ** /* pPingreqPacket */,\r
-                                          size_t * /* pPacketSize */ );\r
-\r
-            /**\r
-             * @brief DISCONNECT packet serializer function.\r
-             * @param[out] uint8_t** Where the DISCONNECT packet is written.\r
-             * @param[out] size_t* Size of the DISCONNECT packet.\r
-             *\r
-             * <b>Default implementation:</b> #_IotMqtt_SerializeDisconnect\r
-             */\r
-            IotMqttError_t ( * disconnect )( uint8_t ** /* pDisconnectPacket */,\r
-                                             size_t * /* pPacketSize */ );\r
-        } serialize; /**< @brief Overrides the packet serialization functions for a single connection. */\r
-\r
-        struct\r
-        {\r
-            /**\r
-             * @brief CONNACK packet deserializer function.\r
-             * @param[in,out] _mqttPacket* Pointer to an MQTT packet struct representing a CONNACK.\r
-             *\r
-             * <b>Default implementation:</b> #_IotMqtt_DeserializeConnack\r
-             */\r
-            IotMqttError_t ( * connack )( struct _mqttPacket * /* pConnack */ );\r
-\r
-            /**\r
-             * @brief PUBLISH packet deserializer function.\r
-             * @param[in,out] _mqttPacket* Pointer to an MQTT packet struct representing a PUBLISH.\r
-             *\r
-             * <b>Default implementation:</b> #_IotMqtt_DeserializePublish\r
-             */\r
-            IotMqttError_t ( * publish )( struct _mqttPacket * /* pPublish */ );\r
-\r
-            /**\r
-             * @brief PUBACK packet deserializer function.\r
-             * @param[in,out] _mqttPacket* Pointer to an MQTT packet struct representing a PUBACK.\r
-             *\r
-             * <b>Default implementation:</b> #_IotMqtt_DeserializePuback\r
-             */\r
-            IotMqttError_t ( * puback )( struct _mqttPacket * pPuback );\r
-\r
-            /**\r
-             * @brief SUBACK packet deserializer function.\r
-             * @param[in,out] _mqttPacket* Pointer to an MQTT packet struct representing a SUBACK.\r
-             *\r
-             * <b>Default implementation:</b> #_IotMqtt_DeserializeSuback\r
-             */\r
-            IotMqttError_t ( * suback )( struct _mqttPacket * /* pSuback */ );\r
-\r
-            /**\r
-             * @brief UNSUBACK packet deserializer function.\r
-             * @param[in,out] _mqttPacket* Pointer to an MQTT packet struct representing an UNSUBACK.\r
-             *\r
-             * <b>Default implementation:</b> #_IotMqtt_DeserializeUnsuback\r
-             */\r
-            IotMqttError_t ( * unsuback )( struct _mqttPacket * /* pUnsuback */ );\r
-\r
-            /**\r
-             * @brief PINGRESP packet deserializer function.\r
-             * @param[in,out] _mqttPacket* Pointer to an MQTT packet struct representing a PINGRESP.\r
-             *\r
-             * <b>Default implementation:</b> #_IotMqtt_DeserializePingresp\r
-             */\r
-            IotMqttError_t ( * pingresp )( struct _mqttPacket * /* pPingresp */ );\r
-        } deserialize; /**< @brief Overrides the packet deserialization functions for a single connection. */\r
-    } IotMqttSerializer_t;\r
-#else /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */\r
-\r
-/* When MQTT packet serializer overrides are disabled, this struct is an\r
- * incomplete type. */\r
-    typedef struct IotMqttSerializer IotMqttSerializer_t;\r
-\r
-#endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */\r
-\r
-/**\r
- * @ingroup mqtt_datatypes_paramstructs\r
- * @brief Infomation on the transport-layer network connection for the new MQTT\r
- * connection.\r
- *\r
- * @paramfor @ref mqtt_function_connect\r
- *\r
- * The MQTT library needs to be able to send and receive data over a network.\r
- * This struct provides an interface for interacting with the network.\r
- *\r
- * @initializer{IotMqttNetworkInfo_t,IOT_MQTT_NETWORK_INFO_INITIALIZER}\r
- */\r
-typedef struct IotMqttNetworkInfo\r
-{\r
-    /**\r
-     * @brief Whether a new network connection should be created.\r
-     *\r
-     * When this value is `true`, a new transport-layer network connection will\r
-     * be created along with the MQTT connection. #IotMqttNetworkInfo_t::pNetworkServerInfo\r
-     * and #IotMqttNetworkInfo_t::pNetworkCredentialInfo are valid when this value\r
-     * is `true`.\r
-     *\r
-     * When this value is `false`, the MQTT connection will use a transport-layer\r
-     * network connection that has already been established. The MQTT library will\r
-     * still set the appropriate receive callback even if the network connection\r
-     * has been established.\r
-     * #IotMqttNetworkInfo_t::pNetworkConnection, which represents an established\r
-     * network connection, is valid when this value is `false`.\r
-     */\r
-    bool createNetworkConnection;\r
-\r
-    union\r
-    {\r
-        struct\r
-        {\r
-            /**\r
-             * @brief Information on the MQTT server, passed as `pConnectionInfo` to\r
-             * #IotNetworkInterface_t::create.\r
-             *\r
-             * This member is opaque to the MQTT library. It is passed to the network\r
-             * interface when creating a new network connection. It is only valid when\r
-             * #IotMqttNetworkInfo_t::createNetworkConnection is `true`.\r
-             */\r
-            void * pNetworkServerInfo;\r
-\r
-            /**\r
-             * @brief Credentials for the MQTT server, passed as `pCredentialInfo` to\r
-             * #IotNetworkInterface_t::create.\r
-             *\r
-             * This member is opaque to the MQTT library. It is passed to the network\r
-             * interface when creating a new network connection. It is only valid when\r
-             * #IotMqttNetworkInfo_t::createNetworkConnection is `true`.\r
-             */\r
-            void * pNetworkCredentialInfo;\r
-        } setup;\r
-\r
-        /**\r
-         * @brief An established transport-layer network connection.\r
-         *\r
-         * This member is opaque to the MQTT library. It is passed to the network\r
-         * interface to reference an established network connection. It is only\r
-         * valid when #IotMqttNetworkInfo_t::createNetworkConnection is `false`.\r
-         */\r
-        void * pNetworkConnection;\r
-    } u /**< @brief Valid member depends of IotMqttNetworkInfo_t.createNetworkConnection. */;\r
-\r
-    /**\r
-     * @brief The network functions used by the new MQTT connection.\r
-     *\r
-     * @attention The function pointers of the network interface must remain valid\r
-     * for the lifetime of the MQTT connection.\r
-     */\r
-    const IotNetworkInterface_t * pNetworkInterface;\r
-\r
-    /**\r
-     * @brief A callback function to invoke when this MQTT connection is disconnected.\r
-     */\r
-    IotMqttCallbackInfo_t disconnectCallback;\r
-\r
-    #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
-\r
-        /**\r
-         * @brief MQTT packet serializer overrides used by the new MQTT connection.\r
-         *\r
-         * @attention The function pointers of the MQTT serializer overrides must\r
-         * remain valid for the lifetime of the MQTT connection.\r
-         */\r
-        const IotMqttSerializer_t * pMqttSerializer;\r
-    #endif\r
-} IotMqttNetworkInfo_t;\r
-\r
-/*------------------------- MQTT defined constants --------------------------*/\r
-\r
-/**\r
- * @constantspage{mqtt,MQTT library}\r
- *\r
- * @section mqtt_constants_initializers MQTT Initializers\r
- * @brief Provides default values for the data types of the MQTT library.\r
- *\r
- * @snippet this define_mqtt_initializers\r
- *\r
- * All user-facing data types of the MQTT library should be initialized using\r
- * one of the following.\r
- *\r
- * @warning Failing to initialize an MQTT data type with the appropriate initializer\r
- * may result in undefined behavior!\r
- * @note The initializers may change at any time in future versions, but their\r
- * names will remain the same.\r
- *\r
- * <b>Example</b>\r
- * @code{c}\r
- * IotMqttNetworkInfo_t networkInfo = IOT_MQTT_NETWORK_INFO_INITIALIZER;\r
- * IotMqttSerializer_t serializer = IOT_MQTT_SERIALIZER_INITIALIZER;\r
- * IotMqttConnectInfo_t connectInfo = IOT_MQTT_CONNECT_INFO_INITIALIZER;\r
- * IotMqttPublishInfo_t publishInfo = IOT_MQTT_PUBLISH_INFO_INITIALIZER;\r
- * IotMqttSubscription_t subscription = IOT_MQTT_SUBSCRIPTION_INITIALIZER;\r
- * IotMqttCallbackInfo_t callbackInfo = IOT_MQTT_CALLBACK_INFO_INITIALIZER;\r
- * IotMqttConnection_t connection = IOT_MQTT_CONNECTION_INITIALIZER;\r
- * IotMqttOperation_t operation = IOT_MQTT_OPERATION_INITIALIZER;\r
- * @endcode\r
- *\r
- * @section mqtt_constants_flags MQTT Function Flags\r
- * @brief Flags that modify the behavior of MQTT library functions.\r
- * - #IOT_MQTT_FLAG_WAITABLE <br>\r
- *   @copybrief IOT_MQTT_FLAG_WAITABLE\r
- * - #IOT_MQTT_FLAG_CLEANUP_ONLY <br>\r
- *   @copybrief IOT_MQTT_FLAG_CLEANUP_ONLY\r
- *\r
- * Flags should be bitwise-ORed with each other to change the behavior of\r
- * @ref mqtt_function_subscribe, @ref mqtt_function_unsubscribe,\r
- * @ref mqtt_function_publish, or @ref mqtt_function_disconnect.\r
- *\r
- * @note The values of the flags may change at any time in future versions, but\r
- * their names will remain the same. Additionally, flags that may be used together\r
- * will be bitwise-exclusive of each other.\r
- */\r
-\r
-/* @[define_mqtt_initializers] */\r
-/** @brief Initializer for #IotMqttNetworkInfo_t. */\r
-#define IOT_MQTT_NETWORK_INFO_INITIALIZER     { .createNetworkConnection = true }\r
-/** @brief Initializer for #IotMqttSerializer_t. */\r
-#define IOT_MQTT_SERIALIZER_INITIALIZER       { 0 }\r
-/** @brief Initializer for #IotMqttConnectInfo_t. */\r
-#define IOT_MQTT_CONNECT_INFO_INITIALIZER     { .cleanSession = true }\r
-/** @brief Initializer for #IotMqttPublishInfo_t. */\r
-#define IOT_MQTT_PUBLISH_INFO_INITIALIZER     { .qos = IOT_MQTT_QOS_0 }\r
-/** @brief Initializer for #IotMqttSubscription_t. */\r
-#define IOT_MQTT_SUBSCRIPTION_INITIALIZER     { .qos = IOT_MQTT_QOS_0 }\r
-/** @brief Initializer for #IotMqttCallbackInfo_t. */\r
-#define IOT_MQTT_CALLBACK_INFO_INITIALIZER    { 0 }\r
-/** @brief Initializer for #IotMqttConnection_t. */\r
-#define IOT_MQTT_CONNECTION_INITIALIZER       NULL\r
-/** @brief Initializer for #IotMqttOperation_t. */\r
-#define IOT_MQTT_OPERATION_INITIALIZER        NULL\r
-/* @[define_mqtt_initializers] */\r
-\r
-/**\r
- * @brief Allows the use of @ref mqtt_function_wait for blocking until completion.\r
- *\r
- * This flag is always valid for @ref mqtt_function_subscribe and\r
- * @ref mqtt_function_unsubscribe. If passed to @ref mqtt_function_publish,\r
- * the parameter [pPublishInfo->qos](@ref IotMqttPublishInfo_t.qos) must not be `0`.\r
- *\r
- * An #IotMqttOperation_t <b>MUST</b> be provided if this flag is set. Additionally, an\r
- * #IotMqttCallbackInfo_t <b>MUST NOT</b> be provided.\r
- *\r
- * @note If this flag is set, @ref mqtt_function_wait <b>MUST</b> be called to clean up\r
- * resources.\r
- */\r
-#define IOT_MQTT_FLAG_WAITABLE        ( 0x00000001 )\r
-\r
-/**\r
- * @brief Causes @ref mqtt_function_disconnect to only free memory and not send\r
- * an MQTT DISCONNECT packet.\r
- *\r
- * This flag is only valid for @ref mqtt_function_disconnect. It should be passed\r
- * to @ref mqtt_function_disconnect if the network goes offline or is otherwise\r
- * unusable.\r
- */\r
-#define IOT_MQTT_FLAG_CLEANUP_ONLY    ( 0x00000001 )\r
-\r
-#endif /* ifndef IOT_MQTT_TYPES_H_ */\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_ble_mqtt_serialize.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_ble_mqtt_serialize.c
deleted file mode 100644 (file)
index 143b442..0000000
+++ /dev/null
@@ -1,1528 +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 aws_mqtt_lib_ble.c\r
- * @brief MQTT library for BLE.\r
- */\r
-/* The config header is always included first. */\r
-#include "iot_config.h"\r
-\r
-/* Standard includes. */\r
-#include <string.h>\r
-#include <stdio.h>\r
-\r
-/* FreeRTOS includes. */\r
-#include "FreeRTOS.h"\r
-\r
-#include "iot_ble_config.h"\r
-\r
-\r
-/* MQTT internal includes. */\r
-#include "platform/iot_threads.h"\r
-#include "iot_serializer.h"\r
-#include "platform/iot_network_ble.h"\r
-#include "iot_ble_data_transfer.h"\r
-#include "iot_ble_mqtt_serialize.h"\r
-#include "private/iot_mqtt_internal.h"\r
-\r
-#define _INVALID_MQTT_PACKET_TYPE        ( 0xF0 )\r
-\r
-\r
-#define _IS_VALID_SERIALIZER_RET( ret, pSerializerBuf )                                \\r
-    (  ( ret == IOT_SERIALIZER_SUCCESS ) ||                                        \\r
-          (  ( !pSerializerBuf ) && ( ret == IOT_SERIALIZER_BUFFER_TOO_SMALL ) ) )\r
-\r
-#define _NUM_CONNECT_PARMAS                   ( 4 )\r
-#define _NUM_DEFAULT_PUBLISH_PARMAS           ( 4 )\r
-#define _NUM_PUBACK_PARMAS                    ( 2 )\r
-#define _NUM_SUBACK_PARAMS                    ( 4 )\r
-#define _NUM_UNSUBACK_PARAMS                  ( 3 )\r
-#define _NUM_DISCONNECT_PARAMS                ( 1 )\r
-#define _NUM_PINGREQUEST_PARAMS               ( 1 )\r
-\r
-const IotMqttSerializer_t IotBleMqttSerializer = {\r
-    .serialize.connect       = IotBleMqtt_SerializeConnect,\r
-    .serialize.publish       = IotBleMqtt_SerializePublish,\r
-    .serialize.publishSetDup = IotBleMqtt_PublishSetDup,\r
-    .serialize.puback        = IotBleMqtt_SerializePuback,\r
-    .serialize.subscribe     = IotBleMqtt_SerializeSubscribe,\r
-    .serialize.unsubscribe   = IotBleMqtt_SerializeUnsubscribe,\r
-    .serialize.pingreq       = IotBleMqtt_SerializePingreq,\r
-    .serialize.disconnect    = IotBleMqtt_SerializeDisconnect,\r
-    .freePacket              = IotBleMqtt_FreePacket,\r
-    .getPacketType           = IotBleMqtt_GetPacketType,\r
-    .getRemainingLength      = IotBleMqtt_GetRemainingLength,\r
-    .deserialize.connack     = IotBleMqtt_DeserializeConnack,\r
-    .deserialize.publish     = IotBleMqtt_DeserializePublish,\r
-    .deserialize.puback      = IotBleMqtt_DeserializePuback,\r
-    .deserialize.suback      = IotBleMqtt_DeserializeSuback,\r
-    .deserialize.unsuback    = IotBleMqtt_DeserializeUnsuback,\r
-    .deserialize.pingresp    = IotBleMqtt_DeserializePingresp\r
-};\r
-\r
-/**\r
- * @brief Guards access to the packet identifier counter.\r
- *\r
- * Each packet should have a unique packet identifier. This mutex ensures that only\r
- * one thread at a time may read the global packet identifer.\r
- */\r
-\r
-\r
-/**\r
- * @brief Generates a monotonically increasing identifier used in  MQTT message\r
- *\r
- * @return Identifier for the MQTT message\r
- */\r
-static uint16_t _nextPacketIdentifier( void );\r
-\r
-\r
-static inline uint16_t _getNumPublishParams( const IotMqttPublishInfo_t * const pPublish )\r
-{\r
-   return ( pPublish->qos > 0 ) ?  ( _NUM_DEFAULT_PUBLISH_PARMAS + 1 ) : _NUM_DEFAULT_PUBLISH_PARMAS;\r
-}\r
-\r
-static IotSerializerError_t _serializeConnect( const IotMqttConnectInfo_t * const pConnectInfo,\r
-                                       uint8_t* const pBuffer,\r
-                                       size_t* const pSize );\r
-static IotSerializerError_t _serializePublish( const IotMqttPublishInfo_t * const pPublishInfo,\r
-                                                  uint8_t * pBuffer,\r
-                                                  size_t  * pSize,\r
-                                                  uint16_t packetIdentifier );\r
-static IotSerializerError_t _serializePubAck( uint16_t packetIdentifier,\r
-                                      uint8_t * pBuffer,\r
-                                      size_t  * pSize );\r
-\r
-\r
-\r
-static IotSerializerError_t _serializeSubscribe( const IotMqttSubscription_t * const pSubscriptionList,\r
-                                               size_t subscriptionCount,\r
-                                               uint8_t * const pBuffer,\r
-                                               size_t * const pSize,\r
-                                               uint16_t packetIdentifier );\r
-\r
-static IotSerializerError_t _serializeUnSubscribe( const IotMqttSubscription_t * const pSubscriptionList,\r
-                                               size_t subscriptionCount,\r
-                                               uint8_t * const pBuffer,\r
-                                               size_t * const pSize,\r
-                                               uint16_t packetIdentifier );\r
-\r
-static IotSerializerError_t _serializeDisconnect( uint8_t * const pBuffer,\r
-                                                size_t * const pSize );\r
-\r
-\r
-static IotSerializerError_t _serializePingRequest( uint8_t * const pBuffer,\r
-                                                size_t * const pSize );\r
-\r
-#if LIBRARY_LOG_LEVEL > AWS_IOT_LOG_NONE\r
-\r
-/**\r
- * @brief If logging is enabled, define a log configuration that only prints the log\r
- * string. This is used when printing out details of deserialized MQTT packets.\r
- */\r
-static const IotLogConfig_t _logHideAll =\r
-{\r
-    .hideLibraryName = true,\r
-    .hideLogLevel    = true,\r
-    .hideTimestring  = true\r
-};\r
-#endif\r
-\r
-\r
-static IotMutex_t _packetIdentifierMutex;\r
-\r
-\r
-/* Declaration of snprintf. The header stdio.h is not included because it\r
- * includes conflicting symbols on some platforms. */\r
-extern int snprintf( char * s,\r
-                     size_t n,\r
-                     const char * format,\r
-                     ... );\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static uint16_t _nextPacketIdentifier( void )\r
-{\r
-    static uint16_t nextPacketIdentifier = 1;\r
-    uint16_t newPacketIdentifier = 0;\r
-\r
-    /* Lock the packet identifier mutex so that only one thread may read and\r
-         * modify nextPacketIdentifier. */\r
-     IotMutex_Lock( &_packetIdentifierMutex );\r
-\r
-    /* Read the next packet identifier. */\r
-    newPacketIdentifier = nextPacketIdentifier;\r
-\r
-    /* The next packet identifier will be greater by 2. This prevents packet\r
-     * identifiers from ever being 0, which is not allowed by MQTT 3.1.1. Packet\r
-     * identifiers will follow the sequence 1,3,5...65535,1,3,5... */\r
-    nextPacketIdentifier = ( uint16_t ) ( nextPacketIdentifier + ( ( uint16_t ) 2 ) );\r
-\r
-    /* Unlock the packet identifier mutex. */\r
-    IotMutex_Unlock( &_packetIdentifierMutex );\r
-\r
-    return newPacketIdentifier;\r
-}\r
-\r
-static IotSerializerError_t _serializeConnect( const IotMqttConnectInfo_t * const pConnectInfo,\r
-                                       uint8_t* const pBuffer,\r
-                                       size_t* const pSize )\r
-{\r
-    IotSerializerError_t error = IOT_SERIALIZER_SUCCESS;\r
-    IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM ;\r
-    IotSerializerEncoderObject_t connectMap = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP;\r
-    IotSerializerScalarData_t data = { 0 };\r
-\r
-    error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize );\r
-    if( error == IOT_SERIALIZER_SUCCESS )\r
-    {\r
-\r
-        error = IOT_BLE_MESG_ENCODER.openContainer(\r
-                &encoderObj,\r
-                &connectMap,\r
-                _NUM_CONNECT_PARMAS );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
-        data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_CONNECT;\r
-        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &connectMap, IOT_BLE_MQTT_MSG_TYPE, data );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        data.type = IOT_SERIALIZER_SCALAR_TEXT_STRING;\r
-        data.value.u.string.pString = ( uint8_t * ) pConnectInfo->pClientIdentifier;\r
-        data.value.u.string.length = pConnectInfo->clientIdentifierLength;\r
-        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &connectMap, IOT_BLE_MQTT_CLIENT_ID, data );\r
-    }\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        data.type = IOT_SERIALIZER_SCALAR_TEXT_STRING;\r
-        data.value.u.string.pString = ( uint8_t * ) clientcredentialMQTT_BROKER_ENDPOINT;\r
-        data.value.u.string.length = strlen( clientcredentialMQTT_BROKER_ENDPOINT );\r
-        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &connectMap, IOT_BLE_MQTT_BROKER_EP, data );\r
-    }\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        data.type = IOT_SERIALIZER_SCALAR_BOOL;\r
-        data.value.u.booleanValue = pConnectInfo->cleanSession;\r
-        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &connectMap, IOT_BLE_MQTT_CLEAN_SESSION, data );\r
-    }\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &connectMap );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        if( pBuffer == NULL )\r
-        {\r
-            *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj );\r
-        }\r
-        else\r
-        {\r
-            *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer );\r
-        }\r
-\r
-        IOT_BLE_MESG_ENCODER.destroy( &encoderObj );\r
-        error = IOT_SERIALIZER_SUCCESS;\r
-\r
-    }\r
-\r
-    return error;\r
-}\r
-\r
-static IotSerializerError_t _serializePublish( const IotMqttPublishInfo_t * const pPublishInfo,\r
-                                                  uint8_t * pBuffer,\r
-                                                  size_t  * pSize,\r
-                                                  uint16_t packetIdentifier )\r
-{\r
-    IotSerializerError_t error = IOT_SERIALIZER_SUCCESS;\r
-    IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM ;\r
-    IotSerializerEncoderObject_t publishMap = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP;\r
-    IotSerializerScalarData_t data = { 0 };\r
-    uint16_t numPublishParams = _getNumPublishParams( pPublishInfo );\r
-\r
-    error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize );\r
-\r
-    if( error == IOT_SERIALIZER_SUCCESS )\r
-    {\r
-\r
-\r
-        error = IOT_BLE_MESG_ENCODER.openContainer(\r
-                &encoderObj,\r
-                &publishMap,\r
-                numPublishParams );\r
-    }\r
-\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
-        data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_PUBLISH;\r
-        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &publishMap, IOT_BLE_MQTT_MSG_TYPE, data );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        data.type = IOT_SERIALIZER_SCALAR_TEXT_STRING;\r
-        data.value.u.string.pString = ( uint8_t * ) pPublishInfo->pTopicName;\r
-        data.value.u.string.length = pPublishInfo->topicNameLength;\r
-        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &publishMap, IOT_BLE_MQTT_TOPIC, data );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-\r
-        data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
-        data.value.u.signedInt = pPublishInfo->qos;\r
-        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &publishMap, IOT_BLE_MQTT_QOS, data );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        data.type = IOT_SERIALIZER_SCALAR_BYTE_STRING;\r
-        data.value.u.string.pString = ( uint8_t * ) pPublishInfo->pPayload;\r
-        data.value.u.string.length = pPublishInfo->payloadLength;\r
-        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &publishMap, IOT_BLE_MQTT_PAYLOAD, data );\r
-    }\r
-\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        if( pPublishInfo->qos != 0 )\r
-        {\r
-            data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
-            data.value.u.signedInt = packetIdentifier;\r
-            error = IOT_BLE_MESG_ENCODER.appendKeyValue( &publishMap, IOT_BLE_MQTT_MESSAGE_ID, data );\r
-\r
-        }\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-\r
-        error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &publishMap );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        if( pBuffer == NULL )\r
-        {\r
-            *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj );\r
-\r
-        }\r
-        else\r
-        {\r
-            *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer );\r
-        }\r
-        IOT_BLE_MESG_ENCODER.destroy( &encoderObj );\r
-        error = IOT_SERIALIZER_SUCCESS;\r
-    }\r
-\r
-\r
-    return error;\r
-}\r
-\r
-static IotSerializerError_t _serializePubAck( uint16_t packetIdentifier,\r
-                                      uint8_t * pBuffer,\r
-                                      size_t  * pSize )\r
-\r
-{\r
-    IotSerializerError_t error = IOT_SERIALIZER_SUCCESS;\r
-    IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM ;\r
-    IotSerializerEncoderObject_t pubAckMap = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP;\r
-    IotSerializerScalarData_t data = { 0 };\r
-\r
-    error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize );\r
-\r
-    if( error == IOT_SERIALIZER_SUCCESS )\r
-    {\r
-\r
-        error = IOT_BLE_MESG_ENCODER.openContainer(\r
-                &encoderObj,\r
-                &pubAckMap,\r
-                _NUM_PUBACK_PARMAS );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
-        data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_PUBACK;\r
-        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &pubAckMap, IOT_BLE_MQTT_MSG_TYPE, data );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
-        data.value.u.signedInt = packetIdentifier;\r
-        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &pubAckMap, IOT_BLE_MQTT_MESSAGE_ID, data );\r
-    }\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &pubAckMap );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        if( pBuffer == NULL )\r
-        {\r
-            *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj );\r
-        }\r
-        else\r
-        {\r
-            *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer );\r
-        }\r
-        IOT_BLE_MESG_ENCODER.destroy( &encoderObj );\r
-        error = IOT_SERIALIZER_SUCCESS;\r
-    }\r
-\r
-    return error;\r
-}\r
-\r
-\r
-static IotSerializerError_t _serializeSubscribe( const IotMqttSubscription_t * const pSubscriptionList,\r
-                                               size_t subscriptionCount,\r
-                                               uint8_t * const pBuffer,\r
-                                               size_t * const pSize,\r
-                                               uint16_t packetIdentifier )\r
-{\r
-    IotSerializerError_t error = IOT_SERIALIZER_SUCCESS;\r
-    IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM ;\r
-    IotSerializerEncoderObject_t subscribeMap = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP;\r
-    IotSerializerEncoderObject_t subscriptionArray = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_ARRAY;\r
-    IotSerializerScalarData_t data = { 0 };\r
-    uint16_t idx;\r
-\r
-    error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize );\r
-\r
-    if( error == IOT_SERIALIZER_SUCCESS )\r
-    {\r
-        error = IOT_BLE_MESG_ENCODER.openContainer(\r
-                &encoderObj,\r
-                &subscribeMap,\r
-                _NUM_SUBACK_PARAMS );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
-        data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_SUBSCRIBE;\r
-        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &subscribeMap, IOT_BLE_MQTT_MSG_TYPE, data );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-\r
-        error = IOT_BLE_MESG_ENCODER.openContainerWithKey(\r
-                &subscribeMap,\r
-                IOT_BLE_MQTT_TOPIC_LIST,\r
-                &subscriptionArray,\r
-                subscriptionCount );\r
-    }\r
-\r
-    for( idx = 0; idx < subscriptionCount; idx++ )\r
-    {\r
-        if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-        {\r
-            data.type = IOT_SERIALIZER_SCALAR_TEXT_STRING;\r
-            data.value.u.string.pString = ( uint8_t * ) pSubscriptionList[ idx ].pTopicFilter;\r
-            data.value.u.string.length = pSubscriptionList[ idx ].topicFilterLength;\r
-            error = IOT_BLE_MESG_ENCODER.append( &subscriptionArray, data );\r
-        }\r
-        else\r
-        {\r
-            break;\r
-        }\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        error = IOT_BLE_MESG_ENCODER.closeContainer( &subscribeMap, &subscriptionArray );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-\r
-        error = IOT_BLE_MESG_ENCODER.openContainerWithKey(\r
-                &subscribeMap,\r
-                IOT_BLE_MQTT_QOS_LIST,\r
-                &subscriptionArray,\r
-                subscriptionCount );\r
-    }\r
-\r
-\r
-    for( idx = 0; idx < subscriptionCount; idx++ )\r
-    {\r
-        if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-        {\r
-\r
-            data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
-            data.value.u.signedInt = pSubscriptionList[ idx ].qos;\r
-            error = IOT_BLE_MESG_ENCODER.append( &subscriptionArray, data );\r
-        }\r
-        else\r
-        {\r
-            break;\r
-        }\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        error = IOT_BLE_MESG_ENCODER.closeContainer( &subscribeMap, &subscriptionArray );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-\r
-        data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
-        data.value.u.signedInt = packetIdentifier;\r
-        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &subscribeMap, IOT_BLE_MQTT_MESSAGE_ID, data );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &subscribeMap );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        if( pBuffer == NULL )\r
-        {\r
-            *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj );\r
-        }\r
-        else\r
-        {\r
-            *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer );\r
-        }\r
-\r
-        IOT_BLE_MESG_ENCODER.destroy( &encoderObj );\r
-        error = IOT_SERIALIZER_SUCCESS;\r
-    }\r
-    return error;\r
-}\r
-\r
-static IotSerializerError_t _serializeUnSubscribe( const IotMqttSubscription_t * const pSubscriptionList,\r
-                                               size_t subscriptionCount,\r
-                                               uint8_t * const pBuffer,\r
-                                               size_t * const pSize,\r
-                                               uint16_t packetIdentifier )\r
-{\r
-    IotSerializerError_t error = IOT_SERIALIZER_SUCCESS;\r
-    IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM;\r
-    IotSerializerEncoderObject_t subscribeMap = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP;\r
-    IotSerializerEncoderObject_t subscriptionArray = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_ARRAY;\r
-    IotSerializerScalarData_t data = { 0 };\r
-    uint16_t idx;\r
-\r
-    error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize );\r
-\r
-    if( error == IOT_SERIALIZER_SUCCESS )\r
-    {\r
-\r
-        error = IOT_BLE_MESG_ENCODER.openContainer(\r
-                &encoderObj,\r
-                &subscribeMap,\r
-                _NUM_UNSUBACK_PARAMS );\r
-    }\r
-\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
-        data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_UNSUBSCRIBE;\r
-        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &subscribeMap, IOT_BLE_MQTT_MSG_TYPE, data );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        error = IOT_BLE_MESG_ENCODER.openContainerWithKey (\r
-                &subscribeMap,\r
-                IOT_BLE_MQTT_TOPIC_LIST,\r
-                &subscriptionArray,\r
-                subscriptionCount );\r
-    }\r
-\r
-    for( idx = 0; idx < subscriptionCount; idx++ )\r
-    {\r
-        if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-        {\r
-            data.type = IOT_SERIALIZER_SCALAR_TEXT_STRING;\r
-            data.value.u.string.pString = ( uint8_t * ) pSubscriptionList[ idx ].pTopicFilter;\r
-            data.value.u.string.length = pSubscriptionList[ idx ].topicFilterLength;\r
-            error = IOT_BLE_MESG_ENCODER.append( &subscriptionArray, data );\r
-        }\r
-        else\r
-        {\r
-            break;\r
-        }\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        error = IOT_BLE_MESG_ENCODER.closeContainer( &subscribeMap, &subscriptionArray );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
-        data.value.u.signedInt = packetIdentifier;\r
-        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &subscribeMap, IOT_BLE_MQTT_MESSAGE_ID, data );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &subscribeMap );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        if( pBuffer == NULL )\r
-        {\r
-            *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj );\r
-\r
-        }\r
-        else\r
-        {\r
-            *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer );\r
-        }\r
-        IOT_BLE_MESG_ENCODER.destroy( &encoderObj );\r
-        error = IOT_SERIALIZER_SUCCESS;\r
-    }\r
-\r
-    return error;\r
-}\r
-\r
-static IotSerializerError_t _serializeDisconnect( uint8_t * const pBuffer,\r
-                                                size_t * const pSize )\r
-{\r
-    IotSerializerError_t error = IOT_SERIALIZER_SUCCESS;\r
-    IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM;\r
-    IotSerializerEncoderObject_t disconnectMap = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP;\r
-    IotSerializerScalarData_t data = { 0 };\r
-\r
-    error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize );\r
-\r
-    if( error == IOT_SERIALIZER_SUCCESS )\r
-    {\r
-        error = IOT_BLE_MESG_ENCODER.openContainer(\r
-                &encoderObj,\r
-                &disconnectMap,\r
-                _NUM_DISCONNECT_PARAMS );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
-        data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_DISCONNECT;\r
-        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &disconnectMap, IOT_BLE_MQTT_MSG_TYPE, data );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &disconnectMap );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        if( pBuffer == NULL )\r
-        {\r
-            *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj );\r
-        }\r
-        else\r
-        {\r
-            *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer );\r
-        }\r
-        IOT_BLE_MESG_ENCODER.destroy( &encoderObj );\r
-        error = IOT_SERIALIZER_SUCCESS;\r
-    }\r
-\r
-    return error;\r
-}\r
-\r
-static IotSerializerError_t _serializePingRequest( uint8_t * const pBuffer,\r
-                                                   size_t * const pSize )\r
-{\r
-    IotSerializerError_t error = IOT_SERIALIZER_SUCCESS;\r
-    IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM;\r
-    IotSerializerEncoderObject_t pingRequest = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP;\r
-    IotSerializerScalarData_t data = { 0 };\r
-\r
-    error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize );\r
-\r
-    if( error == IOT_SERIALIZER_SUCCESS )\r
-    {\r
-        error = IOT_BLE_MESG_ENCODER.openContainer(\r
-                &encoderObj,\r
-                &pingRequest,\r
-                _NUM_PINGREQUEST_PARAMS );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
-         data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_PINGREQ;\r
-        error = IOT_BLE_MESG_ENCODER.appendKeyValue( &pingRequest, IOT_BLE_MQTT_MSG_TYPE, data );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &pingRequest );\r
-    }\r
-\r
-    if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
-    {\r
-        if( pBuffer == NULL )\r
-        {\r
-            *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj );\r
-        }\r
-        else\r
-        {\r
-            *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer );\r
-        }\r
-        IOT_BLE_MESG_ENCODER.destroy( &encoderObj );\r
-        error = IOT_SERIALIZER_SUCCESS;\r
-    }\r
-\r
-    return error;\r
-}\r
-\r
-\r
-bool IotBleMqtt_InitSerialize( void )\r
-{\r
-       /* Create the packet identifier mutex. */\r
-       return IotMutex_Create( &_packetIdentifierMutex, false );\r
-}\r
-\r
-void IotBleMqtt_CleanupSerialize( void )\r
-{\r
-       /* Destroy the packet identifier mutex */\r
-       IotMutex_Destroy( &_packetIdentifierMutex );\r
-}\r
-\r
-\r
-IotMqttError_t IotBleMqtt_SerializeConnect( const IotMqttConnectInfo_t * const pConnectInfo,\r
-                                                           uint8_t ** const pConnectPacket,\r
-                                                           size_t * const pPacketSize )\r
-{\r
-       uint8_t * pBuffer = NULL;\r
-       size_t bufLen = 0;\r
-       IotSerializerError_t error;\r
-       IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
-\r
-\r
-       error = _serializeConnect( pConnectInfo, NULL, &bufLen );\r
-       if( error != IOT_SERIALIZER_SUCCESS )\r
-       {\r
-           IotLogError( "Failed to find length of serialized CONNECT message, error = %d", error );\r
-           ret = IOT_MQTT_BAD_PARAMETER;\r
-       }\r
-\r
-       if( ret == IOT_MQTT_SUCCESS )\r
-       {\r
-\r
-           pBuffer = IotMqtt_MallocMessage( bufLen );\r
-\r
-           /* If Memory cannot be allocated log an error and return */\r
-           if( pBuffer == NULL )\r
-           {\r
-               IotLogError( "Failed to allocate memory for CONNECT packet." );\r
-               ret =  IOT_MQTT_NO_MEMORY;\r
-           }\r
-       }\r
-\r
-       if( ret == IOT_MQTT_SUCCESS )\r
-       {\r
-           error = _serializeConnect( pConnectInfo, pBuffer, &bufLen );\r
-           if( error != IOT_SERIALIZER_SUCCESS )\r
-           {\r
-               IotLogError( "Failed to serialize CONNECT message, error = %d", error );\r
-               ret = IOT_MQTT_BAD_PARAMETER;\r
-           }\r
-       }\r
-\r
-       if( ret == IOT_MQTT_SUCCESS )\r
-       {\r
-           *pConnectPacket = pBuffer;\r
-           *pPacketSize = bufLen;\r
-       }\r
-       else\r
-       {\r
-           *pConnectPacket = NULL;\r
-           *pPacketSize = 0;\r
-           if( pBuffer != NULL )\r
-           {\r
-               IotMqtt_FreeMessage( pBuffer );\r
-           }\r
-       }\r
-\r
-    return ret;\r
-}\r
-\r
-IotMqttError_t IotBleMqtt_DeserializeConnack( _mqttPacket_t * pConnack )\r
-{\r
-\r
-    IotSerializerDecoderObject_t decoderObj = { 0 }, decoderValue = { 0 };\r
-    IotSerializerError_t error;\r
-    IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
-    int64_t respCode = 0L;\r
-\r
-    error = IOT_BLE_MESG_DECODER.init( &decoderObj, ( uint8_t * ) pConnack->pRemainingData, pConnack->remainingLength );\r
-    if( ( error != IOT_SERIALIZER_SUCCESS )\r
-            || ( decoderObj.type != IOT_SERIALIZER_CONTAINER_MAP ) )\r
-    {\r
-        IotLogError( "Malformed CONNACK, decoding the packet failed, decoder error = %d, type: %d", error, decoderObj.type );\r
-        ret = IOT_MQTT_BAD_RESPONSE;\r
-    }\r
-\r
-\r
-    if( ret == IOT_MQTT_SUCCESS )\r
-    {\r
-\r
-        error = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_STATUS, &decoderValue );\r
-        if ( ( error != IOT_SERIALIZER_SUCCESS ) ||\r
-                ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) )\r
-        {\r
-            IotLogError( "Invalid CONNACK, response code decode failed, error = %d, decoded value type = %d", error, decoderValue.type );\r
-            ret = IOT_MQTT_BAD_RESPONSE;\r
-        }\r
-        else\r
-        {\r
-\r
-            respCode =  decoderValue.u.value.u.signedInt;\r
-            if( ( respCode != IOT_BLE_MQTT_STATUS_CONNECTING )\r
-                    && ( respCode != IOT_BLE_MQTT_STATUS_CONNECTED ) )\r
-            {\r
-                ret = IOT_MQTT_SERVER_REFUSED;\r
-            }\r
-        }\r
-    }\r
-\r
-    IOT_BLE_MESG_DECODER.destroy( &decoderObj );\r
-\r
-    return ret;\r
-}\r
-\r
-IotMqttError_t IotBleMqtt_SerializePublish( const IotMqttPublishInfo_t * const pPublishInfo,\r
-                                                  uint8_t ** const pPublishPacket,\r
-                                                  size_t * const pPacketSize,\r
-                                                  uint16_t * const pPacketIdentifier,\r
-                                                                                                 uint8_t ** pPacketIdentifierHigh )\r
-{\r
-\r
-    uint8_t * pBuffer = NULL;\r
-    size_t bufLen = 0;\r
-    uint16_t usPacketIdentifier = 0;\r
-    IotSerializerError_t error;\r
-    IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
-\r
-    (void)pPacketIdentifierHigh;\r
-\r
-    if( pPublishInfo->qos != 0 )\r
-    {\r
-        usPacketIdentifier = _nextPacketIdentifier();\r
-    }\r
-\r
-    error = _serializePublish( pPublishInfo, NULL, &bufLen, usPacketIdentifier );\r
-    if( error != IOT_SERIALIZER_SUCCESS  )\r
-    {\r
-        IotLogError( "Failed to find size of serialized PUBLISH message, error = %d", error );\r
-        ret = IOT_MQTT_BAD_PARAMETER;\r
-    }\r
-\r
-    if( ret == IOT_MQTT_SUCCESS )\r
-    {\r
-\r
-        pBuffer = IotMqtt_MallocMessage( bufLen );\r
-        /* If Memory cannot be allocated log an error and return */\r
-        if( pBuffer == NULL )\r
-        {\r
-            IotLogError( "Failed to allocate memory for PUBLISH packet." );\r
-            ret =  IOT_MQTT_NO_MEMORY;\r
-        }\r
-    }\r
-\r
-    if( ret == IOT_MQTT_SUCCESS )\r
-    {\r
-\r
-        error = _serializePublish( pPublishInfo, pBuffer, &bufLen, usPacketIdentifier );\r
-        if( error != IOT_SERIALIZER_SUCCESS )\r
-        {\r
-            IotLogError( "Failed to serialize PUBLISH message, error = %d", error );\r
-            ret = IOT_MQTT_BAD_PARAMETER;\r
-        }\r
-    }\r
-\r
-    if( ret == IOT_MQTT_SUCCESS )\r
-    {\r
-        *pPublishPacket = pBuffer;\r
-        *pPacketSize = bufLen;\r
-        *pPacketIdentifier = usPacketIdentifier;\r
-    }\r
-    else\r
-    {\r
-        if( pBuffer != NULL )\r
-        {\r
-            IotMqtt_FreeMessage( pBuffer );\r
-        }\r
-        *pPublishPacket = NULL;\r
-        *pPacketSize = 0;\r
-    }\r
-\r
-    return ret;\r
-}\r
-\r
-void IotBleMqtt_PublishSetDup( uint8_t * const pPublishPacket, uint8_t * pPacketIdentifierHigh, uint16_t * const pNewPacketIdentifier  )\r
-{\r
-       /** TODO: Currently DUP flag is not supported by BLE SDKs **/\r
-}\r
-\r
-IotMqttError_t IotBleMqtt_DeserializePublish( _mqttPacket_t * pPublish )\r
-{\r
-\r
-    IotSerializerDecoderObject_t decoderObj = { 0 }, decoderValue = { 0 };\r
-    IotSerializerError_t xSerializerRet;\r
-    IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
-\r
-    xSerializerRet = IOT_BLE_MESG_DECODER.init( &decoderObj, ( uint8_t * ) pPublish->pRemainingData, pPublish->remainingLength );\r
-    if ( (xSerializerRet != IOT_SERIALIZER_SUCCESS ) ||\r
-            ( decoderObj.type != IOT_SERIALIZER_CONTAINER_MAP ) )\r
-    {\r
-\r
-        IotLogError( "Decoding PUBLISH packet failed, decoder error = %d, object type = %d", xSerializerRet, decoderObj.type );\r
-        ret = IOT_MQTT_BAD_RESPONSE;\r
-    }\r
-\r
-    if( ret == IOT_MQTT_SUCCESS )\r
-    {\r
-        xSerializerRet = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_QOS, &decoderValue );\r
-        if ( ( xSerializerRet != IOT_SERIALIZER_SUCCESS ) ||\r
-                 ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) )\r
-        {\r
-            IotLogError( "QOS Value decode failed, error = %d, decoded value type = %d", xSerializerRet, decoderValue.type );\r
-            ret = IOT_MQTT_BAD_RESPONSE;\r
-        }\r
-        else\r
-        {\r
-               pPublish->u.pIncomingPublish->u.publish.publishInfo.qos = decoderValue.u.value.u.signedInt;\r
-        }\r
-    }\r
-\r
-    if( ret == IOT_MQTT_SUCCESS )\r
-    {\r
-        decoderValue.u.value.u.string.pString = NULL;\r
-        decoderValue.u.value.u.string.length = 0;\r
-        xSerializerRet = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_TOPIC, &decoderValue );\r
-\r
-        if( ( xSerializerRet != IOT_SERIALIZER_SUCCESS ) ||\r
-                ( decoderValue.type != IOT_SERIALIZER_SCALAR_TEXT_STRING ) )\r
-        {\r
-            IotLogError( "Topic value decode failed, error = %d", xSerializerRet );\r
-            ret = IOT_MQTT_BAD_RESPONSE;\r
-        }\r
-        else\r
-        {\r
-               pPublish->u.pIncomingPublish->u.publish.publishInfo.pTopicName = ( const char* ) decoderValue.u.value.u.string.pString;\r
-               pPublish->u.pIncomingPublish->u.publish.publishInfo.topicNameLength = decoderValue.u.value.u.string.length;\r
-        }\r
-    }\r
-\r
-    if( ret == IOT_MQTT_SUCCESS )\r
-    {\r
-        decoderValue.u.value.u.string.pString = NULL;\r
-        decoderValue.u.value.u.string.length = 0;\r
-        xSerializerRet = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_PAYLOAD, &decoderValue );\r
-\r
-        if( ( xSerializerRet != IOT_SERIALIZER_SUCCESS ) ||\r
-                ( decoderValue.type != IOT_SERIALIZER_SCALAR_BYTE_STRING ) )\r
-        {\r
-            IotLogError( "Payload value decode failed, error = %d", xSerializerRet );\r
-            ret = IOT_MQTT_BAD_RESPONSE;\r
-        }\r
-        else\r
-        {\r
-               pPublish->u.pIncomingPublish->u.publish.publishInfo.pPayload = ( const char* ) decoderValue.u.value.u.string.pString;\r
-               pPublish->u.pIncomingPublish->u.publish.publishInfo.payloadLength = decoderValue.u.value.u.string.length;\r
-        }\r
-    }\r
-\r
-    if( ret == IOT_MQTT_SUCCESS )\r
-    {\r
-        if( pPublish->u.pIncomingPublish->u.publish.publishInfo.qos != 0 )\r
-        {\r
-            xSerializerRet = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_MESSAGE_ID, &decoderValue );\r
-            if ( ( xSerializerRet != IOT_SERIALIZER_SUCCESS ) ||\r
-                    ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) )\r
-            {\r
-                IotLogError( "Message identifier decode failed, error = %d, decoded value type = %d", xSerializerRet, decoderValue.type );\r
-                ret = IOT_MQTT_BAD_RESPONSE;\r
-            }\r
-            else\r
-            {\r
-               pPublish->packetIdentifier  = ( uint16_t ) decoderValue.u.value.u.signedInt;\r
-            }\r
-        }\r
-    }\r
-\r
-    if( ret == IOT_MQTT_SUCCESS  )\r
-    {\r
-       pPublish->u.pIncomingPublish->u.publish.publishInfo.retain = false;\r
-    }\r
-\r
-    IOT_BLE_MESG_DECODER.destroy( &decoderObj );\r
-\r
-    return ret;\r
-}\r
-\r
-IotMqttError_t IotBleMqtt_SerializePuback( uint16_t packetIdentifier,\r
-                                                      uint8_t ** const pPubackPacket,\r
-                                                      size_t * const pPacketSize )\r
-{\r
-    uint8_t * pBuffer = NULL;\r
-    size_t bufLen = 0;\r
-    IotSerializerError_t error;\r
-    IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
-\r
-    error = _serializePubAck( packetIdentifier, NULL, &bufLen );\r
-\r
-    if( error != IOT_SERIALIZER_SUCCESS )\r
-    {\r
-        IotLogError( "Failed to find size of serialized PUBACK message, error = %d", error );\r
-        ret = IOT_MQTT_BAD_PARAMETER;\r
-    }\r
-\r
-\r
-    if( ret == IOT_MQTT_SUCCESS )\r
-    {\r
-        pBuffer = IotMqtt_MallocMessage( bufLen );\r
-\r
-        /* If Memory cannot be allocated log an error and return */\r
-        if( pBuffer == NULL )\r
-        {\r
-            IotLogError( "Failed to allocate memory for PUBACK packet, packet identifier = %d", packetIdentifier );\r
-            ret = IOT_MQTT_NO_MEMORY;\r
-        }\r
-    }\r
-\r
-\r
-    if( ret == IOT_MQTT_SUCCESS )\r
-    {\r
-        error = _serializePubAck( packetIdentifier, pBuffer, &bufLen );\r
-\r
-        if( error != IOT_SERIALIZER_SUCCESS )\r
-        {\r
-            IotLogError( "Failed to find size of serialized PUBACK message, error = %d", error );\r
-            ret = IOT_MQTT_BAD_PARAMETER;\r
-        }\r
-    }\r
-\r
-\r
-    if( ret == IOT_MQTT_SUCCESS )\r
-    {\r
-        *pPubackPacket = pBuffer;\r
-        *pPacketSize = bufLen;\r
-    }\r
-    else\r
-    {\r
-        if( pBuffer != NULL )\r
-        {\r
-            IotMqtt_FreeMessage( pBuffer );\r
-        }\r
-\r
-        *pPubackPacket = NULL;\r
-        *pPacketSize = 0;\r
-    }\r
-\r
-       return ret;\r
-\r
-}\r
-\r
-IotMqttError_t IotBleMqtt_DeserializePuback( _mqttPacket_t * pPuback )\r
-{\r
-\r
-    IotSerializerDecoderObject_t decoderObj = { 0 }, decoderValue = { 0 };\r
-    IotSerializerError_t error;\r
-    IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
-\r
-    error = IOT_BLE_MESG_DECODER.init( &decoderObj, ( uint8_t * ) pPuback->pRemainingData, pPuback->remainingLength );\r
-\r
-    if ( ( error != IOT_SERIALIZER_SUCCESS )\r
-            || ( decoderObj.type != IOT_SERIALIZER_CONTAINER_MAP ) )\r
-    {\r
-        IotLogError( "Malformed PUBACK, decoding the packet failed, decoder error = %d, object type: %d", error, decoderObj.type );\r
-        ret = IOT_MQTT_BAD_RESPONSE;\r
-    }\r
-\r
-\r
-    if( ret == IOT_MQTT_SUCCESS )\r
-    {\r
-\r
-        error = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_MESSAGE_ID, &decoderValue );\r
-\r
-        if ( ( error != IOT_SERIALIZER_SUCCESS ) ||\r
-                ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) )\r
-        {\r
-            IotLogError( "Message ID decode failed, error = %d, decoded value type = %d", error, decoderValue.type );\r
-            ret = IOT_MQTT_BAD_RESPONSE;\r
-        }\r
-        else\r
-        {\r
-               pPuback->packetIdentifier = ( uint16_t ) decoderValue.u.value.u.signedInt;\r
-        }\r
-    }\r
-\r
-    IOT_BLE_MESG_DECODER.destroy( &decoderObj );\r
-\r
-    return ret;\r
-\r
-}\r
-\r
-IotMqttError_t IotBleMqtt_SerializeSubscribe( const IotMqttSubscription_t * const pSubscriptionList,\r
-                                                         size_t subscriptionCount,\r
-                                                         uint8_t ** const pSubscribePacket,\r
-                                                         size_t * const pPacketSize,\r
-                                                         uint16_t * const pPacketIdentifier )\r
-{\r
-    uint8_t * pBuffer = NULL;\r
-    size_t bufLen = 0;\r
-    uint16_t usPacketIdentifier = 0;\r
-    IotSerializerError_t error;\r
-    IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
-\r
-    usPacketIdentifier = _nextPacketIdentifier();\r
-\r
-    error = _serializeSubscribe( pSubscriptionList, subscriptionCount, NULL, &bufLen, usPacketIdentifier );\r
-    if( error != IOT_SERIALIZER_SUCCESS )\r
-    {\r
-        IotLogError( "Failed to find serialized length of SUBSCRIBE message, error = %d", error );\r
-        ret = IOT_MQTT_BAD_PARAMETER;\r
-    }\r
-\r
-    if( ret == IOT_MQTT_SUCCESS )\r
-    {\r
-        pBuffer = IotMqtt_MallocMessage( bufLen );\r
-\r
-        /* If Memory cannot be allocated log an error and return */\r
-        if( pBuffer == NULL )\r
-        {\r
-            IotLogError( "Failed to allocate memory for SUBSCRIBE message." );\r
-            ret = IOT_MQTT_NO_MEMORY;\r
-        }\r
-    }\r
-\r
-    if( ret == IOT_MQTT_SUCCESS )\r
-    {\r
-        error = _serializeSubscribe( pSubscriptionList, subscriptionCount, pBuffer, &bufLen, usPacketIdentifier );\r
-        if( error != IOT_SERIALIZER_SUCCESS )\r
-        {\r
-            IotLogError( "Failed to serialize SUBSCRIBE message, error = %d", error );\r
-            ret = IOT_MQTT_BAD_PARAMETER;\r
-        }\r
-    }\r
-\r
-    if( ret == IOT_MQTT_SUCCESS )\r
-    {\r
-        *pSubscribePacket = pBuffer;\r
-        *pPacketSize = bufLen;\r
-        *pPacketIdentifier = usPacketIdentifier;\r
-    }\r
-    else\r
-    {\r
-        if( pBuffer != NULL )\r
-        {\r
-            IotMqtt_FreeMessage( pBuffer );\r
-        }\r
-\r
-        *pSubscribePacket = NULL;\r
-        *pPacketSize = 0;\r
-    }\r
-\r
-    return ret;\r
-}\r
-\r
-IotMqttError_t IotBleMqtt_DeserializeSuback( _mqttPacket_t * pSuback )\r
-{\r
-\r
-    IotSerializerDecoderObject_t decoderObj = { 0 }, decoderValue = { 0 };\r
-    IotSerializerError_t error;\r
-    int64_t subscriptionStatus;\r
-    IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
-\r
-    error = IOT_BLE_MESG_DECODER.init( &decoderObj, ( uint8_t * ) pSuback->pRemainingData, pSuback->remainingLength );\r
-\r
-    if ( ( error != IOT_SERIALIZER_SUCCESS )\r
-            || ( decoderObj.type != IOT_SERIALIZER_CONTAINER_MAP ) )\r
-    {\r
-        IotLogError( "Malformed SUBACK, decoding the packet failed, decoder error = %d, type: %d", error, decoderObj.type );\r
-        ret = IOT_MQTT_BAD_RESPONSE;\r
-    }\r
-\r
-    if( ret == IOT_MQTT_SUCCESS )\r
-    {\r
-\r
-        error = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_MESSAGE_ID, &decoderValue );\r
-        if ( ( error != IOT_SERIALIZER_SUCCESS ) ||\r
-                ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) )\r
-        {\r
-            IotLogError( "Message ID decode failed, error = %d, decoded value type = %d", error, decoderValue.type );\r
-            ret = IOT_MQTT_BAD_RESPONSE;\r
-        }\r
-        else\r
-        {\r
-               pSuback->packetIdentifier = ( uint16_t ) decoderValue.u.value.u.signedInt;\r
-        }\r
-    }\r
-\r
-    if( ret == IOT_MQTT_SUCCESS )\r
-    {\r
-        error = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_STATUS, &decoderValue );\r
-        if ( ( error != IOT_SERIALIZER_SUCCESS ) ||\r
-                ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) )\r
-        {\r
-            IotLogError( "Status code decode failed, error = %d, decoded value type = %d", error, decoderValue.type );\r
-            ret = IOT_MQTT_BAD_RESPONSE;\r
-        }\r
-        else\r
-        {\r
-            subscriptionStatus = ( uint16_t ) decoderValue.u.value.u.signedInt;\r
-            switch( subscriptionStatus )\r
-            {\r
-                case 0x00:\r
-                case 0x01:\r
-                case 0x02:\r
-                    IotLog( IOT_LOG_DEBUG,\r
-                               &_logHideAll,\r
-                               "Topic accepted, max QoS %hhu.", subscriptionStatus );\r
-                    ret = IOT_MQTT_SUCCESS;\r
-                    break;\r
-                case 0x80:\r
-                    IotLog( IOT_LOG_DEBUG,\r
-                               &_logHideAll,\r
-                               "Topic refused." );\r
-\r
-                    /* Remove a rejected subscription from the subscription manager. */\r
-                    _IotMqtt_RemoveSubscriptionByPacket(\r
-                               pSuback->u.pMqttConnection,\r
-                                                       pSuback->packetIdentifier,\r
-                            0 );\r
-                    ret = IOT_MQTT_SERVER_REFUSED;\r
-                    break;\r
-                default:\r
-                    IotLog( IOT_LOG_DEBUG,\r
-                               &_logHideAll,\r
-                               "Bad SUBSCRIBE status %hhu.", subscriptionStatus );\r
-\r
-                    ret = IOT_MQTT_BAD_RESPONSE;\r
-                    break;\r
-            }\r
-        }\r
-\r
-    }\r
-\r
-    IOT_BLE_MESG_DECODER.destroy( &decoderObj );\r
-\r
-       return ret;\r
-}\r
-\r
-IotMqttError_t IotBleMqtt_SerializeUnsubscribe( const IotMqttSubscription_t * const pSubscriptionList,\r
-               size_t subscriptionCount,\r
-               uint8_t ** const pUnsubscribePacket,\r
-               size_t * const pPacketSize,\r
-               uint16_t * const pPacketIdentifier )\r
-{\r
-\r
-       uint8_t * pBuffer = NULL;\r
-    size_t bufLen = 0;\r
-    uint16_t usPacketIdentifier = 0;\r
-    IotSerializerError_t error;\r
-    IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
-\r
-    usPacketIdentifier = _nextPacketIdentifier();\r
-\r
-    error = _serializeUnSubscribe( pSubscriptionList, subscriptionCount, NULL, &bufLen, usPacketIdentifier );\r
-    if( error != IOT_SERIALIZER_SUCCESS )\r
-    {\r
-        IotLogError( "Failed to find serialized length of UNSUBSCRIBE message, error = %d", error );\r
-        ret = IOT_MQTT_BAD_PARAMETER;\r
-    }\r
-\r
-    if( ret == IOT_MQTT_SUCCESS )\r
-    {\r
-        pBuffer = IotMqtt_MallocMessage( bufLen );\r
-\r
-        /* If Memory cannot be allocated log an error and return */\r
-        if( pBuffer == NULL )\r
-        {\r
-            IotLogError( "Failed to allocate memory for UNSUBSCRIBE message." );\r
-            ret = IOT_MQTT_NO_MEMORY;\r
-        }\r
-    }\r
-\r
-    if( ret == IOT_MQTT_SUCCESS )\r
-    {\r
-        error = _serializeUnSubscribe( pSubscriptionList, subscriptionCount, pBuffer, &bufLen, usPacketIdentifier );\r
-        if( error != IOT_SERIALIZER_SUCCESS )\r
-        {\r
-            IotLogError( "Failed to serialize UNSUBSCRIBE message, error = %d", error );\r
-            ret = IOT_MQTT_BAD_PARAMETER;\r
-        }\r
-    }\r
-\r
-    if( ret == IOT_MQTT_SUCCESS )\r
-    {\r
-        *pUnsubscribePacket = pBuffer;\r
-        *pPacketSize = bufLen;\r
-        *pPacketIdentifier = usPacketIdentifier;\r
-    }\r
-    else\r
-    {\r
-        if( pBuffer != NULL )\r
-        {\r
-            IotMqtt_FreeMessage( pBuffer );\r
-        }\r
-\r
-        *pUnsubscribePacket = NULL;\r
-        *pPacketSize = 0;\r
-    }\r
-\r
-    return ret;\r
-}\r
-\r
-IotMqttError_t IotBleMqtt_DeserializeUnsuback( _mqttPacket_t * pUnsuback )\r
-{\r
-    IotSerializerDecoderObject_t decoderObj = { 0 }, decoderValue = { 0 };\r
-    IotSerializerError_t error;\r
-    IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
-\r
-    error = IOT_BLE_MESG_DECODER.init( &decoderObj, ( uint8_t * ) pUnsuback->pRemainingData, pUnsuback->remainingLength );\r
-    if( ( error != IOT_SERIALIZER_SUCCESS )\r
-            || ( decoderObj.type != IOT_SERIALIZER_CONTAINER_MAP ) )\r
-    {\r
-        IotLogError( "Malformed UNSUBACK, decoding the packet failed, decoder error = %d, type:%d ", error, decoderObj.type );\r
-        ret = IOT_MQTT_BAD_RESPONSE;\r
-    }\r
-\r
-    if( ret == IOT_MQTT_SUCCESS )\r
-    {\r
-        error = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_MESSAGE_ID, &decoderValue );\r
-        if ( ( error != IOT_SERIALIZER_SUCCESS ) ||\r
-                ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) )\r
-        {\r
-            IotLogError( "UNSUBACK Message identifier decode failed, error = %d, decoded value type = %d", error, decoderValue.type );\r
-            ret = IOT_MQTT_BAD_RESPONSE;\r
-\r
-        }\r
-        else\r
-        {\r
-               pUnsuback->packetIdentifier = ( uint16_t ) decoderValue.u.value.u.signedInt;\r
-        }\r
-    }\r
-\r
-    IOT_BLE_MESG_DECODER.destroy( &decoderObj );\r
-\r
-       return IOT_MQTT_SUCCESS;\r
-}\r
-\r
-IotMqttError_t IotBleMqtt_SerializeDisconnect( uint8_t ** const pDisconnectPacket,\r
-                                                          size_t * const pPacketSize )\r
-{\r
-       uint8_t *pBuffer = NULL;\r
-       size_t bufLen = 0;\r
-       IotSerializerError_t error;\r
-       IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
-\r
-       error = _serializeDisconnect( NULL, &bufLen);\r
-       if( error != IOT_SERIALIZER_SUCCESS )\r
-       {\r
-           IotLogError( "Failed to find serialized length of DISCONNECT message, error = %d", error );\r
-           ret = IOT_MQTT_BAD_PARAMETER;\r
-       }\r
-\r
-       if( ret == IOT_MQTT_SUCCESS )\r
-       {\r
-           pBuffer = IotMqtt_MallocMessage( bufLen );\r
-\r
-           /* If Memory cannot be allocated log an error and return */\r
-           if( pBuffer == NULL )\r
-           {\r
-               IotLogError( "Failed to allocate memory for DISCONNECT message." );\r
-               ret = IOT_MQTT_NO_MEMORY;\r
-           }\r
-       }\r
-\r
-\r
-       if( ret == IOT_MQTT_SUCCESS )\r
-       {\r
-           error = _serializeDisconnect( pBuffer, &bufLen );\r
-           if( error != IOT_SERIALIZER_SUCCESS )\r
-           {\r
-               IotLogError( "Failed to serialize DISCONNECT message, error = %d", error );\r
-               ret = IOT_MQTT_BAD_PARAMETER;\r
-           }\r
-       }\r
-\r
-       if( ret == IOT_MQTT_SUCCESS )\r
-       {\r
-           *pDisconnectPacket = pBuffer;\r
-           *pPacketSize = bufLen;\r
-       }\r
-       else\r
-       {\r
-           if( pBuffer != NULL )\r
-           {\r
-               IotMqtt_FreeMessage( pBuffer );\r
-           }\r
-\r
-           *pDisconnectPacket = NULL;\r
-           *pPacketSize = 0;\r
-       }\r
-\r
-       return ret;\r
-}\r
-\r
-size_t IotBleMqtt_GetRemainingLength ( void * pNetworkConnection,\r
-                                       const IotNetworkInterface_t * pNetworkInterface )\r
-{\r
-    const uint8_t *pBuffer;\r
-    size_t length;\r
-\r
-    IotBleDataTransfer_PeekReceiveBuffer( *( IotBleDataTransferChannel_t ** ) ( pNetworkConnection ), &pBuffer, &length );\r
-\r
-    return length;\r
-}\r
-\r
-\r
-uint8_t IotBleMqtt_GetPacketType( void * pNetworkConnection, const IotNetworkInterface_t * pNetworkInterface )\r
-{\r
-\r
-    IotSerializerDecoderObject_t decoderObj = { 0 }, decoderValue = { 0 };\r
-    IotSerializerError_t error;\r
-    uint8_t value = 0xFF, packetType = _INVALID_MQTT_PACKET_TYPE;\r
-    const uint8_t *pBuffer;\r
-    size_t length;\r
-\r
-    IotBleDataTransfer_PeekReceiveBuffer( *( IotBleDataTransferChannel_t ** ) ( pNetworkConnection ), &pBuffer, &length );\r
-\r
-    error = IOT_BLE_MESG_DECODER.init( &decoderObj, pBuffer, length );\r
-\r
-    if( ( error == IOT_SERIALIZER_SUCCESS )\r
-            && ( decoderObj.type == IOT_SERIALIZER_CONTAINER_MAP ) )\r
-    {\r
-\r
-        error = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_MSG_TYPE, &decoderValue );\r
-\r
-        if ( ( error == IOT_SERIALIZER_SUCCESS ) &&\r
-                ( decoderValue.type == IOT_SERIALIZER_SCALAR_SIGNED_INT ) )\r
-        {\r
-            value = ( uint16_t ) decoderValue.u.value.u.signedInt;\r
-\r
-            /** Left shift by 4 bits as MQTT library expects packet type to be upper 4 bits **/\r
-            packetType = value << 4;\r
-        }\r
-        else\r
-        {\r
-            IotLogError( "Packet type decode failed, error = %d, decoded value type = %d", error, decoderValue.type );\r
-        }\r
-    }\r
-    else\r
-    {\r
-        IotLogError( "Decoding the packet failed, decoder error = %d, type = %d", error, decoderObj.type );\r
-    }\r
-\r
-    IOT_BLE_MESG_DECODER.destroy( &decoderObj );\r
-\r
-    return packetType;\r
-}\r
-\r
-IotMqttError_t IotBleMqtt_SerializePingreq( uint8_t ** const pPingreqPacket,\r
-                                            size_t * const pPacketSize )\r
-{\r
-    uint8_t *pBuffer = NULL;\r
-       size_t bufLen = 0;\r
-       IotSerializerError_t error;\r
-       IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
-\r
-       error = _serializePingRequest( NULL, &bufLen);\r
-       if( error != IOT_SERIALIZER_SUCCESS )\r
-       {\r
-           IotLogError( "Failed to find serialized length of DISCONNECT message, error = %d", error );\r
-           ret = IOT_MQTT_BAD_PARAMETER;\r
-       }\r
-\r
-       if( ret == IOT_MQTT_SUCCESS )\r
-       {\r
-           pBuffer = IotMqtt_MallocMessage( bufLen );\r
-\r
-           /* If Memory cannot be allocated log an error and return */\r
-           if( pBuffer == NULL )\r
-           {\r
-               IotLogError( "Failed to allocate memory for DISCONNECT message." );\r
-               ret = IOT_MQTT_NO_MEMORY;\r
-           }\r
-       }\r
-\r
-       if( ret == IOT_MQTT_SUCCESS )\r
-       {\r
-           error = _serializePingRequest( pBuffer, &bufLen );\r
-           if( error != IOT_SERIALIZER_SUCCESS )\r
-           {\r
-               IotLogError( "Failed to serialize DISCONNECT message, error = %d", error );\r
-               ret = IOT_MQTT_BAD_PARAMETER;\r
-           }\r
-       }\r
-\r
-       if( ret == IOT_MQTT_SUCCESS )\r
-       {\r
-           *pPingreqPacket = pBuffer;\r
-           *pPacketSize = bufLen;\r
-       }\r
-       else\r
-       {\r
-           if( pBuffer != NULL )\r
-           {\r
-               IotMqtt_FreeMessage( pBuffer );\r
-           }\r
-\r
-           *pPingreqPacket = NULL;\r
-           *pPacketSize = 0;\r
-       }\r
-\r
-    return ret;\r
-\r
-}\r
-\r
-IotMqttError_t IotBleMqtt_DeserializePingresp( _mqttPacket_t * pPingresp )\r
-{\r
-    /* Ping Response for BLE contains only packet type field in CBOR, which is already decoded\r
-       in IotBleMqtt_GetPacketType() function. Returning IOT_MQTT_SUCCESS. */\r
-    return IOT_MQTT_SUCCESS;\r
-}\r
-\r
-void IotBleMqtt_FreePacket( uint8_t * pPacket )\r
-{\r
-    IotMqtt_FreeMessage( pPacket );\r
-}\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_mqtt_agent.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_mqtt_agent.c
deleted file mode 100644 (file)
index 9a73b25..0000000
+++ /dev/null
@@ -1,794 +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_agent.c\r
- * @brief MQTT Agent implementation. Provides backwards compatibility between\r
- * MQTT v2 and MQTT v1.\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
-/* FreeRTOS includes. */\r
-#include "FreeRTOS.h"\r
-#include "semphr.h"\r
-\r
-/* MQTT v1 includes. */\r
-#include "iot_mqtt_agent.h"\r
-#include "iot_mqtt_agent_config.h"\r
-#include "iot_mqtt_agent_config_defaults.h"\r
-\r
-/* MQTT v2 include. */\r
-#include "iot_mqtt.h"\r
-\r
-/* Platform network include. */\r
-#include "platform/iot_network_freertos.h"\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/**\r
- * @brief Converts FreeRTOS ticks to milliseconds.\r
- */\r
-#define mqttTICKS_TO_MS( xTicks )    ( xTicks * 1000 / configTICK_RATE_HZ )\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/**\r
- * @brief Stores data to convert between the MQTT v1 subscription callback\r
- * and the MQTT v2 subscription callback.\r
- */\r
-#if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 )\r
-    typedef struct MQTTCallback\r
-    {\r
-        BaseType_t xInUse;                                                     /**< Whether this instance is in-use. */\r
-        MQTTPublishCallback_t xFunction;                                       /**< MQTT v1 callback function. */\r
-        void * pvParameter;                                                    /**< Parameter to xFunction. */\r
-\r
-        uint16_t usTopicFilterLength;                                          /**< Length of pcTopicFilter. */\r
-        char pcTopicFilter[ mqttconfigSUBSCRIPTION_MANAGER_MAX_TOPIC_LENGTH ]; /**< Topic filter. */\r
-    } MQTTCallback_t;\r
-#endif\r
-\r
-/**\r
- * @brief Stores data on an active MQTT connection.\r
- */\r
-typedef struct MQTTConnection\r
-{\r
-    IotMqttConnection_t xMQTTConnection; /**< MQTT v2 connection handle. */\r
-    MQTTAgentCallback_t pxCallback;      /**< MQTT v1 global callback. */\r
-    void * pvUserData;                   /**< Parameter to pxCallback. */\r
-    StaticSemaphore_t xConnectionMutex;  /**< Protects from concurrent accesses. */\r
-    #if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 )\r
-        MQTTCallback_t xCallbacks        /**< Conversion table of MQTT v1 to MQTT v2 subscription callbacks. */\r
-        [ mqttconfigSUBSCRIPTION_MANAGER_MAX_SUBSCRIPTIONS ];\r
-    #endif\r
-} MQTTConnection_t;\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/**\r
- * @brief Convert an MQTT v2 return code to an MQTT v1 return code.\r
- *\r
- * @param[in] xMqttStatus The MQTT v2 return code.\r
- *\r
- * @return An equivalent MQTT v1 return code.\r
- */\r
-static inline MQTTAgentReturnCode_t prvConvertReturnCode( IotMqttError_t xMqttStatus );\r
-\r
-/**\r
- * @brief Wraps an MQTT v1 publish callback.\r
- *\r
- * @param[in] pvParameter The MQTT connection.\r
- * @param[in] pxPublish Information about the incoming publish.\r
- */\r
-static void prvPublishCallbackWrapper( void * pvParameter,\r
-                                       IotMqttCallbackParam_t * const pxPublish );\r
-\r
-/**\r
- * @brief Wraps an MQTT v1 disconnect callback.\r
- *\r
- * @param[in] pvCallbackContext The MQTT connection.\r
- * @param[in] pxDisconnect Information about the disconnect.\r
- */\r
-static void prvDisconnectCallbackWrapper( void * pvParameter,\r
-                                          IotMqttCallbackParam_t * pxDisconnect );\r
-\r
-#if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 )\r
-\r
-/**\r
- * @brief Store an MQTT v1 callback in the conversion table.\r
- *\r
- * @param[in] pxConnection Where to store the callback.\r
- * @param[in] pcTopicFilter Topic filter to store.\r
- * @param[in] usTopicFilterLength Length of pcTopicFilter.\r
- * @param[in] xCallback MQTT v1 callback to store.\r
- * @param[in] pvParameter Parameter to xCallback.\r
- *\r
- * @return pdPASS if the callback was successfully stored; pdFAIL otherwise.\r
- */\r
-    static BaseType_t prvStoreCallback( MQTTConnection_t * const pxConnection,\r
-                                        const char * const pcTopicFilter,\r
-                                        uint16_t usTopicFilterLength,\r
-                                        MQTTPublishCallback_t xCallback,\r
-                                        void * pvParameter );\r
-\r
-/**\r
- * @brief Search the callback conversion table for the given topic filter.\r
- *\r
- * @param[in] pxConnection The connection containing the conversion table.\r
- * @param[in] pcTopicFilter The topic filter to search for.\r
- * @param[in] usTopicFilterLength The length of pcTopicFilter.\r
- *\r
- * @return A pointer to the callback entry if found; NULL otherwise.\r
- * @note This function should be called with pxConnection->xConnectionMutex\r
- * locked.\r
- */\r
-    static MQTTCallback_t * prvFindCallback( MQTTConnection_t * const pxConnection,\r
-                                             const char * const pcTopicFilter,\r
-                                             uint16_t usTopicFilterLength );\r
-\r
-/**\r
- * @brief Remove a topic filter from the callback conversion table.\r
- *\r
- * @param[in] pxConnection The connection containing the conversion table.\r
- * @param[in] pcTopicFilter The topic filter to remove.\r
- * @param[in] usTopicFilterLength The length of pcTopic.\r
- */\r
-    static void prvRemoveCallback( MQTTConnection_t * const pxConnection,\r
-                                   const char * const pcTopicFilter,\r
-                                   uint16_t usTopicFilterLength );\r
-#endif /* if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) */\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/**\r
- * @brief The number of available MQTT brokers, controlled by the constant\r
- * mqttconfigMAX_BROKERS;\r
- */\r
-static UBaseType_t uxAvailableBrokers = mqttconfigMAX_BROKERS;\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static inline MQTTAgentReturnCode_t prvConvertReturnCode( IotMqttError_t xMqttStatus )\r
-{\r
-    MQTTAgentReturnCode_t xStatus = eMQTTAgentSuccess;\r
-\r
-    switch( xMqttStatus )\r
-    {\r
-        case IOT_MQTT_SUCCESS:\r
-        case IOT_MQTT_STATUS_PENDING:\r
-            xStatus = eMQTTAgentSuccess;\r
-            break;\r
-\r
-        case IOT_MQTT_TIMEOUT:\r
-            xStatus = eMQTTAgentTimeout;\r
-            break;\r
-\r
-        default:\r
-            xStatus = eMQTTAgentFailure;\r
-            break;\r
-    }\r
-\r
-    return xStatus;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvPublishCallbackWrapper( void * pvParameter,\r
-                                       IotMqttCallbackParam_t * const pxPublish )\r
-{\r
-    BaseType_t xStatus = pdPASS;\r
-    size_t xBufferSize = 0;\r
-    uint8_t * pucMqttBuffer = NULL;\r
-    MQTTBool_t xCallbackReturn = eMQTTFalse;\r
-    MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) pvParameter;\r
-    MQTTAgentCallbackParams_t xPublishData = { .xMQTTEvent = eMQTTAgentPublish };\r
-\r
-    /* Calculate the size of the MQTT buffer that must be allocated. */\r
-    if( xStatus == pdPASS )\r
-    {\r
-        xBufferSize = pxPublish->u.message.info.topicNameLength +\r
-                      pxPublish->u.message.info.payloadLength;\r
-\r
-        /* Check for overflow. */\r
-        if( ( xBufferSize < pxPublish->u.message.info.topicNameLength ) ||\r
-            ( xBufferSize < pxPublish->u.message.info.payloadLength ) )\r
-        {\r
-            mqttconfigDEBUG_LOG( ( "Incoming PUBLISH message and topic name length too large.\r\n" ) );\r
-            xStatus = pdFAIL;\r
-        }\r
-    }\r
-\r
-    /* Allocate an MQTT buffer for the callback. */\r
-    if( xStatus == pdPASS )\r
-    {\r
-        pucMqttBuffer = pvPortMalloc( xBufferSize );\r
-\r
-        if( pucMqttBuffer == NULL )\r
-        {\r
-            mqttconfigDEBUG_LOG( ( "Failed to allocate memory for MQTT buffer.\r\n" ) );\r
-            xStatus = pdFAIL;\r
-        }\r
-        else\r
-        {\r
-            /* Copy the topic name and payload. The topic name and payload must be\r
-             * copied in case the user decides to take ownership of the MQTT buffer.\r
-             * The original buffer containing the MQTT topic name and payload may\r
-             * contain further unprocessed packets and must remain property of the\r
-             * MQTT library. Therefore, the topic name and payload are copied into\r
-             * another buffer for the user. */\r
-            ( void ) memcpy( pucMqttBuffer,\r
-                             pxPublish->u.message.info.pTopicName,\r
-                             pxPublish->u.message.info.topicNameLength );\r
-            ( void ) memcpy( pucMqttBuffer + pxPublish->u.message.info.topicNameLength,\r
-                             pxPublish->u.message.info.pPayload,\r
-                             pxPublish->u.message.info.payloadLength );\r
-\r
-            /* Set the members of the callback parameter. */\r
-            xPublishData.xMQTTEvent = eMQTTAgentPublish;\r
-            xPublishData.u.xPublishData.pucTopic = pucMqttBuffer;\r
-            xPublishData.u.xPublishData.usTopicLength = pxPublish->u.message.info.topicNameLength;\r
-            xPublishData.u.xPublishData.pvData = pucMqttBuffer + pxPublish->u.message.info.topicNameLength;\r
-            xPublishData.u.xPublishData.ulDataLength = ( uint32_t ) pxPublish->u.message.info.payloadLength;\r
-            xPublishData.u.xPublishData.xQos = ( MQTTQoS_t ) pxPublish->u.message.info.qos;\r
-            xPublishData.u.xPublishData.xBuffer = pucMqttBuffer;\r
-        }\r
-    }\r
-\r
-    if( xStatus == pdPASS )\r
-    {\r
-        #if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 )\r
-            /* When subscription management is enabled, search for a matching subscription. */\r
-            MQTTCallback_t * pxCallbackEntry = prvFindCallback( pxConnection,\r
-                                                                pxPublish->u.message.pTopicFilter,\r
-                                                                pxPublish->u.message.topicFilterLength );\r
-\r
-            /* Check if a matching MQTT v1 subscription was found. */\r
-            if( pxCallbackEntry != NULL )\r
-            {\r
-                /* Invoke the topic-specific callback if it exists. */\r
-                if( pxCallbackEntry->xFunction != NULL )\r
-                {\r
-                    xCallbackReturn = pxCallbackEntry->xFunction( pxCallbackEntry->pvParameter,\r
-                                                                  &( xPublishData.u.xPublishData ) );\r
-                }\r
-                else\r
-                {\r
-                    /* Otherwise, invoke the global callback. */\r
-                    if( pxConnection->pxCallback != NULL )\r
-                    {\r
-                        xCallbackReturn = ( MQTTBool_t ) pxConnection->pxCallback( pxConnection->pvUserData,\r
-                                                                                   &xPublishData );\r
-                    }\r
-                }\r
-            }\r
-        #else /* if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) */\r
-\r
-            /* When subscription management is disabled, invoke the global callback\r
-             * if one exists. */\r
-\r
-            /* When subscription management is disabled, the topic filter must be "#". */\r
-            mqttconfigASSERT( *( xPublish.message.pTopicFilter ) == '#' );\r
-            mqttconfigASSERT( xPublish.message.topicFilterLength == 1 );\r
-\r
-            if( pxConnection->pxCallback != NULL )\r
-            {\r
-                xCallbackReturn = ( MQTTBool_t ) pxConnection->pxCallback( pxConnection->pvUserData,\r
-                                                                           &xPublishData );\r
-            }\r
-        #endif /* if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) */\r
-    }\r
-\r
-    /* Free the MQTT buffer if the user did not take ownership of it. */\r
-    if( ( xCallbackReturn == eMQTTFalse ) && ( pucMqttBuffer != NULL ) )\r
-    {\r
-        vPortFree( pucMqttBuffer );\r
-    }\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvDisconnectCallbackWrapper( void * pvParameter,\r
-                                          IotMqttCallbackParam_t * pxDisconnect )\r
-{\r
-    MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) pvParameter;\r
-    MQTTAgentCallbackParams_t xCallbackParams = { .xMQTTEvent = eMQTTAgentDisconnect };\r
-\r
-    ( void ) pxDisconnect;\r
-\r
-    /* This function should only be called if a callback was set. */\r
-    mqttconfigASSERT( pxConnection->pxCallback != NULL );\r
-\r
-    /* Invoke the MQTT v1 callback. Ignore the return value. */\r
-    pxConnection->pxCallback( pxConnection->pvUserData,\r
-                              &xCallbackParams );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 )\r
-    static BaseType_t prvStoreCallback( MQTTConnection_t * const pxConnection,\r
-                                        const char * const pcTopicFilter,\r
-                                        uint16_t usTopicFilterLength,\r
-                                        MQTTPublishCallback_t xCallback,\r
-                                        void * pvParameter )\r
-    {\r
-        MQTTCallback_t * pxCallback = NULL;\r
-        BaseType_t xStatus = pdFAIL, i = 0;\r
-\r
-        /* Prevent other tasks from modifying stored callbacks while this function\r
-         * runs. */\r
-        if( xSemaphoreTake( ( QueueHandle_t ) &( pxConnection->xConnectionMutex ),\r
-                            portMAX_DELAY ) == pdTRUE )\r
-        {\r
-            /* Check if the topic filter already has an entry. */\r
-            pxCallback = prvFindCallback( pxConnection, pcTopicFilter, usTopicFilterLength );\r
-\r
-            if( pxCallback == NULL )\r
-            {\r
-                /* If no entry was found, find a free entry. */\r
-                for( i = 0; i < mqttconfigSUBSCRIPTION_MANAGER_MAX_SUBSCRIPTIONS; i++ )\r
-                {\r
-                    if( pxConnection->xCallbacks[ i ].xInUse == pdFALSE )\r
-                    {\r
-                        pxConnection->xCallbacks[ i ].xInUse = pdTRUE;\r
-                        pxCallback = &( pxConnection->xCallbacks[ i ] );\r
-                        break;\r
-                    }\r
-                }\r
-            }\r
-\r
-            /* Set the members of the callback entry. */\r
-            if( i < mqttconfigSUBSCRIPTION_MANAGER_MAX_SUBSCRIPTIONS )\r
-            {\r
-                pxCallback->pvParameter = pvParameter;\r
-                pxCallback->usTopicFilterLength = usTopicFilterLength;\r
-                pxCallback->xFunction = xCallback;\r
-                ( void ) strncpy( pxCallback->pcTopicFilter, pcTopicFilter, usTopicFilterLength );\r
-                xStatus = pdPASS;\r
-            }\r
-\r
-            ( void ) xSemaphoreGive( ( QueueHandle_t ) &( pxConnection->xConnectionMutex ) );\r
-        }\r
-\r
-        return xStatus;\r
-    }\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-    static MQTTCallback_t * prvFindCallback( MQTTConnection_t * const pxConnection,\r
-                                             const char * const pcTopicFilter,\r
-                                             uint16_t usTopicFilterLength )\r
-    {\r
-        BaseType_t i = 0;\r
-        MQTTCallback_t * pxResult = NULL;\r
-\r
-        /* Search the callback conversion table for the topic filter. */\r
-        for( i = 0; i < mqttconfigSUBSCRIPTION_MANAGER_MAX_SUBSCRIPTIONS; i++ )\r
-        {\r
-            if( ( pxConnection->xCallbacks[ i ].usTopicFilterLength == usTopicFilterLength ) &&\r
-                ( strncmp( pxConnection->xCallbacks[ i ].pcTopicFilter,\r
-                           pcTopicFilter,\r
-                           usTopicFilterLength ) == 0 ) )\r
-            {\r
-                pxResult = &( pxConnection->xCallbacks[ i ] );\r
-                break;\r
-            }\r
-        }\r
-\r
-        return pxResult;\r
-    }\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-    static void prvRemoveCallback( MQTTConnection_t * const pxConnection,\r
-                                   const char * const pcTopicFilter,\r
-                                   uint16_t usTopicFilterLength )\r
-    {\r
-        MQTTCallback_t * pxCallback = NULL;\r
-\r
-        /* Prevent other tasks from modifying stored callbacks while this function\r
-         * runs. */\r
-        if( xSemaphoreTake( ( QueueHandle_t ) &( pxConnection->xConnectionMutex ),\r
-                            portMAX_DELAY ) == pdTRUE )\r
-        {\r
-            /* Find the given topic filter. */\r
-            pxCallback = prvFindCallback( pxConnection, pcTopicFilter, usTopicFilterLength );\r
-\r
-            if( pxCallback != NULL )\r
-            {\r
-                /* Clear the callback entry. */\r
-                mqttconfigASSERT( pxCallback->xInUse == pdTRUE );\r
-                ( void ) memset( pxCallback, 0x00, sizeof( MQTTCallback_t ) );\r
-            }\r
-\r
-            ( void ) xSemaphoreGive( ( QueueHandle_t ) &( pxConnection->xConnectionMutex ) );\r
-        }\r
-    }\r
-#endif /* if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) */\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttConnection_t MQTT_AGENT_Getv2Connection( MQTTAgentHandle_t xMQTTHandle )\r
-{\r
-    MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) xMQTTHandle;\r
-\r
-    return pxConnection->xMQTTConnection;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-BaseType_t MQTT_AGENT_Init( void )\r
-{\r
-    BaseType_t xStatus = pdFALSE;\r
-\r
-    /* Call the initialization function of MQTT v2. */\r
-    if( IotMqtt_Init() == IOT_MQTT_SUCCESS )\r
-    {\r
-        xStatus = pdTRUE;\r
-    }\r
-\r
-    return xStatus;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-MQTTAgentReturnCode_t MQTT_AGENT_Create( MQTTAgentHandle_t * const pxMQTTHandle )\r
-{\r
-    MQTTConnection_t * pxNewConnection = NULL;\r
-    MQTTAgentReturnCode_t xStatus = eMQTTAgentSuccess;\r
-\r
-    /* Check how many brokers are available; fail if all brokers are in use. */\r
-    taskENTER_CRITICAL();\r
-    {\r
-        if( uxAvailableBrokers == 0 )\r
-        {\r
-            xStatus = eMQTTAgentFailure;\r
-        }\r
-        else\r
-        {\r
-            uxAvailableBrokers--;\r
-            mqttconfigASSERT( uxAvailableBrokers <= mqttconfigMAX_BROKERS );\r
-        }\r
-    }\r
-    taskEXIT_CRITICAL();\r
-\r
-    /* Allocate memory for an MQTT connection. */\r
-    if( xStatus == eMQTTAgentSuccess )\r
-    {\r
-        pxNewConnection = pvPortMalloc( sizeof( MQTTConnection_t ) );\r
-\r
-        if( pxNewConnection == NULL )\r
-        {\r
-            xStatus = eMQTTAgentFailure;\r
-\r
-            taskENTER_CRITICAL();\r
-            {\r
-                uxAvailableBrokers++;\r
-                mqttconfigASSERT( uxAvailableBrokers <= mqttconfigMAX_BROKERS );\r
-            }\r
-            taskEXIT_CRITICAL();\r
-        }\r
-        else\r
-        {\r
-            ( void ) memset( pxNewConnection, 0x00, sizeof( MQTTConnection_t ) );\r
-            pxNewConnection->xMQTTConnection = IOT_MQTT_CONNECTION_INITIALIZER;\r
-        }\r
-    }\r
-\r
-    /* Create the connection mutex and set the output parameter. */\r
-    if( xStatus == eMQTTAgentSuccess )\r
-    {\r
-        ( void ) xSemaphoreCreateMutexStatic( &( pxNewConnection->xConnectionMutex ) );\r
-        *pxMQTTHandle = ( MQTTAgentHandle_t ) pxNewConnection;\r
-    }\r
-\r
-    return xStatus;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-MQTTAgentReturnCode_t MQTT_AGENT_Delete( MQTTAgentHandle_t xMQTTHandle )\r
-{\r
-    MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) xMQTTHandle;\r
-\r
-    /* Clean up any allocated MQTT or network resources. */\r
-    if( pxConnection->xMQTTConnection != IOT_MQTT_CONNECTION_INITIALIZER )\r
-    {\r
-        IotMqtt_Disconnect( pxConnection->xMQTTConnection, IOT_MQTT_FLAG_CLEANUP_ONLY );\r
-        pxConnection->xMQTTConnection = IOT_MQTT_CONNECTION_INITIALIZER;\r
-    }\r
-\r
-    /* Free memory used by the MQTT connection. */\r
-    vPortFree( pxConnection );\r
-\r
-    /* Increment the number of available brokers. */\r
-    taskENTER_CRITICAL();\r
-    {\r
-        uxAvailableBrokers++;\r
-        mqttconfigASSERT( uxAvailableBrokers <= mqttconfigMAX_BROKERS );\r
-    }\r
-    taskEXIT_CRITICAL();\r
-\r
-    return eMQTTAgentSuccess;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-MQTTAgentReturnCode_t MQTT_AGENT_Connect( MQTTAgentHandle_t xMQTTHandle,\r
-                                          const MQTTAgentConnectParams_t * const pxConnectParams,\r
-                                          TickType_t xTimeoutTicks )\r
-{\r
-    MQTTAgentReturnCode_t xStatus = eMQTTAgentSuccess;\r
-    IotMqttError_t xMqttStatus = IOT_MQTT_STATUS_PENDING;\r
-    MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) xMQTTHandle;\r
-    IotNetworkServerInfo_t xServerInfo = { 0 };\r
-    IotNetworkCredentials_t xCredentials = AWS_IOT_NETWORK_CREDENTIALS_AFR_INITIALIZER, * pxCredentials = NULL;\r
-    IotMqttNetworkInfo_t xNetworkInfo = IOT_MQTT_NETWORK_INFO_INITIALIZER;\r
-    IotMqttConnectInfo_t xMqttConnectInfo = IOT_MQTT_CONNECT_INFO_INITIALIZER;\r
-\r
-    /* Copy the global callback and parameter. */\r
-    pxConnection->pxCallback = pxConnectParams->pxCallback;\r
-    pxConnection->pvUserData = pxConnectParams->pvUserData;\r
-\r
-    /* Set the TLS info for a secured connection. */\r
-    if( ( pxConnectParams->xSecuredConnection == pdTRUE ) ||\r
-        ( ( pxConnectParams->xFlags & mqttagentREQUIRE_TLS ) == mqttagentREQUIRE_TLS ) )\r
-    {\r
-        pxCredentials = &xCredentials;\r
-\r
-        /* Set the server certificate. Other credentials are set by the initializer. */\r
-        xCredentials.pRootCa = pxConnectParams->pcCertificate;\r
-        xCredentials.rootCaSize = ( size_t ) pxConnectParams->ulCertificateSize;\r
-\r
-        /* Disable ALPN if requested. */\r
-        if( ( pxConnectParams->xFlags & mqttagentUSE_AWS_IOT_ALPN_443 ) == 0 )\r
-        {\r
-            xCredentials.pAlpnProtos = NULL;\r
-        }\r
-\r
-        /* Disable SNI if requested. */\r
-        if( ( pxConnectParams->xURLIsIPAddress == pdTRUE ) ||\r
-            ( ( pxConnectParams->xFlags & mqttagentURL_IS_IP_ADDRESS ) == mqttagentURL_IS_IP_ADDRESS ) )\r
-        {\r
-            xCredentials.disableSni = true;\r
-        }\r
-    }\r
-\r
-    /* Set the server info. */\r
-    xServerInfo.pHostName = pxConnectParams->pcURL;\r
-    xServerInfo.port = pxConnectParams->usPort;\r
-\r
-    /* Set the members of the network info. */\r
-    xNetworkInfo.createNetworkConnection = true;\r
-    xNetworkInfo.u.setup.pNetworkServerInfo = &xServerInfo;\r
-    xNetworkInfo.u.setup.pNetworkCredentialInfo = pxCredentials;\r
-    xNetworkInfo.pNetworkInterface = IOT_NETWORK_INTERFACE_AFR;\r
-\r
-    if( pxConnectParams->pxCallback != NULL )\r
-    {\r
-        xNetworkInfo.disconnectCallback.function = prvDisconnectCallbackWrapper;\r
-        xNetworkInfo.disconnectCallback.pCallbackContext = pxConnection;\r
-    }\r
-\r
-    /* Set the members of the MQTT connect info. */\r
-    xMqttConnectInfo.awsIotMqttMode = true;\r
-    xMqttConnectInfo.cleanSession = true;\r
-    xMqttConnectInfo.pClientIdentifier = ( const char * ) ( pxConnectParams->pucClientId );\r
-    xMqttConnectInfo.clientIdentifierLength = pxConnectParams->usClientIdLength;\r
-    xMqttConnectInfo.keepAliveSeconds = mqttconfigKEEP_ALIVE_INTERVAL_SECONDS;\r
-\r
-    /* Call MQTT v2's CONNECT function. */\r
-    xMqttStatus = IotMqtt_Connect( &xNetworkInfo,\r
-                                   &xMqttConnectInfo,\r
-                                   mqttTICKS_TO_MS( xTimeoutTicks ),\r
-                                   &( pxConnection->xMQTTConnection ) );\r
-    xStatus = prvConvertReturnCode( xMqttStatus );\r
-\r
-    /* Add a subscription to "#" to support the global callback when subscription\r
-     * manager is disabled. */\r
-    #if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 0 )\r
-        IotMqttSubscription_t xGlobalSubscription = IOT_MQTT_SUBSCRIPTION_INITIALIZER;\r
-        IotMqttReference_t xGlobalSubscriptionRef = IOT_MQTT_REFERENCE_INITIALIZER;\r
-\r
-        if( xStatus == eMQTTAgentSuccess )\r
-        {\r
-            xGlobalSubscription.pTopicFilter = "#";\r
-            xGlobalSubscription.topicFilterLength = 1;\r
-            xGlobalSubscription.qos = 0;\r
-            xGlobalSubscription.callback.param1 = pxConnection;\r
-            xGlobalSubscription.callback.function = prvPublishCallbackWrapper;\r
-\r
-            xMqttStatus = IotMqtt_Subscribe( pxConnection->xMQTTConnection,\r
-                                             &xGlobalSubscription,\r
-                                             1,\r
-                                             IOT_MQTT_FLAG_WAITABLE,\r
-                                             NULL,\r
-                                             &xGlobalSubscriptionRef );\r
-            xStatus = prvConvertReturnCode( xMqttStatus );\r
-        }\r
-\r
-        /* Wait for the subscription to "#" to complete. */\r
-        if( xStatus == eMQTTAgentSuccess )\r
-        {\r
-            xMqttStatus = IotMqtt_Wait( xGlobalSubscriptionRef,\r
-                                        mqttTICKS_TO_MS( xTimeoutTicks ) );\r
-            xStatus = prvConvertReturnCode( xMqttStatus );\r
-        }\r
-    #endif /* if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) */\r
-\r
-    return xStatus;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-MQTTAgentReturnCode_t MQTT_AGENT_Disconnect( MQTTAgentHandle_t xMQTTHandle,\r
-                                             TickType_t xTimeoutTicks )\r
-{\r
-    MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) xMQTTHandle;\r
-\r
-    /* MQTT v2's DISCONNECT function does not have a timeout argument. */\r
-    ( void ) xTimeoutTicks;\r
-\r
-    /* Check that the connection is established. */\r
-    if( pxConnection->xMQTTConnection != IOT_MQTT_CONNECTION_INITIALIZER )\r
-    {\r
-        /* Call MQTT v2's DISCONNECT function. */\r
-        IotMqtt_Disconnect( pxConnection->xMQTTConnection,\r
-                            0 );\r
-        pxConnection->xMQTTConnection = IOT_MQTT_CONNECTION_INITIALIZER;\r
-    }\r
-\r
-    return eMQTTAgentSuccess;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-MQTTAgentReturnCode_t MQTT_AGENT_Subscribe( MQTTAgentHandle_t xMQTTHandle,\r
-                                            const MQTTAgentSubscribeParams_t * const pxSubscribeParams,\r
-                                            TickType_t xTimeoutTicks )\r
-{\r
-    MQTTAgentReturnCode_t xStatus = eMQTTAgentSuccess;\r
-    IotMqttError_t xMqttStatus = IOT_MQTT_STATUS_PENDING;\r
-    MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) xMQTTHandle;\r
-    IotMqttSubscription_t xSubscription = IOT_MQTT_SUBSCRIPTION_INITIALIZER;\r
-\r
-    /* Store the topic filter if subscription management is enabled. */\r
-    #if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 )\r
-        /* Check topic filter length. */\r
-        if( pxSubscribeParams->usTopicLength > mqttconfigSUBSCRIPTION_MANAGER_MAX_TOPIC_LENGTH )\r
-        {\r
-            xStatus = eMQTTAgentFailure;\r
-        }\r
-\r
-        /* Store the subscription. */\r
-        if( prvStoreCallback( pxConnection,\r
-                              ( const char * ) pxSubscribeParams->pucTopic,\r
-                              pxSubscribeParams->usTopicLength,\r
-                              pxSubscribeParams->pxPublishCallback,\r
-                              pxSubscribeParams->pvPublishCallbackContext ) == pdFAIL )\r
-        {\r
-            xStatus = eMQTTAgentFailure;\r
-        }\r
-    #endif /* if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) */\r
-\r
-    /* Call MQTT v2 blocking SUBSCRIBE function. */\r
-    if( xStatus == eMQTTAgentSuccess )\r
-    {\r
-        /* Set the members of the MQTT subscription. */\r
-        xSubscription.pTopicFilter = ( const char * ) ( pxSubscribeParams->pucTopic );\r
-        xSubscription.topicFilterLength = pxSubscribeParams->usTopicLength;\r
-        xSubscription.qos = ( IotMqttQos_t ) pxSubscribeParams->xQoS;\r
-        xSubscription.callback.pCallbackContext = pxConnection;\r
-        xSubscription.callback.function = prvPublishCallbackWrapper;\r
-\r
-        xMqttStatus = IotMqtt_TimedSubscribe( pxConnection->xMQTTConnection,\r
-                                              &xSubscription,\r
-                                              1,\r
-                                              0,\r
-                                              mqttTICKS_TO_MS( xTimeoutTicks ) );\r
-        xStatus = prvConvertReturnCode( xMqttStatus );\r
-    }\r
-\r
-    return xStatus;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-MQTTAgentReturnCode_t MQTT_AGENT_Unsubscribe( MQTTAgentHandle_t xMQTTHandle,\r
-                                              const MQTTAgentUnsubscribeParams_t * const pxUnsubscribeParams,\r
-                                              TickType_t xTimeoutTicks )\r
-{\r
-    IotMqttError_t xMqttStatus = IOT_MQTT_STATUS_PENDING;\r
-    MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) xMQTTHandle;\r
-    IotMqttSubscription_t xSubscription = IOT_MQTT_SUBSCRIPTION_INITIALIZER;\r
-\r
-    /* Remove any subscription callback that may be registered. */\r
-    #if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 )\r
-        prvRemoveCallback( pxConnection,\r
-                           ( const char * ) ( pxUnsubscribeParams->pucTopic ),\r
-                           pxUnsubscribeParams->usTopicLength );\r
-    #endif\r
-\r
-    /* Set the members of the subscription to remove. */\r
-    xSubscription.pTopicFilter = ( const char * ) ( pxUnsubscribeParams->pucTopic );\r
-    xSubscription.topicFilterLength = pxUnsubscribeParams->usTopicLength;\r
-    xSubscription.callback.pCallbackContext = pxConnection;\r
-    xSubscription.callback.function = prvPublishCallbackWrapper;\r
-\r
-    /* Call MQTT v2 blocking UNSUBSCRIBE function. */\r
-    xMqttStatus = IotMqtt_TimedUnsubscribe( pxConnection->xMQTTConnection,\r
-                                            &xSubscription,\r
-                                            1,\r
-                                            0,\r
-                                            mqttTICKS_TO_MS( xTimeoutTicks ) );\r
-\r
-    return prvConvertReturnCode( xMqttStatus );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-MQTTAgentReturnCode_t MQTT_AGENT_Publish( MQTTAgentHandle_t xMQTTHandle,\r
-                                          const MQTTAgentPublishParams_t * const pxPublishParams,\r
-                                          TickType_t xTimeoutTicks )\r
-{\r
-    IotMqttError_t xMqttStatus = IOT_MQTT_STATUS_PENDING;\r
-    MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) xMQTTHandle;\r
-    IotMqttPublishInfo_t xPublishInfo = IOT_MQTT_PUBLISH_INFO_INITIALIZER;\r
-\r
-    /* Set the members of the publish info. */\r
-    xPublishInfo.pTopicName = ( const char * ) pxPublishParams->pucTopic;\r
-    xPublishInfo.topicNameLength = pxPublishParams->usTopicLength;\r
-    xPublishInfo.qos = ( IotMqttQos_t ) pxPublishParams->xQoS;\r
-    xPublishInfo.pPayload = ( const void * ) pxPublishParams->pvData;\r
-    xPublishInfo.payloadLength = pxPublishParams->ulDataLength;\r
-\r
-    /* Call the MQTT v2 blocking PUBLISH function. */\r
-    xMqttStatus = IotMqtt_TimedPublish( pxConnection->xMQTTConnection,\r
-                                        &xPublishInfo,\r
-                                        0,\r
-                                        mqttTICKS_TO_MS( xTimeoutTicks ) );\r
-\r
-    return prvConvertReturnCode( xMqttStatus );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-MQTTAgentReturnCode_t MQTT_AGENT_ReturnBuffer( MQTTAgentHandle_t xMQTTHandle,\r
-                                               MQTTBufferHandle_t xBufferHandle )\r
-{\r
-    ( void ) xMQTTHandle;\r
-\r
-    /* Free the MQTT buffer. */\r
-    vPortFree( xBufferHandle );\r
-\r
-    return eMQTTAgentSuccess;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_mqtt_api.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_mqtt_api.c
deleted file mode 100644 (file)
index 7df5326..0000000
+++ /dev/null
@@ -1,2018 +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_api.c\r
- * @brief Implements most user-facing functions of the MQTT library.\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_clock.h"\r
-#include "platform/iot_threads.h"\r
-\r
-/* Validate MQTT configuration settings. */\r
-#if IOT_MQTT_ENABLE_ASSERTS != 0 && IOT_MQTT_ENABLE_ASSERTS != 1\r
-    #error "IOT_MQTT_ENABLE_ASSERTS must be 0 or 1."\r
-#endif\r
-#if IOT_MQTT_ENABLE_METRICS != 0 && IOT_MQTT_ENABLE_METRICS != 1\r
-    #error "IOT_MQTT_ENABLE_METRICS must be 0 or 1."\r
-#endif\r
-#if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES != 0 && IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES != 1\r
-    #error "IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES must be 0 or 1."\r
-#endif\r
-#if IOT_MQTT_RESPONSE_WAIT_MS <= 0\r
-    #error "IOT_MQTT_RESPONSE_WAIT_MS cannot be 0 or negative."\r
-#endif\r
-#if IOT_MQTT_RETRY_MS_CEILING <= 0\r
-    #error "IOT_MQTT_RETRY_MS_CEILING cannot be 0 or negative."\r
-#endif\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/**\r
- * @brief Set the unsubscribed flag of an MQTT subscription.\r
- *\r
- * @param[in] pSubscriptionLink Pointer to the link member of an #_mqttSubscription_t.\r
- * @param[in] pMatch Not used.\r
- *\r
- * @return Always returns `true`.\r
- */\r
-static bool _mqttSubscription_setUnsubscribe( const IotLink_t * pSubscriptionLink,\r
-                                              void * pMatch );\r
-\r
-/**\r
- * @brief Destroy an MQTT subscription if its reference count is 0.\r
- *\r
- * @param[in] pData The subscription to destroy. This parameter is of type\r
- * `void*` for compatibility with [free]\r
- * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
- */\r
-static void _mqttSubscription_tryDestroy( void * pData );\r
-\r
-/**\r
- * @brief Decrement the reference count of an MQTT operation and attempt to\r
- * destroy it.\r
- *\r
- * @param[in] pData The operation data to destroy. This parameter is of type\r
- * `void*` for compatibility with [free]\r
- * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
- */\r
-static void _mqttOperation_tryDestroy( void * pData );\r
-\r
-/**\r
- * @brief Create a keep-alive job for an MQTT connection.\r
- *\r
- * @param[in] pNetworkInfo User-provided network information for the new\r
- * connection.\r
- * @param[in] keepAliveSeconds User-provided keep-alive interval.\r
- * @param[out] pMqttConnection The MQTT connection associated with the keep-alive.\r
- *\r
- * @return `true` if the keep-alive job was successfully created; `false` otherwise.\r
- */\r
-static bool _createKeepAliveJob( const IotMqttNetworkInfo_t * pNetworkInfo,\r
-                                 uint16_t keepAliveSeconds,\r
-                                 _mqttConnection_t * pMqttConnection );\r
-\r
-/**\r
- * @brief Creates a new MQTT connection and initializes its members.\r
- *\r
- * @param[in] awsIotMqttMode Specifies if this connection is to an AWS IoT MQTT server.\r
- * @param[in] pNetworkInfo User-provided network information for the new\r
- * connection.\r
- * @param[in] keepAliveSeconds User-provided keep-alive interval for the new connection.\r
- *\r
- * @return Pointer to a newly-created MQTT connection; `NULL` on failure.\r
- */\r
-static _mqttConnection_t * _createMqttConnection( bool awsIotMqttMode,\r
-                                                  const IotMqttNetworkInfo_t * pNetworkInfo,\r
-                                                  uint16_t keepAliveSeconds );\r
-\r
-/**\r
- * @brief Destroys the members of an MQTT connection.\r
- *\r
- * @param[in] pMqttConnection Which connection to destroy.\r
- */\r
-static void _destroyMqttConnection( _mqttConnection_t * pMqttConnection );\r
-\r
-/**\r
- * @brief The common component of both @ref mqtt_function_subscribe and @ref\r
- * mqtt_function_unsubscribe.\r
- *\r
- * See @ref mqtt_function_subscribe or @ref mqtt_function_unsubscribe for a\r
- * description of the parameters and return values.\r
- */\r
-static IotMqttError_t _subscriptionCommon( IotMqttOperationType_t operation,\r
-                                           IotMqttConnection_t mqttConnection,\r
-                                           const IotMqttSubscription_t * pSubscriptionList,\r
-                                           size_t subscriptionCount,\r
-                                           uint32_t flags,\r
-                                           const IotMqttCallbackInfo_t * pCallbackInfo,\r
-                                           IotMqttOperation_t * pOperationReference );\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static bool _mqttSubscription_setUnsubscribe( const IotLink_t * pSubscriptionLink,\r
-                                              void * pMatch )\r
-{\r
-    /* Because this function is called from a container function, the given link\r
-     * must never be NULL. */\r
-    IotMqtt_Assert( pSubscriptionLink != NULL );\r
-\r
-    _mqttSubscription_t * pSubscription = IotLink_Container( _mqttSubscription_t,\r
-                                                             pSubscriptionLink,\r
-                                                             link );\r
-\r
-    /* Silence warnings about unused parameters. */\r
-    ( void ) pMatch;\r
-\r
-    /* Set the unsubscribed flag. */\r
-    pSubscription->unsubscribed = true;\r
-\r
-    return true;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static void _mqttSubscription_tryDestroy( void * pData )\r
-{\r
-    _mqttSubscription_t * pSubscription = ( _mqttSubscription_t * ) pData;\r
-\r
-    /* Reference count must not be negative. */\r
-    IotMqtt_Assert( pSubscription->references >= 0 );\r
-\r
-    /* Unsubscribed flag should be set. */\r
-    IotMqtt_Assert( pSubscription->unsubscribed == true );\r
-\r
-    /* Free the subscription if it has no references. */\r
-    if( pSubscription->references == 0 )\r
-    {\r
-        IotMqtt_FreeSubscription( pSubscription );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static void _mqttOperation_tryDestroy( void * pData )\r
-{\r
-    _mqttOperation_t * pOperation = ( _mqttOperation_t * ) pData;\r
-    IotTaskPoolError_t taskPoolStatus = IOT_TASKPOOL_SUCCESS;\r
-\r
-    /* Incoming PUBLISH operations may always be freed. */\r
-    if( pOperation->incomingPublish == true )\r
-    {\r
-        /* Cancel the incoming PUBLISH operation's job. */\r
-        taskPoolStatus = IotTaskPool_TryCancel( IOT_SYSTEM_TASKPOOL,\r
-                                                pOperation->job,\r
-                                                NULL );\r
-\r
-        /* If the operation's 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
-        /* Check if the incoming PUBLISH job was canceled. */\r
-        if( taskPoolStatus == IOT_TASKPOOL_SUCCESS )\r
-        {\r
-            /* Job was canceled. Process incoming PUBLISH now to clean up. */\r
-            _IotMqtt_ProcessIncomingPublish( IOT_SYSTEM_TASKPOOL,\r
-                                             pOperation->job,\r
-                                             pOperation );\r
-        }\r
-        else\r
-        {\r
-            /* The executing job will process the PUBLISH, so nothing is done here. */\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        /* Decrement reference count and destroy operation if possible. */\r
-        if( _IotMqtt_DecrementOperationReferences( pOperation, true ) == true )\r
-        {\r
-            _IotMqtt_DestroyOperation( pOperation );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static bool _createKeepAliveJob( const IotMqttNetworkInfo_t * pNetworkInfo,\r
-                                 uint16_t keepAliveSeconds,\r
-                                 _mqttConnection_t * pMqttConnection )\r
-{\r
-    bool status = true;\r
-    IotMqttError_t serializeStatus = IOT_MQTT_SUCCESS;\r
-    IotTaskPoolError_t jobStatus = IOT_TASKPOOL_SUCCESS;\r
-\r
-    /* Network information is not used when MQTT packet serializers are disabled. */\r
-    ( void ) pNetworkInfo;\r
-\r
-    /* Default PINGREQ serializer function. */\r
-    IotMqttError_t ( * serializePingreq )( uint8_t **,\r
-                                           size_t * ) = _IotMqtt_SerializePingreq;\r
-\r
-    /* Convert the keep-alive interval to milliseconds. */\r
-    pMqttConnection->keepAliveMs = keepAliveSeconds * 1000;\r
-    pMqttConnection->nextKeepAliveMs = pMqttConnection->keepAliveMs;\r
-\r
-    /* Choose a PINGREQ serializer function. */\r
-    #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
-        if( pNetworkInfo->pMqttSerializer != NULL )\r
-        {\r
-            if( pNetworkInfo->pMqttSerializer->serialize.pingreq != NULL )\r
-            {\r
-                serializePingreq = pNetworkInfo->pMqttSerializer->serialize.pingreq;\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
-    /* Generate a PINGREQ packet. */\r
-    serializeStatus = serializePingreq( &( pMqttConnection->pPingreqPacket ),\r
-                                        &( pMqttConnection->pingreqPacketSize ) );\r
-\r
-    if( serializeStatus != IOT_MQTT_SUCCESS )\r
-    {\r
-        IotLogError( "Failed to allocate PINGREQ packet for new connection." );\r
-\r
-        status = false;\r
-    }\r
-    else\r
-    {\r
-        /* Create the task pool job that processes keep-alive. */\r
-        jobStatus = IotTaskPool_CreateJob( _IotMqtt_ProcessKeepAlive,\r
-                                           pMqttConnection,\r
-                                           &( pMqttConnection->keepAliveJobStorage ),\r
-                                           &( pMqttConnection->keepAliveJob ) );\r
-\r
-        /* Task pool job creation for a pre-allocated job should never fail.\r
-         * Abort the program if it does. */\r
-        if( jobStatus != IOT_TASKPOOL_SUCCESS )\r
-        {\r
-            IotLogError( "Failed to create keep-alive job for new connection." );\r
-\r
-            IotMqtt_Assert( false );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        /* Keep-alive references its MQTT connection, so increment reference. */\r
-        ( pMqttConnection->references )++;\r
-    }\r
-\r
-    return status;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static _mqttConnection_t * _createMqttConnection( bool awsIotMqttMode,\r
-                                                  const IotMqttNetworkInfo_t * pNetworkInfo,\r
-                                                  uint16_t keepAliveSeconds )\r
-{\r
-    IOT_FUNCTION_ENTRY( bool, true );\r
-    _mqttConnection_t * pMqttConnection = NULL;\r
-    bool referencesMutexCreated = false, subscriptionMutexCreated = false;\r
-\r
-    /* Allocate memory for the new MQTT connection. */\r
-    pMqttConnection = IotMqtt_MallocConnection( sizeof( _mqttConnection_t ) );\r
-\r
-    if( pMqttConnection == NULL )\r
-    {\r
-        IotLogError( "Failed to allocate memory for new connection." );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( false );\r
-    }\r
-    else\r
-    {\r
-        /* Clear the MQTT connection, then copy the MQTT server mode, network\r
-         * interface, and disconnect callback. */\r
-        ( void ) memset( pMqttConnection, 0x00, sizeof( _mqttConnection_t ) );\r
-        pMqttConnection->awsIotMqttMode = awsIotMqttMode;\r
-        pMqttConnection->pNetworkInterface = pNetworkInfo->pNetworkInterface;\r
-        pMqttConnection->disconnectCallback = pNetworkInfo->disconnectCallback;\r
-\r
-        /* Start a new MQTT connection with a reference count of 1. */\r
-        pMqttConnection->references = 1;\r
-    }\r
-\r
-    /* Create the references mutex for a new connection. It is a recursive mutex. */\r
-    referencesMutexCreated = IotMutex_Create( &( pMqttConnection->referencesMutex ), true );\r
-\r
-    if( referencesMutexCreated == false )\r
-    {\r
-        IotLogError( "Failed to create references mutex for new connection." );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( false );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Create the subscription mutex for a new connection. */\r
-    subscriptionMutexCreated = IotMutex_Create( &( pMqttConnection->subscriptionMutex ), false );\r
-\r
-    if( subscriptionMutexCreated == false )\r
-    {\r
-        IotLogError( "Failed to create subscription mutex for new connection." );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( false );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Create the new connection's subscription and operation lists. */\r
-    IotListDouble_Create( &( pMqttConnection->subscriptionList ) );\r
-    IotListDouble_Create( &( pMqttConnection->pendingProcessing ) );\r
-    IotListDouble_Create( &( pMqttConnection->pendingResponse ) );\r
-\r
-    /* AWS IoT service limits set minimum and maximum values for keep-alive interval.\r
-     * Adjust the user-provided keep-alive interval based on these requirements. */\r
-    if( awsIotMqttMode == true )\r
-    {\r
-        if( keepAliveSeconds < AWS_IOT_MQTT_SERVER_MIN_KEEPALIVE )\r
-        {\r
-            keepAliveSeconds = AWS_IOT_MQTT_SERVER_MIN_KEEPALIVE;\r
-        }\r
-        else if( keepAliveSeconds > AWS_IOT_MQTT_SERVER_MAX_KEEPALIVE )\r
-        {\r
-            keepAliveSeconds = AWS_IOT_MQTT_SERVER_MAX_KEEPALIVE;\r
-        }\r
-        else if( keepAliveSeconds == 0 )\r
-        {\r
-            keepAliveSeconds = AWS_IOT_MQTT_SERVER_MAX_KEEPALIVE;\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Check if keep-alive is active for this connection. */\r
-    if( keepAliveSeconds != 0 )\r
-    {\r
-        if( _createKeepAliveJob( pNetworkInfo,\r
-                                 keepAliveSeconds,\r
-                                 pMqttConnection ) == false )\r
-        {\r
-            IOT_SET_AND_GOTO_CLEANUP( false );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Clean up mutexes and connection if this function failed. */\r
-    IOT_FUNCTION_CLEANUP_BEGIN();\r
-\r
-    if( status == false )\r
-    {\r
-        if( subscriptionMutexCreated == true )\r
-        {\r
-            IotMutex_Destroy( &( pMqttConnection->subscriptionMutex ) );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        if( referencesMutexCreated == true )\r
-        {\r
-            IotMutex_Destroy( &( pMqttConnection->referencesMutex ) );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        if( pMqttConnection != NULL )\r
-        {\r
-            IotMqtt_FreeConnection( pMqttConnection );\r
-            pMqttConnection = NULL;\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    return pMqttConnection;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static void _destroyMqttConnection( _mqttConnection_t * pMqttConnection )\r
-{\r
-    IotNetworkError_t networkStatus = IOT_NETWORK_SUCCESS;\r
-\r
-    /* Clean up keep-alive if still allocated. */\r
-    if( pMqttConnection->keepAliveMs != 0 )\r
-    {\r
-        IotLogDebug( "(MQTT connection %p) Cleaning up keep-alive.", pMqttConnection );\r
-\r
-        _IotMqtt_FreePacket( pMqttConnection->pPingreqPacket );\r
-\r
-        /* Clear data about the keep-alive. */\r
-        pMqttConnection->keepAliveMs = 0;\r
-        pMqttConnection->pPingreqPacket = NULL;\r
-        pMqttConnection->pingreqPacketSize = 0;\r
-\r
-        /* Decrement reference count. */\r
-        pMqttConnection->references--;\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* A connection to be destroyed should have no keep-alive and at most 1\r
-     * reference. */\r
-    IotMqtt_Assert( pMqttConnection->references <= 1 );\r
-    IotMqtt_Assert( pMqttConnection->keepAliveMs == 0 );\r
-    IotMqtt_Assert( pMqttConnection->pPingreqPacket == NULL );\r
-    IotMqtt_Assert( pMqttConnection->pingreqPacketSize == 0 );\r
-\r
-    /* Remove all subscriptions. */\r
-    IotMutex_Lock( &( pMqttConnection->subscriptionMutex ) );\r
-    IotListDouble_RemoveAllMatches( &( pMqttConnection->subscriptionList ),\r
-                                    _mqttSubscription_setUnsubscribe,\r
-                                    NULL,\r
-                                    _mqttSubscription_tryDestroy,\r
-                                    offsetof( _mqttSubscription_t, link ) );\r
-    IotMutex_Unlock( &( pMqttConnection->subscriptionMutex ) );\r
-\r
-    /* Destroy an owned network connection. */\r
-    if( pMqttConnection->ownNetworkConnection == true )\r
-    {\r
-        networkStatus = pMqttConnection->pNetworkInterface->destroy( pMqttConnection->pNetworkConnection );\r
-\r
-        if( networkStatus != IOT_NETWORK_SUCCESS )\r
-        {\r
-            IotLogWarn( "(MQTT connection %p) Failed to destroy network connection.",\r
-                        pMqttConnection );\r
-        }\r
-        else\r
-        {\r
-            IotLogInfo( "(MQTT connection %p) Network connection destroyed.",\r
-                        pMqttConnection );\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Destroy mutexes. */\r
-    IotMutex_Destroy( &( pMqttConnection->referencesMutex ) );\r
-    IotMutex_Destroy( &( pMqttConnection->subscriptionMutex ) );\r
-\r
-    IotLogDebug( "(MQTT connection %p) Connection destroyed.", pMqttConnection );\r
-\r
-    /* Free connection. */\r
-    IotMqtt_FreeConnection( pMqttConnection );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static IotMqttError_t _subscriptionCommon( IotMqttOperationType_t operation,\r
-                                           IotMqttConnection_t mqttConnection,\r
-                                           const IotMqttSubscription_t * pSubscriptionList,\r
-                                           size_t subscriptionCount,\r
-                                           uint32_t flags,\r
-                                           const IotMqttCallbackInfo_t * pCallbackInfo,\r
-                                           IotMqttOperation_t * pOperationReference )\r
-{\r
-    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
-    _mqttOperation_t * pSubscriptionOperation = NULL;\r
-\r
-    /* Subscription serializer function. */\r
-    IotMqttError_t ( * serializeSubscription )( const IotMqttSubscription_t *,\r
-                                                size_t,\r
-                                                uint8_t **,\r
-                                                size_t *,\r
-                                                uint16_t * ) = NULL;\r
-\r
-    /* This function should only be called for subscribe or unsubscribe. */\r
-    IotMqtt_Assert( ( operation == IOT_MQTT_SUBSCRIBE ) ||\r
-                    ( operation == IOT_MQTT_UNSUBSCRIBE ) );\r
-\r
-    /* Check that all elements in the subscription list are valid. */\r
-    if( _IotMqtt_ValidateSubscriptionList( operation,\r
-                                           mqttConnection->awsIotMqttMode,\r
-                                           pSubscriptionList,\r
-                                           subscriptionCount ) == false )\r
-    {\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Check that a reference pointer is provided for a waitable operation. */\r
-    if( ( flags & IOT_MQTT_FLAG_WAITABLE ) == IOT_MQTT_FLAG_WAITABLE )\r
-    {\r
-        if( pOperationReference == NULL )\r
-        {\r
-            IotLogError( "Reference must be provided for a waitable %s.",\r
-                         IotMqtt_OperationType( operation ) );\r
-\r
-            IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Choose a subscription serialize function. */\r
-    if( operation == IOT_MQTT_SUBSCRIBE )\r
-    {\r
-        serializeSubscription = _IotMqtt_SerializeSubscribe;\r
-\r
-        #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
-            if( mqttConnection->pSerializer != NULL )\r
-            {\r
-                if( mqttConnection->pSerializer->serialize.subscribe != NULL )\r
-                {\r
-                    serializeSubscription = mqttConnection->pSerializer->serialize.subscribe;\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
-    else\r
-    {\r
-        serializeSubscription = _IotMqtt_SerializeUnsubscribe;\r
-\r
-        #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
-            if( mqttConnection->pSerializer != NULL )\r
-            {\r
-                if( mqttConnection->pSerializer->serialize.unsubscribe != NULL )\r
-                {\r
-                    serializeSubscription = mqttConnection->pSerializer->serialize.unsubscribe;\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
-\r
-    /* Remove the MQTT subscription list for an UNSUBSCRIBE. */\r
-    if( operation == IOT_MQTT_UNSUBSCRIBE )\r
-    {\r
-        _IotMqtt_RemoveSubscriptionByTopicFilter( mqttConnection,\r
-                                                  pSubscriptionList,\r
-                                                  subscriptionCount );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Create a subscription operation. */\r
-    status = _IotMqtt_CreateOperation( mqttConnection,\r
-                                       flags,\r
-                                       pCallbackInfo,\r
-                                       &pSubscriptionOperation );\r
-\r
-    if( status != IOT_MQTT_SUCCESS )\r
-    {\r
-        IOT_GOTO_CLEANUP();\r
-    }\r
-\r
-    /* Check the subscription operation data and set the operation type. */\r
-    IotMqtt_Assert( pSubscriptionOperation->u.operation.status == IOT_MQTT_STATUS_PENDING );\r
-    IotMqtt_Assert( pSubscriptionOperation->u.operation.retry.limit == 0 );\r
-    pSubscriptionOperation->u.operation.type = operation;\r
-\r
-    /* Generate a subscription packet from the subscription list. */\r
-    status = serializeSubscription( pSubscriptionList,\r
-                                    subscriptionCount,\r
-                                    &( pSubscriptionOperation->u.operation.pMqttPacket ),\r
-                                    &( pSubscriptionOperation->u.operation.packetSize ),\r
-                                    &( pSubscriptionOperation->u.operation.packetIdentifier ) );\r
-\r
-    if( status != IOT_MQTT_SUCCESS )\r
-    {\r
-        IOT_GOTO_CLEANUP();\r
-    }\r
-\r
-    /* Check the serialized MQTT packet. */\r
-    IotMqtt_Assert( pSubscriptionOperation->u.operation.pMqttPacket != NULL );\r
-    IotMqtt_Assert( pSubscriptionOperation->u.operation.packetSize > 0 );\r
-\r
-    /* Add the subscription list for a SUBSCRIBE. */\r
-    if( operation == IOT_MQTT_SUBSCRIBE )\r
-    {\r
-        status = _IotMqtt_AddSubscriptions( mqttConnection,\r
-                                            pSubscriptionOperation->u.operation.packetIdentifier,\r
-                                            pSubscriptionList,\r
-                                            subscriptionCount );\r
-\r
-        if( status != IOT_MQTT_SUCCESS )\r
-        {\r
-            IOT_GOTO_CLEANUP();\r
-        }\r
-    }\r
-\r
-    /* Set the reference, if provided. */\r
-    if( pOperationReference != NULL )\r
-    {\r
-        *pOperationReference = pSubscriptionOperation;\r
-    }\r
-\r
-    /* Schedule the subscription operation for network transmission. */\r
-    status = _IotMqtt_ScheduleOperation( pSubscriptionOperation,\r
-                                         _IotMqtt_ProcessSend,\r
-                                         0 );\r
-\r
-    if( status != IOT_MQTT_SUCCESS )\r
-    {\r
-        IotLogError( "(MQTT connection %p) Failed to schedule %s for sending.",\r
-                     mqttConnection,\r
-                     IotMqtt_OperationType( operation ) );\r
-\r
-        if( operation == IOT_MQTT_SUBSCRIBE )\r
-        {\r
-            _IotMqtt_RemoveSubscriptionByPacket( mqttConnection,\r
-                                                 pSubscriptionOperation->u.operation.packetIdentifier,\r
-                                                 -1 );\r
-        }\r
-\r
-        /* Clear the previously set (and now invalid) reference. */\r
-        if( pOperationReference != NULL )\r
-        {\r
-            *pOperationReference = IOT_MQTT_OPERATION_INITIALIZER;\r
-        }\r
-\r
-        IOT_GOTO_CLEANUP();\r
-    }\r
-\r
-    /* Clean up if this function failed. */\r
-    IOT_FUNCTION_CLEANUP_BEGIN();\r
-\r
-    if( status != IOT_MQTT_SUCCESS )\r
-    {\r
-        if( pSubscriptionOperation != NULL )\r
-        {\r
-            _IotMqtt_DestroyOperation( pSubscriptionOperation );\r
-        }\r
-    }\r
-    else\r
-    {\r
-        status = IOT_MQTT_STATUS_PENDING;\r
-\r
-        IotLogInfo( "(MQTT connection %p) %s operation scheduled.",\r
-                    mqttConnection,\r
-                    IotMqtt_OperationType( operation ) );\r
-    }\r
-\r
-    IOT_FUNCTION_CLEANUP_END();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-bool _IotMqtt_IncrementConnectionReferences( _mqttConnection_t * pMqttConnection )\r
-{\r
-    bool disconnected = false;\r
-\r
-    /* Lock the mutex protecting the reference count. */\r
-    IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
-\r
-    /* Reference count must not be negative. */\r
-    IotMqtt_Assert( pMqttConnection->references >= 0 );\r
-\r
-    /* Read connection status. */\r
-    disconnected = pMqttConnection->disconnected;\r
-\r
-    /* Increment the connection's reference count if it is not disconnected. */\r
-    if( disconnected == false )\r
-    {\r
-        ( pMqttConnection->references )++;\r
-        IotLogDebug( "(MQTT connection %p) Reference count changed from %ld to %ld.",\r
-                     pMqttConnection,\r
-                     ( long int ) pMqttConnection->references - 1,\r
-                     ( long int ) pMqttConnection->references );\r
-    }\r
-    else\r
-    {\r
-        IotLogWarn( "(MQTT connection %p) Attempt to use closed connection.", pMqttConnection );\r
-    }\r
-\r
-    IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
-\r
-    return( disconnected == false );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void _IotMqtt_DecrementConnectionReferences( _mqttConnection_t * pMqttConnection )\r
-{\r
-    bool destroyConnection = false;\r
-\r
-    /* Lock the mutex protecting the reference count. */\r
-    IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
-\r
-    /* Decrement reference count. It must not be negative. */\r
-    ( pMqttConnection->references )--;\r
-    IotMqtt_Assert( pMqttConnection->references >= 0 );\r
-\r
-    IotLogDebug( "(MQTT connection %p) Reference count changed from %ld to %ld.",\r
-                 pMqttConnection,\r
-                 ( long int ) pMqttConnection->references + 1,\r
-                 ( long int ) pMqttConnection->references );\r
-\r
-    /* Check if this connection may be destroyed. */\r
-    if( pMqttConnection->references == 0 )\r
-    {\r
-        destroyConnection = true;\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
-\r
-    /* Destroy an unreferenced MQTT connection. */\r
-    if( destroyConnection == true )\r
-    {\r
-        IotLogDebug( "(MQTT connection %p) Connection will be destroyed now.",\r
-                     pMqttConnection );\r
-        _destroyMqttConnection( pMqttConnection );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t IotMqtt_Init( void )\r
-{\r
-    IotMqttError_t status = IOT_MQTT_SUCCESS;\r
-\r
-    /* Call any additional serializer initialization function if serializer\r
-     * overrides are enabled. */\r
-    #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
-        #ifdef _IotMqtt_InitSerializeAdditional\r
-            if( _IotMqtt_InitSerializeAdditional() == false )\r
-            {\r
-                status = IOT_MQTT_INIT_FAILED;\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-        #endif\r
-    #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */\r
-\r
-    /* Log initialization status. */\r
-    if( status != IOT_MQTT_SUCCESS )\r
-    {\r
-        IotLogError( "Failed to initialize MQTT library serializer. " );\r
-    }\r
-    else\r
-    {\r
-        IotLogInfo( "MQTT library successfully initialized." );\r
-    }\r
-\r
-    return status;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void IotMqtt_Cleanup( void )\r
-{\r
-    /* Call any additional serializer cleanup initialization function if serializer\r
-     * overrides are enabled. */\r
-    #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
-        #ifdef _IotMqtt_CleanupSerializeAdditional\r
-            _IotMqtt_CleanupSerializeAdditional();\r
-        #endif\r
-    #endif\r
-\r
-    IotLogInfo( "MQTT library cleanup done." );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t IotMqtt_Connect( const IotMqttNetworkInfo_t * pNetworkInfo,\r
-                                const IotMqttConnectInfo_t * pConnectInfo,\r
-                                uint32_t timeoutMs,\r
-                                IotMqttConnection_t * const pMqttConnection )\r
-{\r
-    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
-    bool networkCreated = false, ownNetworkConnection = false;\r
-    IotNetworkError_t networkStatus = IOT_NETWORK_SUCCESS;\r
-    IotTaskPoolError_t taskPoolStatus = IOT_TASKPOOL_SUCCESS;\r
-    void * pNetworkConnection = NULL;\r
-    _mqttOperation_t * pOperation = NULL;\r
-    _mqttConnection_t * pNewMqttConnection = NULL;\r
-\r
-    /* Default CONNECT serializer function. */\r
-    IotMqttError_t ( * serializeConnect )( const IotMqttConnectInfo_t *,\r
-                                           uint8_t **,\r
-                                           size_t * ) = _IotMqtt_SerializeConnect;\r
-\r
-    /* Network info must not be NULL. */\r
-    if( pNetworkInfo == NULL )\r
-    {\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Validate network interface and connect info. */\r
-    if( _IotMqtt_ValidateConnect( pConnectInfo ) == false )\r
-    {\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* If will info is provided, check that it is valid. */\r
-    if( pConnectInfo->pWillInfo != NULL )\r
-    {\r
-        if( _IotMqtt_ValidatePublish( pConnectInfo->awsIotMqttMode,\r
-                                      pConnectInfo->pWillInfo ) == false )\r
-        {\r
-            IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
-        }\r
-        else if( pConnectInfo->pWillInfo->payloadLength > UINT16_MAX )\r
-        {\r
-            /* Will message payloads cannot be larger than 65535. This restriction\r
-             * applies only to will messages, and not normal PUBLISH messages. */\r
-            IotLogError( "Will payload cannot be larger than 65535." );\r
-\r
-            IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* If previous subscriptions are provided, check that they are valid. */\r
-    if( pConnectInfo->cleanSession == false )\r
-    {\r
-        if( pConnectInfo->pPreviousSubscriptions != NULL )\r
-        {\r
-            if( _IotMqtt_ValidateSubscriptionList( IOT_MQTT_SUBSCRIBE,\r
-                                                   pConnectInfo->awsIotMqttMode,\r
-                                                   pConnectInfo->pPreviousSubscriptions,\r
-                                                   pConnectInfo->previousSubscriptionCount ) == false )\r
-            {\r
-                IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Create a new MQTT connection if requested. Otherwise, copy the existing\r
-     * network connection. */\r
-    if( pNetworkInfo->createNetworkConnection == true )\r
-    {\r
-        networkStatus = pNetworkInfo->pNetworkInterface->create( pNetworkInfo->u.setup.pNetworkServerInfo,\r
-                                                                 pNetworkInfo->u.setup.pNetworkCredentialInfo,\r
-                                                                 &pNetworkConnection );\r
-\r
-        if( networkStatus == IOT_NETWORK_SUCCESS )\r
-        {\r
-            networkCreated = true;\r
-\r
-            /* This MQTT connection owns the network connection it created and\r
-             * should destroy it on cleanup. */\r
-            ownNetworkConnection = true;\r
-        }\r
-        else\r
-        {\r
-            IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NETWORK_ERROR );\r
-        }\r
-    }\r
-    else\r
-    {\r
-        pNetworkConnection = pNetworkInfo->u.pNetworkConnection;\r
-        networkCreated = true;\r
-    }\r
-\r
-    IotLogInfo( "Establishing new MQTT connection." );\r
-\r
-    /* Initialize a new MQTT connection object. */\r
-    pNewMqttConnection = _createMqttConnection( pConnectInfo->awsIotMqttMode,\r
-                                                pNetworkInfo,\r
-                                                pConnectInfo->keepAliveSeconds );\r
-\r
-    if( pNewMqttConnection == NULL )\r
-    {\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NO_MEMORY );\r
-    }\r
-    else\r
-    {\r
-        /* Set the network connection associated with the MQTT connection. */\r
-        pNewMqttConnection->pNetworkConnection = pNetworkConnection;\r
-        pNewMqttConnection->ownNetworkConnection = ownNetworkConnection;\r
-\r
-        /* Set the MQTT packet serializer overrides. */\r
-        #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
-            pNewMqttConnection->pSerializer = pNetworkInfo->pMqttSerializer;\r
-        #endif\r
-    }\r
-\r
-    /* Set the MQTT receive callback. */\r
-    networkStatus = pNewMqttConnection->pNetworkInterface->setReceiveCallback( pNetworkConnection,\r
-                                                                               IotMqtt_ReceiveCallback,\r
-                                                                               pNewMqttConnection );\r
-\r
-    if( networkStatus != IOT_NETWORK_SUCCESS )\r
-    {\r
-        IotLogError( "Failed to set MQTT network receive callback." );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NETWORK_ERROR );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Create a CONNECT operation. */\r
-    status = _IotMqtt_CreateOperation( pNewMqttConnection,\r
-                                       IOT_MQTT_FLAG_WAITABLE,\r
-                                       NULL,\r
-                                       &pOperation );\r
-\r
-    if( status != IOT_MQTT_SUCCESS )\r
-    {\r
-        IOT_GOTO_CLEANUP();\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Ensure the members set by operation creation and serialization\r
-     * are appropriate for a blocking CONNECT. */\r
-    IotMqtt_Assert( pOperation->u.operation.status == IOT_MQTT_STATUS_PENDING );\r
-    IotMqtt_Assert( ( pOperation->u.operation.flags & IOT_MQTT_FLAG_WAITABLE )\r
-                    == IOT_MQTT_FLAG_WAITABLE );\r
-    IotMqtt_Assert( pOperation->u.operation.retry.limit == 0 );\r
-\r
-    /* Set the operation type. */\r
-    pOperation->u.operation.type = IOT_MQTT_CONNECT;\r
-\r
-    /* Add previous session subscriptions. */\r
-    if( pConnectInfo->pPreviousSubscriptions != NULL )\r
-    {\r
-        /* Previous subscription count should have been validated as nonzero. */\r
-        IotMqtt_Assert( pConnectInfo->previousSubscriptionCount > 0 );\r
-\r
-        status = _IotMqtt_AddSubscriptions( pNewMqttConnection,\r
-                                            2,\r
-                                            pConnectInfo->pPreviousSubscriptions,\r
-                                            pConnectInfo->previousSubscriptionCount );\r
-\r
-        if( status != IOT_MQTT_SUCCESS )\r
-        {\r
-            IOT_GOTO_CLEANUP();\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Choose a CONNECT serializer function. */\r
-    #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
-        if( pNewMqttConnection->pSerializer != NULL )\r
-        {\r
-            if( pNewMqttConnection->pSerializer->serialize.connect != NULL )\r
-            {\r
-                serializeConnect = pNewMqttConnection->pSerializer->serialize.connect;\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
-    /* Convert the connect info and will info objects to an MQTT CONNECT packet. */\r
-    status = serializeConnect( pConnectInfo,\r
-                               &( pOperation->u.operation.pMqttPacket ),\r
-                               &( pOperation->u.operation.packetSize ) );\r
-\r
-    if( status != IOT_MQTT_SUCCESS )\r
-    {\r
-        IOT_GOTO_CLEANUP();\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Check the serialized MQTT packet. */\r
-    IotMqtt_Assert( pOperation->u.operation.pMqttPacket != NULL );\r
-    IotMqtt_Assert( pOperation->u.operation.packetSize > 0 );\r
-\r
-    /* Add the CONNECT operation to the send queue for network transmission. */\r
-    status = _IotMqtt_ScheduleOperation( pOperation,\r
-                                         _IotMqtt_ProcessSend,\r
-                                         0 );\r
-\r
-    if( status != IOT_MQTT_SUCCESS )\r
-    {\r
-        IotLogError( "Failed to enqueue CONNECT for sending." );\r
-    }\r
-    else\r
-    {\r
-        /* Wait for the CONNECT operation to complete, i.e. wait for CONNACK. */\r
-        status = IotMqtt_Wait( pOperation,\r
-                               timeoutMs );\r
-\r
-        /* The call to wait cleans up the CONNECT operation, so set the pointer\r
-         * to NULL. */\r
-        pOperation = NULL;\r
-    }\r
-\r
-    /* When a connection is successfully established, schedule keep-alive job. */\r
-    if( status == IOT_MQTT_SUCCESS )\r
-    {\r
-        /* Check if a keep-alive job should be scheduled. */\r
-        if( pNewMqttConnection->keepAliveMs != 0 )\r
-        {\r
-            IotLogDebug( "Scheduling first MQTT keep-alive job." );\r
-\r
-            taskPoolStatus = IotTaskPool_ScheduleDeferred( IOT_SYSTEM_TASKPOOL,\r
-                                                           pNewMqttConnection->keepAliveJob,\r
-                                                           pNewMqttConnection->nextKeepAliveMs );\r
-\r
-            if( taskPoolStatus != IOT_TASKPOOL_SUCCESS )\r
-            {\r
-                IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_SCHEDULING_ERROR );\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    IOT_FUNCTION_CLEANUP_BEGIN();\r
-\r
-    if( status != IOT_MQTT_SUCCESS )\r
-    {\r
-        IotLogError( "Failed to establish new MQTT connection, error %s.",\r
-                     IotMqtt_strerror( status ) );\r
-\r
-        /* The network connection must be closed if it was created. */\r
-        if( networkCreated == true )\r
-        {\r
-            networkStatus = pNetworkInfo->pNetworkInterface->close( pNetworkConnection );\r
-\r
-            if( networkStatus != IOT_NETWORK_SUCCESS )\r
-            {\r
-                IotLogWarn( "Failed to close network connection." );\r
-            }\r
-            else\r
-            {\r
-                IotLogInfo( "Network connection closed on error." );\r
-            }\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        if( pOperation != NULL )\r
-        {\r
-            _IotMqtt_DestroyOperation( pOperation );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        if( pNewMqttConnection != NULL )\r
-        {\r
-            _destroyMqttConnection( pNewMqttConnection );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        IotLogInfo( "New MQTT connection %p established.", pMqttConnection );\r
-\r
-        /* Set the output parameter. */\r
-        *pMqttConnection = pNewMqttConnection;\r
-    }\r
-\r
-    IOT_FUNCTION_CLEANUP_END();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void IotMqtt_Disconnect( IotMqttConnection_t mqttConnection,\r
-                         uint32_t flags )\r
-{\r
-    bool disconnected = false;\r
-    IotMqttError_t status = IOT_MQTT_STATUS_PENDING;\r
-    _mqttOperation_t * pOperation = NULL;\r
-\r
-    IotLogInfo( "(MQTT connection %p) Disconnecting connection.", mqttConnection );\r
-\r
-    /* Read the connection status. */\r
-    IotMutex_Lock( &( mqttConnection->referencesMutex ) );\r
-    disconnected = mqttConnection->disconnected;\r
-    IotMutex_Unlock( &( mqttConnection->referencesMutex ) );\r
-\r
-    /* Only send a DISCONNECT packet if the connection is active and the "cleanup only"\r
-     * flag is not set. */\r
-    if( disconnected == false )\r
-    {\r
-        if( ( flags & IOT_MQTT_FLAG_CLEANUP_ONLY ) == 0 )\r
-        {\r
-            /* Create a DISCONNECT operation. This function blocks until the DISCONNECT\r
-             * packet is sent, so it sets IOT_MQTT_FLAG_WAITABLE. */\r
-            status = _IotMqtt_CreateOperation( mqttConnection,\r
-                                               IOT_MQTT_FLAG_WAITABLE,\r
-                                               NULL,\r
-                                               &pOperation );\r
-\r
-            if( status == IOT_MQTT_SUCCESS )\r
-            {\r
-                /* Ensure that the members set by operation creation and serialization\r
-                 * are appropriate for a blocking DISCONNECT. */\r
-                IotMqtt_Assert( pOperation->u.operation.status == IOT_MQTT_STATUS_PENDING );\r
-                IotMqtt_Assert( ( pOperation->u.operation.flags & IOT_MQTT_FLAG_WAITABLE )\r
-                                == IOT_MQTT_FLAG_WAITABLE );\r
-                IotMqtt_Assert( pOperation->u.operation.retry.limit == 0 );\r
-\r
-                /* Set the operation type. */\r
-                pOperation->u.operation.type = IOT_MQTT_DISCONNECT;\r
-\r
-                /* Choose a disconnect serializer. */\r
-                IotMqttError_t ( * serializeDisconnect )( uint8_t **,\r
-                                                          size_t * ) = _IotMqtt_SerializeDisconnect;\r
-\r
-                #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
-                    if( mqttConnection->pSerializer != NULL )\r
-                    {\r
-                        if( mqttConnection->pSerializer->serialize.disconnect != NULL )\r
-                        {\r
-                            serializeDisconnect = mqttConnection->pSerializer->serialize.disconnect;\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
-                /* Generate a DISCONNECT packet. */\r
-                status = serializeDisconnect( &( pOperation->u.operation.pMqttPacket ),\r
-                                              &( pOperation->u.operation.packetSize ) );\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-\r
-            if( status == IOT_MQTT_SUCCESS )\r
-            {\r
-                /* Check the serialized MQTT packet. */\r
-                IotMqtt_Assert( pOperation->u.operation.pMqttPacket != NULL );\r
-                IotMqtt_Assert( pOperation->u.operation.packetSize > 0 );\r
-\r
-                /* Schedule the DISCONNECT operation for network transmission. */\r
-                if( _IotMqtt_ScheduleOperation( pOperation,\r
-                                                _IotMqtt_ProcessSend,\r
-                                                0 ) != IOT_MQTT_SUCCESS )\r
-                {\r
-                    IotLogWarn( "(MQTT connection %p) Failed to schedule DISCONNECT for sending.",\r
-                                mqttConnection );\r
-                    _IotMqtt_DestroyOperation( pOperation );\r
-                }\r
-                else\r
-                {\r
-                    /* Wait a short time for the DISCONNECT packet to be transmitted. */\r
-                    status = IotMqtt_Wait( pOperation,\r
-                                           IOT_MQTT_RESPONSE_WAIT_MS );\r
-\r
-                    /* A wait on DISCONNECT should only ever return SUCCESS, TIMEOUT,\r
-                     * or NETWORK ERROR. */\r
-                    if( status == IOT_MQTT_SUCCESS )\r
-                    {\r
-                        IotLogInfo( "(MQTT connection %p) Connection disconnected.", mqttConnection );\r
-                    }\r
-                    else\r
-                    {\r
-                        IotMqtt_Assert( ( status == IOT_MQTT_TIMEOUT ) ||\r
-                                        ( status == IOT_MQTT_NETWORK_ERROR ) );\r
-\r
-                        IotLogWarn( "(MQTT connection %p) DISCONNECT not sent, error %s.",\r
-                                    mqttConnection,\r
-                                    IotMqtt_strerror( status ) );\r
-                    }\r
-                }\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Close the underlying network connection. This also cleans up keep-alive. */\r
-    _IotMqtt_CloseNetworkConnection( IOT_MQTT_DISCONNECT_CALLED,\r
-                                     mqttConnection );\r
-\r
-    /* Check if the connection may be destroyed. */\r
-    IotMutex_Lock( &( mqttConnection->referencesMutex ) );\r
-\r
-    /* At this point, the connection should be marked disconnected. */\r
-    IotMqtt_Assert( mqttConnection->disconnected == true );\r
-\r
-    /* Attempt cancel and destroy each operation in the connection's lists. */\r
-    IotListDouble_RemoveAll( &( mqttConnection->pendingProcessing ),\r
-                             _mqttOperation_tryDestroy,\r
-                             offsetof( _mqttOperation_t, link ) );\r
-\r
-    IotListDouble_RemoveAll( &( mqttConnection->pendingResponse ),\r
-                             _mqttOperation_tryDestroy,\r
-                             offsetof( _mqttOperation_t, link ) );\r
-\r
-    IotMutex_Unlock( &( mqttConnection->referencesMutex ) );\r
-\r
-    /* Decrement the connection reference count and destroy it if possible. */\r
-    _IotMqtt_DecrementConnectionReferences( mqttConnection );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t IotMqtt_Subscribe( IotMqttConnection_t mqttConnection,\r
-                                  const IotMqttSubscription_t * pSubscriptionList,\r
-                                  size_t subscriptionCount,\r
-                                  uint32_t flags,\r
-                                  const IotMqttCallbackInfo_t * pCallbackInfo,\r
-                                  IotMqttOperation_t * pSubscribeOperation )\r
-{\r
-    return _subscriptionCommon( IOT_MQTT_SUBSCRIBE,\r
-                                mqttConnection,\r
-                                pSubscriptionList,\r
-                                subscriptionCount,\r
-                                flags,\r
-                                pCallbackInfo,\r
-                                pSubscribeOperation );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t IotMqtt_TimedSubscribe( IotMqttConnection_t mqttConnection,\r
-                                       const IotMqttSubscription_t * pSubscriptionList,\r
-                                       size_t subscriptionCount,\r
-                                       uint32_t flags,\r
-                                       uint32_t timeoutMs )\r
-{\r
-    IotMqttError_t status = IOT_MQTT_STATUS_PENDING;\r
-    IotMqttOperation_t subscribeOperation = IOT_MQTT_OPERATION_INITIALIZER;\r
-\r
-    /* Flags are not used, but the parameter is present for future compatibility. */\r
-    ( void ) flags;\r
-\r
-    /* Call the asynchronous SUBSCRIBE function. */\r
-    status = IotMqtt_Subscribe( mqttConnection,\r
-                                pSubscriptionList,\r
-                                subscriptionCount,\r
-                                IOT_MQTT_FLAG_WAITABLE,\r
-                                NULL,\r
-                                &subscribeOperation );\r
-\r
-    /* Wait for the SUBSCRIBE operation to complete. */\r
-    if( status == IOT_MQTT_STATUS_PENDING )\r
-    {\r
-        status = IotMqtt_Wait( subscribeOperation, timeoutMs );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Ensure that a status was set. */\r
-    IotMqtt_Assert( status != IOT_MQTT_STATUS_PENDING );\r
-\r
-    return status;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t IotMqtt_Unsubscribe( IotMqttConnection_t mqttConnection,\r
-                                    const IotMqttSubscription_t * pSubscriptionList,\r
-                                    size_t subscriptionCount,\r
-                                    uint32_t flags,\r
-                                    const IotMqttCallbackInfo_t * pCallbackInfo,\r
-                                    IotMqttOperation_t * pUnsubscribeOperation )\r
-{\r
-    return _subscriptionCommon( IOT_MQTT_UNSUBSCRIBE,\r
-                                mqttConnection,\r
-                                pSubscriptionList,\r
-                                subscriptionCount,\r
-                                flags,\r
-                                pCallbackInfo,\r
-                                pUnsubscribeOperation );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t IotMqtt_TimedUnsubscribe( IotMqttConnection_t mqttConnection,\r
-                                         const IotMqttSubscription_t * pSubscriptionList,\r
-                                         size_t subscriptionCount,\r
-                                         uint32_t flags,\r
-                                         uint32_t timeoutMs )\r
-{\r
-    IotMqttError_t status = IOT_MQTT_STATUS_PENDING;\r
-    IotMqttOperation_t unsubscribeOperation = IOT_MQTT_OPERATION_INITIALIZER;\r
-\r
-    /* Flags are not used, but the parameter is present for future compatibility. */\r
-    ( void ) flags;\r
-\r
-    /* Call the asynchronous UNSUBSCRIBE function. */\r
-    status = IotMqtt_Unsubscribe( mqttConnection,\r
-                                  pSubscriptionList,\r
-                                  subscriptionCount,\r
-                                  IOT_MQTT_FLAG_WAITABLE,\r
-                                  NULL,\r
-                                  &unsubscribeOperation );\r
-\r
-    /* Wait for the UNSUBSCRIBE operation to complete. */\r
-    if( status == IOT_MQTT_STATUS_PENDING )\r
-    {\r
-        status = IotMqtt_Wait( unsubscribeOperation, timeoutMs );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Ensure that a status was set. */\r
-    IotMqtt_Assert( status != IOT_MQTT_STATUS_PENDING );\r
-\r
-    return status;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t IotMqtt_Publish( IotMqttConnection_t mqttConnection,\r
-                                const IotMqttPublishInfo_t * pPublishInfo,\r
-                                uint32_t flags,\r
-                                const IotMqttCallbackInfo_t * pCallbackInfo,\r
-                                IotMqttOperation_t * pPublishOperation )\r
-{\r
-    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
-    _mqttOperation_t * pOperation = NULL;\r
-    uint8_t ** pPacketIdentifierHigh = NULL;\r
-\r
-    /* Default PUBLISH serializer function. */\r
-    IotMqttError_t ( * serializePublish )( const IotMqttPublishInfo_t *,\r
-                                           uint8_t **,\r
-                                           size_t *,\r
-                                           uint16_t *,\r
-                                           uint8_t ** ) = _IotMqtt_SerializePublish;\r
-\r
-    /* Check that the PUBLISH information is valid. */\r
-    if( _IotMqtt_ValidatePublish( mqttConnection->awsIotMqttMode,\r
-                                  pPublishInfo ) == false )\r
-    {\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Check that no notification is requested for a QoS 0 publish. */\r
-    if( pPublishInfo->qos == IOT_MQTT_QOS_0 )\r
-    {\r
-        if( pCallbackInfo != NULL )\r
-        {\r
-            IotLogError( "QoS 0 PUBLISH should not have notification parameters set." );\r
-\r
-            IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
-        }\r
-        else if( ( flags & IOT_MQTT_FLAG_WAITABLE ) != 0 )\r
-        {\r
-            IotLogError( "QoS 0 PUBLISH should not have notification parameters set." );\r
-\r
-            IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        if( pPublishOperation != NULL )\r
-        {\r
-            IotLogWarn( "Ignoring reference parameter for QoS 0 publish." );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Check that a reference pointer is provided for a waitable operation. */\r
-    if( ( flags & IOT_MQTT_FLAG_WAITABLE ) == IOT_MQTT_FLAG_WAITABLE )\r
-    {\r
-        if( pPublishOperation == NULL )\r
-        {\r
-            IotLogError( "Reference must be provided for a waitable PUBLISH." );\r
-\r
-            IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Create a PUBLISH operation. */\r
-    status = _IotMqtt_CreateOperation( mqttConnection,\r
-                                       flags,\r
-                                       pCallbackInfo,\r
-                                       &pOperation );\r
-\r
-    if( status != IOT_MQTT_SUCCESS )\r
-    {\r
-        IOT_GOTO_CLEANUP();\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Check the PUBLISH operation data and set the operation type. */\r
-    IotMqtt_Assert( pOperation->u.operation.status == IOT_MQTT_STATUS_PENDING );\r
-    pOperation->u.operation.type = IOT_MQTT_PUBLISH_TO_SERVER;\r
-\r
-    /* Choose a PUBLISH serializer function. */\r
-    #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
-        if( mqttConnection->pSerializer != NULL )\r
-        {\r
-            if( mqttConnection->pSerializer->serialize.publish != NULL )\r
-            {\r
-                serializePublish = mqttConnection->pSerializer->serialize.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
-    /* In AWS IoT MQTT mode, a pointer to the packet identifier must be saved. */\r
-    if( mqttConnection->awsIotMqttMode == true )\r
-    {\r
-        pPacketIdentifierHigh = &( pOperation->u.operation.pPacketIdentifierHigh );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Generate a PUBLISH packet from pPublishInfo. */\r
-    status = serializePublish( pPublishInfo,\r
-                               &( pOperation->u.operation.pMqttPacket ),\r
-                               &( pOperation->u.operation.packetSize ),\r
-                               &( pOperation->u.operation.packetIdentifier ),\r
-                               pPacketIdentifierHigh );\r
-\r
-    if( status != IOT_MQTT_SUCCESS )\r
-    {\r
-        IOT_GOTO_CLEANUP();\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Check the serialized MQTT packet. */\r
-    IotMqtt_Assert( pOperation->u.operation.pMqttPacket != NULL );\r
-    IotMqtt_Assert( pOperation->u.operation.packetSize > 0 );\r
-\r
-    /* Initialize PUBLISH retry if retryLimit is set. */\r
-    if( pPublishInfo->retryLimit > 0 )\r
-    {\r
-        /* A QoS 0 PUBLISH may not be retried. */\r
-        if( pPublishInfo->qos != IOT_MQTT_QOS_0 )\r
-        {\r
-            pOperation->u.operation.retry.limit = pPublishInfo->retryLimit;\r
-            pOperation->u.operation.retry.nextPeriod = pPublishInfo->retryMs;\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Set the reference, if provided. */\r
-    if( pPublishInfo->qos != IOT_MQTT_QOS_0 )\r
-    {\r
-        if( pPublishOperation != NULL )\r
-        {\r
-            *pPublishOperation = pOperation;\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Add the PUBLISH operation to the send queue for network transmission. */\r
-    status = _IotMqtt_ScheduleOperation( pOperation,\r
-                                         _IotMqtt_ProcessSend,\r
-                                         0 );\r
-\r
-    if( status != IOT_MQTT_SUCCESS )\r
-    {\r
-        IotLogError( "(MQTT connection %p) Failed to enqueue PUBLISH for sending.",\r
-                     mqttConnection );\r
-\r
-        /* Clear the previously set (and now invalid) reference. */\r
-        if( pPublishInfo->qos != IOT_MQTT_QOS_0 )\r
-        {\r
-            if( pPublishOperation != NULL )\r
-            {\r
-                *pPublishOperation = IOT_MQTT_OPERATION_INITIALIZER;\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        IOT_GOTO_CLEANUP();\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Clean up the PUBLISH operation if this function fails. Otherwise, set the\r
-     * appropriate return code based on QoS. */\r
-    IOT_FUNCTION_CLEANUP_BEGIN();\r
-\r
-    if( status != IOT_MQTT_SUCCESS )\r
-    {\r
-        if( pOperation != NULL )\r
-        {\r
-            _IotMqtt_DestroyOperation( pOperation );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        if( pPublishInfo->qos > IOT_MQTT_QOS_0 )\r
-        {\r
-            status = IOT_MQTT_STATUS_PENDING;\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        IotLogInfo( "(MQTT connection %p) MQTT PUBLISH operation queued.",\r
-                    mqttConnection );\r
-    }\r
-\r
-    IOT_FUNCTION_CLEANUP_END();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t IotMqtt_TimedPublish( IotMqttConnection_t mqttConnection,\r
-                                     const IotMqttPublishInfo_t * pPublishInfo,\r
-                                     uint32_t flags,\r
-                                     uint32_t timeoutMs )\r
-{\r
-    IotMqttError_t status = IOT_MQTT_STATUS_PENDING;\r
-    IotMqttOperation_t publishOperation = IOT_MQTT_OPERATION_INITIALIZER,\r
-                       * pPublishOperation = NULL;\r
-\r
-    /* Clear the flags. */\r
-    flags = 0;\r
-\r
-    /* Set the waitable flag and reference for QoS 1 PUBLISH. */\r
-    if( pPublishInfo->qos == IOT_MQTT_QOS_1 )\r
-    {\r
-        flags = IOT_MQTT_FLAG_WAITABLE;\r
-        pPublishOperation = &publishOperation;\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Call the asynchronous PUBLISH function. */\r
-    status = IotMqtt_Publish( mqttConnection,\r
-                              pPublishInfo,\r
-                              flags,\r
-                              NULL,\r
-                              pPublishOperation );\r
-\r
-    /* Wait for a queued QoS 1 PUBLISH to complete. */\r
-    if( pPublishInfo->qos == IOT_MQTT_QOS_1 )\r
-    {\r
-        if( status == IOT_MQTT_STATUS_PENDING )\r
-        {\r
-            status = IotMqtt_Wait( publishOperation, timeoutMs );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    return status;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t IotMqtt_Wait( IotMqttOperation_t operation,\r
-                             uint32_t timeoutMs )\r
-{\r
-    IotMqttError_t status = IOT_MQTT_SUCCESS;\r
-    _mqttConnection_t * pMqttConnection = operation->pMqttConnection;\r
-\r
-    /* Validate the given operation reference. */\r
-    if( _IotMqtt_ValidateOperation( operation ) == false )\r
-    {\r
-        status = IOT_MQTT_BAD_PARAMETER;\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Check the MQTT connection status. */\r
-    if( status == IOT_MQTT_SUCCESS )\r
-    {\r
-        IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
-\r
-        if( pMqttConnection->disconnected == true )\r
-        {\r
-            IotLogError( "(MQTT connection %p, %s operation %p) MQTT connection is closed. "\r
-                         "Operation cannot be waited on.",\r
-                         pMqttConnection,\r
-                         IotMqtt_OperationType( operation->u.operation.type ),\r
-                         operation );\r
-\r
-            status = IOT_MQTT_NETWORK_ERROR;\r
-        }\r
-        else\r
-        {\r
-            IotLogInfo( "(MQTT connection %p, %s operation %p) Waiting for operation completion.",\r
-                        pMqttConnection,\r
-                        IotMqtt_OperationType( operation->u.operation.type ),\r
-                        operation );\r
-        }\r
-\r
-        IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
-\r
-        /* Only wait on an operation if the MQTT connection is active. */\r
-        if( status == IOT_MQTT_SUCCESS )\r
-        {\r
-            if( IotSemaphore_TimedWait( &( operation->u.operation.notify.waitSemaphore ),\r
-                                        timeoutMs ) == false )\r
-            {\r
-                status = IOT_MQTT_TIMEOUT;\r
-\r
-                /* Attempt to cancel the job of the timed out operation. */\r
-                ( void ) _IotMqtt_DecrementOperationReferences( operation, true );\r
-\r
-                /* Clean up lingering subscriptions from a timed-out SUBSCRIBE. */\r
-                if( operation->u.operation.type == IOT_MQTT_SUBSCRIBE )\r
-                {\r
-                    IotLogDebug( "(MQTT connection %p, SUBSCRIBE operation %p) Cleaning up"\r
-                                 " subscriptions of timed-out SUBSCRIBE.",\r
-                                 pMqttConnection,\r
-                                 operation );\r
-\r
-                    _IotMqtt_RemoveSubscriptionByPacket( pMqttConnection,\r
-                                                         operation->u.operation.packetIdentifier,\r
-                                                         -1 );\r
-                }\r
-                else\r
-                {\r
-                    EMPTY_ELSE_MARKER;\r
-                }\r
-            }\r
-            else\r
-            {\r
-                /* Retrieve the status of the completed operation. */\r
-                status = operation->u.operation.status;\r
-            }\r
-\r
-            IotLogInfo( "(MQTT connection %p, %s operation %p) Wait complete with result %s.",\r
-                        pMqttConnection,\r
-                        IotMqtt_OperationType( operation->u.operation.type ),\r
-                        operation,\r
-                        IotMqtt_strerror( status ) );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        /* Wait is finished; decrement operation reference count. */\r
-        if( _IotMqtt_DecrementOperationReferences( operation, false ) == true )\r
-        {\r
-            _IotMqtt_DestroyOperation( operation );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    return status;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-const char * IotMqtt_strerror( IotMqttError_t status )\r
-{\r
-    const char * pMessage = NULL;\r
-\r
-    switch( status )\r
-    {\r
-        case IOT_MQTT_SUCCESS:\r
-            pMessage = "SUCCESS";\r
-            break;\r
-\r
-        case IOT_MQTT_STATUS_PENDING:\r
-            pMessage = "PENDING";\r
-            break;\r
-\r
-        case IOT_MQTT_INIT_FAILED:\r
-            pMessage = "INITIALIZATION FAILED";\r
-            break;\r
-\r
-        case IOT_MQTT_BAD_PARAMETER:\r
-            pMessage = "BAD PARAMETER";\r
-            break;\r
-\r
-        case IOT_MQTT_NO_MEMORY:\r
-            pMessage = "NO MEMORY";\r
-            break;\r
-\r
-        case IOT_MQTT_NETWORK_ERROR:\r
-            pMessage = "NETWORK ERROR";\r
-            break;\r
-\r
-        case IOT_MQTT_SCHEDULING_ERROR:\r
-            pMessage = "SCHEDULING ERROR";\r
-            break;\r
-\r
-        case IOT_MQTT_BAD_RESPONSE:\r
-            pMessage = "BAD RESPONSE RECEIVED";\r
-            break;\r
-\r
-        case IOT_MQTT_TIMEOUT:\r
-            pMessage = "TIMEOUT";\r
-            break;\r
-\r
-        case IOT_MQTT_SERVER_REFUSED:\r
-            pMessage = "SERVER REFUSED";\r
-            break;\r
-\r
-        case IOT_MQTT_RETRY_NO_RESPONSE:\r
-            pMessage = "NO RESPONSE";\r
-            break;\r
-\r
-        default:\r
-            pMessage = "INVALID STATUS";\r
-            break;\r
-    }\r
-\r
-    return pMessage;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-const char * IotMqtt_OperationType( IotMqttOperationType_t operation )\r
-{\r
-    const char * pMessage = NULL;\r
-\r
-    switch( operation )\r
-    {\r
-        case IOT_MQTT_CONNECT:\r
-            pMessage = "CONNECT";\r
-            break;\r
-\r
-        case IOT_MQTT_PUBLISH_TO_SERVER:\r
-            pMessage = "PUBLISH";\r
-            break;\r
-\r
-        case IOT_MQTT_PUBACK:\r
-            pMessage = "PUBACK";\r
-            break;\r
-\r
-        case IOT_MQTT_SUBSCRIBE:\r
-            pMessage = "SUBSCRIBE";\r
-            break;\r
-\r
-        case IOT_MQTT_UNSUBSCRIBE:\r
-            pMessage = "UNSUBSCRIBE";\r
-            break;\r
-\r
-        case IOT_MQTT_PINGREQ:\r
-            pMessage = "PINGREQ";\r
-            break;\r
-\r
-        case IOT_MQTT_DISCONNECT:\r
-            pMessage = "DISCONNECT";\r
-            break;\r
-\r
-        default:\r
-            pMessage = "INVALID OPERATION";\r
-            break;\r
-    }\r
-\r
-    return pMessage;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/* Provide access to internal functions and variables if testing. */\r
-#if IOT_BUILD_TESTS == 1\r
-    #include "iot_test_access_mqtt_api.c"\r
-#endif\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_mqtt_network.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_mqtt_network.c
deleted file mode 100644 (file)
index 169a292..0000000
+++ /dev/null
@@ -1,912 +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
-/*-----------------------------------------------------------*/\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
-\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
-            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
-                IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
-\r
-                if( pMqttConnection->keepAliveFailure == false )\r
-                {\r
-                    IotLogWarn( "(MQTT connection %p) Unexpected PINGRESP received.",\r
-                                pMqttConnection );\r
-                }\r
-                else\r
-                {\r
-                    IotLogDebug( "(MQTT connection %p) PINGRESP successfully parsed.",\r
-                                 pMqttConnection );\r
-\r
-                    pMqttConnection->keepAliveFailure = false;\r
-                }\r
-\r
-                IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\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 serializeStatus = IOT_MQTT_SUCCESS;\r
-    uint8_t * pPuback = NULL;\r
-    size_t pubackSize = 0, bytesSent = 0;\r
-\r
-    /* Default PUBACK serializer and free packet functions. */\r
-    IotMqttError_t ( * serializePuback )( uint16_t,\r
-                                          uint8_t **,\r
-                                          size_t * ) = _IotMqtt_SerializePuback;\r
-    void ( * freePacket )( uint8_t * ) = _IotMqtt_FreePacket;\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
-    #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
-            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
-    /* Generate a PUBACK packet from the packet identifier. */\r
-    serializeStatus = serializePuback( packetIdentifier,\r
-                                       &pPuback,\r
-                                       &pubackSize );\r
-\r
-    if( serializeStatus != IOT_MQTT_SUCCESS )\r
-    {\r
-        IotLogWarn( "(MQTT connection %p) Failed to generate PUBACK packet for "\r
-                    "received PUBLISH %hu.",\r
-                    pMqttConnection,\r
-                    packetIdentifier );\r
-    }\r
-    else\r
-    {\r
-        bytesSent = pMqttConnection->pNetworkInterface->send( pMqttConnection->pNetworkConnection,\r
-                                                              pPuback,\r
-                                                              pubackSize );\r
-\r
-        if( bytesSent != pubackSize )\r
-        {\r
-            IotLogWarn( "(MQTT connection %p) Failed to send PUBACK for received"\r
-                        " PUBLISH %hu.",\r
-                        pMqttConnection,\r
-                        packetIdentifier );\r
-        }\r
-        else\r
-        {\r
-            IotLogDebug( "(MQTT connection %p) PUBACK for received PUBLISH %hu sent.",\r
-                         pMqttConnection,\r
-                         packetIdentifier );\r
-        }\r
-\r
-        freePacket( pPuback );\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
-\r
-    /* Mark the MQTT connection as disconnected and the keep-alive as failed. */\r
-    IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
-    pMqttConnection->disconnected = true;\r
-    pMqttConnection->keepAliveFailure = true;\r
-\r
-    if( pMqttConnection->keepAliveMs != 0 )\r
-    {\r
-        /* Keep-alive must have a PINGREQ allocated. */\r
-        IotMqtt_Assert( pMqttConnection->pPingreqPacket != NULL );\r
-        IotMqtt_Assert( pMqttConnection->pingreqPacketSize != 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->keepAliveJob,\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
-            /* Clean up PINGREQ packet and job. */\r
-            _IotMqtt_FreePacket( pMqttConnection->pPingreqPacket );\r
-\r
-            /* Clear data about the keep-alive. */\r
-            pMqttConnection->keepAliveMs = 0;\r
-            pMqttConnection->pPingreqPacket = NULL;\r
-            pMqttConnection->pingreqPacketSize = 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
-    IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
-\r
-    /* Close the network connection. */\r
-    if( pMqttConnection->pNetworkInterface->close != NULL )\r
-    {\r
-        closeStatus = pMqttConnection->pNetworkInterface->close( pMqttConnection->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( pMqttConnection->disconnectCallback.function != NULL )\r
-    {\r
-        /* Set the members of the callback parameter. */\r
-        callbackParam.mqttConnection = pMqttConnection;\r
-        callbackParam.u.disconnectReason = disconnectReason;\r
-\r
-        pMqttConnection->disconnectCallback.function( pMqttConnection->disconnectCallback.pCallbackContext,\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
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_mqtt_operation.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_mqtt_operation.c
deleted file mode 100644 (file)
index 7923d62..0000000
+++ /dev/null
@@ -1,1332 +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_operation.c\r
- * @brief Implements functions that process MQTT operations.\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_clock.h"\r
-#include "platform/iot_threads.h"\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/**\r
- * @brief First parameter to #_mqttOperation_match.\r
- */\r
-typedef struct _operationMatchParam\r
-{\r
-    IotMqttOperationType_t type;        /**< @brief The type of operation to look for. */\r
-    const uint16_t * pPacketIdentifier; /**< @brief The packet identifier associated with the operation.\r
-                                         * Set to `NULL` to ignore packet identifier. */\r
-} _operationMatchParam_t;\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/**\r
- * @brief Match an MQTT operation by type and packet identifier.\r
- *\r
- * @param[in] pOperationLink Pointer to the link member of an #_mqttOperation_t.\r
- * @param[in] pMatch Pointer to an #_operationMatchParam_t.\r
- *\r
- * @return `true` if the operation matches the parameters in `pArgument`; `false`\r
- * otherwise.\r
- */\r
-static bool _mqttOperation_match( const IotLink_t * pOperationLink,\r
-                                  void * pMatch );\r
-\r
-/**\r
- * @brief Check if an operation with retry has exceeded its retry limit.\r
- *\r
- * If a PUBLISH operation is available for retry, this function also sets any\r
- * necessary DUP flags.\r
- *\r
- * @param[in] pOperation The operation to check.\r
- *\r
- * @return `true` if the operation may be retried; `false` otherwise.\r
- */\r
-static bool _checkRetryLimit( _mqttOperation_t * pOperation );\r
-\r
-/**\r
- * @brief Schedule the next send of an operation with retry.\r
- *\r
- * @param[in] pOperation The operation to schedule.\r
- *\r
- * @return `true` if the reschedule succeeded; `false` otherwise.\r
- */\r
-static bool _scheduleNextRetry( _mqttOperation_t * pOperation );\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static bool _mqttOperation_match( const IotLink_t * pOperationLink,\r
-                                  void * pMatch )\r
-{\r
-    bool match = false;\r
-\r
-    /* Because this function is called from a container function, the given link\r
-     * must never be NULL. */\r
-    IotMqtt_Assert( pOperationLink != NULL );\r
-\r
-    _mqttOperation_t * pOperation = IotLink_Container( _mqttOperation_t,\r
-                                                       pOperationLink,\r
-                                                       link );\r
-    _operationMatchParam_t * pParam = ( _operationMatchParam_t * ) pMatch;\r
-\r
-    /* Check for matching operations. */\r
-    if( pParam->type == pOperation->u.operation.type )\r
-    {\r
-        /* Check for matching packet identifiers. */\r
-        if( pParam->pPacketIdentifier == NULL )\r
-        {\r
-            match = true;\r
-        }\r
-        else\r
-        {\r
-            match = ( *( pParam->pPacketIdentifier ) == pOperation->u.operation.packetIdentifier );\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    return match;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static bool _checkRetryLimit( _mqttOperation_t * pOperation )\r
-{\r
-    _mqttConnection_t * pMqttConnection = pOperation->pMqttConnection;\r
-    bool status = true;\r
-\r
-    /* Choose a set DUP function. */\r
-    void ( * publishSetDup )( uint8_t *,\r
-                              uint8_t *,\r
-                              uint16_t * ) = _IotMqtt_PublishSetDup;\r
-\r
-    #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
-        if( pMqttConnection->pSerializer != NULL )\r
-        {\r
-            if( pMqttConnection->pSerializer->serialize.publishSetDup != NULL )\r
-            {\r
-                publishSetDup = pMqttConnection->pSerializer->serialize.publishSetDup;\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
-    /* Only PUBLISH may be retried. */\r
-    IotMqtt_Assert( pOperation->u.operation.type == IOT_MQTT_PUBLISH_TO_SERVER );\r
-\r
-    /* Check if the retry limit is exhausted. */\r
-    if( pOperation->u.operation.retry.count > pOperation->u.operation.retry.limit )\r
-    {\r
-        /* The retry count may be at most one more than the retry limit, which\r
-         * accounts for the final check for a PUBACK. */\r
-        IotMqtt_Assert( pOperation->u.operation.retry.count == pOperation->u.operation.retry.limit + 1 );\r
-\r
-        IotLogDebug( "(MQTT connection %p, PUBLISH operation %p) No response received after %lu retries.",\r
-                     pMqttConnection,\r
-                     pOperation,\r
-                     pOperation->u.operation.retry.limit );\r
-\r
-        status = false;\r
-    }\r
-    /* Check if this is the first retry. */\r
-    else if( pOperation->u.operation.retry.count == 1 )\r
-    {\r
-        /* Always set the DUP flag on the first retry. */\r
-        publishSetDup( pOperation->u.operation.pMqttPacket,\r
-                       pOperation->u.operation.pPacketIdentifierHigh,\r
-                       &( pOperation->u.operation.packetIdentifier ) );\r
-    }\r
-    else\r
-    {\r
-        /* In AWS IoT MQTT mode, the DUP flag (really a change to the packet\r
-         * identifier) must be reset on every retry. */\r
-        if( pMqttConnection->awsIotMqttMode == true )\r
-        {\r
-            publishSetDup( pOperation->u.operation.pMqttPacket,\r
-                           pOperation->u.operation.pPacketIdentifierHigh,\r
-                           &( pOperation->u.operation.packetIdentifier ) );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-\r
-    return status;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static bool _scheduleNextRetry( _mqttOperation_t * pOperation )\r
-{\r
-    bool firstRetry = false;\r
-    uint32_t scheduleDelay = 0;\r
-    IotMqttError_t status = IOT_MQTT_STATUS_PENDING;\r
-    _mqttConnection_t * pMqttConnection = pOperation->pMqttConnection;\r
-\r
-    /* This function should never be called with retry count greater than\r
-     * retry limit. */\r
-    IotMqtt_Assert( pOperation->u.operation.retry.count <= pOperation->u.operation.retry.limit );\r
-\r
-    /* Increment the retry count. */\r
-    ( pOperation->u.operation.retry.count )++;\r
-\r
-    /* Check for a response shortly for the final retry. Otherwise, calculate the\r
-     * next retry period. */\r
-    if( pOperation->u.operation.retry.count > pOperation->u.operation.retry.limit )\r
-    {\r
-        scheduleDelay = IOT_MQTT_RESPONSE_WAIT_MS;\r
-\r
-        IotLogDebug( "(MQTT connection %p, PUBLISH operation %p) Final retry was sent. Will check "\r
-                     "for response in %d ms.",\r
-                     pMqttConnection,\r
-                     pOperation,\r
-                     IOT_MQTT_RESPONSE_WAIT_MS );\r
-    }\r
-    else\r
-    {\r
-        scheduleDelay = pOperation->u.operation.retry.nextPeriod;\r
-\r
-        /* Double the retry period, subject to a ceiling value. */\r
-        pOperation->u.operation.retry.nextPeriod *= 2;\r
-\r
-        if( pOperation->u.operation.retry.nextPeriod > IOT_MQTT_RETRY_MS_CEILING )\r
-        {\r
-            pOperation->u.operation.retry.nextPeriod = IOT_MQTT_RETRY_MS_CEILING;\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        IotLogDebug( "(MQTT connection %p, PUBLISH operation %p) Scheduling retry %lu of %lu in %lu ms.",\r
-                     pMqttConnection,\r
-                     pOperation,\r
-                     ( unsigned long ) pOperation->u.operation.retry.count,\r
-                     ( unsigned long ) pOperation->u.operation.retry.limit,\r
-                     ( unsigned long ) scheduleDelay );\r
-\r
-        /* Check if this is the first retry. */\r
-        firstRetry = ( pOperation->u.operation.retry.count == 1 );\r
-\r
-        /* On the first retry, the PUBLISH will be moved from the pending processing\r
-         * list to the pending responses list. Lock the connection references mutex\r
-         * to manipulate the lists. */\r
-        if( firstRetry == true )\r
-        {\r
-            IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-\r
-    /* Reschedule the PUBLISH for another send. */\r
-    status = _IotMqtt_ScheduleOperation( pOperation,\r
-                                         _IotMqtt_ProcessSend,\r
-                                         scheduleDelay );\r
-\r
-    /* Check for successful reschedule. */\r
-    if( status == IOT_MQTT_SUCCESS )\r
-    {\r
-        /* Move a successfully rescheduled PUBLISH from the pending processing\r
-         * list to the pending responses list on the first retry. */\r
-        if( firstRetry == true )\r
-        {\r
-            /* Operation must be linked. */\r
-            IotMqtt_Assert( IotLink_IsLinked( &( pOperation->link ) ) == true );\r
-\r
-            /* Transfer to pending response list. */\r
-            IotListDouble_Remove( &( pOperation->link ) );\r
-            IotListDouble_InsertHead( &( pMqttConnection->pendingResponse ),\r
-                                      &( pOperation->link ) );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* The references mutex only needs to be unlocked on the first retry, since\r
-     * only the first retry manipulates the connection lists. */\r
-    if( firstRetry == true )\r
-    {\r
-        IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    return( status == IOT_MQTT_SUCCESS );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t _IotMqtt_CreateOperation( _mqttConnection_t * pMqttConnection,\r
-                                         uint32_t flags,\r
-                                         const IotMqttCallbackInfo_t * pCallbackInfo,\r
-                                         _mqttOperation_t ** pNewOperation )\r
-{\r
-    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
-    bool decrementOnError = false;\r
-    _mqttOperation_t * pOperation = NULL;\r
-    bool waitable = ( ( flags & IOT_MQTT_FLAG_WAITABLE ) == IOT_MQTT_FLAG_WAITABLE );\r
-\r
-    /* If the waitable flag is set, make sure that there's no callback. */\r
-    if( waitable == true )\r
-    {\r
-        if( pCallbackInfo != NULL )\r
-        {\r
-            IotLogError( "Callback should not be set for a waitable operation." );\r
-\r
-            return IOT_MQTT_BAD_PARAMETER;\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    IotLogDebug( "(MQTT connection %p) Creating new operation record.",\r
-                 pMqttConnection );\r
-\r
-    /* Increment the reference count for the MQTT connection when creating a new\r
-     * operation. */\r
-    if( _IotMqtt_IncrementConnectionReferences( pMqttConnection ) == false )\r
-    {\r
-        IotLogError( "(MQTT connection %p) New operation record cannot be created"\r
-                     " for a closed connection",\r
-                     pMqttConnection );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NETWORK_ERROR );\r
-    }\r
-    else\r
-    {\r
-        /* Reference count will need to be decremented on error. */\r
-        decrementOnError = true;\r
-    }\r
-\r
-    /* Allocate memory for a new operation. */\r
-    pOperation = IotMqtt_MallocOperation( sizeof( _mqttOperation_t ) );\r
-\r
-    if( pOperation == NULL )\r
-    {\r
-        IotLogError( "(MQTT connection %p) Failed to allocate memory for new "\r
-                     "operation record.",\r
-                     pMqttConnection );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NO_MEMORY );\r
-    }\r
-    else\r
-    {\r
-        /* Clear the operation data. */\r
-        ( void ) memset( pOperation, 0x00, sizeof( _mqttOperation_t ) );\r
-\r
-        /* Initialize some members of the new operation. */\r
-        pOperation->pMqttConnection = pMqttConnection;\r
-        pOperation->u.operation.jobReference = 1;\r
-        pOperation->u.operation.flags = flags;\r
-        pOperation->u.operation.status = IOT_MQTT_STATUS_PENDING;\r
-    }\r
-\r
-    /* Check if the waitable flag is set. If it is, create a semaphore to\r
-     * wait on. */\r
-    if( waitable == true )\r
-    {\r
-        /* Create a semaphore to wait on for a waitable operation. */\r
-        if( IotSemaphore_Create( &( pOperation->u.operation.notify.waitSemaphore ), 0, 1 ) == false )\r
-        {\r
-            IotLogError( "(MQTT connection %p) Failed to create semaphore for "\r
-                         "waitable operation.",\r
-                         pMqttConnection );\r
-\r
-            IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NO_MEMORY );\r
-        }\r
-        else\r
-        {\r
-            /* A waitable operation is created with an additional reference for the\r
-             * Wait function. */\r
-            ( pOperation->u.operation.jobReference )++;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        /* If the waitable flag isn't set but a callback is, copy the callback\r
-         * information. */\r
-        if( pCallbackInfo != NULL )\r
-        {\r
-            pOperation->u.operation.notify.callback = *pCallbackInfo;\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-\r
-    /* Add this operation to the MQTT connection's operation list. */\r
-    IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
-    IotListDouble_InsertHead( &( pMqttConnection->pendingProcessing ),\r
-                              &( pOperation->link ) );\r
-    IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
-\r
-    /* Set the output parameter. */\r
-    *pNewOperation = pOperation;\r
-\r
-    /* Clean up operation and decrement reference count if this function failed. */\r
-    IOT_FUNCTION_CLEANUP_BEGIN();\r
-\r
-    if( status != IOT_MQTT_SUCCESS )\r
-    {\r
-        if( decrementOnError == true )\r
-        {\r
-            _IotMqtt_DecrementConnectionReferences( pMqttConnection );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        if( pOperation != NULL )\r
-        {\r
-            IotMqtt_FreeOperation( pOperation );\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
-bool _IotMqtt_DecrementOperationReferences( _mqttOperation_t * pOperation,\r
-                                            bool cancelJob )\r
-{\r
-    bool destroyOperation = false;\r
-    IotTaskPoolError_t taskPoolStatus = IOT_TASKPOOL_SUCCESS;\r
-    _mqttConnection_t * pMqttConnection = pOperation->pMqttConnection;\r
-\r
-    /* Attempt to cancel the operation's job. */\r
-    if( cancelJob == true )\r
-    {\r
-        taskPoolStatus = IotTaskPool_TryCancel( IOT_SYSTEM_TASKPOOL,\r
-                                                pOperation->job,\r
-                                                NULL );\r
-\r
-        /* If the operation's 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
-        if( taskPoolStatus == IOT_TASKPOOL_SUCCESS )\r
-        {\r
-            IotLogDebug( "(MQTT connection %p, %s operation %p) Job canceled.",\r
-                         pMqttConnection,\r
-                         IotMqtt_OperationType( pOperation->u.operation.type ),\r
-                         pOperation );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Decrement job reference count. */\r
-    if( taskPoolStatus == IOT_TASKPOOL_SUCCESS )\r
-    {\r
-        IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
-        pOperation->u.operation.jobReference--;\r
-\r
-        IotLogDebug( "(MQTT connection %p, %s operation %p) Job reference changed"\r
-                     " from %ld to %ld.",\r
-                     pMqttConnection,\r
-                     IotMqtt_OperationType( pOperation->u.operation.type ),\r
-                     pOperation,\r
-                     pOperation->u.operation.jobReference + 1,\r
-                     pOperation->u.operation.jobReference );\r
-\r
-        /* The job reference count must be 0 or 1 after the decrement. */\r
-        IotMqtt_Assert( ( pOperation->u.operation.jobReference == 0 ) ||\r
-                        ( pOperation->u.operation.jobReference == 1 ) );\r
-\r
-        /* This operation may be destroyed if its reference count is 0. */\r
-        if( pOperation->u.operation.jobReference == 0 )\r
-        {\r
-            destroyOperation = true;\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    return destroyOperation;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void _IotMqtt_DestroyOperation( _mqttOperation_t * pOperation )\r
-{\r
-    _mqttConnection_t * pMqttConnection = pOperation->pMqttConnection;\r
-\r
-    /* Default free packet function. */\r
-    void ( * freePacket )( uint8_t * ) = _IotMqtt_FreePacket;\r
-\r
-    IotLogDebug( "(MQTT connection %p, %s operation %p) Destroying operation.",\r
-                 pMqttConnection,\r
-                 IotMqtt_OperationType( pOperation->u.operation.type ),\r
-                 pOperation );\r
-\r
-    /* The job reference count must be between 0 and 2. */\r
-    IotMqtt_Assert( ( pOperation->u.operation.jobReference >= 0 ) &&\r
-                    ( pOperation->u.operation.jobReference <= 2 ) );\r
-\r
-    /* Jobs to be destroyed should be removed from the MQTT connection's\r
-     * lists. */\r
-    IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
-\r
-    if( IotLink_IsLinked( &( pOperation->link ) ) == true )\r
-    {\r
-        IotLogDebug( "(MQTT connection %p, %s operation %p) Removed operation from connection lists.",\r
-                     pMqttConnection,\r
-                     IotMqtt_OperationType( pOperation->u.operation.type ),\r
-                     pOperation,\r
-                     pMqttConnection );\r
-\r
-        IotListDouble_Remove( &( pOperation->link ) );\r
-    }\r
-    else\r
-    {\r
-        IotLogDebug( "(MQTT connection %p, %s operation %p) Operation was not present in connection lists.",\r
-                     pMqttConnection,\r
-                     IotMqtt_OperationType( pOperation->u.operation.type ),\r
-                     pOperation );\r
-    }\r
-\r
-    IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
-\r
-    /* Free any allocated MQTT packet. */\r
-    if( pOperation->u.operation.pMqttPacket != NULL )\r
-    {\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
-                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
-        freePacket( pOperation->u.operation.pMqttPacket );\r
-\r
-        IotLogDebug( "(MQTT connection %p, %s operation %p) MQTT packet freed.",\r
-                     pMqttConnection,\r
-                     IotMqtt_OperationType( pOperation->u.operation.type ),\r
-                     pOperation );\r
-    }\r
-    else\r
-    {\r
-        IotLogDebug( "(MQTT connection %p, %s operation %p) Operation has no allocated MQTT packet.",\r
-                     pMqttConnection,\r
-                     IotMqtt_OperationType( pOperation->u.operation.type ),\r
-                     pOperation );\r
-    }\r
-\r
-    /* Check if a wait semaphore was created for this operation. */\r
-    if( ( pOperation->u.operation.flags & IOT_MQTT_FLAG_WAITABLE ) == IOT_MQTT_FLAG_WAITABLE )\r
-    {\r
-        IotSemaphore_Destroy( &( pOperation->u.operation.notify.waitSemaphore ) );\r
-\r
-        IotLogDebug( "(MQTT connection %p, %s operation %p) Wait semaphore destroyed.",\r
-                     pMqttConnection,\r
-                     IotMqtt_OperationType( pOperation->u.operation.type ),\r
-                     pOperation );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    IotLogDebug( "(MQTT connection %p, %s operation %p) Operation record destroyed.",\r
-                 pMqttConnection,\r
-                 IotMqtt_OperationType( pOperation->u.operation.type ),\r
-                 pOperation );\r
-\r
-    /* Free the memory used to hold operation data. */\r
-    IotMqtt_FreeOperation( pOperation );\r
-\r
-    /* Decrement the MQTT connection's reference count after destroying an\r
-     * operation. */\r
-    _IotMqtt_DecrementConnectionReferences( pMqttConnection );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void _IotMqtt_ProcessKeepAlive( IotTaskPool_t pTaskPool,\r
-                                IotTaskPoolJob_t pKeepAliveJob,\r
-                                void * pContext )\r
-{\r
-    bool status = true;\r
-    IotTaskPoolError_t taskPoolStatus = IOT_TASKPOOL_SUCCESS;\r
-    size_t bytesSent = 0;\r
-\r
-    /* Retrieve the MQTT connection from the context. */\r
-    _mqttConnection_t * pMqttConnection = ( _mqttConnection_t * ) pContext;\r
-\r
-    /* Check parameters. */\r
-    IotMqtt_Assert( pTaskPool == IOT_SYSTEM_TASKPOOL );\r
-    IotMqtt_Assert( pKeepAliveJob == pMqttConnection->keepAliveJob );\r
-\r
-    /* Check that keep-alive interval is valid. The MQTT spec states its maximum\r
-     * value is 65,535 seconds. */\r
-    IotMqtt_Assert( pMqttConnection->keepAliveMs <= 65535000 );\r
-\r
-    /* Only two values are valid for the next keep alive job delay. */\r
-    IotMqtt_Assert( ( pMqttConnection->nextKeepAliveMs == pMqttConnection->keepAliveMs ) ||\r
-                    ( pMqttConnection->nextKeepAliveMs == IOT_MQTT_RESPONSE_WAIT_MS ) );\r
-\r
-    IotLogDebug( "(MQTT connection %p) Keep-alive job started.", pMqttConnection );\r
-\r
-    /* Re-create the keep-alive job for rescheduling. This should never fail. */\r
-    taskPoolStatus = IotTaskPool_CreateJob( _IotMqtt_ProcessKeepAlive,\r
-                                            pContext,\r
-                                            IotTaskPool_GetJobStorageFromHandle( pKeepAliveJob ),\r
-                                            &pKeepAliveJob );\r
-    IotMqtt_Assert( taskPoolStatus == IOT_TASKPOOL_SUCCESS );\r
-\r
-    IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
-\r
-    /* Determine whether to send a PINGREQ or check for PINGRESP. */\r
-    if( pMqttConnection->nextKeepAliveMs == pMqttConnection->keepAliveMs )\r
-    {\r
-        IotLogDebug( "(MQTT connection %p) Sending PINGREQ.", pMqttConnection );\r
-\r
-        /* Because PINGREQ may be used to keep the MQTT connection alive, it is\r
-         * more important than other operations. Bypass the queue of jobs for\r
-         * operations by directly sending the PINGREQ in this job. */\r
-        bytesSent = pMqttConnection->pNetworkInterface->send( pMqttConnection->pNetworkConnection,\r
-                                                              pMqttConnection->pPingreqPacket,\r
-                                                              pMqttConnection->pingreqPacketSize );\r
-\r
-        if( bytesSent != pMqttConnection->pingreqPacketSize )\r
-        {\r
-            IotLogError( "(MQTT connection %p) Failed to send PINGREQ.", pMqttConnection );\r
-            status = false;\r
-        }\r
-        else\r
-        {\r
-            /* Assume the keep-alive will fail. The network receive callback will\r
-             * clear the failure flag upon receiving a PINGRESP. */\r
-            pMqttConnection->keepAliveFailure = true;\r
-\r
-            /* Schedule a check for PINGRESP. */\r
-            pMqttConnection->nextKeepAliveMs = IOT_MQTT_RESPONSE_WAIT_MS;\r
-\r
-            IotLogDebug( "(MQTT connection %p) PINGREQ sent. Scheduling check for PINGRESP in %d ms.",\r
-                         pMqttConnection,\r
-                         IOT_MQTT_RESPONSE_WAIT_MS );\r
-        }\r
-    }\r
-    else\r
-    {\r
-        IotLogDebug( "(MQTT connection %p) Checking for PINGRESP.", pMqttConnection );\r
-\r
-        if( pMqttConnection->keepAliveFailure == false )\r
-        {\r
-            IotLogDebug( "(MQTT connection %p) PINGRESP was received.", pMqttConnection );\r
-\r
-            /* PINGRESP was received. Schedule the next PINGREQ transmission. */\r
-            pMqttConnection->nextKeepAliveMs = pMqttConnection->keepAliveMs;\r
-        }\r
-        else\r
-        {\r
-            IotLogError( "(MQTT connection %p) Failed to receive PINGRESP within %d ms.",\r
-                         pMqttConnection,\r
-                         IOT_MQTT_RESPONSE_WAIT_MS );\r
-\r
-            /* The network receive callback did not clear the failure flag. */\r
-            status = false;\r
-        }\r
-    }\r
-\r
-    /* When a PINGREQ is successfully sent, reschedule this job to check for a\r
-     * response shortly. */\r
-    if( status == true )\r
-    {\r
-        taskPoolStatus = IotTaskPool_ScheduleDeferred( pTaskPool,\r
-                                                       pKeepAliveJob,\r
-                                                       pMqttConnection->nextKeepAliveMs );\r
-\r
-        if( taskPoolStatus == IOT_TASKPOOL_SUCCESS )\r
-        {\r
-            IotLogDebug( "(MQTT connection %p) Next keep-alive job in %d ms.",\r
-                         pMqttConnection,\r
-                         IOT_MQTT_RESPONSE_WAIT_MS );\r
-        }\r
-        else\r
-        {\r
-            IotLogError( "(MQTT connection %p) Failed to reschedule keep-alive job, error %s.",\r
-                         pMqttConnection,\r
-                         IotTaskPool_strerror( taskPoolStatus ) );\r
-\r
-            status = false;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Close the connection on failures. */\r
-    if( status == false )\r
-    {\r
-        _IotMqtt_CloseNetworkConnection( IOT_MQTT_KEEP_ALIVE_TIMEOUT,\r
-                                         pMqttConnection );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void _IotMqtt_ProcessIncomingPublish( IotTaskPool_t pTaskPool,\r
-                                      IotTaskPoolJob_t pPublishJob,\r
-                                      void * pContext )\r
-{\r
-    _mqttOperation_t * pOperation = pContext;\r
-    IotMqttCallbackParam_t callbackParam = { .mqttConnection = NULL };\r
-\r
-    /* Check parameters. The task pool and job parameter is not used when asserts\r
-     * are disabled. */\r
-    ( void ) pTaskPool;\r
-    ( void ) pPublishJob;\r
-    IotMqtt_Assert( pTaskPool == IOT_SYSTEM_TASKPOOL );\r
-    IotMqtt_Assert( pOperation->incomingPublish == true );\r
-    IotMqtt_Assert( pPublishJob == pOperation->job );\r
-\r
-    /* Remove the operation from the pending processing list. */\r
-    IotMutex_Lock( &( pOperation->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( &( pOperation->pMqttConnection->referencesMutex ) );\r
-\r
-    /* Process the current PUBLISH. */\r
-    callbackParam.u.message.info = pOperation->u.publish.publishInfo;\r
-\r
-    _IotMqtt_InvokeSubscriptionCallback( pOperation->pMqttConnection,\r
-                                         &callbackParam );\r
-\r
-    /* Free any buffers associated with the current PUBLISH message. */\r
-    if( pOperation->u.publish.pReceivedData != NULL )\r
-    {\r
-        IotMqtt_FreeMessage( ( void * ) pOperation->u.publish.pReceivedData );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Free the incoming PUBLISH operation. */\r
-    IotMqtt_FreeOperation( pOperation );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void _IotMqtt_ProcessSend( IotTaskPool_t pTaskPool,\r
-                           IotTaskPoolJob_t pSendJob,\r
-                           void * pContext )\r
-{\r
-    size_t bytesSent = 0;\r
-    bool destroyOperation = false, waitable = false, networkPending = false;\r
-    _mqttOperation_t * pOperation = ( _mqttOperation_t * ) pContext;\r
-    _mqttConnection_t * pMqttConnection = pOperation->pMqttConnection;\r
-\r
-    /* Check parameters. The task pool and job parameter is not used when asserts\r
-     * are disabled. */\r
-    ( void ) pTaskPool;\r
-    ( void ) pSendJob;\r
-    IotMqtt_Assert( pTaskPool == IOT_SYSTEM_TASKPOOL );\r
-    IotMqtt_Assert( pSendJob == pOperation->job );\r
-\r
-    /* The given operation must have an allocated packet and be waiting for a status. */\r
-    IotMqtt_Assert( pOperation->u.operation.pMqttPacket != NULL );\r
-    IotMqtt_Assert( pOperation->u.operation.packetSize != 0 );\r
-    IotMqtt_Assert( pOperation->u.operation.status == IOT_MQTT_STATUS_PENDING );\r
-\r
-    /* Check if this operation is waitable. */\r
-    waitable = ( pOperation->u.operation.flags & IOT_MQTT_FLAG_WAITABLE ) == IOT_MQTT_FLAG_WAITABLE;\r
-\r
-    /* Check PUBLISH retry counts and limits. */\r
-    if( pOperation->u.operation.retry.limit > 0 )\r
-    {\r
-        if( _checkRetryLimit( pOperation ) == false )\r
-        {\r
-            pOperation->u.operation.status = IOT_MQTT_RETRY_NO_RESPONSE;\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Send an operation that is waiting for a response. */\r
-    if( pOperation->u.operation.status == IOT_MQTT_STATUS_PENDING )\r
-    {\r
-        IotLogDebug( "(MQTT connection %p, %s operation %p) Sending MQTT packet.",\r
-                     pMqttConnection,\r
-                     IotMqtt_OperationType( pOperation->u.operation.type ),\r
-                     pOperation );\r
-\r
-        /* Transmit the MQTT packet from the operation over the network. */\r
-        bytesSent = pMqttConnection->pNetworkInterface->send( pMqttConnection->pNetworkConnection,\r
-                                                              pOperation->u.operation.pMqttPacket,\r
-                                                              pOperation->u.operation.packetSize );\r
-\r
-        /* Check transmission status. */\r
-        if( bytesSent != pOperation->u.operation.packetSize )\r
-        {\r
-            pOperation->u.operation.status = IOT_MQTT_NETWORK_ERROR;\r
-        }\r
-        else\r
-        {\r
-            /* DISCONNECT operations are considered successful upon successful\r
-             * transmission. In addition, non-waitable operations with no callback\r
-             * may also be considered successful. */\r
-            if( pOperation->u.operation.type == IOT_MQTT_DISCONNECT )\r
-            {\r
-                /* DISCONNECT operations are always waitable. */\r
-                IotMqtt_Assert( waitable == true );\r
-\r
-                pOperation->u.operation.status = IOT_MQTT_SUCCESS;\r
-            }\r
-            else if( waitable == false )\r
-            {\r
-                if( pOperation->u.operation.notify.callback.function == NULL )\r
-                {\r
-                    pOperation->u.operation.status = IOT_MQTT_SUCCESS;\r
-                }\r
-                else\r
-                {\r
-                    EMPTY_ELSE_MARKER;\r
-                }\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Check if this operation requires further processing. */\r
-    if( pOperation->u.operation.status == IOT_MQTT_STATUS_PENDING )\r
-    {\r
-        /* Check if this operation should be scheduled for retransmission. */\r
-        if( pOperation->u.operation.retry.limit > 0 )\r
-        {\r
-            if( _scheduleNextRetry( pOperation ) == false )\r
-            {\r
-                pOperation->u.operation.status = IOT_MQTT_SCHEDULING_ERROR;\r
-            }\r
-            else\r
-            {\r
-                /* A successfully scheduled PUBLISH retry is awaiting a response\r
-                 * from the network. */\r
-                networkPending = true;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            /* Decrement reference count to signal completion of send job. Check\r
-             * if the operation should be destroyed. */\r
-            if( waitable == true )\r
-            {\r
-                destroyOperation = _IotMqtt_DecrementOperationReferences( pOperation, false );\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-\r
-            /* If the operation should not be destroyed, transfer it from the\r
-             * pending processing to the pending response list. */\r
-            if( destroyOperation == false )\r
-            {\r
-                IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
-\r
-                /* Operation must be linked. */\r
-                IotMqtt_Assert( IotLink_IsLinked( &( pOperation->link ) ) );\r
-\r
-                /* Transfer to pending response list. */\r
-                IotListDouble_Remove( &( pOperation->link ) );\r
-                IotListDouble_InsertHead( &( pMqttConnection->pendingResponse ),\r
-                                          &( pOperation->link ) );\r
-\r
-                IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
-\r
-                /* This operation is now awaiting a response from the network. */\r
-                networkPending = true;\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Destroy the operation or notify of completion if necessary. */\r
-    if( destroyOperation == true )\r
-    {\r
-        _IotMqtt_DestroyOperation( pOperation );\r
-    }\r
-    else\r
-    {\r
-        /* Do not check the operation status if a network response is pending,\r
-         * since a network response could modify the status. */\r
-        if( networkPending == false )\r
-        {\r
-            /* Notify of operation completion if this job set a status. */\r
-            if( pOperation->u.operation.status != IOT_MQTT_STATUS_PENDING )\r
-            {\r
-                _IotMqtt_Notify( pOperation );\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void _IotMqtt_ProcessCompletedOperation( IotTaskPool_t pTaskPool,\r
-                                         IotTaskPoolJob_t pOperationJob,\r
-                                         void * pContext )\r
-{\r
-    _mqttOperation_t * pOperation = ( _mqttOperation_t * ) pContext;\r
-    IotMqttCallbackParam_t callbackParam = { 0 };\r
-\r
-    /* Check parameters. The task pool and job parameter is not used when asserts\r
-     * are disabled. */\r
-    ( void ) pTaskPool;\r
-    ( void ) pOperationJob;\r
-    IotMqtt_Assert( pTaskPool == IOT_SYSTEM_TASKPOOL );\r
-    IotMqtt_Assert( pOperationJob == pOperation->job );\r
-\r
-    /* The operation's callback function and status must be set. */\r
-    IotMqtt_Assert( pOperation->u.operation.notify.callback.function != NULL );\r
-    IotMqtt_Assert( pOperation->u.operation.status != IOT_MQTT_STATUS_PENDING );\r
-\r
-    callbackParam.mqttConnection = pOperation->pMqttConnection;\r
-    callbackParam.u.operation.type = pOperation->u.operation.type;\r
-    callbackParam.u.operation.reference = pOperation;\r
-    callbackParam.u.operation.result = pOperation->u.operation.status;\r
-\r
-    /* Invoke the user callback function. */\r
-    pOperation->u.operation.notify.callback.function( pOperation->u.operation.notify.callback.pCallbackContext,\r
-                                                      &callbackParam );\r
-\r
-    /* Attempt to destroy the operation once the user callback returns. */\r
-    if( _IotMqtt_DecrementOperationReferences( pOperation, false ) == true )\r
-    {\r
-        _IotMqtt_DestroyOperation( pOperation );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t _IotMqtt_ScheduleOperation( _mqttOperation_t * pOperation,\r
-                                           IotTaskPoolRoutine_t jobRoutine,\r
-                                           uint32_t delay )\r
-{\r
-    IotMqttError_t status = IOT_MQTT_SUCCESS;\r
-    IotTaskPoolError_t taskPoolStatus = IOT_TASKPOOL_SUCCESS;\r
-\r
-    /* Check that job routine is valid. */\r
-    IotMqtt_Assert( ( jobRoutine == _IotMqtt_ProcessSend ) ||\r
-                    ( jobRoutine == _IotMqtt_ProcessCompletedOperation ) ||\r
-                    ( jobRoutine == _IotMqtt_ProcessIncomingPublish ) );\r
-\r
-    /* Creating a new job should never fail when parameters are valid. */\r
-    taskPoolStatus = IotTaskPool_CreateJob( jobRoutine,\r
-                                            pOperation,\r
-                                            &( pOperation->jobStorage ),\r
-                                            &( pOperation->job ) );\r
-    IotMqtt_Assert( taskPoolStatus == IOT_TASKPOOL_SUCCESS );\r
-\r
-    /* Schedule the new job with a delay. */\r
-    taskPoolStatus = IotTaskPool_ScheduleDeferred( IOT_SYSTEM_TASKPOOL,\r
-                                                   pOperation->job,\r
-                                                   delay );\r
-\r
-    if( taskPoolStatus != IOT_TASKPOOL_SUCCESS )\r
-    {\r
-        /* Scheduling a newly-created job should never be invalid or illegal. */\r
-        IotMqtt_Assert( taskPoolStatus != IOT_TASKPOOL_BAD_PARAMETER );\r
-        IotMqtt_Assert( taskPoolStatus != IOT_TASKPOOL_ILLEGAL_OPERATION );\r
-\r
-        IotLogWarn( "(MQTT connection %p, %s operation %p) Failed to schedule operation job, error %s.",\r
-                    pOperation->pMqttConnection,\r
-                    IotMqtt_OperationType( pOperation->u.operation.type ),\r
-                    pOperation,\r
-                    IotTaskPool_strerror( taskPoolStatus ) );\r
-\r
-        status = IOT_MQTT_SCHEDULING_ERROR;\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    return status;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-_mqttOperation_t * _IotMqtt_FindOperation( _mqttConnection_t * pMqttConnection,\r
-                                           IotMqttOperationType_t type,\r
-                                           const uint16_t * pPacketIdentifier )\r
-{\r
-    bool waitable = false;\r
-    IotTaskPoolError_t taskPoolStatus = IOT_TASKPOOL_SUCCESS;\r
-    _mqttOperation_t * pResult = NULL;\r
-    IotLink_t * pResultLink = NULL;\r
-    _operationMatchParam_t param = { .type = type, .pPacketIdentifier = pPacketIdentifier };\r
-\r
-    if( pPacketIdentifier != NULL )\r
-    {\r
-        IotLogDebug( "(MQTT connection %p) Searching for operation %s pending response "\r
-                     "with packet identifier %hu.",\r
-                     pMqttConnection,\r
-                     IotMqtt_OperationType( type ),\r
-                     *pPacketIdentifier );\r
-    }\r
-    else\r
-    {\r
-        IotLogDebug( "(MQTT connection %p) Searching for operation %s pending response.",\r
-                     pMqttConnection,\r
-                     IotMqtt_OperationType( type ) );\r
-    }\r
-\r
-    /* Find and remove the first matching element in the list. */\r
-    IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
-    pResultLink = IotListDouble_FindFirstMatch( &( pMqttConnection->pendingResponse ),\r
-                                                NULL,\r
-                                                _mqttOperation_match,\r
-                                                &param );\r
-\r
-    /* Check if a match was found. */\r
-    if( pResultLink != NULL )\r
-    {\r
-        /* Get operation pointer and check if it is waitable. */\r
-        pResult = IotLink_Container( _mqttOperation_t, pResultLink, link );\r
-        waitable = ( pResult->u.operation.flags & IOT_MQTT_FLAG_WAITABLE ) == IOT_MQTT_FLAG_WAITABLE;\r
-\r
-        /* Check if the matched operation is a PUBLISH with retry. If it is, cancel\r
-         * the retry job. */\r
-        if( pResult->u.operation.retry.limit > 0 )\r
-        {\r
-            taskPoolStatus = IotTaskPool_TryCancel( IOT_SYSTEM_TASKPOOL,\r
-                                                    pResult->job,\r
-                                                    NULL );\r
-\r
-            /* If the retry job could not be canceled, then it is currently\r
-             * executing. Ignore the operation. */\r
-            if( taskPoolStatus != IOT_TASKPOOL_SUCCESS )\r
-            {\r
-                pResult = NULL;\r
-            }\r
-            else\r
-            {\r
-                /* Check job reference counts. A waitable operation should have a\r
-                 * count of 2; a non-waitable operation should have a count of 1. */\r
-                IotMqtt_Assert( pResult->u.operation.jobReference == ( 1 + ( waitable == true ) ) );\r
-            }\r
-        }\r
-        else\r
-        {\r
-            /* An operation with no retry in the pending responses list should\r
-             * always have a job reference of 1. */\r
-            IotMqtt_Assert( pResult->u.operation.jobReference == 1 );\r
-\r
-            /* Increment job references of a waitable operation to prevent Wait from\r
-             * destroying this operation if it times out. */\r
-            if( waitable == true )\r
-            {\r
-                ( pResult->u.operation.jobReference )++;\r
-\r
-                IotLogDebug( "(MQTT connection %p, %s operation %p) Job reference changed from %ld to %ld.",\r
-                             pMqttConnection,\r
-                             IotMqtt_OperationType( type ),\r
-                             pResult,\r
-                             ( long int ) ( pResult->u.operation.jobReference - 1 ),\r
-                             ( long int ) ( pResult->u.operation.jobReference ) );\r
-            }\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    if( pResult != NULL )\r
-    {\r
-        IotLogDebug( "(MQTT connection %p) Found operation %s." ,\r
-                     pMqttConnection,\r
-                     IotMqtt_OperationType( type ) );\r
-\r
-        /* Remove the matched operation from the list. */\r
-        IotListDouble_Remove( &( pResult->link ) );\r
-    }\r
-    else\r
-    {\r
-        IotLogDebug( "(MQTT connection %p) Operation %s not found.",\r
-                     pMqttConnection,\r
-                     IotMqtt_OperationType( type ) );\r
-    }\r
-\r
-    IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
-\r
-    return pResult;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void _IotMqtt_Notify( _mqttOperation_t * pOperation )\r
-{\r
-    IotMqttError_t status = IOT_MQTT_SCHEDULING_ERROR;\r
-    _mqttConnection_t * pMqttConnection = pOperation->pMqttConnection;\r
-\r
-    /* Check if operation is waitable. */\r
-    bool waitable = ( pOperation->u.operation.flags & IOT_MQTT_FLAG_WAITABLE ) == IOT_MQTT_FLAG_WAITABLE;\r
-\r
-    /* Remove any lingering subscriptions if a SUBSCRIBE failed. Rejected\r
-     * subscriptions are removed by the deserializer, so not removed here. */\r
-    if( pOperation->u.operation.type == IOT_MQTT_SUBSCRIBE )\r
-    {\r
-        switch( pOperation->u.operation.status )\r
-        {\r
-            case IOT_MQTT_SUCCESS:\r
-                break;\r
-\r
-            case IOT_MQTT_SERVER_REFUSED:\r
-                break;\r
-\r
-            default:\r
-                _IotMqtt_RemoveSubscriptionByPacket( pOperation->pMqttConnection,\r
-                                                     pOperation->u.operation.packetIdentifier,\r
-                                                     -1 );\r
-                break;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Schedule callback invocation for non-waitable operation. */\r
-    if( waitable == false )\r
-    {\r
-        /* Non-waitable operation should have job reference of 1. */\r
-        IotMqtt_Assert( pOperation->u.operation.jobReference == 1 );\r
-\r
-        /* Schedule an invocation of the callback. */\r
-        if( pOperation->u.operation.notify.callback.function != NULL )\r
-        {\r
-            IotMutex_Lock( &( pMqttConnection->referencesMutex ) );\r
-\r
-            status = _IotMqtt_ScheduleOperation( pOperation,\r
-                                                 _IotMqtt_ProcessCompletedOperation,\r
-                                                 0 );\r
-\r
-            if( status == IOT_MQTT_SUCCESS )\r
-            {\r
-                IotLogDebug( "(MQTT connection %p, %s operation %p) Callback scheduled.",\r
-                             pOperation->pMqttConnection,\r
-                             IotMqtt_OperationType( pOperation->u.operation.type ),\r
-                             pOperation );\r
-\r
-                /* Place the scheduled operation back in the list of operations pending\r
-                 * processing. */\r
-                if( IotLink_IsLinked( &( pOperation->link ) ) == true )\r
-                {\r
-                    IotListDouble_Remove( &( pOperation->link ) );\r
-                }\r
-                else\r
-                {\r
-                    EMPTY_ELSE_MARKER;\r
-                }\r
-\r
-                IotListDouble_InsertHead( &( pMqttConnection->pendingProcessing ),\r
-                                          &( pOperation->link ) );\r
-            }\r
-            else\r
-            {\r
-                IotLogWarn( "(MQTT connection %p, %s operation %p) Failed to schedule callback.",\r
-                            pOperation->pMqttConnection,\r
-                            IotMqtt_OperationType( pOperation->u.operation.type ),\r
-                            pOperation );\r
-            }\r
-\r
-            IotMutex_Unlock( &( pMqttConnection->referencesMutex ) );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Operations that weren't scheduled may be destroyed. */\r
-    if( status == IOT_MQTT_SCHEDULING_ERROR )\r
-    {\r
-        /* Decrement reference count of operations not scheduled. */\r
-        if( _IotMqtt_DecrementOperationReferences( pOperation, false ) == true )\r
-        {\r
-            _IotMqtt_DestroyOperation( pOperation );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        /* Post to a waitable operation's semaphore. */\r
-        if( waitable == true )\r
-        {\r
-            IotLogDebug( "(MQTT connection %p, %s operation %p) Waitable operation "\r
-                         "notified of completion.",\r
-                         pOperation->pMqttConnection,\r
-                         IotMqtt_OperationType( pOperation->u.operation.type ),\r
-                         pOperation );\r
-\r
-            IotSemaphore_Post( &( pOperation->u.operation.notify.waitSemaphore ) );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        IotMqtt_Assert( status == IOT_MQTT_SUCCESS );\r
-    }\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_mqtt_serialize.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_mqtt_serialize.c
deleted file mode 100644 (file)
index f42c80c..0000000
+++ /dev/null
@@ -1,1939 +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_serialize.c\r
- * @brief Implements functions that generate and decode MQTT network packets.\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 includes. */\r
-#include "private/iot_mqtt_internal.h"\r
-\r
-/* Platform layer includes. */\r
-#include "platform/iot_threads.h"\r
-\r
-/* Atomic operations. */\r
-#include "iot_atomic.h"\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/*\r
- * Macros for reading the high and low byte of a 2-byte unsigned int.\r
- */\r
-#define UINT16_HIGH_BYTE( x )    ( ( uint8_t ) ( x >> 8 ) )            /**< @brief Get high byte. */\r
-#define UINT16_LOW_BYTE( x )     ( ( uint8_t ) ( x & 0x00ff ) )        /**< @brief Get low byte. */\r
-\r
-/**\r
- * @brief Macro for decoding a 2-byte unsigned int from a sequence of bytes.\r
- *\r
- * @param[in] ptr A uint8_t* that points to the high byte.\r
- */\r
-#define UINT16_DECODE( ptr )                                \\r
-    ( uint16_t ) ( ( ( ( uint16_t ) ( *( ptr ) ) ) << 8 ) | \\r
-                   ( ( uint16_t ) ( *( ptr + 1 ) ) ) )\r
-\r
-/**\r
- * @brief Macro for setting a bit in a 1-byte unsigned int.\r
- *\r
- * @param[in] x The unsigned int to set.\r
- * @param[in] position Which bit to set.\r
- */\r
-#define UINT8_SET_BIT( x, position )      ( x = ( uint8_t ) ( x | ( 0x01 << position ) ) )\r
-\r
-/**\r
- * @brief Macro for checking if a bit is set in a 1-byte unsigned int.\r
- *\r
- * @param[in] x The unsigned int to check.\r
- * @param[in] position Which bit to check.\r
- */\r
-#define UINT8_CHECK_BIT( x, position )    ( ( x & ( 0x01 << position ) ) == ( 0x01 << position ) )\r
-\r
-/*\r
- * Positions of each flag in the "Connect Flag" field of an MQTT CONNECT\r
- * packet.\r
- */\r
-#define MQTT_CONNECT_FLAG_CLEAN                     ( 1 )  /**< @brief Clean session. */\r
-#define MQTT_CONNECT_FLAG_WILL                      ( 2 )  /**< @brief Will present. */\r
-#define MQTT_CONNECT_FLAG_WILL_QOS1                 ( 3 )  /**< @brief Will QoS1. */\r
-#define MQTT_CONNECT_FLAG_WILL_QOS2                 ( 4 )  /**< @brief Will QoS2. */\r
-#define MQTT_CONNECT_FLAG_WILL_RETAIN               ( 5 )  /**< @brief Will retain. */\r
-#define MQTT_CONNECT_FLAG_PASSWORD                  ( 6 )  /**< @brief Password present. */\r
-#define MQTT_CONNECT_FLAG_USERNAME                  ( 7 )  /**< @brief Username present. */\r
-\r
-/*\r
- * Positions of each flag in the first byte of an MQTT PUBLISH packet's\r
- * fixed header.\r
- */\r
-#define MQTT_PUBLISH_FLAG_RETAIN                    ( 0 )  /**< @brief Message retain flag. */\r
-#define MQTT_PUBLISH_FLAG_QOS1                      ( 1 )  /**< @brief Publish QoS 1. */\r
-#define MQTT_PUBLISH_FLAG_QOS2                      ( 2 )  /**< @brief Publish QoS 2. */\r
-#define MQTT_PUBLISH_FLAG_DUP                       ( 3 )  /**< @brief Duplicate message. */\r
-\r
-/**\r
- * @brief The constant specifying MQTT version 3.1.1. Placed in the CONNECT packet.\r
- */\r
-#define MQTT_VERSION_3_1_1                          ( ( uint8_t ) 4U )\r
-\r
-/**\r
- * @brief Per the MQTT 3.1.1 spec, the largest "Remaining Length" of an MQTT\r
- * packet is this value.\r
- */\r
-#define MQTT_MAX_REMAINING_LENGTH                   ( 268435455UL )\r
-\r
-/**\r
- * @brief The maximum possible size of a CONNECT packet.\r
- *\r
- * All strings in a CONNECT packet are constrained to 2-byte lengths, giving a\r
- * maximum length smaller than the max "Remaining Length" constant above.\r
- */\r
-#define MQTT_PACKET_CONNECT_MAX_SIZE                ( 327700UL )\r
-\r
-/*\r
- * Constants relating to CONNACK packets, defined by MQTT 3.1.1 spec.\r
- */\r
-#define MQTT_PACKET_CONNACK_REMAINING_LENGTH        ( ( uint8_t ) 2 )    /**< @brief A CONNACK packet always has a "Remaining length" of 2. */\r
-#define MQTT_PACKET_CONNACK_SESSION_PRESENT_MASK    ( ( uint8_t ) 0x01 ) /**< @brief The "Session Present" bit is always the lowest bit. */\r
-\r
-/*\r
- * Constants relating to PUBLISH and PUBACK packets, defined by MQTT\r
- * 3.1.1 spec.\r
- */\r
-#define MQTT_PACKET_PUBACK_SIZE                     ( 4 )               /**< @brief A PUBACK packet is always 4 bytes in size. */\r
-#define MQTT_PACKET_PUBACK_REMAINING_LENGTH         ( ( uint8_t ) 2 )   /**< @brief A PUBACK packet always has a "Remaining length" of 2. */\r
-\r
-/*\r
- * Constants relating to SUBACK and UNSUBACK packets, defined by MQTT\r
- * 3.1.1 spec.\r
- */\r
-#define MQTT_PACKET_SUBACK_MINIMUM_SIZE             ( 5 )               /**< @brief The size of the smallest valid SUBACK packet. */\r
-#define MQTT_PACKET_UNSUBACK_REMAINING_LENGTH       ( ( uint8_t ) 2 )   /**< @brief An UNSUBACK packet always has a "Remaining length" of 2. */\r
-\r
-/*\r
- * Constants relating to PINGREQ and PINGRESP packets, defined by MQTT 3.1.1 spec.\r
- */\r
-#define MQTT_PACKET_PINGREQ_SIZE                    ( 2 ) /**< @brief A PINGREQ packet is always 2 bytes in size. */\r
-#define MQTT_PACKET_PINGRESP_REMAINING_LENGTH       ( 0 ) /**< @brief A PINGRESP packet always has a "Remaining length" of 0. */\r
-\r
-/*\r
- * Constants relating to DISCONNECT packets, defined by MQTT 3.1.1 spec.\r
- */\r
-#define MQTT_PACKET_DISCONNECT_SIZE                 ( 2 ) /**< @brief A DISCONNECT packet is always 2 bytes in size. */\r
-\r
-/* Username for metrics with AWS IoT. */\r
-#if AWS_IOT_MQTT_ENABLE_METRICS == 1 || DOXYGEN == 1\r
-    #ifndef AWS_IOT_METRICS_USERNAME\r
-\r
-/**\r
- * @brief Specify C SDK and version.\r
- */\r
-        #define AWS_IOT_METRICS_USERNAME           "?SDK=C&Version=4.0.0"\r
-\r
-/**\r
- * @brief The length of #AWS_IOT_METRICS_USERNAME.\r
- */\r
-        #define AWS_IOT_METRICS_USERNAME_LENGTH    ( ( uint16_t ) sizeof( AWS_IOT_METRICS_USERNAME ) - 1 )\r
-    #endif /* ifndef AWS_IOT_METRICS_USERNAME */\r
-#endif /* if AWS_IOT_MQTT_ENABLE_METRICS == 1 || DOXYGEN == 1 */\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/**\r
- * @brief Generate and return a 2-byte packet identifier.\r
- *\r
- * This packet identifier will be nonzero.\r
- *\r
- * @return The packet identifier.\r
- */\r
-static uint16_t _nextPacketIdentifier( void );\r
-\r
-/**\r
- * @brief Calculate the number of bytes required to encode an MQTT\r
- * "Remaining length" field.\r
- *\r
- * @param[in] length The value of the "Remaining length" to encode.\r
- *\r
- * @return The size of the encoding of length. This is always `1`, `2`, `3`, or `4`.\r
- */\r
-static size_t _remainingLengthEncodedSize( size_t length );\r
-\r
-/**\r
- * @brief Encode the "Remaining length" field per MQTT spec.\r
- *\r
- * @param[out] pDestination Where to write the encoded "Remaining length".\r
- * @param[in] length The "Remaining length" to encode.\r
- *\r
- * @return Pointer to the end of the encoded "Remaining length", which is 1-4\r
- * bytes greater than `pDestination`.\r
- *\r
- * @warning This function does not check the size of `pDestination`! Ensure that\r
- * `pDestination` is large enough to hold the encoded "Remaining length" using\r
- * the function #_remainingLengthEncodedSize to avoid buffer overflows.\r
- */\r
-static uint8_t * _encodeRemainingLength( uint8_t * pDestination,\r
-                                         size_t length );\r
-\r
-/**\r
- * @brief Encode a C string as a UTF-8 string, per MQTT 3.1.1 spec.\r
- *\r
- * @param[out] pDestination Where to write the encoded string.\r
- * @param[in] source The string to encode.\r
- * @param[in] sourceLength The length of source.\r
- *\r
- * @return Pointer to the end of the encoded string, which is `sourceLength+2`\r
- * bytes greater than `pDestination`.\r
- *\r
- * @warning This function does not check the size of `pDestination`! Ensure that\r
- * `pDestination` is large enough to hold `sourceLength+2` bytes to avoid a buffer\r
- * overflow.\r
- */\r
-static uint8_t * _encodeString( uint8_t * pDestination,\r
-                                const char * source,\r
-                                uint16_t sourceLength );\r
-\r
-/**\r
- * @brief Calculate the size and "Remaining length" of a CONNECT packet generated\r
- * from the given parameters.\r
- *\r
- * @param[in] pConnectInfo User-provided CONNECT information struct.\r
- * @param[out] pRemainingLength Output for calculated "Remaining length" field.\r
- * @param[out] pPacketSize Output for calculated total packet size.\r
- *\r
- * @return `true` if the packet is within the length allowed by MQTT 3.1.1 spec; `false`\r
- * otherwise. If this function returns `false`, the output parameters should be ignored.\r
- */\r
-static bool _connectPacketSize( const IotMqttConnectInfo_t * pConnectInfo,\r
-                                size_t * pRemainingLength,\r
-                                size_t * pPacketSize );\r
-\r
-/**\r
- * @brief Calculate the size and "Remaining length" of a PUBLISH packet generated\r
- * from the given parameters.\r
- *\r
- * @param[in] pPublishInfo User-provided PUBLISH information struct.\r
- * @param[out] pRemainingLength Output for calculated "Remaining length" field.\r
- * @param[out] pPacketSize Output for calculated total packet size.\r
- *\r
- * @return `true` if the packet is within the length allowed by MQTT 3.1.1 spec; `false`\r
- * otherwise. If this function returns `false`, the output parameters should be ignored.\r
- */\r
-static bool _publishPacketSize( const IotMqttPublishInfo_t * pPublishInfo,\r
-                                size_t * pRemainingLength,\r
-                                size_t * pPacketSize );\r
-\r
-/**\r
- * @brief Calculate the size and "Remaining length" of a SUBSCRIBE or UNSUBSCRIBE\r
- * packet generated from the given parameters.\r
- *\r
- * @param[in] type Either IOT_MQTT_SUBSCRIBE or IOT_MQTT_UNSUBSCRIBE.\r
- * @param[in] pSubscriptionList User-provided array of subscriptions.\r
- * @param[in] subscriptionCount Size of `pSubscriptionList`.\r
- * @param[out] pRemainingLength Output for calculated "Remaining length" field.\r
- * @param[out] pPacketSize Output for calculated total packet size.\r
- *\r
- * @return `true` if the packet is within the length allowed by MQTT 3.1.1 spec; `false`\r
- * otherwise. If this function returns `false`, the output parameters should be ignored.\r
- */\r
-static bool _subscriptionPacketSize( IotMqttOperationType_t type,\r
-                                     const IotMqttSubscription_t * pSubscriptionList,\r
-                                     size_t subscriptionCount,\r
-                                     size_t * pRemainingLength,\r
-                                     size_t * pPacketSize );\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-#if LIBRARY_LOG_LEVEL > IOT_LOG_NONE\r
-\r
-/**\r
- * @brief If logging is enabled, define a log configuration that only prints the log\r
- * string. This is used when printing out details of deserialized MQTT packets.\r
- */\r
-    static const IotLogConfig_t _logHideAll =\r
-    {\r
-        .hideLibraryName = true,\r
-        .hideLogLevel    = true,\r
-        .hideTimestring  = true\r
-    };\r
-#endif\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static uint16_t _nextPacketIdentifier( void )\r
-{\r
-    /* MQTT specifies 2 bytes for the packet identifier; however, operating on\r
-     * 32-bit integers is generally faster. */\r
-    static uint32_t nextPacketIdentifier = 1;\r
-\r
-    /* The next packet identifier will be greater by 2. This prevents packet\r
-     * identifiers from ever being 0, which is not allowed by MQTT 3.1.1. Packet\r
-     * identifiers will follow the sequence 1,3,5...65535,1,3,5... */\r
-    return ( uint16_t ) Atomic_Add_u32( &nextPacketIdentifier, 2 );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static size_t _remainingLengthEncodedSize( size_t length )\r
-{\r
-    size_t encodedSize = 0;\r
-\r
-    /* length should have already been checked before calling this function. */\r
-    IotMqtt_Assert( length <= MQTT_MAX_REMAINING_LENGTH );\r
-\r
-    /* Determine how many bytes are needed to encode length.\r
-     * The values below are taken from the MQTT 3.1.1 spec. */\r
-\r
-    /* 1 byte is needed to encode lengths between 0 and 127. */\r
-    if( length < 128 )\r
-    {\r
-        encodedSize = 1;\r
-    }\r
-    /* 2 bytes are needed to encode lengths between 128 and 16,383. */\r
-    else if( length < 16384 )\r
-    {\r
-        encodedSize = 2;\r
-    }\r
-    /* 3 bytes are needed to encode lengths between 16,384 and 2,097,151. */\r
-    else if( length < 2097152 )\r
-    {\r
-        encodedSize = 3;\r
-    }\r
-    /* 4 bytes are needed to encode lengths between 2,097,152 and 268,435,455. */\r
-    else\r
-    {\r
-        encodedSize = 4;\r
-    }\r
-\r
-    return encodedSize;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static uint8_t * _encodeRemainingLength( uint8_t * pDestination,\r
-                                         size_t length )\r
-{\r
-    uint8_t lengthByte = 0, * pLengthEnd = pDestination;\r
-\r
-    /* This algorithm is copied from the MQTT v3.1.1 spec. */\r
-    do\r
-    {\r
-        lengthByte = length % 128;\r
-        length = length / 128;\r
-\r
-        /* Set the high bit of this byte, indicating that there's more data. */\r
-        if( length > 0 )\r
-        {\r
-            UINT8_SET_BIT( lengthByte, 7 );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        /* Output a single encoded byte. */\r
-        *pLengthEnd = lengthByte;\r
-        pLengthEnd++;\r
-    } while( length > 0 );\r
-\r
-    return pLengthEnd;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static uint8_t * _encodeString( uint8_t * pDestination,\r
-                                const char * source,\r
-                                uint16_t sourceLength )\r
-{\r
-    /* The first byte of a UTF-8 string is the high byte of the string length. */\r
-    *pDestination = UINT16_HIGH_BYTE( sourceLength );\r
-    pDestination++;\r
-\r
-    /* The second byte of a UTF-8 string is the low byte of the string length. */\r
-    *pDestination = UINT16_LOW_BYTE( sourceLength );\r
-    pDestination++;\r
-\r
-    /* Copy the string into pDestination. */\r
-    ( void ) memcpy( pDestination, source, sourceLength );\r
-\r
-    /* Return the pointer to the end of the encoded string. */\r
-    pDestination += sourceLength;\r
-\r
-    return pDestination;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static bool _connectPacketSize( const IotMqttConnectInfo_t * pConnectInfo,\r
-                                size_t * pRemainingLength,\r
-                                size_t * pPacketSize )\r
-{\r
-    bool status = true;\r
-    size_t connectPacketSize = 0, remainingLength = 0;\r
-\r
-    /* The CONNECT packet will always include a 10-byte variable header. */\r
-    connectPacketSize += 10U;\r
-\r
-    /* Add the length of the client identifier if provided. */\r
-    if( pConnectInfo->clientIdentifierLength > 0 )\r
-    {\r
-        connectPacketSize += pConnectInfo->clientIdentifierLength + sizeof( uint16_t );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Add the lengths of the will message and topic name if provided. */\r
-    if( pConnectInfo->pWillInfo != NULL )\r
-    {\r
-        connectPacketSize += pConnectInfo->pWillInfo->topicNameLength + sizeof( uint16_t ) +\r
-                             pConnectInfo->pWillInfo->payloadLength + sizeof( uint16_t );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Depending on the status of metrics, add the length of the metrics username\r
-     * or the user-provided username. */\r
-    if( pConnectInfo->awsIotMqttMode == true )\r
-    {\r
-        #if AWS_IOT_MQTT_ENABLE_METRICS == 1\r
-            connectPacketSize += AWS_IOT_METRICS_USERNAME_LENGTH + sizeof( uint16_t );\r
-        #endif\r
-    }\r
-    else\r
-    {\r
-        /* Add the lengths of the username and password if provided and not\r
-         * connecting to an AWS IoT MQTT server. */\r
-        if( pConnectInfo->pUserName != NULL )\r
-        {\r
-            connectPacketSize += pConnectInfo->userNameLength + sizeof( uint16_t );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        if( pConnectInfo->pPassword != NULL )\r
-        {\r
-            connectPacketSize += pConnectInfo->passwordLength + sizeof( uint16_t );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-\r
-    /* At this point, the "Remaining Length" field of the MQTT CONNECT packet has\r
-     * been calculated. */\r
-    remainingLength = connectPacketSize;\r
-\r
-    /* Calculate the full size of the MQTT CONNECT packet by adding the size of\r
-     * the "Remaining Length" field plus 1 byte for the "Packet Type" field. */\r
-    connectPacketSize += 1 + _remainingLengthEncodedSize( connectPacketSize );\r
-\r
-    /* Check that the CONNECT packet is within the bounds of the MQTT spec. */\r
-    if( connectPacketSize > MQTT_PACKET_CONNECT_MAX_SIZE )\r
-    {\r
-        status = false;\r
-    }\r
-    else\r
-    {\r
-        *pRemainingLength = remainingLength;\r
-        *pPacketSize = connectPacketSize;\r
-    }\r
-\r
-    return status;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static bool _publishPacketSize( const IotMqttPublishInfo_t * pPublishInfo,\r
-                                size_t * pRemainingLength,\r
-                                size_t * pPacketSize )\r
-{\r
-    bool status = true;\r
-    size_t publishPacketSize = 0, payloadLimit = 0;\r
-\r
-    /* The variable header of a PUBLISH packet always contains the topic name. */\r
-    publishPacketSize += pPublishInfo->topicNameLength + sizeof( uint16_t );\r
-\r
-    /* The variable header of a QoS 1 or 2 PUBLISH packet contains a 2-byte\r
-     * packet identifier. */\r
-    if( pPublishInfo->qos > IOT_MQTT_QOS_0 )\r
-    {\r
-        publishPacketSize += sizeof( uint16_t );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Calculate the maximum allowed size of the payload for the given parameters.\r
-     * This calculation excludes the "Remaining length" encoding, whose size is not\r
-     * yet known. */\r
-    payloadLimit = MQTT_MAX_REMAINING_LENGTH - publishPacketSize - 1;\r
-\r
-    /* Ensure that the given payload fits within the calculated limit. */\r
-    if( pPublishInfo->payloadLength > payloadLimit )\r
-    {\r
-        status = false;\r
-    }\r
-    else\r
-    {\r
-        /* Add the length of the PUBLISH payload. At this point, the "Remaining length"\r
-         * has been calculated. */\r
-        publishPacketSize += pPublishInfo->payloadLength;\r
-\r
-        /* Now that the "Remaining length" is known, recalculate the payload limit\r
-         * based on the size of its encoding. */\r
-        payloadLimit -= _remainingLengthEncodedSize( publishPacketSize );\r
-\r
-        /* Check that the given payload fits within the size allowed by MQTT spec. */\r
-        if( pPublishInfo->payloadLength > payloadLimit )\r
-        {\r
-            status = false;\r
-        }\r
-        else\r
-        {\r
-            /* Set the "Remaining length" output parameter and calculate the full\r
-             * size of the PUBLISH packet. */\r
-            *pRemainingLength = publishPacketSize;\r
-\r
-            publishPacketSize += 1 + _remainingLengthEncodedSize( publishPacketSize );\r
-            *pPacketSize = publishPacketSize;\r
-        }\r
-    }\r
-\r
-    return status;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static bool _subscriptionPacketSize( IotMqttOperationType_t type,\r
-                                     const IotMqttSubscription_t * pSubscriptionList,\r
-                                     size_t subscriptionCount,\r
-                                     size_t * pRemainingLength,\r
-                                     size_t * pPacketSize )\r
-{\r
-    bool status = true;\r
-    size_t i = 0, subscriptionPacketSize = 0;\r
-\r
-    /* Only SUBSCRIBE and UNSUBSCRIBE operations should call this function. */\r
-    IotMqtt_Assert( ( type == IOT_MQTT_SUBSCRIBE ) || ( type == IOT_MQTT_UNSUBSCRIBE ) );\r
-\r
-    /* The variable header of a subscription packet consists of a 2-byte packet\r
-     * identifier. */\r
-    subscriptionPacketSize += sizeof( uint16_t );\r
-\r
-    /* Sum the lengths of all subscription topic filters; add 1 byte for each\r
-     * subscription's QoS if type is IOT_MQTT_SUBSCRIBE. */\r
-    for( i = 0; i < subscriptionCount; i++ )\r
-    {\r
-        /* Add the length of the topic filter. */\r
-        subscriptionPacketSize += pSubscriptionList[ i ].topicFilterLength + sizeof( uint16_t );\r
-\r
-        /* Only SUBSCRIBE packets include the QoS. */\r
-        if( type == IOT_MQTT_SUBSCRIBE )\r
-        {\r
-            subscriptionPacketSize += 1;\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-\r
-    /* At this point, the "Remaining length" has been calculated. Return error\r
-     * if the "Remaining length" exceeds what is allowed by MQTT 3.1.1. Otherwise,\r
-     * set the output parameter.*/\r
-    if( subscriptionPacketSize > MQTT_MAX_REMAINING_LENGTH )\r
-    {\r
-        status = false;\r
-    }\r
-    else\r
-    {\r
-        *pRemainingLength = subscriptionPacketSize;\r
-\r
-        /* Calculate the full size of the subscription packet by adding the size of the\r
-         * "Remaining length" field plus 1 byte for the "Packet type" field. Set the\r
-         * pPacketSize output parameter. */\r
-        subscriptionPacketSize += 1 + _remainingLengthEncodedSize( subscriptionPacketSize );\r
-        *pPacketSize = subscriptionPacketSize;\r
-    }\r
-\r
-    return status;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-uint8_t _IotMqtt_GetPacketType( void * pNetworkConnection,\r
-                                const IotNetworkInterface_t * pNetworkInterface )\r
-{\r
-    uint8_t packetType = 0xff;\r
-\r
-    /* The MQTT packet type is in the first byte of the packet. */\r
-    ( void ) _IotMqtt_GetNextByte( pNetworkConnection,\r
-                                   pNetworkInterface,\r
-                                   &packetType );\r
-\r
-    return packetType;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-size_t _IotMqtt_GetRemainingLength( void * pNetworkConnection,\r
-                                    const IotNetworkInterface_t * pNetworkInterface )\r
-{\r
-    uint8_t encodedByte = 0;\r
-    size_t remainingLength = 0, multiplier = 1, bytesDecoded = 0, expectedSize = 0;\r
-\r
-    /* This algorithm is copied from the MQTT v3.1.1 spec. */\r
-    do\r
-    {\r
-        if( multiplier > 2097152 ) /* 128 ^ 3 */\r
-        {\r
-            remainingLength = MQTT_REMAINING_LENGTH_INVALID;\r
-            break;\r
-        }\r
-        else\r
-        {\r
-            if( _IotMqtt_GetNextByte( pNetworkConnection,\r
-                                      pNetworkInterface,\r
-                                      &encodedByte ) == true )\r
-            {\r
-                remainingLength += ( encodedByte & 0x7F ) * multiplier;\r
-                multiplier *= 128;\r
-                bytesDecoded++;\r
-            }\r
-            else\r
-            {\r
-                remainingLength = MQTT_REMAINING_LENGTH_INVALID;\r
-                break;\r
-            }\r
-        }\r
-    } while( ( encodedByte & 0x80 ) != 0 );\r
-\r
-    /* Check that the decoded remaining length conforms to the MQTT specification. */\r
-    if( remainingLength != MQTT_REMAINING_LENGTH_INVALID )\r
-    {\r
-        expectedSize = _remainingLengthEncodedSize( remainingLength );\r
-\r
-        if( bytesDecoded != expectedSize )\r
-        {\r
-            remainingLength = MQTT_REMAINING_LENGTH_INVALID;\r
-        }\r
-        else\r
-        {\r
-            /* Valid remaining length should be at most 4 bytes. */\r
-            IotMqtt_Assert( bytesDecoded <= 4 );\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    return remainingLength;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t _IotMqtt_SerializeConnect( const IotMqttConnectInfo_t * pConnectInfo,\r
-                                          uint8_t ** pConnectPacket,\r
-                                          size_t * pPacketSize )\r
-{\r
-    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
-    uint8_t connectFlags = 0;\r
-    size_t remainingLength = 0, connectPacketSize = 0;\r
-    uint8_t * pBuffer = NULL;\r
-\r
-    /* Calculate the "Remaining length" field and total packet size. If it exceeds\r
-     * what is allowed in the MQTT standard, return an error. */\r
-    if( _connectPacketSize( pConnectInfo, &remainingLength, &connectPacketSize ) == false )\r
-    {\r
-        IotLogError( "Connect packet length exceeds %lu, which is the maximum"\r
-                     " size allowed by MQTT 3.1.1.",\r
-                     MQTT_PACKET_CONNECT_MAX_SIZE );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Total size of the connect packet should be larger than the "Remaining length"\r
-     * field. */\r
-    IotMqtt_Assert( connectPacketSize > remainingLength );\r
-\r
-    /* Allocate memory to hold the CONNECT packet. */\r
-    pBuffer = IotMqtt_MallocMessage( connectPacketSize );\r
-\r
-    /* Check that sufficient memory was allocated. */\r
-    if( pBuffer == NULL )\r
-    {\r
-        IotLogError( "Failed to allocate memory for CONNECT packet." );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NO_MEMORY );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Set the output parameters. The remainder of this function always succeeds. */\r
-    *pConnectPacket = pBuffer;\r
-    *pPacketSize = connectPacketSize;\r
-\r
-    /* The first byte in the CONNECT packet is the control packet type. */\r
-    *pBuffer = MQTT_PACKET_TYPE_CONNECT;\r
-    pBuffer++;\r
-\r
-    /* The remaining length of the CONNECT packet is encoded starting from the\r
-     * second byte. The remaining length does not include the length of the fixed\r
-     * header or the encoding of the remaining length. */\r
-    pBuffer = _encodeRemainingLength( pBuffer, remainingLength );\r
-\r
-    /* The string "MQTT" is placed at the beginning of the CONNECT packet's variable\r
-     * header. This string is 4 bytes long. */\r
-    pBuffer = _encodeString( pBuffer, "MQTT", 4 );\r
-\r
-    /* The MQTT protocol version is the second byte of the variable header. */\r
-    *pBuffer = MQTT_VERSION_3_1_1;\r
-    pBuffer++;\r
-\r
-    /* Set the CONNECT flags based on the given parameters. */\r
-    if( pConnectInfo->cleanSession == true )\r
-    {\r
-        UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_CLEAN );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Username and password depend on MQTT mode. */\r
-    if( pConnectInfo->awsIotMqttMode == true )\r
-    {\r
-        /* Set the username flag for AWS IoT metrics. The AWS IoT MQTT server\r
-         * never uses a password. */\r
-        #if AWS_IOT_MQTT_ENABLE_METRICS == 1\r
-            UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_USERNAME );\r
-        #endif\r
-    }\r
-    else\r
-    {\r
-        /* Set the flags for username and password if provided. */\r
-        if( pConnectInfo->pUserName != NULL )\r
-        {\r
-            UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_USERNAME );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        if( pConnectInfo->pPassword != NULL )\r
-        {\r
-            UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_PASSWORD );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-\r
-    /* Set will flag if an LWT is provided. */\r
-    if( pConnectInfo->pWillInfo != NULL )\r
-    {\r
-        UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_WILL );\r
-\r
-        /* Flags only need to be changed for will QoS 1 and 2. */\r
-        switch( pConnectInfo->pWillInfo->qos )\r
-        {\r
-            case IOT_MQTT_QOS_1:\r
-                UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_WILL_QOS1 );\r
-                break;\r
-\r
-            case IOT_MQTT_QOS_2:\r
-                UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_WILL_QOS2 );\r
-                break;\r
-\r
-            default:\r
-                break;\r
-        }\r
-\r
-        if( pConnectInfo->pWillInfo->retain == true )\r
-        {\r
-            UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_WILL_RETAIN );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    *pBuffer = connectFlags;\r
-    pBuffer++;\r
-\r
-    /* Write the 2 bytes of the keep alive interval into the CONNECT packet. */\r
-    *pBuffer = UINT16_HIGH_BYTE( pConnectInfo->keepAliveSeconds );\r
-    *( pBuffer + 1 ) = UINT16_LOW_BYTE( pConnectInfo->keepAliveSeconds );\r
-    pBuffer += 2;\r
-\r
-    /* Write the client identifier into the CONNECT packet. */\r
-    pBuffer = _encodeString( pBuffer,\r
-                             pConnectInfo->pClientIdentifier,\r
-                             pConnectInfo->clientIdentifierLength );\r
-\r
-    /* Write the will topic name and message into the CONNECT packet if provided. */\r
-    if( pConnectInfo->pWillInfo != NULL )\r
-    {\r
-        pBuffer = _encodeString( pBuffer,\r
-                                 pConnectInfo->pWillInfo->pTopicName,\r
-                                 pConnectInfo->pWillInfo->topicNameLength );\r
-\r
-        pBuffer = _encodeString( pBuffer,\r
-                                 pConnectInfo->pWillInfo->pPayload,\r
-                                 ( uint16_t ) pConnectInfo->pWillInfo->payloadLength );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* If metrics are enabled, write the metrics username into the CONNECT packet.\r
-     * Otherwise, write the username and password only when not connecting to an\r
-     * AWS IoT MQTT server. */\r
-    if( pConnectInfo->awsIotMqttMode == true )\r
-    {\r
-        #if AWS_IOT_MQTT_ENABLE_METRICS == 1\r
-            IotLogInfo( "Anonymous metrics (SDK language, SDK version) will be provided to AWS IoT. "\r
-                        "Recompile with AWS_IOT_MQTT_ENABLE_METRICS set to 0 to disable." );\r
-\r
-            pBuffer = _encodeString( pBuffer,\r
-                                     AWS_IOT_METRICS_USERNAME,\r
-                                     AWS_IOT_METRICS_USERNAME_LENGTH );\r
-        #endif\r
-    }\r
-    else\r
-    {\r
-        if( pConnectInfo->pUserName != NULL )\r
-        {\r
-            pBuffer = _encodeString( pBuffer,\r
-                                     pConnectInfo->pUserName,\r
-                                     pConnectInfo->userNameLength );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        if( pConnectInfo->pPassword != NULL )\r
-        {\r
-            pBuffer = _encodeString( pBuffer,\r
-                                     pConnectInfo->pPassword,\r
-                                     pConnectInfo->passwordLength );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-\r
-    /* Ensure that the difference between the end and beginning of the buffer\r
-     * is equal to connectPacketSize, i.e. pBuffer did not overflow. */\r
-    IotMqtt_Assert( ( size_t ) ( pBuffer - *pConnectPacket ) == connectPacketSize );\r
-\r
-    /* Print out the serialized CONNECT packet for debugging purposes. */\r
-    IotLog_PrintBuffer( "MQTT CONNECT packet:", *pConnectPacket, connectPacketSize );\r
-\r
-    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t _IotMqtt_DeserializeConnack( _mqttPacket_t * pConnack )\r
-{\r
-    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
-    const uint8_t * pRemainingData = pConnack->pRemainingData;\r
-\r
-    /* If logging is enabled, declare the CONNACK response code strings. The\r
-     * fourth byte of CONNACK indexes into this array for the corresponding response. */\r
-    #if LIBRARY_LOG_LEVEL > IOT_LOG_NONE\r
-        static const char * pConnackResponses[ 6 ] =\r
-        {\r
-            "Connection accepted.",                               /* 0 */\r
-            "Connection refused: unacceptable protocol version.", /* 1 */\r
-            "Connection refused: identifier rejected.",           /* 2 */\r
-            "Connection refused: server unavailable",             /* 3 */\r
-            "Connection refused: bad user name or password.",     /* 4 */\r
-            "Connection refused: not authorized."                 /* 5 */\r
-        };\r
-    #endif\r
-\r
-    /* Check that the control packet type is 0x20. */\r
-    if( pConnack->type != MQTT_PACKET_TYPE_CONNACK )\r
-    {\r
-        IotLog( IOT_LOG_ERROR,\r
-                &_logHideAll,\r
-                "Bad control packet type 0x%02x.",\r
-                pConnack->type );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* According to MQTT 3.1.1, the second byte of CONNACK must specify a\r
-     * "Remaining length" of 2. */\r
-    if( pConnack->remainingLength != MQTT_PACKET_CONNACK_REMAINING_LENGTH )\r
-    {\r
-        IotLog( IOT_LOG_ERROR,\r
-                &_logHideAll,\r
-                "CONNACK does not have remaining length of %d.",\r
-                MQTT_PACKET_CONNACK_REMAINING_LENGTH );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Check the reserved bits in CONNACK. The high 7 bits of the second byte\r
-     * in CONNACK must be 0. */\r
-    if( ( pRemainingData[ 0 ] | 0x01 ) != 0x01 )\r
-    {\r
-        IotLog( IOT_LOG_ERROR,\r
-                &_logHideAll,\r
-                "Reserved bits in CONNACK incorrect." );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Determine if the "Session Present" bit it set. This is the lowest bit of\r
-     * the second byte in CONNACK. */\r
-    if( ( pRemainingData[ 0 ] & MQTT_PACKET_CONNACK_SESSION_PRESENT_MASK )\r
-        == MQTT_PACKET_CONNACK_SESSION_PRESENT_MASK )\r
-    {\r
-        IotLog( IOT_LOG_DEBUG,\r
-                &_logHideAll,\r
-                "CONNACK session present bit set." );\r
-\r
-        /* MQTT 3.1.1 specifies that the fourth byte in CONNACK must be 0 if the\r
-         * "Session Present" bit is set. */\r
-        if( pRemainingData[ 1 ] != 0 )\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
-        IotLog( IOT_LOG_DEBUG,\r
-                &_logHideAll,\r
-                "CONNACK session present bit not set." );\r
-    }\r
-\r
-    /* In MQTT 3.1.1, only values 0 through 5 are valid CONNACK response codes. */\r
-    if( pRemainingData[ 1 ] > 5 )\r
-    {\r
-        IotLog( IOT_LOG_DEBUG,\r
-                &_logHideAll,\r
-                "CONNACK response %hhu is not valid.",\r
-                pRemainingData[ 1 ] );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Print the appropriate message for the CONNACK response code if logs are\r
-     * enabled. */\r
-    #if LIBRARY_LOG_LEVEL > IOT_LOG_NONE\r
-        IotLog( IOT_LOG_DEBUG,\r
-                &_logHideAll,\r
-                "%s",\r
-                pConnackResponses[ pRemainingData[ 1 ] ] );\r
-    #endif\r
-\r
-    /* A nonzero CONNACK response code means the connection was refused. */\r
-    if( pRemainingData[ 1 ] > 0 )\r
-    {\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_SERVER_REFUSED );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t _IotMqtt_SerializePublish( const IotMqttPublishInfo_t * pPublishInfo,\r
-                                          uint8_t ** pPublishPacket,\r
-                                          size_t * pPacketSize,\r
-                                          uint16_t * pPacketIdentifier,\r
-                                          uint8_t ** pPacketIdentifierHigh )\r
-{\r
-    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
-    uint8_t publishFlags = 0;\r
-    uint16_t packetIdentifier = 0;\r
-    size_t remainingLength = 0, publishPacketSize = 0;\r
-    uint8_t * pBuffer = NULL;\r
-\r
-    /* Calculate the "Remaining length" field and total packet size. If it exceeds\r
-     * what is allowed in the MQTT standard, return an error. */\r
-    if( _publishPacketSize( pPublishInfo, &remainingLength, &publishPacketSize ) == false )\r
-    {\r
-        IotLogError( "Publish packet remaining length exceeds %lu, which is the "\r
-                     "maximum size allowed by MQTT 3.1.1.",\r
-                     MQTT_MAX_REMAINING_LENGTH );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Total size of the publish packet should be larger than the "Remaining length"\r
-     * field. */\r
-    IotMqtt_Assert( publishPacketSize > remainingLength );\r
-\r
-    /* Allocate memory to hold the PUBLISH packet. */\r
-    pBuffer = IotMqtt_MallocMessage( publishPacketSize );\r
-\r
-    /* Check that sufficient memory was allocated. */\r
-    if( pBuffer == NULL )\r
-    {\r
-        IotLogError( "Failed to allocate memory for PUBLISH packet." );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NO_MEMORY );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Set the output parameters. The remainder of this function always succeeds. */\r
-    *pPublishPacket = pBuffer;\r
-    *pPacketSize = publishPacketSize;\r
-\r
-    /* The first byte of a PUBLISH packet contains the packet type and flags. */\r
-    publishFlags = MQTT_PACKET_TYPE_PUBLISH;\r
-\r
-    if( pPublishInfo->qos == IOT_MQTT_QOS_1 )\r
-    {\r
-        UINT8_SET_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS1 );\r
-    }\r
-    else if( pPublishInfo->qos == IOT_MQTT_QOS_2 )\r
-    {\r
-        UINT8_SET_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS2 );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    if( pPublishInfo->retain == true )\r
-    {\r
-        UINT8_SET_BIT( publishFlags, MQTT_PUBLISH_FLAG_RETAIN );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    *pBuffer = publishFlags;\r
-    pBuffer++;\r
-\r
-    /* The "Remaining length" is encoded from the second byte. */\r
-    pBuffer = _encodeRemainingLength( pBuffer, remainingLength );\r
-\r
-    /* The topic name is placed after the "Remaining length". */\r
-    pBuffer = _encodeString( pBuffer,\r
-                             pPublishInfo->pTopicName,\r
-                             pPublishInfo->topicNameLength );\r
-\r
-    /* A packet identifier is required for QoS 1 and 2 messages. */\r
-    if( pPublishInfo->qos > IOT_MQTT_QOS_0 )\r
-    {\r
-        /* Get the next packet identifier. It should always be nonzero. */\r
-        packetIdentifier = _nextPacketIdentifier();\r
-        IotMqtt_Assert( packetIdentifier != 0 );\r
-\r
-        /* Set the packet identifier output parameters. */\r
-        *pPacketIdentifier = packetIdentifier;\r
-\r
-        if( pPacketIdentifierHigh != NULL )\r
-        {\r
-            *pPacketIdentifierHigh = pBuffer;\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        /* Place the packet identifier into the PUBLISH packet. */\r
-        *pBuffer = UINT16_HIGH_BYTE( packetIdentifier );\r
-        *( pBuffer + 1 ) = UINT16_LOW_BYTE( packetIdentifier );\r
-        pBuffer += 2;\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* The payload is placed after the packet identifier. */\r
-    if( pPublishInfo->payloadLength > 0 )\r
-    {\r
-        ( void ) memcpy( pBuffer, pPublishInfo->pPayload, pPublishInfo->payloadLength );\r
-        pBuffer += pPublishInfo->payloadLength;\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Ensure that the difference between the end and beginning of the buffer\r
-     * is equal to publishPacketSize, i.e. pBuffer did not overflow. */\r
-    IotMqtt_Assert( ( size_t ) ( pBuffer - *pPublishPacket ) == publishPacketSize );\r
-\r
-    /* Print out the serialized PUBLISH packet for debugging purposes. */\r
-    IotLog_PrintBuffer( "MQTT PUBLISH packet:", *pPublishPacket, publishPacketSize );\r
-\r
-    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void _IotMqtt_PublishSetDup( uint8_t * pPublishPacket,\r
-                             uint8_t * pPacketIdentifierHigh,\r
-                             uint16_t * pNewPacketIdentifier )\r
-{\r
-    uint16_t newPacketIdentifier = 0;\r
-\r
-    /* For an AWS IoT MQTT server, change the packet identifier. */\r
-    if( pPacketIdentifierHigh != NULL )\r
-    {\r
-        /* Output parameter for new packet identifier must be provided. */\r
-        IotMqtt_Assert( pNewPacketIdentifier != NULL );\r
-\r
-        /* Generate a new packet identifier. */\r
-        newPacketIdentifier = _nextPacketIdentifier();\r
-\r
-        IotLogDebug( "Changing PUBLISH packet identifier %hu to %hu.",\r
-                     UINT16_DECODE( pPacketIdentifierHigh ),\r
-                     newPacketIdentifier );\r
-\r
-        /* Replace the packet identifier. */\r
-        *pPacketIdentifierHigh = UINT16_HIGH_BYTE( newPacketIdentifier );\r
-        *( pPacketIdentifierHigh + 1 ) = UINT16_LOW_BYTE( newPacketIdentifier );\r
-        *pNewPacketIdentifier = newPacketIdentifier;\r
-    }\r
-    else\r
-    {\r
-        /* For a compliant MQTT 3.1.1 server, set the DUP flag. */\r
-        UINT8_SET_BIT( *pPublishPacket, MQTT_PUBLISH_FLAG_DUP );\r
-\r
-        IotLogDebug( "PUBLISH DUP flag set." );\r
-    }\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t _IotMqtt_DeserializePublish( _mqttPacket_t * pPublish )\r
-{\r
-    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
-    IotMqttPublishInfo_t * pOutput = &( pPublish->u.pIncomingPublish->u.publish.publishInfo );\r
-    uint8_t publishFlags = 0;\r
-    const uint8_t * pVariableHeader = pPublish->pRemainingData, * pPacketIdentifierHigh = NULL;\r
-\r
-    /* The flags are the lower 4 bits of the first byte in PUBLISH. */\r
-    publishFlags = pPublish->type;\r
-\r
-    /* Parse the Retain bit. */\r
-    pOutput->retain = UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_RETAIN );\r
-\r
-    IotLog( IOT_LOG_DEBUG,\r
-            &_logHideAll,\r
-            "Retain bit is %d.", pOutput->retain );\r
-\r
-    /* Check for QoS 2. */\r
-    if( UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS2 ) == true )\r
-    {\r
-        /* PUBLISH packet is invalid if both QoS 1 and QoS 2 bits are set. */\r
-        if( UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS1 ) == true )\r
-        {\r
-            IotLog( IOT_LOG_DEBUG,\r
-                    &_logHideAll,\r
-                    "Bad QoS: 3." );\r
-\r
-            IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        pOutput->qos = IOT_MQTT_QOS_2;\r
-    }\r
-    /* Check for QoS 1. */\r
-    else if( UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS1 ) == true )\r
-    {\r
-        pOutput->qos = IOT_MQTT_QOS_1;\r
-    }\r
-    /* If the PUBLISH isn't QoS 1 or 2, then it's QoS 0. */\r
-    else\r
-    {\r
-        pOutput->qos = IOT_MQTT_QOS_0;\r
-    }\r
-\r
-    IotLog( IOT_LOG_DEBUG,\r
-            &_logHideAll,\r
-            "QoS is %d.", pOutput->qos );\r
-\r
-    /* Parse the DUP bit. */\r
-    if( UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_DUP ) == true )\r
-    {\r
-        IotLog( IOT_LOG_DEBUG,\r
-                &_logHideAll,\r
-                "DUP is 1." );\r
-    }\r
-    else\r
-    {\r
-        IotLog( IOT_LOG_DEBUG,\r
-                &_logHideAll,\r
-                "DUP is 0." );\r
-    }\r
-\r
-    /* Sanity checks for "Remaining length". */\r
-    if( pOutput->qos == IOT_MQTT_QOS_0 )\r
-    {\r
-        /* A QoS 0 PUBLISH must have a remaining length of at least 3 to accommodate\r
-         * topic name length (2 bytes) and topic name (at least 1 byte). */\r
-        if( pPublish->remainingLength < 3 )\r
-        {\r
-            IotLog( IOT_LOG_DEBUG,\r
-                    &_logHideAll,\r
-                    "QoS 0 PUBLISH cannot have a remaining length less than 3." );\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
-        /* A QoS 1 or 2 PUBLISH must have a remaining length of at least 5 to\r
-         * accommodate a packet identifier as well as the topic name length and\r
-         * topic name. */\r
-        if( pPublish->remainingLength < 5 )\r
-        {\r
-            IotLog( IOT_LOG_DEBUG,\r
-                    &_logHideAll,\r
-                    "QoS 1 or 2 PUBLISH cannot have a remaining length less than 5." );\r
-\r
-            IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-\r
-    /* Extract the topic name starting from the first byte of the variable header.\r
-     * The topic name string starts at byte 3 in the variable header. */\r
-    pOutput->topicNameLength = UINT16_DECODE( pVariableHeader );\r
-\r
-    /* Sanity checks for topic name length and "Remaining length". */\r
-    if( pOutput->qos == IOT_MQTT_QOS_0 )\r
-    {\r
-        /* Check that the "Remaining length" is at least as large as the variable\r
-         * header. */\r
-        if( pPublish->remainingLength < pOutput->topicNameLength + sizeof( uint16_t ) )\r
-        {\r
-            IotLog( IOT_LOG_DEBUG,\r
-                    &_logHideAll,\r
-                    "Remaining length cannot be less than variable header length." );\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
-        /* Check that the "Remaining length" is at least as large as the variable\r
-         * header. */\r
-        if( pPublish->remainingLength < pOutput->topicNameLength + 2 * sizeof( uint16_t ) )\r
-        {\r
-            IotLog( IOT_LOG_DEBUG,\r
-                    &_logHideAll,\r
-                    "Remaining length cannot be less than variable header length." );\r
-\r
-            IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-\r
-    /* Parse the topic. */\r
-    pOutput->pTopicName = ( const char * ) ( pVariableHeader + sizeof( uint16_t ) );\r
-\r
-    IotLog( IOT_LOG_DEBUG,\r
-            &_logHideAll,\r
-            "Topic name length %hu: %.*s",\r
-            pOutput->topicNameLength,\r
-            pOutput->topicNameLength,\r
-            pOutput->pTopicName );\r
-\r
-    /* Extract the packet identifier for QoS 1 or 2 PUBLISH packets. Packet\r
-     * identifier starts immediately after the topic name. */\r
-    pPacketIdentifierHigh = ( const uint8_t * ) ( pOutput->pTopicName + pOutput->topicNameLength );\r
-\r
-    if( pOutput->qos > IOT_MQTT_QOS_0 )\r
-    {\r
-        pPublish->packetIdentifier = UINT16_DECODE( pPacketIdentifierHigh );\r
-\r
-        IotLog( IOT_LOG_DEBUG,\r
-                &_logHideAll,\r
-                "Packet identifier %hu.", pPublish->packetIdentifier );\r
-\r
-        /* Packet identifier cannot be 0. */\r
-        if( pPublish->packetIdentifier == 0 )\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
-    /* Calculate the length of the payload. QoS 1 or 2 PUBLISH packets contain\r
-     * a packet identifer, but QoS 0 PUBLISH packets do not. */\r
-    if( pOutput->qos == IOT_MQTT_QOS_0 )\r
-    {\r
-        pOutput->payloadLength = ( uint16_t ) ( pPublish->remainingLength - pOutput->topicNameLength - sizeof( uint16_t ) );\r
-        pOutput->pPayload = pPacketIdentifierHigh;\r
-    }\r
-    else\r
-    {\r
-        pOutput->payloadLength = ( uint16_t ) ( pPublish->remainingLength - pOutput->topicNameLength - 2 * sizeof( uint16_t ) );\r
-        pOutput->pPayload = pPacketIdentifierHigh + sizeof( uint16_t );\r
-    }\r
-\r
-    IotLog( IOT_LOG_DEBUG,\r
-            &_logHideAll,\r
-            "Payload length %hu.", pOutput->payloadLength );\r
-\r
-    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t _IotMqtt_SerializePuback( uint16_t packetIdentifier,\r
-                                         uint8_t ** pPubackPacket,\r
-                                         size_t * pPacketSize )\r
-{\r
-    IotMqttError_t status = IOT_MQTT_SUCCESS;\r
-\r
-    /* Allocate memory for PUBACK. */\r
-    uint8_t * pBuffer = IotMqtt_MallocMessage( MQTT_PACKET_PUBACK_SIZE );\r
-\r
-    if( pBuffer == NULL )\r
-    {\r
-        IotLogError( "Failed to allocate memory for PUBACK packet" );\r
-\r
-        status = IOT_MQTT_NO_MEMORY;\r
-    }\r
-    else\r
-    {\r
-        /* Set the output parameters. The remainder of this function always succeeds. */\r
-        *pPubackPacket = pBuffer;\r
-        *pPacketSize = MQTT_PACKET_PUBACK_SIZE;\r
-\r
-        /* Set the 4 bytes in PUBACK. */\r
-        pBuffer[ 0 ] = MQTT_PACKET_TYPE_PUBACK;\r
-        pBuffer[ 1 ] = MQTT_PACKET_PUBACK_REMAINING_LENGTH;\r
-        pBuffer[ 2 ] = UINT16_HIGH_BYTE( packetIdentifier );\r
-        pBuffer[ 3 ] = UINT16_LOW_BYTE( packetIdentifier );\r
-\r
-        /* Print out the serialized PUBACK packet for debugging purposes. */\r
-        IotLog_PrintBuffer( "MQTT PUBACK packet:", *pPubackPacket, MQTT_PACKET_PUBACK_SIZE );\r
-    }\r
-\r
-    return status;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t _IotMqtt_DeserializePuback( _mqttPacket_t * pPuback )\r
-{\r
-    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
-\r
-    /* Check the "Remaining length" of the received PUBACK. */\r
-    if( pPuback->remainingLength != MQTT_PACKET_PUBACK_REMAINING_LENGTH )\r
-    {\r
-        IotLog( IOT_LOG_ERROR,\r
-                &_logHideAll,\r
-                "PUBACK does not have remaining length of %d.",\r
-                MQTT_PACKET_PUBACK_REMAINING_LENGTH );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Extract the packet identifier (third and fourth bytes) from PUBACK. */\r
-    pPuback->packetIdentifier = UINT16_DECODE( pPuback->pRemainingData );\r
-\r
-    IotLog( IOT_LOG_DEBUG,\r
-            &_logHideAll,\r
-            "Packet identifier %hu.", pPuback->packetIdentifier );\r
-\r
-    /* Packet identifier cannot be 0. */\r
-    if( pPuback->packetIdentifier == 0 )\r
-    {\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Check that the control packet type is 0x40 (this must be done after the\r
-     * packet identifier is parsed). */\r
-    if( pPuback->type != MQTT_PACKET_TYPE_PUBACK )\r
-    {\r
-        IotLog( IOT_LOG_ERROR,\r
-                &_logHideAll,\r
-                "Bad control packet type 0x%02x.",\r
-                pPuback->type );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t _IotMqtt_SerializeSubscribe( const IotMqttSubscription_t * pSubscriptionList,\r
-                                            size_t subscriptionCount,\r
-                                            uint8_t ** pSubscribePacket,\r
-                                            size_t * pPacketSize,\r
-                                            uint16_t * pPacketIdentifier )\r
-{\r
-    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
-    size_t i = 0, subscribePacketSize = 0, remainingLength = 0;\r
-    uint16_t packetIdentifier = 0;\r
-    uint8_t * pBuffer = NULL;\r
-\r
-    /* Calculate the "Remaining length" field and total packet size. If it exceeds\r
-     * what is allowed in the MQTT standard, return an error. */\r
-    if( _subscriptionPacketSize( IOT_MQTT_SUBSCRIBE,\r
-                                 pSubscriptionList,\r
-                                 subscriptionCount,\r
-                                 &remainingLength,\r
-                                 &subscribePacketSize ) == false )\r
-    {\r
-        IotLogError( "Subscribe packet remaining length exceeds %lu, which is the "\r
-                     "maximum size allowed by MQTT 3.1.1.",\r
-                     MQTT_MAX_REMAINING_LENGTH );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Total size of the subscribe packet should be larger than the "Remaining length"\r
-     * field. */\r
-    IotMqtt_Assert( subscribePacketSize > remainingLength );\r
-\r
-    /* Allocate memory to hold the SUBSCRIBE packet. */\r
-    pBuffer = IotMqtt_MallocMessage( subscribePacketSize );\r
-\r
-    /* Check that sufficient memory was allocated. */\r
-    if( pBuffer == NULL )\r
-    {\r
-        IotLogError( "Failed to allocate memory for SUBSCRIBE packet." );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NO_MEMORY );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Set the output parameters. The remainder of this function always succeeds. */\r
-    *pSubscribePacket = pBuffer;\r
-    *pPacketSize = subscribePacketSize;\r
-\r
-    /* The first byte in SUBSCRIBE is the packet type. */\r
-    *pBuffer = MQTT_PACKET_TYPE_SUBSCRIBE;\r
-    pBuffer++;\r
-\r
-    /* Encode the "Remaining length" starting from the second byte. */\r
-    pBuffer = _encodeRemainingLength( pBuffer, remainingLength );\r
-\r
-    /* Get the next packet identifier. It should always be nonzero. */\r
-    packetIdentifier = _nextPacketIdentifier();\r
-    *pPacketIdentifier = packetIdentifier;\r
-    IotMqtt_Assert( packetIdentifier != 0 );\r
-\r
-    /* Place the packet identifier into the SUBSCRIBE packet. */\r
-    *pBuffer = UINT16_HIGH_BYTE( packetIdentifier );\r
-    *( pBuffer + 1 ) = UINT16_LOW_BYTE( packetIdentifier );\r
-    pBuffer += 2;\r
-\r
-    /* Serialize each subscription topic filter and QoS. */\r
-    for( i = 0; i < subscriptionCount; i++ )\r
-    {\r
-        pBuffer = _encodeString( pBuffer,\r
-                                 pSubscriptionList[ i ].pTopicFilter,\r
-                                 pSubscriptionList[ i ].topicFilterLength );\r
-\r
-        /* Place the QoS in the SUBSCRIBE packet. */\r
-        *pBuffer = ( uint8_t ) ( pSubscriptionList[ i ].qos );\r
-        pBuffer++;\r
-    }\r
-\r
-    /* Ensure that the difference between the end and beginning of the buffer\r
-     * is equal to subscribePacketSize, i.e. pBuffer did not overflow. */\r
-    IotMqtt_Assert( ( size_t ) ( pBuffer - *pSubscribePacket ) == subscribePacketSize );\r
-\r
-    /* Print out the serialized SUBSCRIBE packet for debugging purposes. */\r
-    IotLog_PrintBuffer( "MQTT SUBSCRIBE packet:", *pSubscribePacket, subscribePacketSize );\r
-\r
-    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t _IotMqtt_DeserializeSuback( _mqttPacket_t * pSuback )\r
-{\r
-    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
-    size_t i = 0, remainingLength = pSuback->remainingLength;\r
-    uint8_t subscriptionStatus = 0;\r
-    const uint8_t * pVariableHeader = pSuback->pRemainingData;\r
-\r
-    /* A SUBACK must have a remaining length of at least 3 to accommodate the\r
-     * packet identifer and at least 1 return code. */\r
-    if( remainingLength < 3 )\r
-    {\r
-        IotLog( IOT_LOG_DEBUG,\r
-                &_logHideAll,\r
-                "SUBACK cannot have a remaining length less than 3." );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Extract the packet identifier (first 2 bytes of variable header) from SUBACK. */\r
-    pSuback->packetIdentifier = UINT16_DECODE( pVariableHeader );\r
-\r
-    IotLog( IOT_LOG_DEBUG,\r
-            &_logHideAll,\r
-            "Packet identifier %hu.", pSuback->packetIdentifier );\r
-\r
-    /* Check that the control packet type is 0x90 (this must be done after the\r
-     * packet identifier is parsed). */\r
-    if( pSuback->type != MQTT_PACKET_TYPE_SUBACK )\r
-    {\r
-        IotLog( IOT_LOG_ERROR,\r
-                &_logHideAll,\r
-                "Bad control packet type 0x%02x.",\r
-                pSuback->type );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Iterate through each status byte in the SUBACK packet. */\r
-    for( i = 0; i < remainingLength - sizeof( uint16_t ); i++ )\r
-    {\r
-        /* Read a single status byte in SUBACK. */\r
-        subscriptionStatus = *( pVariableHeader + sizeof( uint16_t ) + i );\r
-\r
-        /* MQTT 3.1.1 defines the following values as status codes. */\r
-        switch( subscriptionStatus )\r
-        {\r
-            case 0x00:\r
-            case 0x01:\r
-            case 0x02:\r
-                IotLog( IOT_LOG_DEBUG,\r
-                        &_logHideAll,\r
-                        "Topic filter %lu accepted, max QoS %hhu.",\r
-                        ( unsigned long ) i, subscriptionStatus );\r
-                break;\r
-\r
-            case 0x80:\r
-                IotLog( IOT_LOG_DEBUG,\r
-                        &_logHideAll,\r
-                        "Topic filter %lu refused.", ( unsigned long ) i );\r
-\r
-                /* Remove a rejected subscription from the subscription manager. */\r
-                _IotMqtt_RemoveSubscriptionByPacket( pSuback->u.pMqttConnection,\r
-                                                     pSuback->packetIdentifier,\r
-                                                     ( int32_t ) i );\r
-\r
-                status = IOT_MQTT_SERVER_REFUSED;\r
-\r
-                break;\r
-\r
-            default:\r
-                IotLog( IOT_LOG_DEBUG,\r
-                        &_logHideAll,\r
-                        "Bad SUBSCRIBE status %hhu.", subscriptionStatus );\r
-\r
-                status = IOT_MQTT_BAD_RESPONSE;\r
-\r
-                break;\r
-        }\r
-\r
-        /* Stop parsing the subscription statuses if a bad response was received. */\r
-        if( status == IOT_MQTT_BAD_RESPONSE )\r
-        {\r
-            break;\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-\r
-    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t _IotMqtt_SerializeUnsubscribe( const IotMqttSubscription_t * pSubscriptionList,\r
-                                              size_t subscriptionCount,\r
-                                              uint8_t ** pUnsubscribePacket,\r
-                                              size_t * pPacketSize,\r
-                                              uint16_t * pPacketIdentifier )\r
-{\r
-    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
-    size_t i = 0, unsubscribePacketSize = 0, remainingLength = 0;\r
-    uint16_t packetIdentifier = 0;\r
-    uint8_t * pBuffer = NULL;\r
-\r
-    /* Calculate the "Remaining length" field and total packet size. If it exceeds\r
-     * what is allowed in the MQTT standard, return an error. */\r
-    if( _subscriptionPacketSize( IOT_MQTT_UNSUBSCRIBE,\r
-                                 pSubscriptionList,\r
-                                 subscriptionCount,\r
-                                 &remainingLength,\r
-                                 &unsubscribePacketSize ) == false )\r
-    {\r
-        IotLogError( "Unsubscribe packet remaining length exceeds %lu, which is the "\r
-                     "maximum size allowed by MQTT 3.1.1.",\r
-                     MQTT_MAX_REMAINING_LENGTH );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Total size of the unsubscribe packet should be larger than the "Remaining length"\r
-     * field. */\r
-    IotMqtt_Assert( unsubscribePacketSize > remainingLength );\r
-\r
-    /* Allocate memory to hold the UNSUBSCRIBE packet. */\r
-    pBuffer = IotMqtt_MallocMessage( unsubscribePacketSize );\r
-\r
-    /* Check that sufficient memory was allocated. */\r
-    if( pBuffer == NULL )\r
-    {\r
-        IotLogError( "Failed to allocate memory for UNSUBSCRIBE packet." );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NO_MEMORY );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Set the output parameters. The remainder of this function always succeeds. */\r
-    *pUnsubscribePacket = pBuffer;\r
-    *pPacketSize = unsubscribePacketSize;\r
-\r
-    /* The first byte in UNSUBSCRIBE is the packet type. */\r
-    *pBuffer = MQTT_PACKET_TYPE_UNSUBSCRIBE;\r
-    pBuffer++;\r
-\r
-    /* Encode the "Remaining length" starting from the second byte. */\r
-    pBuffer = _encodeRemainingLength( pBuffer, remainingLength );\r
-\r
-    /* Get the next packet identifier. It should always be nonzero. */\r
-    packetIdentifier = _nextPacketIdentifier();\r
-    *pPacketIdentifier = packetIdentifier;\r
-    IotMqtt_Assert( packetIdentifier != 0 );\r
-\r
-    /* Place the packet identifier into the UNSUBSCRIBE packet. */\r
-    *pBuffer = UINT16_HIGH_BYTE( packetIdentifier );\r
-    *( pBuffer + 1 ) = UINT16_LOW_BYTE( packetIdentifier );\r
-    pBuffer += 2;\r
-\r
-    /* Serialize each subscription topic filter. */\r
-    for( i = 0; i < subscriptionCount; i++ )\r
-    {\r
-        pBuffer = _encodeString( pBuffer,\r
-                                 pSubscriptionList[ i ].pTopicFilter,\r
-                                 pSubscriptionList[ i ].topicFilterLength );\r
-    }\r
-\r
-    /* Ensure that the difference between the end and beginning of the buffer\r
-     * is equal to unsubscribePacketSize, i.e. pBuffer did not overflow. */\r
-    IotMqtt_Assert( ( size_t ) ( pBuffer - *pUnsubscribePacket ) == unsubscribePacketSize );\r
-\r
-    /* Print out the serialized UNSUBSCRIBE packet for debugging purposes. */\r
-    IotLog_PrintBuffer( "MQTT UNSUBSCRIBE packet:", *pUnsubscribePacket, unsubscribePacketSize );\r
-\r
-    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t _IotMqtt_DeserializeUnsuback( _mqttPacket_t * pUnsuback )\r
-{\r
-    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
-\r
-    /* Check the "Remaining length" (second byte) of the received UNSUBACK. */\r
-    if( pUnsuback->remainingLength != MQTT_PACKET_UNSUBACK_REMAINING_LENGTH )\r
-    {\r
-        IotLog( IOT_LOG_ERROR,\r
-                &_logHideAll,\r
-                "UNSUBACK does not have remaining length of %d.",\r
-                MQTT_PACKET_UNSUBACK_REMAINING_LENGTH );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Extract the packet identifier (third and fourth bytes) from UNSUBACK. */\r
-    pUnsuback->packetIdentifier = UINT16_DECODE( pUnsuback->pRemainingData );\r
-\r
-    /* Packet identifier cannot be 0. */\r
-    if( pUnsuback->packetIdentifier == 0 )\r
-    {\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    IotLog( IOT_LOG_DEBUG,\r
-            &_logHideAll,\r
-            "Packet identifier %hu.", pUnsuback->packetIdentifier );\r
-\r
-    /* Check that the control packet type is 0xb0 (this must be done after the\r
-     * packet identifier is parsed). */\r
-    if( pUnsuback->type != MQTT_PACKET_TYPE_UNSUBACK )\r
-    {\r
-        IotLog( IOT_LOG_ERROR,\r
-                &_logHideAll,\r
-                "Bad control packet type 0x%02x.",\r
-                pUnsuback->type );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t _IotMqtt_SerializePingreq( uint8_t ** pPingreqPacket,\r
-                                          size_t * pPacketSize )\r
-{\r
-    /* PINGREQ packets are always the same. */\r
-    static const uint8_t pPingreq[ MQTT_PACKET_PINGREQ_SIZE ] =\r
-    {\r
-        MQTT_PACKET_TYPE_PINGREQ,\r
-        0x00\r
-    };\r
-\r
-    /* Set the output parameters. */\r
-    *pPingreqPacket = ( uint8_t * ) pPingreq;\r
-    *pPacketSize = MQTT_PACKET_PINGREQ_SIZE;\r
-\r
-    /* Print out the PINGREQ packet for debugging purposes. */\r
-    IotLog_PrintBuffer( "MQTT PINGREQ packet:", pPingreq, MQTT_PACKET_PINGREQ_SIZE );\r
-\r
-    return IOT_MQTT_SUCCESS;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t _IotMqtt_DeserializePingresp( _mqttPacket_t * pPingresp )\r
-{\r
-    IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS );\r
-\r
-    /* Check that the control packet type is 0xd0. */\r
-    if( pPingresp->type != MQTT_PACKET_TYPE_PINGRESP )\r
-    {\r
-        IotLog( IOT_LOG_ERROR,\r
-                &_logHideAll,\r
-                "Bad control packet type 0x%02x.",\r
-                pPingresp->type );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Check the "Remaining length" (second byte) of the received PINGRESP. */\r
-    if( pPingresp->remainingLength != MQTT_PACKET_PINGRESP_REMAINING_LENGTH )\r
-    {\r
-        IotLog( IOT_LOG_ERROR,\r
-                &_logHideAll,\r
-                "PINGRESP does not have remaining length of %d.",\r
-                MQTT_PACKET_PINGRESP_REMAINING_LENGTH );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t _IotMqtt_SerializeDisconnect( uint8_t ** pDisconnectPacket,\r
-                                             size_t * pPacketSize )\r
-{\r
-    /* DISCONNECT packets are always the same. */\r
-    static const uint8_t pDisconnect[ MQTT_PACKET_DISCONNECT_SIZE ] =\r
-    {\r
-        MQTT_PACKET_TYPE_DISCONNECT,\r
-        0x00\r
-    };\r
-\r
-    /* Set the output parameters. */\r
-    *pDisconnectPacket = ( uint8_t * ) pDisconnect;\r
-    *pPacketSize = MQTT_PACKET_DISCONNECT_SIZE;\r
-\r
-    /* Print out the DISCONNECT packet for debugging purposes. */\r
-    IotLog_PrintBuffer( "MQTT DISCONNECT packet:", pDisconnect, MQTT_PACKET_DISCONNECT_SIZE );\r
-\r
-    return IOT_MQTT_SUCCESS;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void _IotMqtt_FreePacket( uint8_t * pPacket )\r
-{\r
-    uint8_t packetType = *pPacket;\r
-\r
-    /* Don't call free on DISCONNECT and PINGREQ; those are allocated from static\r
-     * memory. */\r
-    if( packetType != MQTT_PACKET_TYPE_DISCONNECT )\r
-    {\r
-        if( packetType != MQTT_PACKET_TYPE_PINGREQ )\r
-        {\r
-            IotMqtt_FreeMessage( pPacket );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_mqtt_static_memory.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_mqtt_static_memory.c
deleted file mode 100644 (file)
index 000fcba..0000000
+++ /dev/null
@@ -1,207 +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_static_memory.c\r
- * @brief Implementation of MQTT static memory functions.\r
- */\r
-\r
-/* The config header is always included first. */\r
-#include "iot_config.h"\r
-\r
-/* This file should only be compiled if dynamic memory allocation is forbidden. */\r
-#if IOT_STATIC_MEMORY_ONLY == 1\r
-\r
-/* Standard includes. */\r
-#include <stdbool.h>\r
-#include <stddef.h>\r
-#include <string.h>\r
-\r
-/* Static memory include. */\r
-#include "private/iot_static_memory.h"\r
-\r
-/* MQTT internal include. */\r
-#include "private/iot_mqtt_internal.h"\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/**\r
- * @cond DOXYGEN_IGNORE\r
- * Doxygen should ignore this section.\r
- *\r
- * Provide default values for undefined configuration constants.\r
- */\r
-#ifndef IOT_MQTT_CONNECTIONS\r
-    #define IOT_MQTT_CONNECTIONS                   ( 1 )\r
-#endif\r
-#ifndef IOT_MQTT_MAX_IN_PROGRESS_OPERATIONS\r
-    #define IOT_MQTT_MAX_IN_PROGRESS_OPERATIONS    ( 10 )\r
-#endif\r
-#ifndef IOT_MQTT_SUBSCRIPTIONS\r
-    #define IOT_MQTT_SUBSCRIPTIONS                 ( 8 )\r
-#endif\r
-/** @endcond */\r
-\r
-/* Validate static memory configuration settings. */\r
-#if IOT_MQTT_CONNECTIONS <= 0\r
-    #error "IOT_MQTT_CONNECTIONS cannot be 0 or negative."\r
-#endif\r
-#if IOT_MQTT_MAX_IN_PROGRESS_OPERATIONS <= 0\r
-    #error "IOT_MQTT_MAX_IN_PROGRESS_OPERATIONS cannot be 0 or negative."\r
-#endif\r
-#if IOT_MQTT_SUBSCRIPTIONS <= 0\r
-    #error "IOT_MQTT_SUBSCRIPTIONS cannot be 0 or negative."\r
-#endif\r
-\r
-/**\r
- * @brief The size of a static memory MQTT subscription.\r
- *\r
- * Since the pTopic member of #_mqttSubscription_t is variable-length, the constant\r
- * #AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH is used for the length of\r
- * #_mqttSubscription_t.pTopicFilter.\r
- */\r
-#define MQTT_SUBSCRIPTION_SIZE    ( sizeof( _mqttSubscription_t ) + AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH )\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/*\r
- * Static memory buffers and flags, allocated and zeroed at compile-time.\r
- */\r
-static bool _pInUseMqttConnections[ IOT_MQTT_CONNECTIONS ] = { 0 };                               /**< @brief MQTT connection in-use flags. */\r
-static _mqttConnection_t _pMqttConnections[ IOT_MQTT_CONNECTIONS ] = { { 0 } };                   /**< @brief MQTT connections. */\r
-\r
-static bool _pInUseMqttOperations[ IOT_MQTT_MAX_IN_PROGRESS_OPERATIONS ] = { 0 };                        /**< @brief MQTT operation in-use flags. */\r
-static _mqttOperation_t _pMqttOperations[ IOT_MQTT_MAX_IN_PROGRESS_OPERATIONS ] = { { .link = { 0 } } }; /**< @brief MQTT operations. */\r
-\r
-static bool _pInUseMqttSubscriptions[ IOT_MQTT_SUBSCRIPTIONS ] = { 0 };                           /**< @brief MQTT subscription in-use flags. */\r
-static char _pMqttSubscriptions[ IOT_MQTT_SUBSCRIPTIONS ][ MQTT_SUBSCRIPTION_SIZE ] = { { 0 } };  /**< @brief MQTT subscriptions. */\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void * IotMqtt_MallocConnection( size_t size )\r
-{\r
-    int32_t freeIndex = -1;\r
-    void * pNewConnection = NULL;\r
-\r
-    /* Check size argument. */\r
-    if( size == sizeof( _mqttConnection_t ) )\r
-    {\r
-        /* Find a free MQTT connection. */\r
-        freeIndex = IotStaticMemory_FindFree( _pInUseMqttConnections,\r
-                                              IOT_MQTT_CONNECTIONS );\r
-\r
-        if( freeIndex != -1 )\r
-        {\r
-            pNewConnection = &( _pMqttConnections[ freeIndex ] );\r
-        }\r
-    }\r
-\r
-    return pNewConnection;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void IotMqtt_FreeConnection( void * ptr )\r
-{\r
-    /* Return the in-use MQTT connection. */\r
-    IotStaticMemory_ReturnInUse( ptr,\r
-                                 _pMqttConnections,\r
-                                 _pInUseMqttConnections,\r
-                                 IOT_MQTT_CONNECTIONS,\r
-                                 sizeof( _mqttConnection_t ) );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void * IotMqtt_MallocOperation( size_t size )\r
-{\r
-    int32_t freeIndex = -1;\r
-    void * pNewOperation = NULL;\r
-\r
-    /* Check size argument. */\r
-    if( size == sizeof( _mqttOperation_t ) )\r
-    {\r
-        /* Find a free MQTT operation. */\r
-        freeIndex = IotStaticMemory_FindFree( _pInUseMqttOperations,\r
-                                              IOT_MQTT_MAX_IN_PROGRESS_OPERATIONS );\r
-\r
-        if( freeIndex != -1 )\r
-        {\r
-            pNewOperation = &( _pMqttOperations[ freeIndex ] );\r
-        }\r
-    }\r
-\r
-    return pNewOperation;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void IotMqtt_FreeOperation( void * ptr )\r
-{\r
-    /* Return the in-use MQTT operation. */\r
-    IotStaticMemory_ReturnInUse( ptr,\r
-                                 _pMqttOperations,\r
-                                 _pInUseMqttOperations,\r
-                                 IOT_MQTT_MAX_IN_PROGRESS_OPERATIONS,\r
-                                 sizeof( _mqttOperation_t ) );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void * IotMqtt_MallocSubscription( size_t size )\r
-{\r
-    int32_t freeIndex = -1;\r
-    void * pNewSubscription = NULL;\r
-\r
-    if( size <= MQTT_SUBSCRIPTION_SIZE )\r
-    {\r
-        /* Get the index of a free MQTT subscription. */\r
-        freeIndex = IotStaticMemory_FindFree( _pInUseMqttSubscriptions,\r
-                                              IOT_MQTT_SUBSCRIPTIONS );\r
-\r
-        if( freeIndex != -1 )\r
-        {\r
-            pNewSubscription = &( _pMqttSubscriptions[ freeIndex ][ 0 ] );\r
-        }\r
-    }\r
-\r
-    return pNewSubscription;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void IotMqtt_FreeSubscription( void * ptr )\r
-{\r
-    /* Return the in-use MQTT subscription. */\r
-    IotStaticMemory_ReturnInUse( ptr,\r
-                                 _pMqttSubscriptions,\r
-                                 _pInUseMqttSubscriptions,\r
-                                 IOT_MQTT_SUBSCRIPTIONS,\r
-                                 MQTT_SUBSCRIPTION_SIZE );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-#endif\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_mqtt_subscription.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_mqtt_subscription.c
deleted file mode 100644 (file)
index 99664de..0000000
+++ /dev/null
@@ -1,648 +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_subscription.c\r
- * @brief Implements functions that manage subscriptions for an MQTT connection.\r
- */\r
-\r
-/* The config header is always included first. */\r
-#include "iot_config.h"\r
-\r
-/* Standard includes. */\r
-#include <stdbool.h>\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
-/*-----------------------------------------------------------*/\r
-\r
-/**\r
- * @brief First parameter to #_topicMatch.\r
- */\r
-typedef struct _topicMatchParams\r
-{\r
-    const char * pTopicName;  /**< @brief The topic name to parse. */\r
-    uint16_t topicNameLength; /**< @brief Length of #_topicMatchParams_t.pTopicName. */\r
-    bool exactMatchOnly;      /**< @brief Whether to allow wildcards or require exact matches. */\r
-} _topicMatchParams_t;\r
-\r
-/**\r
- * @brief First parameter to #_packetMatch.\r
- */\r
-typedef struct _packetMatchParams\r
-{\r
-    uint16_t packetIdentifier; /**< Packet identifier to match. */\r
-    int32_t order;             /**< Order to match. Set to `-1` to ignore. */\r
-} _packetMatchParams_t;\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/**\r
- * @brief Matches a topic name (from a publish) with a topic filter (from a\r
- * subscription).\r
- *\r
- * @param[in] pSubscriptionLink Pointer to the link member of an #_mqttSubscription_t.\r
- * @param[in] pMatch Pointer to a #_topicMatchParams_t.\r
- *\r
- * @return `true` if the arguments match the subscription topic filter; `false`\r
- * otherwise.\r
- */\r
-static bool _topicMatch( const IotLink_t * pSubscriptionLink,\r
-                         void * pMatch );\r
-\r
-/**\r
- * @brief Matches a packet identifier and order.\r
- *\r
- * @param[in] pSubscriptionLink Pointer to the link member of an #_mqttSubscription_t.\r
- * @param[in] pMatch Pointer to a #_packetMatchParams_t.\r
- *\r
- * @return `true` if the arguments match the subscription's packet info; `false`\r
- * otherwise.\r
- */\r
-static bool _packetMatch( const IotLink_t * pSubscriptionLink,\r
-                          void * pMatch );\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static bool _topicMatch( const IotLink_t * pSubscriptionLink,\r
-                         void * pMatch )\r
-{\r
-    IOT_FUNCTION_ENTRY( bool, false );\r
-    uint16_t nameIndex = 0, filterIndex = 0;\r
-\r
-    /* Because this function is called from a container function, the given link\r
-     * must never be NULL. */\r
-    IotMqtt_Assert( pSubscriptionLink != NULL );\r
-\r
-    _mqttSubscription_t * pSubscription = IotLink_Container( _mqttSubscription_t,\r
-                                                             pSubscriptionLink,\r
-                                                             link );\r
-    _topicMatchParams_t * pParam = ( _topicMatchParams_t * ) pMatch;\r
-\r
-    /* Extract the relevant strings and lengths from parameters. */\r
-    const char * pTopicName = pParam->pTopicName;\r
-    const char * pTopicFilter = pSubscription->pTopicFilter;\r
-    const uint16_t topicNameLength = pParam->topicNameLength;\r
-    const uint16_t topicFilterLength = pSubscription->topicFilterLength;\r
-\r
-    /* Check for an exact match. */\r
-    if( topicNameLength == topicFilterLength )\r
-    {\r
-        status = ( strncmp( pTopicName, pTopicFilter, topicNameLength ) == 0 );\r
-\r
-        IOT_GOTO_CLEANUP();\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* If the topic lengths are different but an exact match is required, return\r
-     * false. */\r
-    if( pParam->exactMatchOnly == true )\r
-    {\r
-        IOT_SET_AND_GOTO_CLEANUP( false );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    while( ( nameIndex < topicNameLength ) && ( filterIndex < topicFilterLength ) )\r
-    {\r
-        /* Check if the character in the topic name matches the corresponding\r
-         * character in the topic filter string. */\r
-        if( pTopicName[ nameIndex ] == pTopicFilter[ filterIndex ] )\r
-        {\r
-            /* Handle special corner cases as documented by the MQTT protocol spec. */\r
-\r
-            /* Filter "sport/#" also matches "sport" since # includes the parent level. */\r
-            if( nameIndex == topicNameLength - 1 )\r
-            {\r
-                if( filterIndex == topicFilterLength - 3 )\r
-                {\r
-                    if( pTopicFilter[ filterIndex + 1 ] == '/' )\r
-                    {\r
-                        if( pTopicFilter[ filterIndex + 2 ] == '#' )\r
-                        {\r
-                            IOT_SET_AND_GOTO_CLEANUP( true );\r
-                        }\r
-                        else\r
-                        {\r
-                            EMPTY_ELSE_MARKER;\r
-                        }\r
-                    }\r
-                    else\r
-                    {\r
-                        EMPTY_ELSE_MARKER;\r
-                    }\r
-                }\r
-                else\r
-                {\r
-                    EMPTY_ELSE_MARKER;\r
-                }\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-\r
-            /* Filter "sport/+" also matches the "sport/" but not "sport". */\r
-            if( nameIndex == topicNameLength - 1 )\r
-            {\r
-                if( filterIndex == topicFilterLength - 2 )\r
-                {\r
-                    if( pTopicFilter[ filterIndex + 1 ] == '+' )\r
-                    {\r
-                        IOT_SET_AND_GOTO_CLEANUP( true );\r
-                    }\r
-                    else\r
-                    {\r
-                        EMPTY_ELSE_MARKER;\r
-                    }\r
-                }\r
-                else\r
-                {\r
-                    EMPTY_ELSE_MARKER;\r
-                }\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            /* Check for wildcards. */\r
-            if( pTopicFilter[ filterIndex ] == '+' )\r
-            {\r
-                /* Move topic name index to the end of the current level.\r
-                 * This is identified by '/'. */\r
-                while( nameIndex < topicNameLength && pTopicName[ nameIndex ] != '/' )\r
-                {\r
-                    nameIndex++;\r
-                }\r
-\r
-                /* Increment filter index to skip '/'. */\r
-                filterIndex++;\r
-                continue;\r
-            }\r
-            else if( pTopicFilter[ filterIndex ] == '#' )\r
-            {\r
-                /* Subsequent characters don't need to be checked if the for the\r
-                 * multi-level wildcard. */\r
-                IOT_SET_AND_GOTO_CLEANUP( true );\r
-            }\r
-            else\r
-            {\r
-                /* Any character mismatch other than '+' or '#' means the topic\r
-                 * name does not match the topic filter. */\r
-                IOT_SET_AND_GOTO_CLEANUP( false );\r
-            }\r
-        }\r
-\r
-        /* Increment indexes. */\r
-        nameIndex++;\r
-        filterIndex++;\r
-    }\r
-\r
-    /* If the end of both strings has been reached, they match. */\r
-    if( ( nameIndex == topicNameLength ) && ( filterIndex == topicFilterLength ) )\r
-    {\r
-        IOT_SET_AND_GOTO_CLEANUP( true );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static bool _packetMatch( const IotLink_t * pSubscriptionLink,\r
-                          void * pMatch )\r
-{\r
-    bool match = false;\r
-\r
-    /* Because this function is called from a container function, the given link\r
-     * must never be NULL. */\r
-    IotMqtt_Assert( pSubscriptionLink != NULL );\r
-\r
-    _mqttSubscription_t * pSubscription = IotLink_Container( _mqttSubscription_t,\r
-                                                             pSubscriptionLink,\r
-                                                             link );\r
-    _packetMatchParams_t * pParam = ( _packetMatchParams_t * ) pMatch;\r
-\r
-    /* Compare packet identifiers. */\r
-    if( pParam->packetIdentifier == pSubscription->packetInfo.identifier )\r
-    {\r
-        /* Compare orders if order is not -1. */\r
-        if( pParam->order == -1 )\r
-        {\r
-            match = true;\r
-        }\r
-        else\r
-        {\r
-            match = ( ( size_t ) pParam->order ) == pSubscription->packetInfo.order;\r
-        }\r
-    }\r
-\r
-    /* If this subscription should be removed, check the reference count. */\r
-    if( match == true )\r
-    {\r
-        /* Reference count must not be negative. */\r
-        IotMqtt_Assert( pSubscription->references >= 0 );\r
-\r
-        /* If the reference count is positive, this subscription cannot be\r
-         * removed yet because there are subscription callbacks using it. */\r
-        if( pSubscription->references > 0 )\r
-        {\r
-            match = false;\r
-\r
-            /* Set the unsubscribed flag. The last active subscription callback\r
-             * will remove and clean up this subscription. */\r
-            pSubscription->unsubscribed = true;\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    return match;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotMqttError_t _IotMqtt_AddSubscriptions( _mqttConnection_t * pMqttConnection,\r
-                                          uint16_t subscribePacketIdentifier,\r
-                                          const IotMqttSubscription_t * pSubscriptionList,\r
-                                          size_t subscriptionCount )\r
-{\r
-    IotMqttError_t status = IOT_MQTT_SUCCESS;\r
-    size_t i = 0;\r
-    _mqttSubscription_t * pNewSubscription = NULL;\r
-    IotLink_t * pSubscriptionLink = NULL;\r
-    _topicMatchParams_t topicMatchParams = { .exactMatchOnly = true };\r
-\r
-    IotMutex_Lock( &( pMqttConnection->subscriptionMutex ) );\r
-\r
-    for( i = 0; i < subscriptionCount; i++ )\r
-    {\r
-        /* Check if this topic filter is already registered. */\r
-        topicMatchParams.pTopicName = pSubscriptionList[ i ].pTopicFilter;\r
-        topicMatchParams.topicNameLength = pSubscriptionList[ i ].topicFilterLength;\r
-        pSubscriptionLink = IotListDouble_FindFirstMatch( &( pMqttConnection->subscriptionList ),\r
-                                                          NULL,\r
-                                                          _topicMatch,\r
-                                                          &topicMatchParams );\r
-\r
-        if( pSubscriptionLink != NULL )\r
-        {\r
-            pNewSubscription = IotLink_Container( _mqttSubscription_t, pSubscriptionLink, link );\r
-\r
-            /* The lengths of exactly matching topic filters must match. */\r
-            IotMqtt_Assert( pNewSubscription->topicFilterLength == pSubscriptionList[ i ].topicFilterLength );\r
-\r
-            /* Replace the callback and packet info with the new parameters. */\r
-            pNewSubscription->callback = pSubscriptionList[ i ].callback;\r
-            pNewSubscription->packetInfo.identifier = subscribePacketIdentifier;\r
-            pNewSubscription->packetInfo.order = i;\r
-        }\r
-        else\r
-        {\r
-            /* Allocate memory for a new subscription. */\r
-            pNewSubscription = IotMqtt_MallocSubscription( sizeof( _mqttSubscription_t ) +\r
-                                                           pSubscriptionList[ i ].topicFilterLength );\r
-\r
-            if( pNewSubscription == NULL )\r
-            {\r
-                status = IOT_MQTT_NO_MEMORY;\r
-                break;\r
-            }\r
-            else\r
-            {\r
-                /* Clear the new subscription. */\r
-                ( void ) memset( pNewSubscription,\r
-                                 0x00,\r
-                                 sizeof( _mqttSubscription_t ) + pSubscriptionList[ i ].topicFilterLength );\r
-\r
-                /* Set the members of the new subscription and add it to the list. */\r
-                pNewSubscription->packetInfo.identifier = subscribePacketIdentifier;\r
-                pNewSubscription->packetInfo.order = i;\r
-                pNewSubscription->callback = pSubscriptionList[ i ].callback;\r
-                pNewSubscription->topicFilterLength = pSubscriptionList[ i ].topicFilterLength;\r
-                ( void ) memcpy( pNewSubscription->pTopicFilter,\r
-                                 pSubscriptionList[ i ].pTopicFilter,\r
-                                 ( size_t ) ( pSubscriptionList[ i ].topicFilterLength ) );\r
-\r
-                IotListDouble_InsertHead( &( pMqttConnection->subscriptionList ),\r
-                                          &( pNewSubscription->link ) );\r
-            }\r
-        }\r
-    }\r
-\r
-    IotMutex_Unlock( &( pMqttConnection->subscriptionMutex ) );\r
-\r
-    /* If memory allocation failed, remove all previously added subscriptions. */\r
-    if( status != IOT_MQTT_SUCCESS )\r
-    {\r
-        _IotMqtt_RemoveSubscriptionByTopicFilter( pMqttConnection,\r
-                                                  pSubscriptionList,\r
-                                                  i );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    return status;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void _IotMqtt_InvokeSubscriptionCallback( _mqttConnection_t * pMqttConnection,\r
-                                          IotMqttCallbackParam_t * pCallbackParam )\r
-{\r
-    _mqttSubscription_t * pSubscription = NULL;\r
-    IotLink_t * pCurrentLink = NULL, * pNextLink = NULL;\r
-    void * pCallbackContext = NULL;\r
-\r
-    void ( * callbackFunction )( void *,\r
-                                 IotMqttCallbackParam_t * ) = NULL;\r
-    _topicMatchParams_t topicMatchParams =\r
-    {\r
-        .pTopicName      = pCallbackParam->u.message.info.pTopicName,\r
-        .topicNameLength = pCallbackParam->u.message.info.topicNameLength,\r
-        .exactMatchOnly  = false\r
-    };\r
-\r
-    /* Prevent any other thread from modifying the subscription list while this\r
-     * function is searching. */\r
-    IotMutex_Lock( &( pMqttConnection->subscriptionMutex ) );\r
-\r
-    /* Search the subscription list for all matching subscriptions starting at\r
-     * the list head. */\r
-    while( true )\r
-    {\r
-        pCurrentLink = IotListDouble_FindFirstMatch( &( pMqttConnection->subscriptionList ),\r
-                                                     pCurrentLink,\r
-                                                     _topicMatch,\r
-                                                     &topicMatchParams );\r
-\r
-        /* No subscription found. Exit loop. */\r
-        if( pCurrentLink == NULL )\r
-        {\r
-            break;\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        /* Subscription found. Calculate pointer to subscription object. */\r
-        pSubscription = IotLink_Container( _mqttSubscription_t, pCurrentLink, link );\r
-\r
-        /* Subscription validation should not have allowed a NULL callback function. */\r
-        IotMqtt_Assert( pSubscription->callback.function != NULL );\r
-\r
-        /* Increment the subscription's reference count. */\r
-        ( pSubscription->references )++;\r
-\r
-        /* Copy the necessary members of the subscription before releasing the\r
-         * subscription list mutex. */\r
-        pCallbackContext = pSubscription->callback.pCallbackContext;\r
-        callbackFunction = pSubscription->callback.function;\r
-\r
-        /* Unlock the subscription list mutex. */\r
-        IotMutex_Unlock( &( pMqttConnection->subscriptionMutex ) );\r
-\r
-        /* Set the members of the callback parameter. */\r
-        pCallbackParam->mqttConnection = pMqttConnection;\r
-        pCallbackParam->u.message.pTopicFilter = pSubscription->pTopicFilter;\r
-        pCallbackParam->u.message.topicFilterLength = pSubscription->topicFilterLength;\r
-\r
-        /* Invoke the subscription callback. */\r
-        callbackFunction( pCallbackContext, pCallbackParam );\r
-\r
-        /* Lock the subscription list mutex to decrement the reference count. */\r
-        IotMutex_Lock( &( pMqttConnection->subscriptionMutex ) );\r
-\r
-        /* Decrement the reference count. It must still be positive. */\r
-        ( pSubscription->references )--;\r
-        IotMqtt_Assert( pSubscription->references >= 0 );\r
-\r
-        /* Save the pointer to the next link in case this subscription is freed. */\r
-        pNextLink = pCurrentLink->pNext;\r
-\r
-        /* Remove this subscription if it has no references and the unsubscribed\r
-         * flag is set. */\r
-        if( pSubscription->unsubscribed == true )\r
-        {\r
-            /* An unsubscribed subscription should have been removed from the list. */\r
-            IotMqtt_Assert( IotLink_IsLinked( &( pSubscription->link ) ) == false );\r
-\r
-            /* Free subscriptions with no references. */\r
-            if( pSubscription->references == 0 )\r
-            {\r
-                IotMqtt_FreeSubscription( pSubscription );\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        /* Move current link pointer. */\r
-        pCurrentLink = pNextLink;\r
-    }\r
-\r
-    IotMutex_Unlock( &( pMqttConnection->subscriptionMutex ) );\r
-\r
-    _IotMqtt_DecrementConnectionReferences( pMqttConnection );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void _IotMqtt_RemoveSubscriptionByPacket( _mqttConnection_t * pMqttConnection,\r
-                                          uint16_t packetIdentifier,\r
-                                          int32_t order )\r
-{\r
-    const _packetMatchParams_t packetMatchParams =\r
-    {\r
-        .packetIdentifier = packetIdentifier,\r
-        .order            = order\r
-    };\r
-\r
-    IotMutex_Lock( &( pMqttConnection->subscriptionMutex ) );\r
-    IotListDouble_RemoveAllMatches( &( pMqttConnection->subscriptionList ),\r
-                                    _packetMatch,\r
-                                    ( void * ) ( &packetMatchParams ),\r
-                                    IotMqtt_FreeSubscription,\r
-                                    offsetof( _mqttSubscription_t, link ) );\r
-    IotMutex_Unlock( &( pMqttConnection->subscriptionMutex ) );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void _IotMqtt_RemoveSubscriptionByTopicFilter( _mqttConnection_t * pMqttConnection,\r
-                                               const IotMqttSubscription_t * pSubscriptionList,\r
-                                               size_t subscriptionCount )\r
-{\r
-    size_t i = 0;\r
-    _mqttSubscription_t * pSubscription = NULL;\r
-    IotLink_t * pSubscriptionLink = NULL;\r
-    _topicMatchParams_t topicMatchParams = { 0 };\r
-\r
-    /* Prevent any other thread from modifying the subscription list while this\r
-     * function is running. */\r
-    IotMutex_Lock( &( pMqttConnection->subscriptionMutex ) );\r
-\r
-    /* Find and remove each topic filter from the list. */\r
-    for( i = 0; i < subscriptionCount; i++ )\r
-    {\r
-        topicMatchParams.pTopicName = pSubscriptionList[ i ].pTopicFilter;\r
-        topicMatchParams.topicNameLength = pSubscriptionList[ i ].topicFilterLength;\r
-        topicMatchParams.exactMatchOnly = true;\r
-\r
-        pSubscriptionLink = IotListDouble_FindFirstMatch( &( pMqttConnection->subscriptionList ),\r
-                                                          NULL,\r
-                                                          _topicMatch,\r
-                                                          &topicMatchParams );\r
-\r
-        if( pSubscriptionLink != NULL )\r
-        {\r
-            pSubscription = IotLink_Container( _mqttSubscription_t, pSubscriptionLink, link );\r
-\r
-            /* Reference count must not be negative. */\r
-            IotMqtt_Assert( pSubscription->references >= 0 );\r
-\r
-            /* Remove subscription from list. */\r
-            IotListDouble_Remove( pSubscriptionLink );\r
-\r
-            /* Check the reference count. This subscription cannot be removed if\r
-             * there are subscription callbacks using it. */\r
-            if( pSubscription->references > 0 )\r
-            {\r
-                /* Set the unsubscribed flag. The last active subscription callback\r
-                 * will remove and clean up this subscription. */\r
-                pSubscription->unsubscribed = true;\r
-            }\r
-            else\r
-            {\r
-                /* Free a subscription with no references. */\r
-                IotMqtt_FreeSubscription( pSubscription );\r
-            }\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-\r
-    IotMutex_Unlock( &( pMqttConnection->subscriptionMutex ) );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-bool IotMqtt_IsSubscribed( IotMqttConnection_t mqttConnection,\r
-                           const char * pTopicFilter,\r
-                           uint16_t topicFilterLength,\r
-                           IotMqttSubscription_t * pCurrentSubscription )\r
-{\r
-    bool status = false;\r
-    _mqttSubscription_t * pSubscription = NULL;\r
-    IotLink_t * pSubscriptionLink = NULL;\r
-    _topicMatchParams_t topicMatchParams =\r
-    {\r
-        .pTopicName      = pTopicFilter,\r
-        .topicNameLength = topicFilterLength,\r
-        .exactMatchOnly  = true\r
-    };\r
-\r
-    /* Prevent any other thread from modifying the subscription list while this\r
-     * function is running. */\r
-    IotMutex_Lock( &( mqttConnection->subscriptionMutex ) );\r
-\r
-    /* Search for a matching subscription. */\r
-    pSubscriptionLink = IotListDouble_FindFirstMatch( &( mqttConnection->subscriptionList ),\r
-                                                      NULL,\r
-                                                      _topicMatch,\r
-                                                      &topicMatchParams );\r
-\r
-    /* Check if a matching subscription was found. */\r
-    if( pSubscriptionLink != NULL )\r
-    {\r
-        pSubscription = IotLink_Container( _mqttSubscription_t, pSubscriptionLink, link );\r
-\r
-        /* Copy the matching subscription to the output parameter. */\r
-        if( pCurrentSubscription != NULL )\r
-        {\r
-            pCurrentSubscription->pTopicFilter = pTopicFilter;\r
-            pCurrentSubscription->topicFilterLength = topicFilterLength;\r
-            pCurrentSubscription->qos = IOT_MQTT_QOS_0;\r
-            pCurrentSubscription->callback = pSubscription->callback;\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        status = true;\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    IotMutex_Unlock( &( mqttConnection->subscriptionMutex ) );\r
-\r
-    return status;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/* Provide access to internal functions and variables if testing. */\r
-#if IOT_BUILD_TESTS == 1\r
-    #include "iot_test_access_mqtt_subscription.c"\r
-#endif\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_mqtt_validate.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/iot_mqtt_validate.c
deleted file mode 100644 (file)
index 8556959..0000000
+++ /dev/null
@@ -1,593 +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_validate.c\r
- * @brief Implements functions that validate the structs of the MQTT library.\r
- */\r
-\r
-/* The config header is always included first. */\r
-#include "iot_config.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
-/*-----------------------------------------------------------*/\r
-\r
-bool _IotMqtt_ValidateConnect( const IotMqttConnectInfo_t * pConnectInfo )\r
-{\r
-    IOT_FUNCTION_ENTRY( bool, true );\r
-\r
-    /* Check for NULL. */\r
-    if( pConnectInfo == NULL )\r
-    {\r
-        IotLogError( "MQTT connection information cannot be NULL." );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( false );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Check that a client identifier was set. */\r
-    if( pConnectInfo->pClientIdentifier == NULL )\r
-    {\r
-        IotLogError( "Client identifier must be set." );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( false );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Check for a zero-length client identifier. Zero-length client identifiers\r
-     * are not allowed with clean sessions. */\r
-    if( pConnectInfo->clientIdentifierLength == 0 )\r
-    {\r
-        IotLogWarn( "A zero-length client identifier was provided." );\r
-\r
-        if( pConnectInfo->cleanSession == true )\r
-        {\r
-            IotLogError( "A zero-length client identifier cannot be used with a clean session." );\r
-\r
-            IOT_SET_AND_GOTO_CLEANUP( false );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Check that the number of persistent session subscriptions is valid. */\r
-    if( pConnectInfo->cleanSession == false )\r
-    {\r
-        if( pConnectInfo->pPreviousSubscriptions != NULL )\r
-        {\r
-            if( pConnectInfo->previousSubscriptionCount == 0 )\r
-            {\r
-                IotLogError( "Previous subscription count cannot be 0." );\r
-\r
-                IOT_SET_AND_GOTO_CLEANUP( false );\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* In MQTT 3.1.1, servers are not obligated to accept client identifiers longer\r
-     * than 23 characters. */\r
-    if( pConnectInfo->clientIdentifierLength > 23 )\r
-    {\r
-        IotLogWarn( "A client identifier length of %hu is longer than 23, which is "\r
-                    "the longest client identifier a server must accept.",\r
-                    pConnectInfo->clientIdentifierLength );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Check for compatibility with the AWS IoT MQTT service limits. */\r
-    if( pConnectInfo->awsIotMqttMode == true )\r
-    {\r
-        /* Check that client identifier is within the service limit. */\r
-        if( pConnectInfo->clientIdentifierLength > AWS_IOT_MQTT_SERVER_MAX_CLIENTID )\r
-        {\r
-            IotLogError( "AWS IoT does not support client identifiers longer than %d bytes.",\r
-                         AWS_IOT_MQTT_SERVER_MAX_CLIENTID );\r
-\r
-            IOT_SET_AND_GOTO_CLEANUP( false );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        /* Check for compliance with AWS IoT keep-alive limits. */\r
-        if( pConnectInfo->keepAliveSeconds == 0 )\r
-        {\r
-            IotLogWarn( "AWS IoT does not support disabling keep-alive. Default keep-alive "\r
-                        "of %d seconds will be used.",\r
-                        AWS_IOT_MQTT_SERVER_MAX_KEEPALIVE );\r
-        }\r
-        else if( pConnectInfo->keepAliveSeconds < AWS_IOT_MQTT_SERVER_MIN_KEEPALIVE )\r
-        {\r
-            IotLogWarn( "AWS IoT does not support keep-alive intervals less than %d seconds. "\r
-                        "An interval of %d seconds will be used.",\r
-                        AWS_IOT_MQTT_SERVER_MIN_KEEPALIVE,\r
-                        AWS_IOT_MQTT_SERVER_MIN_KEEPALIVE );\r
-        }\r
-        else if( pConnectInfo->keepAliveSeconds > AWS_IOT_MQTT_SERVER_MAX_KEEPALIVE )\r
-        {\r
-            IotLogWarn( "AWS IoT does not support keep-alive intervals greater than %d seconds. "\r
-                        "An interval of %d seconds will be used.",\r
-                        AWS_IOT_MQTT_SERVER_MAX_KEEPALIVE,\r
-                        AWS_IOT_MQTT_SERVER_MAX_KEEPALIVE );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-bool _IotMqtt_ValidatePublish( bool awsIotMqttMode,\r
-                               const IotMqttPublishInfo_t * pPublishInfo )\r
-{\r
-    IOT_FUNCTION_ENTRY( bool, true );\r
-\r
-    /* Check for NULL. */\r
-    if( pPublishInfo == NULL )\r
-    {\r
-        IotLogError( "Publish information cannot be NULL." );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( false );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Check topic name for NULL or zero-length. */\r
-    if( pPublishInfo->pTopicName == NULL )\r
-    {\r
-        IotLogError( "Publish topic name must be set." );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    if( pPublishInfo->topicNameLength == 0 )\r
-    {\r
-        IotLogError( "Publish topic name length cannot be 0." );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( false );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Only allow NULL payloads with zero length. */\r
-    if( pPublishInfo->pPayload == NULL )\r
-    {\r
-        if( pPublishInfo->payloadLength != 0 )\r
-        {\r
-            IotLogError( "Nonzero payload length cannot have a NULL payload." );\r
-\r
-            IOT_SET_AND_GOTO_CLEANUP( false );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Check for a valid QoS. */\r
-    if( pPublishInfo->qos != IOT_MQTT_QOS_0 )\r
-    {\r
-        if( pPublishInfo->qos != IOT_MQTT_QOS_1 )\r
-        {\r
-            IotLogError( "Publish QoS must be either 0 or 1." );\r
-\r
-            IOT_SET_AND_GOTO_CLEANUP( false );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Check the retry parameters. */\r
-    if( pPublishInfo->retryLimit > 0 )\r
-    {\r
-        if( pPublishInfo->retryMs == 0 )\r
-        {\r
-            IotLogError( "Publish retry time must be positive." );\r
-\r
-            IOT_SET_AND_GOTO_CLEANUP( false );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Check for compatibility with AWS IoT MQTT server. */\r
-    if( awsIotMqttMode == true )\r
-    {\r
-        /* Check for retained message. */\r
-        if( pPublishInfo->retain == true )\r
-        {\r
-            IotLogError( "AWS IoT does not support retained publish messages." );\r
-\r
-            IOT_SET_AND_GOTO_CLEANUP( false );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        /* Check topic name length. */\r
-        if( pPublishInfo->topicNameLength > AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH )\r
-        {\r
-            IotLogError( "AWS IoT does not support topic names longer than %d bytes.",\r
-                         AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH );\r
-\r
-            IOT_SET_AND_GOTO_CLEANUP( false );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-bool _IotMqtt_ValidateOperation( IotMqttOperation_t operation )\r
-{\r
-    IOT_FUNCTION_ENTRY( bool, true );\r
-\r
-    /* Check for NULL. */\r
-    if( operation == NULL )\r
-    {\r
-        IotLogError( "Operation reference cannot be NULL." );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( false );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* Check that reference is waitable. */\r
-    if( ( operation->u.operation.flags & IOT_MQTT_FLAG_WAITABLE ) != IOT_MQTT_FLAG_WAITABLE )\r
-    {\r
-        IotLogError( "Operation is not waitable." );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( false );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-bool _IotMqtt_ValidateSubscriptionList( IotMqttOperationType_t operation,\r
-                                        bool awsIotMqttMode,\r
-                                        const IotMqttSubscription_t * pListStart,\r
-                                        size_t listSize )\r
-{\r
-    IOT_FUNCTION_ENTRY( bool, true );\r
-    size_t i = 0;\r
-    uint16_t j = 0;\r
-    const IotMqttSubscription_t * pListElement = NULL;\r
-\r
-    /* Operation must be either subscribe or unsubscribe. */\r
-    IotMqtt_Assert( ( operation == IOT_MQTT_SUBSCRIBE ) ||\r
-                    ( operation == IOT_MQTT_UNSUBSCRIBE ) );\r
-\r
-    /* Check for empty list. */\r
-    if( pListStart == NULL )\r
-    {\r
-        IotLogError( "Subscription list pointer cannot be NULL." );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( false );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    if( listSize == 0 )\r
-    {\r
-        IotLogError( "Empty subscription list." );\r
-\r
-        IOT_SET_AND_GOTO_CLEANUP( false );\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    /* AWS IoT supports at most 8 topic filters in a single SUBSCRIBE packet. */\r
-    if( awsIotMqttMode == true )\r
-    {\r
-        if( listSize > AWS_IOT_MQTT_SERVER_MAX_TOPIC_FILTERS_PER_SUBSCRIBE )\r
-        {\r
-            IotLogError( "AWS IoT does not support more than %d topic filters per "\r
-                         "subscription request.",\r
-                         AWS_IOT_MQTT_SERVER_MAX_TOPIC_FILTERS_PER_SUBSCRIBE );\r
-\r
-            IOT_SET_AND_GOTO_CLEANUP( false );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        EMPTY_ELSE_MARKER;\r
-    }\r
-\r
-    for( i = 0; i < listSize; i++ )\r
-    {\r
-        pListElement = &( pListStart[ i ] );\r
-\r
-        /* Check for a valid QoS and callback function when subscribing. */\r
-        if( operation == IOT_MQTT_SUBSCRIBE )\r
-        {\r
-            if( pListElement->qos != IOT_MQTT_QOS_0 )\r
-            {\r
-                if( pListElement->qos != IOT_MQTT_QOS_1 )\r
-                {\r
-                    IotLogError( "Subscription QoS must be either 0 or 1." );\r
-\r
-                    IOT_SET_AND_GOTO_CLEANUP( false );\r
-                }\r
-                else\r
-                {\r
-                    EMPTY_ELSE_MARKER;\r
-                }\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-\r
-            if( pListElement->callback.function == NULL )\r
-            {\r
-                IotLogError( "Callback function must be set." );\r
-\r
-                IOT_SET_AND_GOTO_CLEANUP( false );\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        /* Check subscription topic filter. */\r
-        if( pListElement->pTopicFilter == NULL )\r
-        {\r
-            IotLogError( "Subscription topic filter cannot be NULL." );\r
-\r
-            IOT_SET_AND_GOTO_CLEANUP( false );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        if( pListElement->topicFilterLength == 0 )\r
-        {\r
-            IotLogError( "Subscription topic filter length cannot be 0." );\r
-\r
-            IOT_SET_AND_GOTO_CLEANUP( false );\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        /* Check for compatibility with AWS IoT MQTT server. */\r
-        if( awsIotMqttMode == true )\r
-        {\r
-            /* Check topic filter length. */\r
-            if( pListElement->topicFilterLength > AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH )\r
-            {\r
-                IotLogError( "AWS IoT does not support topic filters longer than %d bytes.",\r
-                             AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH );\r
-\r
-                IOT_SET_AND_GOTO_CLEANUP( false );\r
-            }\r
-            else\r
-            {\r
-                EMPTY_ELSE_MARKER;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            EMPTY_ELSE_MARKER;\r
-        }\r
-\r
-        /* Check that the wildcards '+' and '#' are being used correctly. */\r
-        for( j = 0; j < pListElement->topicFilterLength; j++ )\r
-        {\r
-            switch( pListElement->pTopicFilter[ j ] )\r
-            {\r
-                /* Check that the single level wildcard '+' is used correctly. */\r
-                case '+':\r
-\r
-                    /* Unless '+' is the first character in the filter, it must be preceded by '/'. */\r
-                    if( j > 0 )\r
-                    {\r
-                        if( pListElement->pTopicFilter[ j - 1 ] != '/' )\r
-                        {\r
-                            IotLogError( "Invalid topic filter %.*s -- '+' must be preceded by '/'.",\r
-                                         pListElement->topicFilterLength,\r
-                                         pListElement->pTopicFilter );\r
-\r
-                            IOT_SET_AND_GOTO_CLEANUP( false );\r
-                        }\r
-                        else\r
-                        {\r
-                            EMPTY_ELSE_MARKER;\r
-                        }\r
-                    }\r
-                    else\r
-                    {\r
-                        EMPTY_ELSE_MARKER;\r
-                    }\r
-\r
-                    /* Unless '+' is the last character in the filter, it must be succeeded by '/'. */\r
-                    if( j < pListElement->topicFilterLength - 1 )\r
-                    {\r
-                        if( pListElement->pTopicFilter[ j + 1 ] != '/' )\r
-                        {\r
-                            IotLogError( "Invalid topic filter %.*s -- '+' must be succeeded by '/'.",\r
-                                         pListElement->topicFilterLength,\r
-                                         pListElement->pTopicFilter );\r
-\r
-                            IOT_SET_AND_GOTO_CLEANUP( false );\r
-                        }\r
-                        else\r
-                        {\r
-                            EMPTY_ELSE_MARKER;\r
-                        }\r
-                    }\r
-                    else\r
-                    {\r
-                        EMPTY_ELSE_MARKER;\r
-                    }\r
-\r
-                    break;\r
-\r
-                /* Check that the multi-level wildcard '#' is used correctly. */\r
-                case '#':\r
-\r
-                    /* '#' must be the last character in the filter. */\r
-                    if( j != pListElement->topicFilterLength - 1 )\r
-                    {\r
-                        IotLogError( "Invalid topic filter %.*s -- '#' must be the last character.",\r
-                                     pListElement->topicFilterLength,\r
-                                     pListElement->pTopicFilter );\r
-\r
-                        IOT_SET_AND_GOTO_CLEANUP( false );\r
-                    }\r
-                    else\r
-                    {\r
-                        EMPTY_ELSE_MARKER;\r
-                    }\r
-\r
-                    /* Unless '#' is standalone, it must be preceded by '/'. */\r
-                    if( pListElement->topicFilterLength > 1 )\r
-                    {\r
-                        if( pListElement->pTopicFilter[ j - 1 ] != '/' )\r
-                        {\r
-                            IotLogError( "Invalid topic filter %.*s -- '#' must be preceded by '/'.",\r
-                                         pListElement->topicFilterLength,\r
-                                         pListElement->pTopicFilter );\r
-\r
-                            IOT_SET_AND_GOTO_CLEANUP( false );\r
-                        }\r
-                        else\r
-                        {\r
-                            EMPTY_ELSE_MARKER;\r
-                        }\r
-                    }\r
-                    else\r
-                    {\r
-                        EMPTY_ELSE_MARKER;\r
-                    }\r
-\r
-                    break;\r
-\r
-                default:\r
-                    break;\r
-            }\r
-        }\r
-    }\r
-\r
-    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/private/iot_mqtt_internal.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/mqtt/src/private/iot_mqtt_internal.h
deleted file mode 100644 (file)
index 80aef1c..0000000
+++ /dev/null
@@ -1,915 +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_internal.h\r
- * @brief Internal header of MQTT library. This header should not be included in\r
- * typical application code.\r
- */\r
-\r
-#ifndef IOT_MQTT_INTERNAL_H_\r
-#define IOT_MQTT_INTERNAL_H_\r
-\r
-/* The config header is always included first. */\r
-#include "iot_config.h"\r
-\r
-/* Linear containers (lists and queues) include. */\r
-#include "iot_linear_containers.h"\r
-\r
-/* MQTT include. */\r
-#include "iot_mqtt.h"\r
-\r
-/* Task pool include. */\r
-#include "iot_taskpool.h"\r
-\r
-/**\r
- * @def IotMqtt_Assert( expression )\r
- * @brief Assertion macro for the MQTT library.\r
- *\r
- * Set @ref IOT_MQTT_ENABLE_ASSERTS to `1` to enable assertions in the MQTT\r
- * library.\r
- *\r
- * @param[in] expression Expression to be evaluated.\r
- */\r
-#if IOT_MQTT_ENABLE_ASSERTS == 1\r
-    #ifndef IotMqtt_Assert\r
-        #include <assert.h>\r
-        #define IotMqtt_Assert( expression )    assert( expression )\r
-    #endif\r
-#else\r
-    #define IotMqtt_Assert( expression )\r
-#endif\r
-\r
-/* Configure logs for MQTT functions. */\r
-#ifdef IOT_LOG_LEVEL_MQTT\r
-    #define LIBRARY_LOG_LEVEL        IOT_LOG_LEVEL_MQTT\r
-#else\r
-    #ifdef IOT_LOG_LEVEL_GLOBAL\r
-        #define LIBRARY_LOG_LEVEL    IOT_LOG_LEVEL_GLOBAL\r
-    #else\r
-        #define LIBRARY_LOG_LEVEL    IOT_LOG_NONE\r
-    #endif\r
-#endif\r
-\r
-#define LIBRARY_LOG_NAME    ( "MQTT" )\r
-#include "iot_logging_setup.h"\r
-\r
-/*\r
- * Provide default values for undefined memory allocation functions based on\r
- * the usage of dynamic memory allocation.\r
- */\r
-#if IOT_STATIC_MEMORY_ONLY == 1\r
-    #include "private/iot_static_memory.h"\r
-\r
-/**\r
- * @brief Allocate an #_mqttConnection_t. This function should have the same\r
- * signature as [malloc]\r
- * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html).\r
- */\r
-    void * IotMqtt_MallocConnection( size_t size );\r
-\r
-/**\r
- * @brief Free an #_mqttConnection_t. This function should have the same\r
- * signature as [free]\r
- * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
- */\r
-    void IotMqtt_FreeConnection( void * ptr );\r
-\r
-/**\r
- * @brief Allocate memory for an MQTT packet. This function should have the\r
- * same signature as [malloc]\r
- * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html).\r
- */\r
-    #define IotMqtt_MallocMessage    Iot_MallocMessageBuffer\r
-\r
-/**\r
- * @brief Free an MQTT packet. This function should have the same signature\r
- * as [free]\r
- * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
- */\r
-    #define IotMqtt_FreeMessage      Iot_FreeMessageBuffer\r
-\r
-/**\r
- * @brief Allocate an #_mqttOperation_t. This function should have the same\r
- * signature as [malloc]\r
- * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html).\r
- */\r
-    void * IotMqtt_MallocOperation( size_t size );\r
-\r
-/**\r
- * @brief Free an #_mqttOperation_t. This function should have the same\r
- * signature as [free]\r
- * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
- */\r
-    void IotMqtt_FreeOperation( void * ptr );\r
-\r
-/**\r
- * @brief Allocate an #_mqttSubscription_t. This function should have the\r
- * same signature as [malloc]\r
- * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html).\r
- */\r
-    void * IotMqtt_MallocSubscription( size_t size );\r
-\r
-/**\r
- * @brief Free an #_mqttSubscription_t. This function should have the same\r
- * signature as [free]\r
- * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
- */\r
-    void IotMqtt_FreeSubscription( void * ptr );\r
-#else /* if IOT_STATIC_MEMORY_ONLY == 1 */\r
-    #include <stdlib.h>\r
-\r
-    #ifndef IotMqtt_MallocConnection\r
-        #define IotMqtt_MallocConnection    malloc\r
-    #endif\r
-\r
-    #ifndef IotMqtt_FreeConnection\r
-        #define IotMqtt_FreeConnection    free\r
-    #endif\r
-\r
-    #ifndef IotMqtt_MallocMessage\r
-        #define IotMqtt_MallocMessage    malloc\r
-    #endif\r
-\r
-    #ifndef IotMqtt_FreeMessage\r
-        #define IotMqtt_FreeMessage    free\r
-    #endif\r
-\r
-    #ifndef IotMqtt_MallocOperation\r
-        #define IotMqtt_MallocOperation    malloc\r
-    #endif\r
-\r
-    #ifndef IotMqtt_FreeOperation\r
-        #define IotMqtt_FreeOperation    free\r
-    #endif\r
-\r
-    #ifndef IotMqtt_MallocSubscription\r
-        #define IotMqtt_MallocSubscription    malloc\r
-    #endif\r
-\r
-    #ifndef IotMqtt_FreeSubscription\r
-        #define IotMqtt_FreeSubscription    free\r
-    #endif\r
-#endif /* if IOT_STATIC_MEMORY_ONLY == 1 */\r
-\r
-/**\r
- * @cond DOXYGEN_IGNORE\r
- * Doxygen should ignore this section.\r
- *\r
- * Provide default values for undefined configuration constants.\r
- */\r
-#ifndef AWS_IOT_MQTT_ENABLE_METRICS\r
-    #define AWS_IOT_MQTT_ENABLE_METRICS             ( 1 )\r
-#endif\r
-#ifndef IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES\r
-    #define IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES    ( 0 )\r
-#endif\r
-#ifndef IOT_MQTT_RESPONSE_WAIT_MS\r
-    #define IOT_MQTT_RESPONSE_WAIT_MS               ( 1000 )\r
-#endif\r
-#ifndef IOT_MQTT_RETRY_MS_CEILING\r
-    #define IOT_MQTT_RETRY_MS_CEILING               ( 60000 )\r
-#endif\r
-/** @endcond */\r
-\r
-/**\r
- * @brief Marks the empty statement of an `else` branch.\r
- *\r
- * Does nothing, but allows test coverage to detect branches not taken. By default,\r
- * this is defined to nothing. When running code coverage testing, this is defined\r
- * to an assembly NOP.\r
- */\r
-#ifndef EMPTY_ELSE_MARKER\r
-    #define EMPTY_ELSE_MARKER\r
-#endif\r
-\r
-/*\r
- * Constants related to limits defined in AWS Service Limits.\r
- *\r
- * For details, see\r
- * https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html\r
- *\r
- * Used to validate parameters if when connecting to an AWS IoT MQTT server.\r
- */\r
-#define AWS_IOT_MQTT_SERVER_MIN_KEEPALIVE                      ( 30 )   /**< @brief Minumum keep-alive interval accepted by AWS IoT. */\r
-#define AWS_IOT_MQTT_SERVER_MAX_KEEPALIVE                      ( 1200 ) /**< @brief Maximum keep-alive interval accepted by AWS IoT. */\r
-#define AWS_IOT_MQTT_SERVER_MAX_CLIENTID                       ( 128 )  /**< @brief Maximum length of client identifier accepted by AWS IoT. */\r
-#define AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH                   ( 256 )  /**< @brief Maximum length of topic names or filters accepted by AWS IoT. */\r
-#define AWS_IOT_MQTT_SERVER_MAX_TOPIC_FILTERS_PER_SUBSCRIBE    ( 8 )    /**< @brief Maximum number of topic filters in a single SUBSCRIBE packet. */\r
-\r
-/*\r
- * MQTT control packet type and flags. Always the first byte of an MQTT\r
- * packet.\r
- *\r
- * For details, see\r
- * http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/csprd02/mqtt-v3.1.1-csprd02.html#_Toc385349757\r
- */\r
-#define MQTT_PACKET_TYPE_CONNECT                               ( ( uint8_t ) 0x10U ) /**< @brief CONNECT (client-to-server). */\r
-#define MQTT_PACKET_TYPE_CONNACK                               ( ( uint8_t ) 0x20U ) /**< @brief CONNACK (server-to-client). */\r
-#define MQTT_PACKET_TYPE_PUBLISH                               ( ( uint8_t ) 0x30U ) /**< @brief PUBLISH (bi-directional). */\r
-#define MQTT_PACKET_TYPE_PUBACK                                ( ( uint8_t ) 0x40U ) /**< @brief PUBACK (server-to-client). */\r
-#define MQTT_PACKET_TYPE_SUBSCRIBE                             ( ( uint8_t ) 0x82U ) /**< @brief SUBSCRIBE (client-to-server). */\r
-#define MQTT_PACKET_TYPE_SUBACK                                ( ( uint8_t ) 0x90U ) /**< @brief SUBACK (server-to-client). */\r
-#define MQTT_PACKET_TYPE_UNSUBSCRIBE                           ( ( uint8_t ) 0xa2U ) /**< @brief UNSUBSCRIBE (client-to-server). */\r
-#define MQTT_PACKET_TYPE_UNSUBACK                              ( ( uint8_t ) 0xb0U ) /**< @brief UNSUBACK (server-to-client). */\r
-#define MQTT_PACKET_TYPE_PINGREQ                               ( ( uint8_t ) 0xc0U ) /**< @brief PINGREQ (client-to-server). */\r
-#define MQTT_PACKET_TYPE_PINGRESP                              ( ( uint8_t ) 0xd0U ) /**< @brief PINGRESP (server-to-client). */\r
-#define MQTT_PACKET_TYPE_DISCONNECT                            ( ( uint8_t ) 0xe0U ) /**< @brief DISCONNECT (client-to-server). */\r
-\r
-/**\r
- * @brief A value that represents an invalid remaining length.\r
- *\r
- * This value is greater than what is allowed by the MQTT specification.\r
- */\r
-#define MQTT_REMAINING_LENGTH_INVALID                          ( ( size_t ) 268435456 )\r
-\r
-/*---------------------- MQTT internal data structures ----------------------*/\r
-\r
-/**\r
- * @brief Represents an MQTT connection.\r
- */\r
-typedef struct _mqttConnection\r
-{\r
-    bool awsIotMqttMode;                             /**< @brief Specifies if this connection is to an AWS IoT MQTT server. */\r
-    bool ownNetworkConnection;                       /**< @brief Whether this MQTT connection owns its network connection. */\r
-    void * pNetworkConnection;                       /**< @brief References the transport-layer network connection. */\r
-    const IotNetworkInterface_t * pNetworkInterface; /**< @brief Network interface provided to @ref mqtt_function_connect. */\r
-    IotMqttCallbackInfo_t disconnectCallback;        /**< @brief A function to invoke when this connection is disconnected. */\r
-\r
-    #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1\r
-        const IotMqttSerializer_t * pSerializer; /**< @brief MQTT packet serializer overrides. */\r
-    #endif\r
-\r
-    bool disconnected;                              /**< @brief Tracks if this connection has been disconnected. */\r
-    IotMutex_t referencesMutex;                     /**< @brief Recursive mutex. Grants access to connection state and operation lists. */\r
-    int32_t references;                             /**< @brief Counts callbacks and operations using this connection. */\r
-    IotListDouble_t pendingProcessing;              /**< @brief List of operations waiting to be processed by a task pool routine. */\r
-    IotListDouble_t pendingResponse;                /**< @brief List of processed operations awaiting a server response. */\r
-\r
-    IotListDouble_t subscriptionList;               /**< @brief Holds subscriptions associated with this connection. */\r
-    IotMutex_t subscriptionMutex;                   /**< @brief Grants exclusive access to the subscription list. */\r
-\r
-    bool keepAliveFailure;                          /**< @brief Failure flag for keep-alive operation. */\r
-    uint32_t keepAliveMs;                           /**< @brief Keep-alive interval in milliseconds. Its max value (per spec) is 65,535,000. */\r
-    uint32_t nextKeepAliveMs;                       /**< @brief Relative delay for next keep-alive job. */\r
-    IotTaskPoolJobStorage_t keepAliveJobStorage;     /**< @brief Task pool job for processing this connection's keep-alive. */\r
-    IotTaskPoolJob_t keepAliveJob;                  /**< @brief Task pool job for processing this connection's keep-alive. */\r
-    uint8_t * pPingreqPacket;                       /**< @brief An MQTT PINGREQ packet, allocated if keep-alive is active. */\r
-    size_t pingreqPacketSize;                       /**< @brief The size of an allocated PINGREQ packet. */\r
-} _mqttConnection_t;\r
-\r
-/**\r
- * @brief Represents a subscription stored in an MQTT connection.\r
- */\r
-typedef struct _mqttSubscription\r
-{\r
-    IotLink_t link;     /**< @brief List link member. */\r
-\r
-    int32_t references; /**< @brief How many subscription callbacks are using this subscription. */\r
-\r
-    /**\r
-     * @brief Tracks whether @ref mqtt_function_unsubscribe has been called for\r
-     * this subscription.\r
-     *\r
-     * If there are active subscription callbacks, @ref mqtt_function_unsubscribe\r
-     * cannot remove this subscription. Instead, it will set this flag, which\r
-     * schedules the removal of this subscription once all subscription callbacks\r
-     * terminate.\r
-     */\r
-    bool unsubscribed;\r
-\r
-    struct\r
-    {\r
-        uint16_t identifier;        /**< @brief Packet identifier. */\r
-        size_t order;               /**< @brief Order in the packet's list of subscriptions. */\r
-    } packetInfo;                   /**< @brief Information about the SUBSCRIBE packet that registered this subscription. */\r
-\r
-    IotMqttCallbackInfo_t callback; /**< @brief Callback information for this subscription. */\r
-\r
-    uint16_t topicFilterLength;     /**< @brief Length of #_mqttSubscription_t.pTopicFilter. */\r
-    char pTopicFilter[];            /**< @brief The subscription topic filter. */\r
-} _mqttSubscription_t;\r
-\r
-/**\r
- * @brief Internal structure representing a single MQTT operation, such as\r
- * CONNECT, SUBSCRIBE, PUBLISH, etc.\r
- *\r
- * Queues of these structures keeps track of all in-progress MQTT operations.\r
- */\r
-typedef struct _mqttOperation\r
-{\r
-    /* Pointers to neighboring queue elements. */\r
-    IotLink_t link;                      /**< @brief List link member. */\r
-\r
-    bool incomingPublish;                /**< @brief Set to true if this operation an incoming PUBLISH. */\r
-    _mqttConnection_t * pMqttConnection; /**< @brief MQTT connection associated with this operation. */\r
-\r
-    IotTaskPoolJobStorage_t jobStorage;  /**< @brief Task pool job storage associated with this operation. */\r
-    IotTaskPoolJob_t job;                /**< @brief Task pool job associated with this operation. */\r
-\r
-    union\r
-    {\r
-        /* If incomingPublish is false, this struct is valid. */\r
-        struct\r
-        {\r
-            /* Basic operation information. */\r
-            int32_t jobReference;        /**< @brief Tracks if a job is using this operation. Must always be 0, 1, or 2. */\r
-            IotMqttOperationType_t type; /**< @brief What operation this structure represents. */\r
-            uint32_t flags;              /**< @brief Flags passed to the function that created this operation. */\r
-            uint16_t packetIdentifier;   /**< @brief The packet identifier used with this operation. */\r
-\r
-            /* Serialized packet and size. */\r
-            uint8_t * pMqttPacket;           /**< @brief The MQTT packet to send over the network. */\r
-            uint8_t * pPacketIdentifierHigh; /**< @brief The location of the high byte of the packet identifier in the MQTT packet. */\r
-            size_t packetSize;               /**< @brief Size of `pMqttPacket`. */\r
-\r
-            /* How to notify of an operation's completion. */\r
-            union\r
-            {\r
-                IotSemaphore_t waitSemaphore;   /**< @brief Semaphore to be used with @ref mqtt_function_wait. */\r
-                IotMqttCallbackInfo_t callback; /**< @brief User-provided callback function and parameter. */\r
-            } notify;                           /**< @brief How to notify of this operation's completion. */\r
-            IotMqttError_t status;              /**< @brief Result of this operation. This is reported once a response is received. */\r
-\r
-            struct\r
-            {\r
-                uint32_t count;\r
-                uint32_t limit;\r
-                uint32_t nextPeriod;\r
-            } retry;\r
-        } operation;\r
-\r
-        /* If incomingPublish is true, this struct is valid. */\r
-        struct\r
-        {\r
-            IotMqttPublishInfo_t publishInfo; /**< @brief Deserialized PUBLISH. */\r
-            const void * pReceivedData;       /**< @brief Any buffer associated with this PUBLISH that should be freed. */\r
-        } publish;\r
-    } u;                                      /**< @brief Valid member depends on _mqttOperation_t.incomingPublish. */\r
-} _mqttOperation_t;\r
-\r
-/**\r
- * @brief Represents an MQTT packet received from the network.\r
- *\r
- * This struct is used to hold parameters for the deserializers so that all\r
- * deserializers have the same function signature.\r
- */\r
-typedef struct _mqttPacket\r
-{\r
-    union\r
-    {\r
-        /**\r
-         * @brief (Input) MQTT connection associated with this packet. Only used\r
-         * when deserializing SUBACKs.\r
-         */\r
-        _mqttConnection_t * pMqttConnection;\r
-\r
-        /**\r
-         * @brief (Output) Operation representing an incoming PUBLISH. Only used\r
-         * when deserializing PUBLISHes.\r
-         */\r
-        _mqttOperation_t * pIncomingPublish;\r
-    } u;                       /**< @brief Valid member depends on packet being decoded. */\r
-\r
-    uint8_t * pRemainingData;  /**< @brief (Input) The remaining data in MQTT packet. */\r
-    size_t remainingLength;    /**< @brief (Input) Length of the remaining data in the MQTT packet. */\r
-    uint16_t packetIdentifier; /**< @brief (Output) MQTT packet identifier. */\r
-    uint8_t type;              /**< @brief (Input) A value identifying the packet type. */\r
-} _mqttPacket_t;\r
-\r
-/*-------------------- MQTT struct validation functions ---------------------*/\r
-\r
-/**\r
- * @brief Check that an #IotMqttConnectInfo_t is valid.\r
- *\r
- * @param[in] pConnectInfo The #IotMqttConnectInfo_t to validate.\r
- *\r
- * @return `true` if `pConnectInfo` is valid; `false` otherwise.\r
- */\r
-bool _IotMqtt_ValidateConnect( const IotMqttConnectInfo_t * pConnectInfo );\r
-\r
-/**\r
- * @brief Check that an #IotMqttPublishInfo_t is valid.\r
- *\r
- * @param[in] awsIotMqttMode Specifies if this PUBLISH packet is being sent to\r
- * an AWS IoT MQTT server.\r
- * @param[in] pPublishInfo The #IotMqttPublishInfo_t to validate.\r
- *\r
- * @return `true` if `pPublishInfo` is valid; `false` otherwise.\r
- */\r
-bool _IotMqtt_ValidatePublish( bool awsIotMqttMode,\r
-                               const IotMqttPublishInfo_t * pPublishInfo );\r
-\r
-/**\r
- * @brief Check that an #IotMqttOperation_t is valid and waitable.\r
- *\r
- * @param[in] operation The #IotMqttOperation_t to validate.\r
- *\r
- * @return `true` if `operation` is valid; `false` otherwise.\r
- */\r
-bool _IotMqtt_ValidateOperation( IotMqttOperation_t operation );\r
-\r
-/**\r
- * @brief Check that a list of #IotMqttSubscription_t is valid.\r
- *\r
- * @param[in] operation Either #IOT_MQTT_SUBSCRIBE or #IOT_MQTT_UNSUBSCRIBE.\r
- * Some parameters are not validated for #IOT_MQTT_UNSUBSCRIBE.\r
- * @param[in] awsIotMqttMode Specifies if this SUBSCRIBE packet is being sent to\r
- * an AWS IoT MQTT server.\r
- * @param[in] pListStart First element of the list to validate.\r
- * @param[in] listSize Number of elements in the subscription list.\r
- *\r
- * @return `true` if every element in the list is valid; `false` otherwise.\r
- */\r
-bool _IotMqtt_ValidateSubscriptionList( IotMqttOperationType_t operation,\r
-                                        bool awsIotMqttMode,\r
-                                        const IotMqttSubscription_t * pListStart,\r
-                                        size_t listSize );\r
-\r
-/*-------------------- MQTT packet serializer functions ---------------------*/\r
-\r
-/**\r
- * @brief Get the MQTT packet type from a stream of bytes off the network.\r
- *\r
- * @param[in] pNetworkConnection Reference to the network connection.\r
- * @param[in] pNetworkInterface Function pointers used to interact with the\r
- * network.\r
- *\r
- * @return One of the server-to-client MQTT packet types.\r
- *\r
- * @note This function is only used for incoming packets, and may not work\r
- * correctly for outgoing packets.\r
- */\r
-uint8_t _IotMqtt_GetPacketType( void * pNetworkConnection,\r
-                                const IotNetworkInterface_t * pNetworkInterface );\r
-\r
-/**\r
- * @brief Get the remaining length from a stream of bytes off the network.\r
- *\r
- * @param[in] pNetworkConnection Reference to the network connection.\r
- * @param[in] pNetworkInterface Function pointers used to interact with the\r
- * network.\r
- *\r
- * @return The remaining length; #MQTT_REMAINING_LENGTH_INVALID on error.\r
- */\r
-size_t _IotMqtt_GetRemainingLength( void * pNetworkConnection,\r
-                                    const IotNetworkInterface_t * pNetworkInterface );\r
-\r
-/**\r
- * @brief Generate a CONNECT packet from the given parameters.\r
- *\r
- * @param[in] pConnectInfo User-provided CONNECT information.\r
- * @param[out] pConnectPacket Where the CONNECT packet is written.\r
- * @param[out] pPacketSize Size of the packet written to `pConnectPacket`.\r
- *\r
- * @return #IOT_MQTT_SUCCESS or #IOT_MQTT_NO_MEMORY.\r
- */\r
-IotMqttError_t _IotMqtt_SerializeConnect( const IotMqttConnectInfo_t * pConnectInfo,\r
-                                          uint8_t ** pConnectPacket,\r
-                                          size_t * pPacketSize );\r
-\r
-/**\r
- * @brief Deserialize a CONNACK packet.\r
- *\r
- * Converts the packet from a stream of bytes to an #IotMqttError_t. Also\r
- * prints out debug log messages about the packet.\r
- *\r
- * @param[in,out] pConnack Pointer to an MQTT packet struct representing a CONNACK.\r
- *\r
- * @return #IOT_MQTT_SUCCESS if CONNACK specifies that CONNECT was accepted;\r
- * #IOT_MQTT_SERVER_REFUSED if CONNACK specifies that CONNECT was rejected;\r
- * #IOT_MQTT_BAD_RESPONSE if the CONNACK packet doesn't follow MQTT spec.\r
- */\r
-IotMqttError_t _IotMqtt_DeserializeConnack( _mqttPacket_t * pConnack );\r
-\r
-/**\r
- * @brief Generate a PUBLISH packet from the given parameters.\r
- *\r
- * @param[in] pPublishInfo User-provided PUBLISH information.\r
- * @param[out] pPublishPacket Where the PUBLISH packet is written.\r
- * @param[out] pPacketSize Size of the packet written to `pPublishPacket`.\r
- * @param[out] pPacketIdentifier The packet identifier generated for this PUBLISH.\r
- * @param[out] pPacketIdentifierHigh Where the high byte of the packet identifier\r
- * is written.\r
- *\r
- * @return #IOT_MQTT_SUCCESS or #IOT_MQTT_NO_MEMORY.\r
- */\r
-IotMqttError_t _IotMqtt_SerializePublish( const IotMqttPublishInfo_t * pPublishInfo,\r
-                                          uint8_t ** pPublishPacket,\r
-                                          size_t * pPacketSize,\r
-                                          uint16_t * pPacketIdentifier,\r
-                                          uint8_t ** pPacketIdentifierHigh );\r
-\r
-/**\r
- * @brief Set the DUP bit in a QoS 1 PUBLISH packet.\r
- *\r
- * @param[in] pPublishPacket Pointer to the PUBLISH packet to modify.\r
- * @param[in] pPacketIdentifierHigh The high byte of any packet identifier to modify.\r
- * @param[out] pNewPacketIdentifier Since AWS IoT does not support the DUP flag,\r
- * a new packet identifier is generated and should be written here. This parameter\r
- * is only used when connected to an AWS IoT MQTT server.\r
- *\r
- * @note See #IotMqttPublishInfo_t for caveats with retransmission to the\r
- * AWS IoT MQTT server.\r
- */\r
-void _IotMqtt_PublishSetDup( uint8_t * pPublishPacket,\r
-                             uint8_t * pPacketIdentifierHigh,\r
-                             uint16_t * pNewPacketIdentifier );\r
-\r
-/**\r
- * @brief Deserialize a PUBLISH packet received from the server.\r
- *\r
- * Converts the packet from a stream of bytes to an #IotMqttPublishInfo_t and\r
- * extracts the packet identifier. Also prints out debug log messages about the\r
- * packet.\r
- *\r
- * @param[in,out] pPublish Pointer to an MQTT packet struct representing a PUBLISH.\r
- *\r
- * @return #IOT_MQTT_SUCCESS if PUBLISH is valid; #IOT_MQTT_BAD_RESPONSE\r
- * if the PUBLISH packet doesn't follow MQTT spec.\r
- */\r
-IotMqttError_t _IotMqtt_DeserializePublish( _mqttPacket_t * pPublish );\r
-\r
-/**\r
- * @brief Generate a PUBACK packet for the given packet identifier.\r
- *\r
- * @param[in] packetIdentifier The packet identifier to place in PUBACK.\r
- * @param[out] pPubackPacket Where the PUBACK packet is written.\r
- * @param[out] pPacketSize Size of the packet written to `pPubackPacket`.\r
- *\r
- * @return #IOT_MQTT_SUCCESS or #IOT_MQTT_NO_MEMORY.\r
- */\r
-IotMqttError_t _IotMqtt_SerializePuback( uint16_t packetIdentifier,\r
-                                         uint8_t ** pPubackPacket,\r
-                                         size_t * pPacketSize );\r
-\r
-/**\r
- * @brief Deserialize a PUBACK packet.\r
- *\r
- * Converts the packet from a stream of bytes to an #IotMqttError_t and extracts\r
- * the packet identifier. Also prints out debug log messages about the packet.\r
- *\r
- * @param[in,out] pPuback Pointer to an MQTT packet struct representing a PUBACK.\r
- *\r
- * @return #IOT_MQTT_SUCCESS if PUBACK is valid; #IOT_MQTT_BAD_RESPONSE\r
- * if the PUBACK packet doesn't follow MQTT spec.\r
- */\r
-IotMqttError_t _IotMqtt_DeserializePuback( _mqttPacket_t * pPuback );\r
-\r
-/**\r
- * @brief Generate a SUBSCRIBE packet from the given parameters.\r
- *\r
- * @param[in] pSubscriptionList User-provided array of subscriptions.\r
- * @param[in] subscriptionCount Size of `pSubscriptionList`.\r
- * @param[out] pSubscribePacket Where the SUBSCRIBE packet is written.\r
- * @param[out] pPacketSize Size of the packet written to `pSubscribePacket`.\r
- * @param[out] pPacketIdentifier The packet identifier generated for this SUBSCRIBE.\r
- *\r
- * @return #IOT_MQTT_SUCCESS or #IOT_MQTT_NO_MEMORY.\r
- */\r
-IotMqttError_t _IotMqtt_SerializeSubscribe( const IotMqttSubscription_t * pSubscriptionList,\r
-                                            size_t subscriptionCount,\r
-                                            uint8_t ** pSubscribePacket,\r
-                                            size_t * pPacketSize,\r
-                                            uint16_t * pPacketIdentifier );\r
-\r
-/**\r
- * @brief Deserialize a SUBACK packet.\r
- *\r
- * Converts the packet from a stream of bytes to an #IotMqttError_t and extracts\r
- * the packet identifier. Also prints out debug log messages about the packet.\r
- *\r
- * @param[in,out] pSuback Pointer to an MQTT packet struct representing a SUBACK.\r
- *\r
- * @return #IOT_MQTT_SUCCESS if SUBACK is valid; #IOT_MQTT_BAD_RESPONSE\r
- * if the SUBACK packet doesn't follow MQTT spec.\r
- */\r
-IotMqttError_t _IotMqtt_DeserializeSuback( _mqttPacket_t * pSuback );\r
-\r
-/**\r
- * @brief Generate an UNSUBSCRIBE packet from the given parameters.\r
- *\r
- * @param[in] pSubscriptionList User-provided array of subscriptions to remove.\r
- * @param[in] subscriptionCount Size of `pSubscriptionList`.\r
- * @param[out] pUnsubscribePacket Where the UNSUBSCRIBE packet is written.\r
- * @param[out] pPacketSize Size of the packet written to `pUnsubscribePacket`.\r
- * @param[out] pPacketIdentifier The packet identifier generated for this UNSUBSCRIBE.\r
- *\r
- * @return #IOT_MQTT_SUCCESS or #IOT_MQTT_NO_MEMORY.\r
- */\r
-IotMqttError_t _IotMqtt_SerializeUnsubscribe( const IotMqttSubscription_t * pSubscriptionList,\r
-                                              size_t subscriptionCount,\r
-                                              uint8_t ** pUnsubscribePacket,\r
-                                              size_t * pPacketSize,\r
-                                              uint16_t * pPacketIdentifier );\r
-\r
-/**\r
- * @brief Deserialize a UNSUBACK packet.\r
- *\r
- * Converts the packet from a stream of bytes to an #IotMqttError_t and extracts\r
- * the packet identifier. Also prints out debug log messages about the packet.\r
- *\r
- * @param[in,out] pUnsuback Pointer to an MQTT packet struct representing an UNSUBACK.\r
- *\r
- * @return #IOT_MQTT_SUCCESS if UNSUBACK is valid; #IOT_MQTT_BAD_RESPONSE\r
- * if the UNSUBACK packet doesn't follow MQTT spec.\r
- */\r
-IotMqttError_t _IotMqtt_DeserializeUnsuback( _mqttPacket_t * pUnsuback );\r
-\r
-/**\r
- * @brief Generate a PINGREQ packet.\r
- *\r
- * @param[out] pPingreqPacket Where the PINGREQ packet is written.\r
- * @param[out] pPacketSize Size of the packet written to `pPingreqPacket`.\r
- *\r
- * @return Always returns #IOT_MQTT_SUCCESS.\r
- */\r
-IotMqttError_t _IotMqtt_SerializePingreq( uint8_t ** pPingreqPacket,\r
-                                          size_t * pPacketSize );\r
-\r
-/**\r
- * @brief Deserialize a PINGRESP packet.\r
- *\r
- * Converts the packet from a stream of bytes to an #IotMqttError_t. Also\r
- * prints out debug log messages about the packet.\r
- *\r
- * @param[in,out] pPingresp Pointer to an MQTT packet struct representing a PINGRESP.\r
- *\r
- * @return #IOT_MQTT_SUCCESS if PINGRESP is valid; #IOT_MQTT_BAD_RESPONSE\r
- * if the PINGRESP packet doesn't follow MQTT spec.\r
- */\r
-IotMqttError_t _IotMqtt_DeserializePingresp( _mqttPacket_t * pPingresp );\r
-\r
-/**\r
- * @brief Generate a DISCONNECT packet.\r
- *\r
- * @param[out] pDisconnectPacket Where the DISCONNECT packet is written.\r
- * @param[out] pPacketSize Size of the packet written to `pDisconnectPacket`.\r
- *\r
- * @return Always returns #IOT_MQTT_SUCCESS.\r
- */\r
-IotMqttError_t _IotMqtt_SerializeDisconnect( uint8_t ** pDisconnectPacket,\r
-                                             size_t * pPacketSize );\r
-\r
-/**\r
- * @brief Free a packet generated by the serializer.\r
- *\r
- * @param[in] pPacket The packet to free.\r
- */\r
-void _IotMqtt_FreePacket( uint8_t * pPacket );\r
-\r
-/*-------------------- MQTT operation record functions ----------------------*/\r
-\r
-/**\r
- * @brief Create a record for a new in-progress MQTT operation.\r
- *\r
- * @param[in] pMqttConnection The MQTT connection to associate with the operation.\r
- * @param[in] flags Flags variable passed to a user-facing MQTT function.\r
- * @param[in] pCallbackInfo User-provided callback function and parameter.\r
- * @param[out] pNewOperation Set to point to the new operation on success.\r
- *\r
- * @return #IOT_MQTT_SUCCESS, #IOT_MQTT_BAD_PARAMETER, or #IOT_MQTT_NO_MEMORY.\r
- */\r
-IotMqttError_t _IotMqtt_CreateOperation( _mqttConnection_t * pMqttConnection,\r
-                                         uint32_t flags,\r
-                                         const IotMqttCallbackInfo_t * pCallbackInfo,\r
-                                         _mqttOperation_t ** pNewOperation );\r
-\r
-/**\r
- * @brief Decrement the job reference count of an MQTT operation and optionally\r
- * cancel its job.\r
- *\r
- * Checks if the operation may be destroyed afterwards.\r
- *\r
- * @param[in] pOperation The MQTT operation with the job to cancel.\r
- * @param[in] cancelJob Whether to attempt cancellation of the operation's job.\r
- *\r
- * @return `true` if the the operation may be safely destroyed; `false` otherwise.\r
- */\r
-bool _IotMqtt_DecrementOperationReferences( _mqttOperation_t * pOperation,\r
-                                            bool cancelJob );\r
-\r
-/**\r
- * @brief Free resources used to record an MQTT operation. This is called when\r
- * the operation completes.\r
- *\r
- * @param[in] pOperation The operation which completed.\r
- */\r
-void _IotMqtt_DestroyOperation( _mqttOperation_t * pOperation );\r
-\r
-/**\r
- * @brief Task pool routine for processing an MQTT connection's keep-alive.\r
- *\r
- * @param[in] pTaskPool Pointer to the system task pool.\r
- * @param[in] pKeepAliveJob Pointer the an MQTT connection's keep-alive job.\r
- * @param[in] pContext Pointer to an MQTT connection, passed as an opaque context.\r
- */\r
-void _IotMqtt_ProcessKeepAlive( IotTaskPool_t pTaskPool,\r
-                                IotTaskPoolJob_t pKeepAliveJob,\r
-                                void * pContext );\r
-\r
-/**\r
- * @brief Task pool routine for processing an incoming PUBLISH message.\r
- *\r
- * @param[in] pTaskPool Pointer to the system task pool.\r
- * @param[in] pPublishJob Pointer to the incoming PUBLISH operation's job.\r
- * @param[in] pContext Pointer to the incoming PUBLISH operation, passed as an\r
- * opaque context.\r
- */\r
-void _IotMqtt_ProcessIncomingPublish( IotTaskPool_t pTaskPool,\r
-                                      IotTaskPoolJob_t pPublishJob,\r
-                                      void * pContext );\r
-\r
-/**\r
- * @brief Task pool routine for processing an MQTT operation to send.\r
- *\r
- * @param[in] pTaskPool Pointer to the system task pool.\r
- * @param[in] pSendJob Pointer to an operation's job.\r
- * @param[in] pContext Pointer to the operation to send, passed as an opaque\r
- * context.\r
- */\r
-void _IotMqtt_ProcessSend( IotTaskPool_t pTaskPool,\r
-                           IotTaskPoolJob_t pSendJob,\r
-                           void * pContext );\r
-\r
-/**\r
- * @brief Task pool routine for processing a completed MQTT operation.\r
- *\r
- * @param[in] pTaskPool Pointer to the system task pool.\r
- * @param[in] pOperationJob Pointer to the completed operation's job.\r
- * @param[in] pContext Pointer to the completed operation, passed as an opaque\r
- * context.\r
- */\r
-void _IotMqtt_ProcessCompletedOperation( IotTaskPool_t pTaskPool,\r
-                                         IotTaskPoolJob_t pOperationJob,\r
-                                         void * pContext );\r
-\r
-/**\r
- * @brief Schedule an operation for immediate processing.\r
- *\r
- * @param[in] pOperation The operation to schedule.\r
- * @param[in] jobRoutine The routine to run for the job. Must be either\r
- * #_IotMqtt_ProcessSend, #_IotMqtt_ProcessCompletedOperation, or\r
- * #_IotMqtt_ProcessIncomingPublish.\r
- * @param[in] delay A delay before the operation job should be executed. Pass\r
- * `0` to execute ASAP.\r
- *\r
- * @return #IOT_MQTT_SUCCESS or #IOT_MQTT_SCHEDULING_ERROR.\r
- */\r
-IotMqttError_t _IotMqtt_ScheduleOperation( _mqttOperation_t * pOperation,\r
-                                           IotTaskPoolRoutine_t jobRoutine,\r
-                                           uint32_t delay );\r
-\r
-/**\r
- * @brief Search a list of MQTT operations pending responses using an operation\r
- * name and packet identifier. Removes a matching operation from the list if found.\r
- *\r
- * @param[in] pMqttConnection The connection associated with the operation.\r
- * @param[in] type The operation type to look for.\r
- * @param[in] pPacketIdentifier A packet identifier to match. Pass `NULL` to ignore.\r
- *\r
- * @return Pointer to any matching operation; `NULL` if no match was found.\r
- */\r
-_mqttOperation_t * _IotMqtt_FindOperation( _mqttConnection_t * pMqttConnection,\r
-                                           IotMqttOperationType_t type,\r
-                                           const uint16_t * pPacketIdentifier );\r
-\r
-/**\r
- * @brief Notify of a completed MQTT operation.\r
- *\r
- * @param[in] pOperation The MQTT operation which completed.\r
- *\r
- * Depending on the parameters passed to a user-facing MQTT function, the\r
- * notification will cause @ref mqtt_function_wait to return or invoke a\r
- * user-provided callback.\r
- */\r
-void _IotMqtt_Notify( _mqttOperation_t * pOperation );\r
-\r
-/*----------------- MQTT subscription management functions ------------------*/\r
-\r
-/**\r
- * @brief Add an array of subscriptions to the subscription manager.\r
- *\r
- * @param[in] pMqttConnection The MQTT connection associated with the subscriptions.\r
- * @param[in] subscribePacketIdentifier Packet identifier for the subscriptions'\r
- * SUBSCRIBE packet.\r
- * @param[in] pSubscriptionList The first element in the array.\r
- * @param[in] subscriptionCount Number of elements in `pSubscriptionList`.\r
- *\r
- * @return #IOT_MQTT_SUCCESS or #IOT_MQTT_NO_MEMORY.\r
- */\r
-IotMqttError_t _IotMqtt_AddSubscriptions( _mqttConnection_t * pMqttConnection,\r
-                                          uint16_t subscribePacketIdentifier,\r
-                                          const IotMqttSubscription_t * pSubscriptionList,\r
-                                          size_t subscriptionCount );\r
-\r
-/**\r
- * @brief Process a received PUBLISH from the server, invoking any subscription\r
- * callbacks that have a matching topic filter.\r
- *\r
- * @param[in] pMqttConnection The MQTT connection associated with the received\r
- * PUBLISH.\r
- * @param[in] pCallbackParam The parameter to pass to a PUBLISH callback.\r
- */\r
-void _IotMqtt_InvokeSubscriptionCallback( _mqttConnection_t * pMqttConnection,\r
-                                          IotMqttCallbackParam_t * pCallbackParam );\r
-\r
-/**\r
- * @brief Remove a single subscription from the subscription manager by\r
- * packetIdentifier and order.\r
- *\r
- * @param[in] pMqttConnection The MQTT connection associated with the subscriptions.\r
- * @param[in] packetIdentifier The packet identifier associated with the subscription's\r
- * SUBSCRIBE packet.\r
- * @param[in] order The order of the subscription in the SUBSCRIBE packet.\r
- * Pass `-1` to ignore order and remove all subscriptions for `packetIdentifier`.\r
- */\r
-void _IotMqtt_RemoveSubscriptionByPacket( _mqttConnection_t * pMqttConnection,\r
-                                          uint16_t packetIdentifier,\r
-                                          int32_t order );\r
-\r
-/**\r
- * @brief Remove an array of subscriptions from the subscription manager by\r
- * topic filter.\r
- *\r
- * @param[in] pMqttConnection The MQTT connection associated with the subscriptions.\r
- * @param[in] pSubscriptionList The first element in the array.\r
- * @param[in] subscriptionCount Number of elements in `pSubscriptionList`.\r
- */\r
-void _IotMqtt_RemoveSubscriptionByTopicFilter( _mqttConnection_t * pMqttConnection,\r
-                                               const IotMqttSubscription_t * pSubscriptionList,\r
-                                               size_t subscriptionCount );\r
-\r
-/*------------------ MQTT connection management functions -------------------*/\r
-\r
-/**\r
- * @brief Attempt to increment the reference count of an MQTT connection.\r
- *\r
- * @param[in] pMqttConnection The referenced MQTT connection.\r
- *\r
- * @return `true` if the reference count was incremented; `false` otherwise. The\r
- * reference count will not be incremented for a disconnected connection.\r
- */\r
-bool _IotMqtt_IncrementConnectionReferences( _mqttConnection_t * pMqttConnection );\r
-\r
-/**\r
- * @brief Decrement the reference count of an MQTT connection.\r
- *\r
- * Also destroys an unreferenced MQTT connection.\r
- *\r
- * @param[in] pMqttConnection The referenced MQTT connection.\r
- */\r
-void _IotMqtt_DecrementConnectionReferences( _mqttConnection_t * pMqttConnection );\r
-\r
-/**\r
- * @brief Read the next available byte on a network connection.\r
- *\r
- * @param[in] pNetworkConnection Reference to the network connection.\r
- * @param[in] pNetworkInterface Function pointers used to interact with the\r
- * network.\r
- * @param[out] pIncomingByte The byte read from the network.\r
- *\r
- * @return `true` if a byte was successfully received from the network; `false`\r
- * otherwise.\r
- */\r
-bool _IotMqtt_GetNextByte( void * pNetworkConnection,\r
-                           const IotNetworkInterface_t * pNetworkInterface,\r
-                           uint8_t * pIncomingByte );\r
-\r
-/**\r
- * @brief Closes the network connection associated with an MQTT connection.\r
- *\r
- * A network disconnect function must be set in the network interface for the\r
- * network connection to be closed.\r
- *\r
- * @param[in] disconnectReason A reason to pass to the connection's disconnect\r
- * callback.\r
- * @param[in] pMqttConnection The MQTT connection with the network connection\r
- * to close.\r
- */\r
-void _IotMqtt_CloseNetworkConnection( IotMqttDisconnectReason_t disconnectReason,\r
-                                      _mqttConnection_t * pMqttConnection );\r
-\r
-#endif /* ifndef IOT_MQTT_INTERNAL_H_ */\r