From 1629c27d6c6df268e39aaaa1e5fc1593f2fa4558 Mon Sep 17 00:00:00 2001 From: rtel Date: Thu, 30 Jan 2020 00:05:23 +0000 Subject: [PATCH] Remove the FreeRTOS-IoT-Libraries from FreeRTOS-Plus as it was an old copy with a newer copy in FreeRTOS-Labs. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2811 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- .../abstractions/directories.txt | 4 - .../include/platform/iot_network_freertos.h | 137 -- .../platform/iot_platform_types_freertos.h | 84 - .../platform/freertos/iot_clock_freertos.c | 224 -- .../platform/freertos/iot_network_freertos.c | 521 ----- .../platform/freertos/iot_threads_freertos.c | 364 --- .../platform/include/platform/iot_clock.h | 216 -- .../platform/include/platform/iot_metrics.h | 103 - .../platform/include/platform/iot_network.h | 294 --- .../platform/include/platform/iot_threads.h | 355 --- .../include/types/iot_platform_types.h | 158 -- .../c_sdk/directories.txt | 3 - .../c_sdk/standard/common/include/atomic.h | 547 ----- .../standard/common/include/iot_atomic.h | 39 - .../c_sdk/standard/common/include/iot_init.h | 67 - .../common/include/iot_linear_containers.h | 956 -------- .../common/include/iot_logging_setup.h | 223 -- .../standard/common/include/iot_taskpool.h | 558 ----- .../common/include/private/iot_error.h | 117 - .../common/include/private/iot_logging.h | 229 -- .../include/private/iot_static_memory.h | 250 -- .../include/private/iot_taskpool_internal.h | 293 --- .../common/include/types/iot_taskpool_types.h | 362 --- .../standard/common/logging/iot_logging.c | 454 ---- .../iot_logging_task_dynamic_buffers.c | 250 -- .../standard/common/taskpool/iot_taskpool.c | 1192 ---------- .../c_sdk/standard/directories.txt | 7 - .../c_sdk/standard/mqtt/include/iot_mqtt.h | 823 ------- .../standard/mqtt/include/iot_mqtt_agent.h | 358 --- .../include/iot_mqtt_agent_config_defaults.h | 180 -- .../mqtt/include/iot_mqtt_config_defaults.h | 115 - .../standard/mqtt/include/iot_mqtt_lib.h | 113 - .../mqtt/include/types/iot_mqtt_types.h | 1087 --------- .../mqtt/src/iot_ble_mqtt_serialize.c | 1528 ------------- .../c_sdk/standard/mqtt/src/iot_mqtt_agent.c | 794 ------- .../c_sdk/standard/mqtt/src/iot_mqtt_api.c | 2035 ----------------- .../standard/mqtt/src/iot_mqtt_network.c | 986 -------- .../standard/mqtt/src/iot_mqtt_operation.c | 1373 ----------- .../standard/mqtt/src/iot_mqtt_serialize.c | 1939 ---------------- .../mqtt/src/iot_mqtt_static_memory.c | 207 -- .../standard/mqtt/src/iot_mqtt_subscription.c | 645 ------ .../standard/mqtt/src/iot_mqtt_validate.c | 593 ----- .../mqtt/src/private/iot_mqtt_internal.h | 928 -------- .../FreeRTOS-IoT-Libraries/directories.txt | 8 - 44 files changed, 21719 deletions(-) delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/directories.txt delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/include/platform/iot_network_freertos.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/include/platform/iot_platform_types_freertos.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/iot_clock_freertos.c delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/iot_network_freertos.c delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/iot_threads_freertos.c delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/platform/iot_clock.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/platform/iot_metrics.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/platform/iot_network.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/platform/iot_threads.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/types/iot_platform_types.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/directories.txt delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/atomic.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_atomic.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_init.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_linear_containers.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_logging_setup.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_taskpool.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/private/iot_error.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/private/iot_logging.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/private/iot_static_memory.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/private/iot_taskpool_internal.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/types/iot_taskpool_types.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/logging/iot_logging.c delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/logging/iot_logging_task_dynamic_buffers.c delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/taskpool/iot_taskpool.c delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/directories.txt delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt_agent.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt_agent_config_defaults.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt_config_defaults.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt_lib.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/types/iot_mqtt_types.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_ble_mqtt_serialize.c delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_agent.c delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_api.c delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_network.c delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_operation.c delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_serialize.c delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_static_memory.c delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_subscription.c delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_validate.c delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/private/iot_mqtt_internal.h delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/directories.txt diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/directories.txt b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/directories.txt deleted file mode 100644 index 6eb48c195..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/directories.txt +++ /dev/null @@ -1,4 +0,0 @@ -+ platform -Contains FreeRTOS specific implementations of abstractions used within the IoT -libraries. - 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 deleted file mode 100644 index fef3367aa..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/include/platform/iot_network_freertos.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Amazon FreeRTOS Platform V1.0.0 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_network_freertos.h - * @brief Declares the network stack functions specified in iot_network.h for - * FreeRTOS+TCP. - */ - -#ifndef _IOT_NETWORK_FREERTOS_H_ -#define _IOT_NETWORK_FREERTOS_H_ - -/* Standard includes. */ -#include - -/* Platform network include. */ -#include "platform/iot_network.h" - -/** - * @brief Represents a network connection that uses FreeRTOS+TCP sockets. - * - * This is an incomplete type. In application code, only pointers to this type - * should be used. - */ -typedef struct _networkConnection IotNetworkConnectionFreeRTOS_t; - -/** - * @brief Provides a default value for an #IotNetworkConnectionFreeRTOS_t. - * - * All instances of #IotNetworkConnectionFreeRTOS_t should be initialized with - * this constant. - * - * @warning Failing to initialize an #IotNetworkConnectionFreeRTOS_t with this - * initializer may result in undefined behavior! - * @note This initializer may change at any time in future versions, but its - * name will remain the same. - */ -#define IOT_NETWORK_CONNECTION_FREERTOS_INITIALIZER { 0 } - -/** - * @brief Generic initializer for an #IotNetworkServerInfo_t. - * - * @note This initializer may change at any time in future versions, but its - * name will remain the same. - */ -#define IOT_NETWORK_SERVER_INFO_FREERTOS_INITIALIZER { 0 } - -/** - * @brief Generic initializer for an #IotNetworkCredentials_t. - * - * @note This initializer may change at any time in future versions, but its - * name will remain the same. - */ -#define IOT_NETWORK_CREDENTIALS_FREERTOS_INITIALIZER { 0 } - -/** - * @brief Provides a pointer to an #IotNetworkInterface_t that uses the functions - * declared in this file. - */ -#define IOT_NETWORK_INTERFACE_FREERTOS ( &( IotNetworkFreeRTOS ) ) - -/** - * @brief An implementation of #IotNetworkInterface_t::create for FreeRTOS+TCP - * sockets. - */ -IotNetworkError_t IotNetworkFreeRTOS_Create( void * pConnectionInfo, - void * pCredentialInfo, - void ** const pConnection ); - -/** - * @brief An implementation of #IotNetworkInterface_t::setReceiveCallback for - * FreeRTOS+TCP sockets. - */ -IotNetworkError_t IotNetworkFreeRTOS_SetReceiveCallback( void * pConnection, - IotNetworkReceiveCallback_t receiveCallback, - void * pContext ); - -/** - * @brief An implementation of #IotNetworkInterface_t::send for FreeRTOS+TCP - * sockets. - */ -size_t IotNetworkFreeRTOS_Send( void * pConnection, - const uint8_t * pMessage, - size_t messageLength ); - -/** - * @brief An implementation of #IotNetworkInterface_t::receive for FreeRTOS+TCP - * sockets. - */ -size_t IotNetworkFreeRTOS_Receive( void * pConnection, - uint8_t * pBuffer, - size_t bytesRequested ); - -/** - * @brief An implementation of #IotNetworkInterface_t::close for FreeRTOS+TCP - * sockets. - */ -IotNetworkError_t IotNetworkFreeRTOS_Close( void * pConnection ); - -/** - * @brief An implementation of #IotNetworkInterface_t::destroy for FreeRTOS+TCP - * sockets. - */ -IotNetworkError_t IotNetworkFreeRTOS_Destroy( void * pConnection ); - -/** - * @cond DOXYGEN_IGNORE - * Doxygen should ignore this section. - * - * Declaration of a network interface struct using the functions in this file. - */ -extern const IotNetworkInterface_t IotNetworkFreeRTOS; -/** @endcond */ - -#endif /* ifndef _IOT_NETWORK_FREERTOS_H_ */ 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 deleted file mode 100644 index e85534381..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/include/platform/iot_platform_types_freertos.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Amazon FreeRTOS Platform V1.0.0 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_platform_types_posix.h - * @brief Definitions of platform layer types on POSIX systems. - */ - -#ifndef _IOT_PLATFORM_TYPES_AFR_H_ -#define _IOT_PLATFORM_TYPES_AFR_H_ - -#include "timers.h" - -typedef struct iot_mutex_internal -{ - StaticSemaphore_t xMutex; /**< FreeRTOS mutex. */ - BaseType_t recursive; /**< Type; used for indicating if this is reentrant or normal. */ -} iot_mutex_internal_t; - -/** - * @brief The native mutex type on AFR systems. - */ -typedef iot_mutex_internal_t _IotSystemMutex_t; - -typedef struct iot_sem_internal -{ - StaticSemaphore_t xSemaphore; /**< FreeRTOS semaphore. */ -} iot_sem_internal_t; - -/** - * @brief The native semaphore type on AFR systems. - */ -typedef iot_sem_internal_t _IotSystemSemaphore_t; - -/** - * @brief Holds information about an active detached thread so that we can - * delete the FreeRTOS task when it completes - */ -typedef struct threadInfo -{ - void * pArgument; /**< @brief Argument to `threadRoutine`. */ - void ( *threadRoutine )( void * );/**< @brief Thread function to run. */ -} threadInfo_t; - -/** - * @brief Holds information about an active timer. - */ -typedef struct timerInfo -{ - TimerHandle_t timer; /**< @brief Underlying timer. */ - void ( *threadRoutine )( void * ); /**< @brief Thread function to run on timer expiration. */ - void * pArgument; /**< @brief First argument to threadRoutine. */ - StaticTimer_t xTimerBuffer; /**< Memory that holds the FreeRTOS timer. */ - TickType_t xTimerPeriod; /**< Period of this timer. */ -} timerInfo_t; - -/** - * @brief Represents an #IotTimer_t on AFR systems. - */ -typedef timerInfo_t _IotSystemTimer_t; - -#endif /* ifndef _IOT_PLATFORM_TYPES_POSIX_H_ */ 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 deleted file mode 100644 index 4d74b8278..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/iot_clock_freertos.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Amazon FreeRTOS Platform V1.0.0 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_clock_freertos.c - * @brief Implementation of the functions in iot_clock.h for Amazon FreeRTOS systems. - */ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* Standard includes. */ -#include - -/* Platform clock include. */ -#include "platform/iot_platform_types_freertos.h" -#include "platform/iot_clock.h" -#include "task.h" - -/* Configure logs for the functions in this file. */ -#ifdef IOT_LOG_LEVEL_PLATFORM - #define LIBRARY_LOG_LEVEL IOT_LOG_LEVEL_PLATFORM -#else - #ifdef IOT_LOG_LEVEL_GLOBAL - #define LIBRARY_LOG_LEVEL IOT_LOG_LEVEL_GLOBAL - #else - #define LIBRARY_LOG_LEVEL IOT_LOG_NONE - #endif -#endif - -#define LIBRARY_LOG_NAME ( "CLOCK" ) -#include "iot_logging_setup.h" - -/*-----------------------------------------------------------*/ - -/* - * Time conversion constants. - */ -#define _MILLISECONDS_PER_SECOND ( 1000 ) /**< @brief Milliseconds per second. */ -#define _MILLISECONDS_PER_TICK ( _MILLISECONDS_PER_SECOND / configTICK_RATE_HZ ) /**< Milliseconds per FreeRTOS tick. */ - -/*-----------------------------------------------------------*/ - -/* Private Callback function for timer expiry, delegate work to a Task to free - * up the timer task for managing other timers */ -static void prvTimerCallback( TimerHandle_t xTimerHandle ) -{ - _IotSystemTimer_t * pxTimer = ( _IotSystemTimer_t * ) pvTimerGetTimerID( xTimerHandle ); - - /* The value of the timer ID, set in timer_create, should not be NULL. */ - configASSERT( pxTimer != NULL ); - - /* Restart the timer if it is periodic. */ - if( pxTimer->xTimerPeriod > 0 ) - { - xTimerChangePeriod( xTimerHandle, pxTimer->xTimerPeriod, 0 ); - } - - /* Call timer Callback from this task */ - pxTimer->threadRoutine( ( void * ) pxTimer->pArgument ); -} - -/*-----------------------------------------------------------*/ - -bool IotClock_GetTimestring( char * pBuffer, - size_t bufferSize, - size_t * pTimestringLength ) -{ - uint64_t milliSeconds = IotClock_GetTimeMs(); - int timestringLength = 0; - - configASSERT( pBuffer != NULL ); - configASSERT( pTimestringLength != NULL ); - - /* Convert the localTime struct to a string. */ - timestringLength = snprintf( pBuffer, bufferSize, "%llu", milliSeconds ); - - /* Check for error from no string */ - if( timestringLength == 0 ) - { - return false; - } - - /* Set the output parameter. */ - *pTimestringLength = timestringLength; - - return true; -} - -/*-----------------------------------------------------------*/ - -uint64_t IotClock_GetTimeMs( void ) -{ - TimeOut_t xCurrentTime = { 0 }; - - /* This must be unsigned because the behavior of signed integer overflow is undefined. */ - uint64_t ullTickCount = 0ULL; - - /* Get the current tick count and overflow count. vTaskSetTimeOutState() - * is used to get these values because they are both static in tasks.c. */ - vTaskSetTimeOutState( &xCurrentTime ); - - /* Adjust the tick count for the number of times a TickType_t has overflowed. */ - ullTickCount = ( uint64_t ) ( xCurrentTime.xOverflowCount ) << ( sizeof( TickType_t ) * 8 ); - - /* Add the current tick count. */ - ullTickCount += xCurrentTime.xTimeOnEntering; - - /* Return the ticks converted to Milliseconds */ - return ullTickCount * _MILLISECONDS_PER_TICK; -} -/*-----------------------------------------------------------*/ - -void IotClock_SleepMs( uint32_t sleepTimeMs ) -{ - vTaskDelay( pdMS_TO_TICKS( sleepTimeMs ) ); -} - -/*-----------------------------------------------------------*/ - -bool IotClock_TimerCreate( IotTimer_t * pNewTimer, - IotThreadRoutine_t expirationRoutine, - void * pArgument ) -{ - _IotSystemTimer_t * pxTimer = ( _IotSystemTimer_t * ) pNewTimer; - - configASSERT( pNewTimer != NULL ); - configASSERT( expirationRoutine != NULL ); - - IotLogDebug( "Creating new timer %p.", pNewTimer ); - - /* Set the timer expiration routine, argument and period */ - pxTimer->threadRoutine = expirationRoutine; - pxTimer->pArgument = pArgument; - pxTimer->xTimerPeriod = 0; - - /* Create a new FreeRTOS timer. This call will not fail because the - * memory for it has already been allocated, so the output parameter is - * also set. */ - pxTimer->timer = ( TimerHandle_t ) xTimerCreateStatic( "timer", /* Timer name. */ - portMAX_DELAY, /* Initial timer period. Timers are created disarmed. */ - pdFALSE, /* Don't auto-reload timer. */ - ( void * ) pxTimer, /* Timer id. */ - prvTimerCallback, /* Timer expiration callback. */ - &pxTimer->xTimerBuffer ); /* Pre-allocated memory for timer. */ - - return true; -} - -/*-----------------------------------------------------------*/ - -void IotClock_TimerDestroy( IotTimer_t * pTimer ) -{ - _IotSystemTimer_t * pTimerInfo = ( _IotSystemTimer_t * ) pTimer; - - configASSERT( pTimerInfo != NULL ); - configASSERT( pTimerInfo->timer != NULL ); - - IotLogDebug( "Destroying timer %p.", pTimer ); - - if( xTimerIsTimerActive( pTimerInfo->timer ) == pdTRUE ) - { - /* Stop the FreeRTOS timer. Because the timer is statically allocated, no call - * to xTimerDelete is necessary. The timer is stopped so that it's not referenced - * anywhere. xTimerStop will not fail when it has unlimited block time. */ - ( void ) xTimerStop( pTimerInfo->timer, portMAX_DELAY ); - - /* Wait until the timer stop command is processed. */ - while( xTimerIsTimerActive( pTimerInfo->timer ) == pdTRUE ) - { - vTaskDelay( 1 ); - } - } -} - -/*-----------------------------------------------------------*/ - -bool IotClock_TimerArm( IotTimer_t * pTimer, - uint32_t relativeTimeoutMs, - uint32_t periodMs ) -{ - _IotSystemTimer_t * pTimerInfo = ( _IotSystemTimer_t * ) pTimer; - - configASSERT( pTimerInfo != NULL ); - - TimerHandle_t xTimerHandle = pTimerInfo->timer; - - IotLogDebug( "Arming timer %p with timeout %llu and period %llu.", - pTimer, - relativeTimeoutMs, - periodMs ); - - /* Set the timer period in ticks */ - pTimerInfo->xTimerPeriod = pdMS_TO_TICKS( periodMs ); - - /* Set the timer to expire after relativeTimeoutMs, and restart it. */ - ( void ) xTimerChangePeriod( xTimerHandle, pdMS_TO_TICKS( relativeTimeoutMs ), portMAX_DELAY ); - - return true; -} - -/*-----------------------------------------------------------*/ 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 deleted file mode 100644 index dbe55dbbd..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/iot_network_freertos.c +++ /dev/null @@ -1,521 +0,0 @@ -/* - * Amazon FreeRTOS Platform V1.0.0 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_network_freertos.c - * @brief Implementation of the network-related functions from iot_network_freertos.h - * for FreeRTOS+TCP sockets. - */ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* Standard includes. */ -#include - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "semphr.h" -#include "event_groups.h" - -/* FreeRTOS+TCP includes. */ -#include "FreeRTOS_IP.h" -#include "FreeRTOS_Sockets.h" - -/* FreeRTOS-IoT-Libraries includes. */ -#include "private/iot_error.h" -#include "platform/iot_network_freertos.h" - -/* Configure logs for the functions in this file. */ -#ifdef IOT_LOG_LEVEL_NETWORK - #define LIBRARY_LOG_LEVEL IOT_LOG_LEVEL_NETWORK -#else - #ifdef IOT_LOG_LEVEL_GLOBAL - #define LIBRARY_LOG_LEVEL IOT_LOG_LEVEL_GLOBAL - #else - #define LIBRARY_LOG_LEVEL IOT_LOG_NONE - #endif -#endif - -#define LIBRARY_LOG_NAME ( "NET" ) -#include "iot_logging_setup.h" - -/* Provide a default value for the number of milliseconds for a socket poll. - * This is a temporary workaround to deal with the lack of poll(). */ -#ifndef IOT_NETWORK_SOCKET_POLL_MS - #define IOT_NETWORK_SOCKET_POLL_MS ( 1000 ) -#endif - -/** - * @brief The event group bit to set when a connection's socket is shut down. - */ -#define _SHUTDOWN_BITMASK ( 1UL << 0UL ) - -/** - * @brief The event group bit to set when a connection's receive task exits. - */ -#define _RECEIVE_TASK_EXITED_BITMASK ( 1UL << 1UL ) - -/** - * @brief The event group bit to set when the connection is destroyed from the - * receive task. - */ -#define _CONNECTION_DESTROYED_BITMASK ( 1UL << 2UL ) - -/** - * @brief Maximum length of a DNS name. - * - * Per https://tools.ietf.org/html/rfc1035, 253 is the maximum string length - * of a DNS name. - */ -#define _MAX_DNS_NAME_LENGTH ( 253 ) -/*-----------------------------------------------------------*/ - -typedef struct _networkConnection -{ - Socket_t socket; /**< @brief FreeRTOS+TCP sockets handle. */ - SemaphoreHandle_t socketMutex; /**< @brief Prevents concurrent threads from sending on a socket. */ - StaticSemaphore_t socketMutexStorage; /**< @brief Storage space for socketMutex. */ - EventGroupHandle_t connectionEventGroup; /**< @brief Synchronizes with the receive task. */ - StaticEventGroup_t connectionEventGroupStorage; /**< @brief Storage space for connectionEventGroup. */ - TaskHandle_t receiveTask; /**< @brief Handle of the receive task, if any. */ - IotNetworkReceiveCallback_t receiveCallback; /**< @brief Network receive callback, if any. */ - void * pReceiveContext; /**< @brief The context for the receive callback. */ - bool bufferedByteValid; /**< @brief Used to determine if the buffered byte is valid. */ - uint8_t bufferedByte; /**< @brief A single byte buffered from a receive, since FreeRTOS+TCP sockets does not have poll(). */ -} _networkConnection_t; -/*-----------------------------------------------------------*/ - -/** - * @brief An #IotNetworkInterface_t that uses the functions in this file. - */ -const IotNetworkInterface_t IotNetworkFreeRTOS = -{ - .create = IotNetworkFreeRTOS_Create, - .setReceiveCallback = IotNetworkFreeRTOS_SetReceiveCallback, - .send = IotNetworkFreeRTOS_Send, - .receive = IotNetworkFreeRTOS_Receive, - .close = IotNetworkFreeRTOS_Close, - .destroy = IotNetworkFreeRTOS_Destroy -}; -/*-----------------------------------------------------------*/ - -/** - * @brief Destroys a network connection. - * - * @param[in] pNetworkConnection The connection to destroy. - */ -static void _destroyConnection( _networkConnection_t * pNetworkConnection ) -{ - /* Call FreeRTOS+TCP close function to free resources. */ - ( void ) FreeRTOS_closesocket( pNetworkConnection->socket ); - - /* Free the network connection. */ - vPortFree( pNetworkConnection ); -} -/*-----------------------------------------------------------*/ - -/** - * @brief Task routine that waits on incoming network data. - * - * @param[in] pArgument The network connection. - */ -static void _networkReceiveTask( void * pArgument ) -{ - bool destroyConnection = false; - int32_t socketStatus = 0; - EventBits_t connectionEventGroupBits = 0; - - /* Cast network connection to the correct type. */ - _networkConnection_t * pNetworkConnection = pArgument; - - while( true ) - { - /* No buffered byte should be in the connection. */ - configASSERT( pNetworkConnection->bufferedByteValid == false ); - - /* Block and wait for 1 byte of data. This simulates the behavior of poll(). - * THIS IS A TEMPORARY WORKAROUND AND DOES NOT PROVIDE THREAD-SAFETY AGAINST - * MULTIPLE CALLS OF RECEIVE. */ - do - { - socketStatus = FreeRTOS_recv( pNetworkConnection->socket, - &( pNetworkConnection->bufferedByte ), - 1, - 0 ); - - connectionEventGroupBits = xEventGroupGetBits( pNetworkConnection->connectionEventGroup ); - - if( ( connectionEventGroupBits & _SHUTDOWN_BITMASK ) == _SHUTDOWN_BITMASK ) - { - socketStatus = FREERTOS_ECLOSED; - } - - /* Check for timeout. Some ports return 0, some return EWOULDBLOCK. */ - } while( ( socketStatus == 0 ) || ( socketStatus == FREERTOS_EWOULDBLOCK ) ); - - if( socketStatus <= 0 ) - { - break; - } - - pNetworkConnection->bufferedByteValid = true; - - /* Invoke the network callback. */ - pNetworkConnection->receiveCallback( pNetworkConnection, - pNetworkConnection->pReceiveContext ); - - /* Check if the connection was destroyed by the receive callback. This - * does not need to be thread-safe because the destroy connection function - * may only be called once (per its API doc). */ - connectionEventGroupBits = xEventGroupGetBits( pNetworkConnection->connectionEventGroup ); - - if( ( connectionEventGroupBits & _CONNECTION_DESTROYED_BITMASK ) == _CONNECTION_DESTROYED_BITMASK ) - { - destroyConnection = true; - break; - } - } - - IotLogDebug( "Network receive task terminating." ); - - /* If necessary, destroy the network connection before exiting. */ - if( destroyConnection == true ) - { - _destroyConnection( pNetworkConnection ); - } - else - { - /* Set the bit to indicate that the receive task has exited. */ - ( void ) xEventGroupSetBits( pNetworkConnection->connectionEventGroup, - _RECEIVE_TASK_EXITED_BITMASK ); - } - - vTaskDelete( NULL ); -} -/*-----------------------------------------------------------*/ - -IotNetworkError_t IotNetworkFreeRTOS_Create( void * pConnectionInfo, - void * pCredentialInfo, - void ** pConnection ) //_RB_ Why all void* and why a void**? -{ - IOT_FUNCTION_ENTRY( IotNetworkError_t, IOT_NETWORK_SUCCESS ); - Socket_t tcpSocket = FREERTOS_INVALID_SOCKET; - int32_t socketStatus = 0; - struct freertos_sockaddr serverAddress = { 0 }; - const TickType_t receiveTimeout = pdMS_TO_TICKS( IOT_NETWORK_SOCKET_POLL_MS ); - _networkConnection_t * pNewNetworkConnection = NULL; - - /* TLS is not enabled in this version and therefore pCredentialInfo - must be NULL. */ - configASSERT( pCredentialInfo == NULL ); - - /* Cast function parameters to correct types. */ - const IotNetworkServerInfo_t * pServerInfo = pConnectionInfo; - _networkConnection_t ** pNetworkConnection = ( _networkConnection_t ** ) pConnection; - - /* Check host name length against the maximum length allowed. */ - const size_t hostnameLength = strlen( pServerInfo->pHostName ); - - if( hostnameLength > ( size_t ) _MAX_DNS_NAME_LENGTH ) - { - IotLogError( "Host name length exceeds %d, which is the maximum allowed.", - _MAX_DNS_NAME_LENGTH ); - IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_BAD_PARAMETER ); - } - - pNewNetworkConnection = pvPortMalloc( sizeof( _networkConnection_t ) ); - - if( pNewNetworkConnection == NULL ) - { - IotLogError( "Failed to allocate memory for new network connection." ); - IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_NO_MEMORY ); - } - - /* Clear the connection information. */ - ( void ) memset( pNewNetworkConnection, 0x00, sizeof( _networkConnection_t ) ); - - /* Create a new TCP socket. */ - tcpSocket = FreeRTOS_socket( FREERTOS_AF_INET, - FREERTOS_SOCK_STREAM, - FREERTOS_IPPROTO_TCP ); - - if( tcpSocket == FREERTOS_INVALID_SOCKET ) - { - IotLogError( "Failed to create new socket." ); - IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_SYSTEM_ERROR ); - } - - /* Establish connection. */ - serverAddress.sin_family = FREERTOS_AF_INET; - serverAddress.sin_port = FreeRTOS_htons( pServerInfo->port ); - serverAddress.sin_addr = FreeRTOS_gethostbyname( pServerInfo->pHostName ); - serverAddress.sin_len = ( uint8_t ) sizeof( serverAddress ); - - /* Check for errors from DNS lookup. */ - if( serverAddress.sin_addr == 0 ) - { - IotLogError( "Failed to resolve %s.", pServerInfo->pHostName ); - IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_SYSTEM_ERROR ); - } - //_RB_ Connects without setting a read block time. - socketStatus = FreeRTOS_connect( tcpSocket, - &serverAddress, - sizeof( serverAddress ) ); - - if( socketStatus != 0 ) - { - IotLogError( "Failed to establish new connection." ); - IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_SYSTEM_ERROR ); - } - - /* Set a long timeout for receive. */ - socketStatus = FreeRTOS_setsockopt( tcpSocket, - 0, - FREERTOS_SO_RCVTIMEO, - &receiveTimeout, - sizeof( TickType_t ) ); - - if( socketStatus != 0 ) - { - IotLogError( "Failed to set socket receive timeout." ); - IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_SYSTEM_ERROR ); - } - - IOT_FUNCTION_CLEANUP_BEGIN(); - - /* Clean up on failure. */ - if( status != IOT_NETWORK_SUCCESS ) - { - if( tcpSocket != FREERTOS_INVALID_SOCKET ) - { - FreeRTOS_closesocket( tcpSocket ); - } - - /* Clear the connection information. */ - if( pNewNetworkConnection != NULL ) - { - vPortFree( pNewNetworkConnection ); - } - } - else - { - /* Set the socket. */ - pNewNetworkConnection->socket = tcpSocket; - - /* Create the connection event group and socket mutex. */ - pNewNetworkConnection->connectionEventGroup = xEventGroupCreateStatic( &( pNewNetworkConnection->connectionEventGroupStorage ) ); - pNewNetworkConnection->socketMutex = xSemaphoreCreateMutexStatic( &( pNewNetworkConnection->socketMutexStorage ) ); - - /* Set the output parameter. */ - *pNetworkConnection = pNewNetworkConnection; - } - - IOT_FUNCTION_CLEANUP_END(); -} -/*-----------------------------------------------------------*/ - -IotNetworkError_t IotNetworkFreeRTOS_SetReceiveCallback( void * pConnection, - IotNetworkReceiveCallback_t receiveCallback, - void * pContext ) -{ - IotNetworkError_t status = IOT_NETWORK_SUCCESS; - - /* Cast network connection to the correct type. */ - _networkConnection_t * pNetworkConnection = ( _networkConnection_t * ) pConnection; - - /* Set the receive callback and context. */ - pNetworkConnection->receiveCallback = receiveCallback; - pNetworkConnection->pReceiveContext = pContext; - - /* No bit should be set in the connection event group. */ - configASSERT( xEventGroupGetBits( pNetworkConnection->connectionEventGroup ) == 0 ); - - /* Create task that waits for incoming data. */ - if( xTaskCreate( _networkReceiveTask, - "NetRecv", - IOT_NETWORK_RECEIVE_TASK_STACK_SIZE, - pNetworkConnection, - IOT_NETWORK_RECEIVE_TASK_PRIORITY, - &( pNetworkConnection->receiveTask ) ) != pdPASS ) - { - IotLogError( "Failed to create network receive task." ); - - status = IOT_NETWORK_SYSTEM_ERROR; - } - - return status; -} -/*-----------------------------------------------------------*/ - -size_t IotNetworkFreeRTOS_Send( void * pConnection, - const uint8_t * pMessage, - size_t messageLength ) -{ - size_t bytesSent = 0; - int32_t socketStatus = 0; - - /* Cast network connection to the correct type. */ - _networkConnection_t * pNetworkConnection = ( _networkConnection_t * ) pConnection; - - /* Only one thread at a time may send on the connection. Lock the socket - * mutex to prevent other threads from sending. */ - if( xSemaphoreTake( pNetworkConnection->socketMutex, portMAX_DELAY ) == pdTRUE ) - { - socketStatus = FreeRTOS_send( pNetworkConnection->socket, - pMessage, - messageLength, - 0 ); - - if( socketStatus > 0 ) - { - bytesSent = ( size_t ) socketStatus; - } - - xSemaphoreGive( pNetworkConnection->socketMutex ); - } - - return bytesSent; -} -/*-----------------------------------------------------------*/ - -size_t IotNetworkFreeRTOS_Receive( void * pConnection, - uint8_t * pBuffer, - size_t bytesRequested ) -{ - int32_t socketStatus = 0; - size_t bytesReceived = 0, bytesRemaining = bytesRequested; - - /* Cast network connection to the correct type. */ - _networkConnection_t * pNetworkConnection = ( _networkConnection_t * ) pConnection; - - /* Write the buffered byte. THIS IS A TEMPORARY WORKAROUND AND ASSUMES THIS - * FUNCTION IS ALWAYS CALLED FROM THE RECEIVE CALLBACK. */ - if( pNetworkConnection->bufferedByteValid == true ) - { - *pBuffer = pNetworkConnection->bufferedByte; - bytesReceived = 1; - bytesRemaining--; - pNetworkConnection->bufferedByteValid = false; - } - - /* Block and wait for incoming data. */ - while( bytesRemaining > 0 ) - { - socketStatus = FreeRTOS_recv( pNetworkConnection->socket, - pBuffer + bytesReceived, - bytesRemaining, - 0 ); - - if( socketStatus == FREERTOS_EWOULDBLOCK ) - { - /* The return value EWOULDBLOCK means no data was received within - * the socket timeout. Ignore it and try again. */ - continue; - } - else if( socketStatus <= 0 ) - { - IotLogError( "Error %ld while receiving data.", ( long int ) socketStatus ); - break; - } - else - { - bytesReceived += ( size_t ) socketStatus; - bytesRemaining -= ( size_t ) socketStatus; - - configASSERT( bytesReceived + bytesRemaining == bytesRequested ); - } - } - - if( bytesReceived < bytesRequested ) - { - IotLogWarn( "Receive requested %lu bytes, but %lu bytes received instead.", - ( unsigned long ) bytesRequested, - ( unsigned long ) bytesReceived ); - } - else - { - IotLogDebug( "Successfully received %lu bytes.", - ( unsigned long ) bytesRequested ); - } - - return bytesReceived; -} -/*-----------------------------------------------------------*/ - -IotNetworkError_t IotNetworkFreeRTOS_Close( void * pConnection ) -{ - int32_t socketStatus = 0; - - /* Cast network connection to the correct type. */ - _networkConnection_t * pNetworkConnection = ( _networkConnection_t * ) pConnection; - - /* Call socket shutdown function to close connection. */ - socketStatus = FreeRTOS_shutdown( pNetworkConnection->socket, - FREERTOS_SHUT_RDWR ); - - if( socketStatus != 0 ) - { - IotLogWarn( "Failed to close connection." ); - } - - /* Set the shutdown bit in the connection event group. */ - ( void ) xEventGroupSetBits( pNetworkConnection->connectionEventGroup, - _SHUTDOWN_BITMASK ); - - return IOT_NETWORK_SUCCESS; -} -/*-----------------------------------------------------------*/ - -IotNetworkError_t IotNetworkFreeRTOS_Destroy( void * pConnection ) -{ - /* Cast network connection to the correct type. */ - _networkConnection_t * pNetworkConnection = ( _networkConnection_t * ) pConnection; - - /* Check if this function is being called from the receive task. */ - if( xTaskGetCurrentTaskHandle() == pNetworkConnection->receiveTask ) - { - /* Set the bit specifying that the connection is destroyed. */ - ( void ) xEventGroupSetBits( pNetworkConnection->connectionEventGroup, - _CONNECTION_DESTROYED_BITMASK ); - } - else - { - /* If a receive task was created, wait for it to exit. */ - if( pNetworkConnection->receiveTask != NULL ) - { - ( void ) xEventGroupWaitBits( pNetworkConnection->connectionEventGroup, - _RECEIVE_TASK_EXITED_BITMASK, - pdTRUE, - pdTRUE, - portMAX_DELAY ); - } - - _destroyConnection( pNetworkConnection ); - } - - return IOT_NETWORK_SUCCESS; -} -/*-----------------------------------------------------------*/ 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 deleted file mode 100644 index f4a5f97f3..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/iot_threads_freertos.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Amazon FreeRTOS Platform V1.0.0 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_threads_freertos.c - * @brief Implementation of the functions in iot_threads.h for POSIX systems. - */ - -/* The config header is always included first. */ -#include "iot_config.h" - -#include "semphr.h" - -/* Platform threads include. */ -#include "platform/iot_platform_types_freertos.h" -#include "platform/iot_threads.h" -#include "types/iot_platform_types.h" - -/* Configure logs for the functions in this file. */ -#ifdef IOT_LOG_LEVEL_PLATFORM - #define LIBRARY_LOG_LEVEL IOT_LOG_LEVEL_PLATFORM -#else - #ifdef IOT_LOG_LEVEL_GLOBAL - #define LIBRARY_LOG_LEVEL IOT_LOG_LEVEL_GLOBAL - #else - #define LIBRARY_LOG_LEVEL IOT_LOG_NONE - #endif -#endif - -#define LIBRARY_LOG_NAME ( "THREAD" ) -#include "iot_logging_setup.h" - -/* - * Provide default values for undefined memory allocation functions based on - * the usage of dynamic memory allocation. - */ -#ifndef IotThreads_Malloc - #include - -/** - * @brief Memory allocation. This function should have the same signature - * as [malloc](http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html). - */ - #define IotThreads_Malloc malloc -#endif -#ifndef IotThreads_Free - #include - -/** - * @brief Free memory. This function should have the same signature as - * [free](http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html). - */ - #define IotThreads_Free free -#endif - -/*-----------------------------------------------------------*/ - -static void _threadRoutineWrapper( void * pArgument ) -{ - threadInfo_t * pThreadInfo = ( threadInfo_t * ) pArgument; - - /* Run the thread routine. */ - pThreadInfo->threadRoutine( pThreadInfo->pArgument ); - IotThreads_Free( pThreadInfo ); - - vTaskDelete( NULL ); -} - -/*-----------------------------------------------------------*/ - -bool Iot_CreateDetachedThread( IotThreadRoutine_t threadRoutine, - void * pArgument, - int32_t priority, - size_t stackSize ) -{ - bool status = true; - - configASSERT( threadRoutine != NULL ); - - IotLogDebug( "Creating new thread." ); - threadInfo_t * pThreadInfo = IotThreads_Malloc( sizeof( threadInfo_t ) ); - - if( pThreadInfo == NULL ) - { - IotLogDebug( "Unable to allocate memory for threadRoutine %p.", threadRoutine ); - status = false; - } - - /* Create the FreeRTOS task that will run the thread. */ - if( status ) - { - pThreadInfo->threadRoutine = threadRoutine; - pThreadInfo->pArgument = pArgument; - - if( xTaskCreate( _threadRoutineWrapper, - "iot_thread", - ( configSTACK_DEPTH_TYPE ) stackSize, - pThreadInfo, - priority, - NULL ) != pdPASS ) - { - /* Task creation failed. */ - IotLogWarn( "Failed to create thread." ); - IotThreads_Free( pThreadInfo ); - status = false; - } - } - - return status; -} - -/*-----------------------------------------------------------*/ - -bool IotMutex_Create( IotMutex_t * pNewMutex, - bool recursive ) -{ - _IotSystemMutex_t * internalMutex = ( _IotSystemMutex_t * ) pNewMutex; - - configASSERT( internalMutex != NULL ); - - IotLogDebug( "Creating new mutex %p.", pNewMutex ); - - if( recursive ) - { - ( void ) xSemaphoreCreateRecursiveMutexStatic( &internalMutex->xMutex ); - } - else - { - ( void ) xSemaphoreCreateMutexStatic( &internalMutex->xMutex ); - } - - /* remember the type of mutex */ - if( recursive ) - { - internalMutex->recursive = pdTRUE; - } - else - { - internalMutex->recursive = pdFALSE; - } - - return true; -} - -/*-----------------------------------------------------------*/ - -void IotMutex_Destroy( IotMutex_t * pMutex ) -{ - _IotSystemMutex_t * internalMutex = ( _IotSystemMutex_t * ) pMutex; - - configASSERT( internalMutex != NULL ); - - vSemaphoreDelete( ( SemaphoreHandle_t ) &internalMutex->xMutex ); -} - -/*-----------------------------------------------------------*/ - -bool prIotMutexTimedLock( IotMutex_t * pMutex, - TickType_t timeout ) -{ - _IotSystemMutex_t * internalMutex = ( _IotSystemMutex_t * ) pMutex; - BaseType_t lockResult; - - configASSERT( internalMutex != NULL ); - - IotLogDebug( "Locking mutex %p.", internalMutex ); - - /* Call the correct FreeRTOS mutex take function based on mutex type. */ - if( internalMutex->recursive == pdTRUE ) - { - lockResult = xSemaphoreTakeRecursive( ( SemaphoreHandle_t ) &internalMutex->xMutex, timeout ); - } - else - { - lockResult = xSemaphoreTake( ( SemaphoreHandle_t ) &internalMutex->xMutex, timeout ); - } - - return( lockResult == pdTRUE ); -} - -/*-----------------------------------------------------------*/ - -void IotMutex_Lock( IotMutex_t * pMutex ) -{ - prIotMutexTimedLock( pMutex, portMAX_DELAY ); -} - -/*-----------------------------------------------------------*/ - -bool IotMutex_TryLock( IotMutex_t * pMutex ) -{ - return prIotMutexTimedLock( pMutex, 0 ); -} - -/*-----------------------------------------------------------*/ - -void IotMutex_Unlock( IotMutex_t * pMutex ) -{ - _IotSystemMutex_t * internalMutex = ( _IotSystemMutex_t * ) pMutex; - - configASSERT( internalMutex != NULL ); - - IotLogDebug( "Unlocking mutex %p.", internalMutex ); - - /* Call the correct FreeRTOS mutex unlock function based on mutex type. */ - if( internalMutex->recursive == pdTRUE ) - { - ( void ) xSemaphoreGiveRecursive( ( SemaphoreHandle_t ) &internalMutex->xMutex ); - } - else - { - ( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &internalMutex->xMutex ); - } -} - -/*-----------------------------------------------------------*/ - -bool IotSemaphore_Create( IotSemaphore_t * pNewSemaphore, - uint32_t initialValue, - uint32_t maxValue ) -{ - _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pNewSemaphore; - - configASSERT( internalSemaphore != NULL ); - - IotLogDebug( "Creating new semaphore %p.", pNewSemaphore ); - - ( void ) xSemaphoreCreateCountingStatic( maxValue, initialValue, &internalSemaphore->xSemaphore ); - - return true; -} - -/*-----------------------------------------------------------*/ - -uint32_t IotSemaphore_GetCount( IotSemaphore_t * pSemaphore ) -{ - _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore; - UBaseType_t count = 0; - - configASSERT( internalSemaphore != NULL ); - - count = uxSemaphoreGetCount( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore ); - - IotLogDebug( "Semaphore %p has count %d.", pSemaphore, count ); - - return ( uint32_t ) count; -} - -/*-----------------------------------------------------------*/ - -void IotSemaphore_Destroy( IotSemaphore_t * pSemaphore ) -{ - _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore; - - configASSERT( internalSemaphore != NULL ); - - IotLogDebug( "Destroying semaphore %p.", internalSemaphore ); - - vSemaphoreDelete( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore ); -} - -/*-----------------------------------------------------------*/ - -void IotSemaphore_Wait( IotSemaphore_t * pSemaphore ) -{ - _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore; - - configASSERT( internalSemaphore != NULL ); - - IotLogDebug( "Waiting on semaphore %p.", internalSemaphore ); - - /* Take the semaphore using the FreeRTOS API. */ - if( xSemaphoreTake( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore, - portMAX_DELAY ) != pdTRUE ) - { - IotLogWarn( "Failed to wait on semaphore %p.", - pSemaphore ); - - /* Assert here, debugging we always want to know that this happened because you think - * that you are waiting successfully on the semaphore but you are not */ - configASSERT( false ); - } -} - -/*-----------------------------------------------------------*/ - -bool IotSemaphore_TryWait( IotSemaphore_t * pSemaphore ) -{ - _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore; - - configASSERT( internalSemaphore != NULL ); - - IotLogDebug( "Attempting to wait on semaphore %p.", internalSemaphore ); - - return IotSemaphore_TimedWait( pSemaphore, 0 ); -} - -/*-----------------------------------------------------------*/ - -bool IotSemaphore_TimedWait( IotSemaphore_t * pSemaphore, - uint32_t timeoutMs ) -{ - _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore; - - configASSERT( internalSemaphore != NULL ); - - /* Take the semaphore using the FreeRTOS API. Cast the calculation to 64 bit to avoid overflows*/ - if( xSemaphoreTake( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore, - pdMS_TO_TICKS( timeoutMs ) ) != pdTRUE ) - { - /* Only warn if timeout > 0 */ - if( timeoutMs > 0 ) - { - IotLogWarn( "Timeout waiting on semaphore %p.", - internalSemaphore ); - } - - return false; - } - - return true; -} - -/*-----------------------------------------------------------*/ - -void IotSemaphore_Post( IotSemaphore_t * pSemaphore ) -{ - _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore; - - configASSERT( internalSemaphore != NULL ); - - IotLogDebug( "Posting to semaphore %p.", internalSemaphore ); - /* Give the semaphore using the FreeRTOS API. */ - BaseType_t result = xSemaphoreGive( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore ); - - if( result == pdFALSE ) - { - IotLogDebug( "Unable to give semaphore over maximum", internalSemaphore ); - } -} - -/*-----------------------------------------------------------*/ 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 deleted file mode 100644 index 93c7dcb54..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/platform/iot_clock.h +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Amazon FreeRTOS Platform V1.0.0 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_clock.h - * @brief Time-related functions used by libraries in this SDK. - */ - -#ifndef IOT_CLOCK_H_ -#define IOT_CLOCK_H_ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* Standard includes. */ -#include -#include -#include - -/* Platform layer types include. */ -#include "types/iot_platform_types.h" - -/** - * @functionspage{platform_clock,platform clock component,Clock} - * - @functionname{platform_clock_function_gettimestring} - * - @functionname{platform_clock_function_gettimems} - * - @functionname{platform_clock_function_sleepms} - * - @functionname{platform_clock_function_timercreate} - * - @functionname{platform_clock_function_timerdestroy} - * - @functionname{platform_clock_function_timerarm} - */ - -/** - * @functionpage{IotClock_GetTimestring,platform_clock,gettimestring} - * @functionpage{IotClock_GetTimeMs,platform_clock,gettimems} - * @functionpage{IotClock_SleepMs,platform_clock,sleepms} - * @functionpage{IotClock_TimerCreate,platform_clock,timercreate} - * @functionpage{IotClock_TimerDestroy,platform_clock,timerdestroy} - * @functionpage{IotClock_TimerArm,platform_clock,timerarm} - */ - -/** - * @brief Generates a human-readable timestring, such as "01 Jan 2018 12:00". - * - * This function uses the system clock to generate a human-readable timestring. - * This timestring is printed by the [logging functions](@ref logging_functions). - * - * @param[out] pBuffer A buffer to store the timestring in. - * @param[in] bufferSize The size of `pBuffer`. - * @param[out] pTimestringLength The actual length of the timestring stored in - * `pBuffer`. - * - * @return `true` if a timestring was successfully generated; `false` otherwise. - * - * @warning The implementation of this function must not call any [logging functions] - * (@ref logging_functions). - * - * Example - * @code{c} - * char timestring[ 32 ]; - * size_t timestringLength = 0; - * - * if( IotClock_GetTimestring( timestring, 32, ×tringLength ) == true ) - * { - * printf( "Timestring: %.*s", timestringLength, timestring ); - * } - * @endcode - */ -/* @[declare_platform_clock_gettimestring] */ -bool IotClock_GetTimestring( char * pBuffer, - size_t bufferSize, - size_t * pTimestringLength ); -/* @[declare_platform_clock_gettimestring] */ - -/** - * @brief Returns a nonzero, monotonically-increasing system time in milliseconds. - * - * This function reads a millisecond-resolution system clock. The clock should - * always be monotonically-increasing; therefore, real-time clocks that may be - * set by another process are not suitable for this function's implementation. - * - * @return The value of the system clock. This function is not expected to fail. - * - * Example - * @code{c} - * // Get current time. - * uint64_t currentTime = IotClock_GetTimeMs(); - * @endcode - */ -/* @[declare_platform_clock_gettimems] */ -uint64_t IotClock_GetTimeMs( void ); -/* @[declare_platform_clock_gettimems] */ - -/** - * @brief Delay for the given number of milliseconds. - * - * This function suspends its calling thread for at least `sleepTimeMs` milliseconds. - * - * @param[in] sleepTimeMs Sleep time (in milliseconds). - */ -/* @[declare_platform_clock_sleepms] */ -void IotClock_SleepMs( uint32_t sleepTimeMs ); -/* @[declare_platform_clock_sleepms] */ - -/** - * @brief Create a new timer. - * - * This function creates a new, unarmed timer. It must be called on an uninitialized - * #IotTimer_t. This function must not be called on an already-initialized #IotTimer_t. - * - * @param[out] pNewTimer Set to a new timer handle on success. - * @param[in] expirationRoutine The function to run when this timer expires. This - * function should be called in its own detached thread. - * @param[in] pArgument The argument to pass to `expirationRoutine`. - * - * @return `true` if the timer is successfully created; `false` otherwise. - * - * @see @ref platform_clock_function_timerdestroy, @ref platform_clock_function_timerarm - */ -/* @[declare_platform_clock_timercreate] */ -bool IotClock_TimerCreate( IotTimer_t * pNewTimer, - IotThreadRoutine_t expirationRoutine, - void * pArgument ); -/* @[declare_platform_clock_timercreate] */ - -/** - * @brief Free resources used by a timer. - * - * This function frees resources used by a timer. It must be called on an initialized - * #IotTimer_t. No other timer functions should be called on `pTimer` after calling - * this function (unless the timer is re-created). - * - * This function will stop the `pTimer` if it is armed. - * - * @param[in] pTimer The timer to destroy. - * - * @see @ref platform_clock_function_timercreate, @ref platform_clock_function_timerarm - */ -/* @[declare_platform_clock_timerdestroy] */ -void IotClock_TimerDestroy( IotTimer_t * pTimer ); -/* @[declare_platform_clock_timerdestroy] */ - -/** - * @brief Arm a timer to expire at the given relative timeout. - * - * This function arms a timer to run its expiration routine at the given time. - * - * If `periodMs` is nonzero, the timer should expire periodically at intervals - * such as: - * - `relativeTimeoutMs` - * - `relativeTimeoutMs + periodMs` - * - `relativeTimeoutMs + 2 * periodMs` - * - Etc. (subject to some jitter). - * - * Setting `periodMs` to `0` arms a one-shot, non-periodic timer. - * - * @param[in] pTimer The timer to arm. - * @param[in] relativeTimeoutMs When the timer should expire, relative to the time - * this function is called. - * @param[in] periodMs How often the timer should expire again after `relativeTimerMs`. - * - * @return `true` if the timer was successfully armed; `false` otherwise. - * - * @see @ref platform_clock_function_timercreate, @ref platform_clock_function_timerdestroy - * - * Example - * @code{c} - * - * void timerExpirationRoutine( void * pArgument ); - * - * void timerExample( void ) - * { - * IotTimer_t timer; - * - * if( IotClock_TimerCreate( &timer, timerExpirationRoutine, NULL ) == true ) - * { - * // Set the timer to periodically expire every 10 seconds. - * if( IotClock_TimerArm( &timer, 10000, 10000 ) == true ) - * { - * // Wait for timer to expire. - * } - * - * IotClock_TimerDestroy( &timer ); - * } - * } - * @endcode - */ -/* @[declare_platform_clock_timerarm] */ -bool IotClock_TimerArm( IotTimer_t * pTimer, - uint32_t relativeTimeoutMs, - uint32_t periodMs ); -/* @[declare_platform_clock_timerarm] */ - -#endif /* ifndef IOT_CLOCK_H_ */ 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 deleted file mode 100644 index 74eb4f626..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/platform/iot_metrics.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Amazon FreeRTOS Platform V1.0.0 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_metrics.h - * @brief Functions for retrieving [Device Defender](@ref defender) metrics. - * - * The functions in this header are only required by Device Defender. They do not - * need to be implemented if Device Defender is not used. - */ - -#ifndef IOT_METRICS_H_ -#define IOT_METRICS_H_ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* Standard includes. */ -#include - -/* Linear containers (lists and queues) include. */ -#include "iot_linear_containers.h" - -/** - * @functionspage{platform_metrics,platform metrics component,Metrics} - * - @functionname{platform_metrics_function_init} - * - @functionname{platform_metrics_function_cleanup} - * - @functionname{platform_metrics_function_gettcpconnections} - */ - -/** - * @functionpage{IotMetrics_Init,platform_metrics,init} - * @functionpage{IotMetrics_Cleanup,platform_metrics,cleanup} - * @functionpage{IotMetrics_GetTcpConnections,platform_metrics,gettcpconnections} - */ - -/** - * @brief One-time initialization function for the platform metrics component. - * - * This function initializes the platform metrics component. It must be called - * once (and only once) before calling any other metrics or [Device Defender function] - * (@ref defender_functions). Calling this function more than once without first - * calling @ref platform_metrics_function_cleanup may result in a crash. - * - * @return `true` is initialization succeeded; `false` otherwise. - * - * @warning No thread-safety guarantees are provided for this function. - */ -/* @[declare_platform_metrics_init] */ -bool IotMetrics_Init( void ); -/* @[declare_platform_metrics_init] */ - -/** - * @brief One-time deinitialization function for the platform metrics component. - * - * This function frees resources taken in @ref platform_metrics_function_init. - * No other metrics or [Device Defender functions](@ref defender_functions) may - * be called unless @ref platform_metrics_function_init is called again. - * - * @warning No thread-safety guarantees are provided for this function. - */ -/* @[declare_platform_metrics_cleanup] */ -void IotMetrics_Cleanup( void ); -/* @[declare_platform_metrics_cleanup] */ - -/** - * @brief Retrieve a list of active TCP connections from the system. - * - * The provided connections are reported by Device Defender. - * - * @param[in] pContext Context passed as the first parameter of `metricsCallback`. - * @param[in] metricsCallback Called by this function to provide the list of TCP - * connections. The list given by this function is should not be used after the - * callback returns. - */ -/* @[declare_platform_metrics_gettcpconnections] */ -void IotMetrics_GetTcpConnections( void * pContext, - void ( * metricsCallback )( void *, const IotListDouble_t * ) ); -/* @[declare_platform_metrics_gettcpconnections] */ - -#endif /* ifndef IOT_METRICS_H_ */ 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 deleted file mode 100644 index f52e4bb06..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/platform/iot_network.h +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Amazon FreeRTOS Platform V1.0.0 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_network.h - * @brief Abstraction of network functions used by libraries in this SDK. - */ - -#ifndef IOT_NETWORK_H_ -#define IOT_NETWORK_H_ - -/* Standard includes. */ -#include -#include -#include - -/** - * @ingroup platform_datatypes_enums - * @brief Return codes for [network functions](@ref platform_network_functions). - */ -typedef enum IotNetworkError -{ - IOT_NETWORK_SUCCESS = 0, /**< Function successfully completed. */ - IOT_NETWORK_FAILURE, /**< Generic failure not covered by other values. */ - IOT_NETWORK_BAD_PARAMETER, /**< At least one parameter was invalid. */ - IOT_NETWORK_NO_MEMORY, /**< Memory allocation failed. */ - IOT_NETWORK_SYSTEM_ERROR /**< An error occurred when calling a system API. */ -} IotNetworkError_t; - -/** - * @page platform_network_functions Networking - * @brief Functions of the network abstraction component. - * - * The network abstraction component does not declare functions, but uses function - * pointers instead. This allows multiple network stacks to be used at the same time. - * Libraries that require the network will request an #IotNetworkInterface_t - * parameter. The members of the #IotNetworkInterface_t will be called whenever - * the library interacts with the network. - * - * The following function pointers are associated with an #IotNetworkInterface_t. - * Together, they represent a network stack. - * - @functionname{platform_network_function_create} - * - @functionname{platform_network_function_setreceivecallback} - * - @functionname{platform_network_function_send} - * - @functionname{platform_network_function_receive} - * - @functionname{platform_network_function_close} - * - @functionname{platform_network_function_destroy} - * - @functionname{platform_network_function_receivecallback} - */ - -/** - * @functionpage{IotNetworkInterface_t::create,platform_network,create} - * @functionpage{IotNetworkInterface_t::setReceiveCallback,platform_network,setreceivecallback} - * @functionpage{IotNetworkInterface_t::send,platform_network,send} - * @functionpage{IotNetworkInterface_t::receive,platform_network,receive} - * @functionpage{IotNetworkInterface_t::close,platform_network,close} - * @functionpage{IotNetworkInterface_t::destroy,platform_network,destroy} - * @functionpage{IotNetworkReceiveCallback_t,platform_network,receivecallback} - */ - -/** - * @brief Provide an asynchronous notification of incoming network data. - * - * A function with this signature may be set with @ref platform_network_function_setreceivecallback - * to be invoked when data is available on the network. - * - * @param[in] pConnection The connection on which data is available, defined by - * the network stack. - * @param[in] pContext The third argument passed to @ref platform_network_function_setreceivecallback. - */ -/* @[declare_platform_network_receivecallback] */ -typedef void ( * IotNetworkReceiveCallback_t )( void * pConnection, - void * pContext ); -/* @[declare_platform_network_receivecallback] */ - -/** - * @ingroup platform_datatypes_paramstructs - * @brief Represents the functions of a network stack. - * - * Functions that match these signatures should be implemented against a system's - * network stack. See the `platform` directory for existing implementations. - */ -typedef struct IotNetworkInterface -{ - /** - * @brief Create a new network connection. - * - * This function allocates resources and establishes a new network connection. - * @param[in] pConnectionInfo Represents information needed to set up the - * new connection, defined by the network stack. - * @param[in] pCredentialInfo Represents information needed to secure the - * new connection, defined by the network stack. - * @param[out] pConnection Set to represent a new connection, defined by the - * network stack. - * - * @return Any #IotNetworkError_t, as defined by the network stack. - */ - /* @[declare_platform_network_create] */ - IotNetworkError_t ( * create )( void * pConnectionInfo, - void * pCredentialInfo, - void ** pConnection ); - /* @[declare_platform_network_create] */ - - /** - * @brief Register an @ref platform_network_function_receivecallback. - * - * Sets an @ref platform_network_function_receivecallback to be called - * asynchronously when data arrives on the network. The network stack - * should invoke this function "as if" it were the thread routine of a - * detached thread. - * - * Each network connection may only have one receive callback at any time. - * @ref platform_network_function_close is expected to remove any active - * receive callbacks. - * - * @param[in] pConnection The connection to associate with the receive callback. - * @param[in] receiveCallback The function to invoke for incoming network data. - * @param[in] pContext A value to pass as the first parameter to the receive callback. - * - * @return Any #IotNetworkError_t, as defined by the network stack. - * - * @see platform_network_function_receivecallback - */ - /* @[declare_platform_network_setreceivecallback] */ - IotNetworkError_t ( * setReceiveCallback )( void * pConnection, - IotNetworkReceiveCallback_t receiveCallback, - void * pContext ); - /* @[declare_platform_network_setreceivecallback] */ - - /** - * @brief Send data over a return connection. - * - * Attempts to transmit `messageLength` bytes of `pMessage` across the - * connection represented by `pConnection`. Returns the number of bytes - * actually sent, `0` on failure. - * - * @param[in] pConnection The connection used to send data, defined by the - * network stack. - * @param[in] pMessage The message to send. - * @param[in] messageLength The length of `pMessage`. - * - * @return The number of bytes successfully sent, `0` on failure. - */ - /* @[declare_platform_network_send] */ - size_t ( * send )( void * pConnection, - const uint8_t * pMessage, - size_t messageLength ); - /* @[declare_platform_network_send] */ - - /** - * @brief Block and wait for incoming network data. - * - * Wait for a message of size `bytesRequested` to arrive on the network and - * place it in `pBuffer`. - * - * @param[in] pConnection The connection to wait on, defined by the network - * stack. - * @param[out] pBuffer Where to place the incoming network data. This buffer - * must be at least `bytesRequested` in size. - * @param[in] bytesRequested How many bytes to wait for. `pBuffer` must be at - * least this size. - * - * @return The number of bytes successfully received. This should be - * `bytesRequested` when successful. Any other value may indicate an error. - */ - /* @[declare_platform_network_receive] */ - size_t ( * receive )( void * pConnection, - uint8_t * pBuffer, - size_t bytesRequested ); - /* @[declare_platform_network_receive] */ - - /** - * @brief Close a network connection. - * - * This function closes the connection, but does not release the resources - * used by the connection. This allows calls to other networking functions - * to return an error and handle a closed connection without the risk of - * crashing. Once it can be guaranteed that `pConnection` will no longer be - * used, the connection can be destroyed with @ref platform_network_function_destroy. - * - * In addition to closing the connection, this function should also remove - * any active [receive callback](@ref platform_network_function_receivecallback). - * - * @param[in] pConnection The network connection to close, defined by the - * network stack. - * - * @return Any #IotNetworkError_t, as defined by the network stack. - * - * @note It must be safe to call this function on an already-closed connection. - */ - /* @[declare_platform_network_close] */ - IotNetworkError_t ( * close )( void * pConnection ); - /* @[declare_platform_network_close] */ - - /** - * @brief Free resources used by a network connection. - * - * This function releases the resources of a closed connection. It should be - * called after @ref platform_network_function_close. - * - * @param[in] pConnection The network connection to destroy, defined by - * the network stack. - * - * @return Any #IotNetworkError_t, as defined by the network stack. - * - * @attention No function should be called on the network connection after - * calling this function. This function must be safe to call from a - * [receive callback](@ref platform_network_function_receivecallback). - */ - /* @[declare_platform_network_destroy] */ - IotNetworkError_t ( * destroy )( void * pConnection ); - /* @[declare_platform_network_destroy] */ -} IotNetworkInterface_t; - -/** - * @ingroup platform_datatypes_paramstructs - * @brief Information on the remote server for connection setup. - * - * May be passed to #IotNetworkInterface_t.create as `pConnectionInfo`. This - * structure contains commonly-used parameters, but may be replaced with an - * alternative. - */ -typedef struct IotNetworkServerInfo -{ - const char * pHostName; /**< @brief Server host name. Must be NULL-terminated. */ - uint16_t port; /**< @brief Server port in host-order. */ -} IotNetworkServerInfo_t; - -/** - * @ingroup platform_datatypes_paramstructs - * @brief Contains the credentials necessary for connection setup. - * - * May be passed to #IotNetworkInterface_t.create as `pCredentialInfo`. This - * structure contains commonly-used parameters, but may be replaced with an - * alternative. - */ -typedef struct IotNetworkCredentials -{ - /** - * @brief Set this to a non-NULL value to use ALPN. - * - * This string must be NULL-terminated. - * - * See [this link] - * (https://aws.amazon.com/blogs/iot/mqtt-with-tls-client-authentication-on-port-443-why-it-is-useful-and-how-it-works/) - * for more information. - */ - const char * pAlpnProtos; - - /** - * @brief Set this to a non-zero value to use TLS max fragment length - * negotiation (TLS MFLN). - * - * @note The network stack may have a minimum value for this parameter and - * may return an error if this parameter is too small. - */ - size_t maxFragmentLength; - - /** - * @brief Disable server name indication (SNI) for a TLS session. - */ - bool disableSni; - - const char * pRootCa; /**< @brief String representing a trusted server root certificate. */ - size_t rootCaSize; /**< @brief Size associated with #IotNetworkCredentials_t.pRootCa. */ - const char * pClientCert; /**< @brief String representing the client certificate. */ - size_t clientCertSize; /**< @brief Size associated with #IotNetworkCredentials_t.pClientCert. */ - const char * pPrivateKey; /**< @brief String representing the client certificate's private key. */ - size_t privateKeySize; /**< @brief Size associated with #IotNetworkCredentials_t.pPrivateKey. */ -} IotNetworkCredentials_t; - -#endif /* ifndef IOT_NETWORK_H_ */ 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 deleted file mode 100644 index 58571d840..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/platform/iot_threads.h +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Amazon FreeRTOS Platform V1.0.0 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_threads.h - * @brief Threading and synchronization functions used by libraries in this SDK. - */ - -#ifndef IOT_THREADS_H_ -#define IOT_THREADS_H_ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* Standard includes. */ -#include -#include - -/* Platform layer types include. */ -#include "types/iot_platform_types.h" - -/** - * @functionspage{platform_threads,platform thread management,Thread Management} - * - @functionname{platform_threads_function_createdetachedthread} - * - @functionname{platform_threads_function_mutexcreate} - * - @functionname{platform_threads_function_mutexdestroy} - * - @functionname{platform_threads_function_mutexlock} - * - @functionname{platform_threads_function_mutextrylock} - * - @functionname{platform_threads_function_mutexunlock} - * - @functionname{platform_threads_function_semaphorecreate} - * - @functionname{platform_threads_function_semaphoredestroy} - * - @functionname{platform_threads_function_semaphoregetcount} - * - @functionname{platform_threads_function_semaphorewait} - * - @functionname{platform_threads_function_semaphoretrywait} - * - @functionname{platform_threads_function_semaphoretimedwait} - * - @functionname{platform_threads_function_semaphorepost} - */ - -/** - * @functionpage{Iot_CreateDetachedThread,platform_threads,createdetachedthread} - * @functionpage{IotMutex_Create,platform_threads,mutexcreate} - * @functionpage{IotMutex_Destroy,platform_threads,mutexdestroy} - * @functionpage{IotMutex_Lock,platform_threads,mutexlock} - * @functionpage{IotMutex_TryLock,platform_threads,mutextrylock} - * @functionpage{IotMutex_Unlock,platform_threads,mutexunlock} - * @functionpage{IotSemaphore_Create,platform_threads,semaphorecreate} - * @functionpage{IotSemaphore_Destroy,platform_threads,semaphoredestroy} - * @functionpage{IotSemaphore_GetCount,platform_threads,semaphoregetcount} - * @functionpage{IotSemaphore_Wait,platform_threads,semaphorewait} - * @functionpage{IotSemaphore_TryWait,platform_threads,semaphoretrywait} - * @functionpage{IotSemaphore_TimedWait,platform_threads,semaphoretimedwait} - * @functionpage{IotSemaphore_Post,platform_threads,semaphorepost} - */ - -/** - * @brief Create a new detached thread, i.e. a thread that cleans up after itself. - * - * This function creates a new thread. Threads created by this function exit - * upon returning from the thread routine. Any resources taken must be freed - * by the exiting thread. - * - * @param[in] threadRoutine The function this thread should run. - * @param[in] pArgument The argument passed to `threadRoutine`. - * @param[in] priority Represents the priority of the new thread, as defined by - * the system. The value #IOT_THREAD_DEFAULT_PRIORITY (i.e. `0`) must be used to - * represent the system default for thread priority. - * @param[in] stackSize Represents the stack size of the new thread, as defined - * by the system. The value #IOT_THREAD_DEFAULT_STACK_SIZE (i.e. `0`) must be used - * to represent the system default for stack size. - * - * @return `true` if the new thread was successfully created; `false` otherwise. - * - * @code{c} - * // Thread routine. - * void threadRoutine( void * pArgument ); - * - * // Run threadRoutine in a detached thread, using default priority and stack size. - * if( Iot_CreateDetachedThread( threadRoutine, - * NULL, - * IOT_THREAD_DEFAULT_PRIORITY, - * IOT_THREAD_DEFAULT_STACK_SIZE ) == true ) - * { - * // Success - * } - * else - * { - * // Failure, no thread was created. - * } - * @endcode - */ -/* @[declare_platform_threads_createdetachedthread] */ -bool Iot_CreateDetachedThread( IotThreadRoutine_t threadRoutine, - void * pArgument, - int32_t priority, - size_t stackSize ); -/* @[declare_platform_threads_createdetachedthread] */ - -/** - * @brief Create a new mutex. - * - * This function creates a new, unlocked mutex. It must be called on an uninitialized - * #IotMutex_t. This function must not be called on an already-initialized #IotMutex_t. - * - * @param[in] pNewMutex Pointer to the memory that will hold the new mutex. - * @param[in] recursive Set to `true` to create a recursive mutex, i.e. a mutex that - * may be locked multiple times by the same thread. If the system does not support - * recursive mutexes, this function should do nothing and return `false`. - * - * @return `true` if mutex creation succeeds; `false` otherwise. - * - * @see @ref platform_threads_function_mutexdestroy - * - * Example - * @code{c} - * IotMutex_t mutex; - * - * // Create non-recursive mutex. - * if( IotMutex_Create( &mutex, false ) == true ) - * { - * // Lock and unlock the mutex... - * - * // Destroy the mutex when it's no longer needed. - * IotMutex_Destroy( &mutex ); - * } - * @endcode - */ -/* @[declare_platform_threads_mutexcreate] */ -bool IotMutex_Create( IotMutex_t * pNewMutex, bool recursive ); -/* @[declare_platform_threads_mutexcreate] */ - -/** - * @brief Free resources used by a mutex. - * - * This function frees resources used by a mutex. It must be called on an initialized - * #IotMutex_t. No other mutex functions should be called on `pMutex` after calling - * this function (unless the mutex is re-created). - * - * @param[in] pMutex The mutex to destroy. - * - * @warning This function must not be called on a locked mutex. - * @see @ref platform_threads_function_mutexcreate - */ -/* @[declare_platform_threads_mutexdestroy] */ -void IotMutex_Destroy( IotMutex_t * pMutex ); -/* @[declare_platform_threads_mutexdestroy] */ - -/** - * @brief Lock a mutex. This function should only return when the mutex is locked; - * it is not expected to fail. - * - * This function blocks and waits until a mutex is available. It waits forever - * (deadlocks) if `pMutex` is already locked and never unlocked. - * - * @param[in] pMutex The mutex to lock. - * - * @see @ref platform_threads_function_mutextrylock for a nonblocking lock. - */ -/* @[declare_platform_threads_mutexlock] */ -void IotMutex_Lock( IotMutex_t * pMutex ); -/* @[declare_platform_threads_mutexlock] */ - -/** - * @brief Attempt to lock a mutex. Return immediately if the mutex is not available. - * - * If `pMutex` is available, this function immediately locks it and returns. - * Otherwise, this function returns without locking `pMutex`. - * - * @param[in] pMutex The mutex to lock. - * - * @return `true` if the mutex was successfully locked; `false` if the mutex was - * not available. - * - * @see @ref platform_threads_function_mutexlock for a blocking lock. - */ -/* @[declare_platform_threads_mutextrylock] */ -bool IotMutex_TryLock( IotMutex_t * pMutex ); -/* @[declare_platform_threads_mutextrylock] */ - -/** - * @brief Unlock a mutex. This function should only return when the mutex is unlocked; - * it is not expected to fail. - * - * Unlocks a locked mutex. `pMutex` must have been locked by the thread calling - * this function. - * - * @param[in] pMutex The mutex to unlock. - * - * @note This function should not be called on a mutex that is already unlocked. - */ -/* @[declare_platform_threads_mutexunlock] */ -void IotMutex_Unlock( IotMutex_t * pMutex ); -/* @[declare_platform_threads_mutexunlock] */ - -/** - * @brief Create a new counting semaphore. - * - * This function creates a new counting semaphore with a given intial and - * maximum value. It must be called on an uninitialized #IotSemaphore_t. - * This function must not be called on an already-initialized #IotSemaphore_t. - * - * @param[in] pNewSemaphore Pointer to the memory that will hold the new semaphore. - * @param[in] initialValue The semaphore should be initialized with this value. - * @param[in] maxValue The maximum value the semaphore will reach. - * - * @return `true` if semaphore creation succeeds; `false` otherwise. - * - * @see @ref platform_threads_function_semaphoredestroy - * - * Example - * @code{c} - * IotSemaphore_t sem; - * - * // Create a locked binary semaphore. - * if( IotSemaphore_Create( &sem, 0, 1 ) == true ) - * { - * // Unlock the semaphore. - * IotSemaphore_Post( &sem ); - * - * // Destroy the semaphore when it's no longer needed. - * IotSemaphore_Destroy( &sem ); - * } - * @endcode - */ -/* @[declare_platform_threads_semaphorecreate] */ -bool IotSemaphore_Create( IotSemaphore_t * pNewSemaphore, - uint32_t initialValue, - uint32_t maxValue ); -/* @[declare_platform_threads_semaphorecreate] */ - -/** - * @brief Free resources used by a semaphore. - * - * This function frees resources used by a semaphore. It must be called on an initialized - * #IotSemaphore_t. No other semaphore functions should be called on `pSemaphore` after - * calling this function (unless the semaphore is re-created). - * - * @param[in] pSemaphore The semaphore to destroy. - * - * @warning This function must not be called on a semaphore with waiting threads. - * @see @ref platform_threads_function_semaphorecreate - */ -/* @[declare_platform_threads_semaphoredestroy] */ -void IotSemaphore_Destroy( IotSemaphore_t * pSemaphore ); -/* @[declare_platform_threads_semaphoredestroy] */ - -/** - * @brief Query the current count of the semaphore. - * - * This function queries a counting semaphore for its current value. A counting - * semaphore's value is always 0 or positive. - * - * @param[in] pSemaphore The semaphore to query. - * - * @return The current count of the semaphore. This function should not fail. - */ -/* @[declare_platform_threads_semaphoregetcount] */ -uint32_t IotSemaphore_GetCount( IotSemaphore_t * pSemaphore ); -/* @[declare_platform_threads_semaphoregetcount] */ - -/** - * @brief Wait on (lock) a semaphore. This function should only return when the - * semaphore wait succeeds; it is not expected to fail. - * - * This function blocks and waits until a counting semaphore is positive. It - * waits forever (deadlocks) if `pSemaphore` has a count `0` that is never - * [incremented](@ref platform_threads_function_semaphorepost). - * - * @param[in] pSemaphore The semaphore to lock. - * - * @see @ref platform_threads_function_semaphoretrywait for a nonblocking wait; - * @ref platform_threads_function_semaphoretimedwait for a wait with timeout. - */ -/* @[declare_platform_threads_semaphorewait] */ -void IotSemaphore_Wait( IotSemaphore_t * pSemaphore ); -/* @[declare_platform_threads_semaphorewait] */ - -/** - * @brief Attempt to wait on (lock) a semaphore. Return immediately if the semaphore - * is not available. - * - * If the count of `pSemaphore` is positive, this function immediately decrements - * the semaphore and returns. Otherwise, this function returns without decrementing - * `pSemaphore`. - * - * @param[in] pSemaphore The semaphore to lock. - * - * @return `true` if the semaphore wait succeeded; `false` if the semaphore has - * a count of `0`. - * - * @see @ref platform_threads_function_semaphorewait for a blocking wait; - * @ref platform_threads_function_semaphoretimedwait for a wait with timeout. - */ -/* @[declare_platform_threads_semaphoretrywait] */ -bool IotSemaphore_TryWait( IotSemaphore_t * pSemaphore ); -/* @[declare_platform_threads_semaphoretrywait] */ - -/** - * @brief Attempt to wait on (lock) a semaphore with a timeout. - * - * This function blocks and waits until a counting semaphore is positive - * or its timeout expires (whichever is sooner). It decrements - * `pSemaphore` and returns `true` if the semaphore is positive at some - * time during the wait. If `pSemaphore` is always `0` during the wait, - * this function returns `false`. - * - * @param[in] pSemaphore The semaphore to lock. - * @param[in] timeoutMs Relative timeout of semaphore lock. This function returns - * false if the semaphore couldn't be locked within this timeout. - * - * @return `true` if the semaphore wait succeeded; `false` if it timed out. - * - * @see @ref platform_threads_function_semaphoretrywait for a nonblocking wait; - * @ref platform_threads_function_semaphorewait for a blocking wait. - */ -/* @[declare_platform_threads_semaphoretimedwait] */ -bool IotSemaphore_TimedWait( IotSemaphore_t * pSemaphore, - uint32_t timeoutMs ); -/* @[declare_platform_threads_semaphoretimedwait] */ - -/** - * @brief Post to (unlock) a semaphore. This function should only return when the - * semaphore post succeeds; it is not expected to fail. - * - * This function increments the count of a semaphore. Any thread may call this - * function to increment a semaphore's count. - * - * @param[in] pSemaphore The semaphore to unlock. - */ -/* @[declare_platform_threads_semaphorepost] */ -void IotSemaphore_Post( IotSemaphore_t * pSemaphore ); -/* @[declare_platform_threads_semaphorepost] */ - -#endif /* ifndef IOT_THREADS_H_ */ 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 deleted file mode 100644 index e9fc7851c..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/include/types/iot_platform_types.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Amazon FreeRTOS Platform V1.0.0 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_platform_types.h - * @brief Types of the platform layer. - */ - -#ifndef IOT_PLATFORM_TYPES_H_ -#define IOT_PLATFORM_TYPES_H_ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* Linear containers (lists and queues) include for metrics types. */ -#include "iot_linear_containers.h" - -/*------------------------- Thread management types -------------------------*/ - -/** - * @brief A value representing the system default for new thread priority. - */ -#ifndef IOT_THREAD_DEFAULT_PRIORITY - #define IOT_THREAD_DEFAULT_PRIORITY 0 -#endif - -/** - * @brief A value representhing the system default for new thread stack size. - */ -#ifndef IOT_THREAD_DEFAULT_STACK_SIZE - #define IOT_THREAD_DEFAULT_STACK_SIZE 0 -#endif - -/** - * @ingroup platform_datatypes_handles - * @brief The type used to represent mutexes, configured with the type - * `_IotSystemMutex_t`. - * - * - * `_IotSystemMutex_t` will be automatically configured during build and generally - * does not need to be defined. - * - * - * Mutexes should only be released by the threads that take them. - * - * Example
- * To change the type of #IotMutex_t to `long`: - * @code{c} - * typedef long _IotSystemMutex_t; - * #include "iot_threads.h" - * @endcode - */ -typedef _IotSystemMutex_t IotMutex_t; - -/** - * @ingroup platform_datatypes_handles - * @brief The type used to represent semaphores, configured with the type - * `_IotSystemSemaphore_t`. - * - * - * `_IotSystemSemaphore_t` will be automatically configured during build and - * generally does not need to be defined. - * - * - * Semaphores must be counting, and any thread may take (wait on) or release - * (post to) a semaphore. - * - * Example
- * To change the type of #IotSemaphore_t to `long`: - * @code{c} - * typedef long _IotSystemSemaphore_t; - * #include "iot_threads.h" - * @endcode - */ -typedef _IotSystemSemaphore_t IotSemaphore_t; - -/** - * @brief Thread routine function. - * - * @param[in] void * The argument passed to the @ref - * platform_threads_function_createdetachedthread. For application use. - */ -typedef void ( * IotThreadRoutine_t )( void * ); - -/*-------------------------- Clock and timer types --------------------------*/ - -/** - * @ingroup platform_datatypes_handles - * @brief The type used to represent timers, configured with the type - * `_IotSystemTimer_t`. - * - * - * `_IotSystemTimer_t` will be automatically configured during build and generally - * does not need to be defined. - * - * - * Example
- * To change the type of #IotTimer_t to `long`: - * @code{c} - * typedef long _IotSystemTimer_t; - * #include "iot_clock.h" - * @endcode - */ -typedef _IotSystemTimer_t IotTimer_t; - -/*------------------------------ Metrics types ------------------------------*/ - -/** - * @brief The length of the buffer used to store IP addresses for metrics. - * - * This is the length of the longest IPv6 address plus space for the port number - * and NULL terminator. - */ -#define IOT_METRICS_IP_ADDRESS_LENGTH 54 - -/** - * @brief Represents a TCP connection to a remote IPv4 server. - * - * A list of these is provided by @ref platform_metrics_function_gettcpconnections. - */ -typedef struct IotMetricsTcpConnection -{ - IotLink_t link; /**< @brief List link member. */ - void * pNetworkContext; /**< @brief Context that may be used by metrics or Defender. */ - size_t addressLength; /**< @brief The length of the address stored in #IotMetricsTcpConnection_t.pRemoteAddress. */ - - /** - * @brief NULL-terminated IP address and port in text format. - * - * IPv4 addresses will be in the format `xxx.xxx.xxx.xxx:port`. - * IPv6 addresses will be in the format `[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]:port`. - */ - char pRemoteAddress[ IOT_METRICS_IP_ADDRESS_LENGTH ]; -} IotMetricsTcpConnection_t; - -#endif /* ifndef IOT_PLATFORM_TYPES_H_ */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/directories.txt b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/directories.txt deleted file mode 100644 index a5f2fbfb8..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/directories.txt +++ /dev/null @@ -1,3 +0,0 @@ -+ standard -Contains the implementation of IoT libraries that implement standard protocols -and interfaces, such a MQTT. diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/atomic.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/atomic.h deleted file mode 100644 index d44593d8f..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/atomic.h +++ /dev/null @@ -1,547 +0,0 @@ -/* - * FreeRTOS Kernel V10.2.0 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://www.FreeRTOS.org - * http://aws.amazon.com/freertos - * - * 1 tab == 4 spaces! - */ - -/** - * @file atomic.h - * @brief FreeRTOS atomic operation support. - * - * Two implementations of atomic are given in this header file: - * 1. Disabling interrupt globally. - * 2. ISA native atomic support. - * The former is available to all ports (compiler-architecture combination), - * while the latter is only available to ports compiling with GCC (version at - * least 4.7.0), which also have ISA atomic support. - * - * User can select which implementation to use by: - * setting/clearing configUSE_ATOMIC_INSTRUCTION in FreeRTOSConfig.h. - * Define AND set configUSE_ATOMIC_INSTRUCTION to 1 for ISA native atomic support. - * Undefine OR clear configUSE_ATOMIC_INSTRUCTION for disabling global interrupt - * implementation. - * - * @see GCC Built-in Functions for Memory Model Aware Atomic Operations - * https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html - */ - -#ifndef ATOMIC_H -#define ATOMIC_H - -#ifndef INC_FREERTOS_H - #error "include FreeRTOS.h must appear in source files before include atomic.h" -#endif - -/* Standard includes. */ -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 ) - - /* Needed for __atomic_compare_exchange() weak=false. */ - #include - - /* This branch is for GCC compiler and GCC compiler only. */ - #ifndef portFORCE_INLINE - #define portFORCE_INLINE inline __attribute__((always_inline)) - #endif - -#else - - /* Port specific definitions -- entering/exiting critical section. - * Refer template -- ./lib/FreeRTOS/portable/Compiler/Arch/portmacro.h - * - * Every call to ATOMIC_EXIT_CRITICAL() must be closely paired with - * ATOMIC_ENTER_CRITICAL(). - */ - #if defined( portSET_INTERRUPT_MASK_FROM_ISR ) - - /* Nested interrupt scheme is supported in this port. */ - #define ATOMIC_ENTER_CRITICAL() \ - UBaseType_t uxCriticalSectionType = portSET_INTERRUPT_MASK_FROM_ISR() - - #define ATOMIC_EXIT_CRITICAL() \ - portCLEAR_INTERRUPT_MASK_FROM_ISR( uxCriticalSectionType ) - - #else - - /* Nested interrupt scheme is NOT supported in this port. */ - #define ATOMIC_ENTER_CRITICAL() portENTER_CRITICAL() - #define ATOMIC_EXIT_CRITICAL() portEXIT_CRITICAL() - - #endif /* portSET_INTERRUPT_MASK_FROM_ISR() */ - - /* Port specific definition -- "always inline". - * Inline is compiler specific, and may not always get inlined depending on your optimization level. - * Also, inline is considerred as performance optimization for atomic. - * Thus, if portFORCE_INLINE is not provided by portmacro.h, instead of resulting error, - * simply define it. - */ - #ifndef portFORCE_INLINE - #define portFORCE_INLINE - #endif - -#endif /* configUSE_GCC_BUILTIN_ATOMICS */ - -#define ATOMIC_COMPARE_AND_SWAP_SUCCESS 0x1U /**< Compare and swap succeeded, swapped. */ -#define ATOMIC_COMPARE_AND_SWAP_FAILURE 0x0U /**< Compare and swap failed, did not swap. */ - -/*----------------------------- Swap && CAS ------------------------------*/ - -/** - * Atomic compare-and-swap - * - * @brief Performs an atomic compare-and-swap operation on the specified values. - * - * @param[in, out] pDestination Pointer to memory location from where value is - * to be loaded and checked. - * @param[in] ulExchange If condition meets, write this value to memory. - * @param[in] ulComparand Swap condition. - * - * @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped. - * - * @note This function only swaps *pDestination with ulExchange, if previous - * *pDestination value equals ulComparand. - */ -static portFORCE_INLINE uint32_t Atomic_CompareAndSwap_u32( - uint32_t volatile * pDestination, - uint32_t ulExchange, - uint32_t ulComparand ) -{ - - uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE; - -#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 ) - - if ( __atomic_compare_exchange( pDestination, - &ulComparand, - &ulExchange, - false, - __ATOMIC_SEQ_CST, - __ATOMIC_SEQ_CST ) ) - { - ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS; - } - -#else - - ATOMIC_ENTER_CRITICAL(); - - if ( *pDestination == ulComparand ) - { - *pDestination = ulExchange; - ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS; - } - - ATOMIC_EXIT_CRITICAL(); - -#endif - - return ulReturnValue; - -} - -/** - * Atomic swap (pointers) - * - * @brief Atomically sets the address pointed to by *ppDestination to the value - * of *pExchange. - * - * @param[in, out] ppDestination Pointer to memory location from where a pointer - * value is to be loaded and written back to. - * @param[in] pExchange Pointer value to be written to *ppDestination. - * - * @return The initial value of *ppDestination. - */ -static portFORCE_INLINE void * Atomic_SwapPointers_p32( - void * volatile * ppDestination, - void * pExchange ) -{ - void * pReturnValue; - -#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 ) - - __atomic_exchange( ppDestination, &pExchange, &pReturnValue, __ATOMIC_SEQ_CST ); - -#else - - ATOMIC_ENTER_CRITICAL(); - - pReturnValue = *ppDestination; - - *ppDestination = pExchange; - - ATOMIC_EXIT_CRITICAL(); - -#endif - - return pReturnValue; -} - -/** - * Atomic compare-and-swap (pointers) - * - * @brief Performs an atomic compare-and-swap operation on the specified pointer - * values. - * - * @param[in, out] ppDestination Pointer to memory location from where a pointer - * value is to be loaded and checked. - * @param[in] pExchange If condition meets, write this value to memory. - * @param[in] pComparand Swap condition. - * - * @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped. - * - * @note This function only swaps *ppDestination with pExchange, if previous - * *ppDestination value equals pComparand. - */ -static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32( - void * volatile * ppDestination, - void * pExchange, void * pComparand ) -{ - uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE; - -#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 ) - if ( __atomic_compare_exchange( ppDestination, - &pComparand, - &pExchange, - false, - __ATOMIC_SEQ_CST, - __ATOMIC_SEQ_CST ) ) - { - ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS; - } - -#else - - ATOMIC_ENTER_CRITICAL(); - - if ( *ppDestination == pComparand ) - { - *ppDestination = pExchange; - ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS; - } - - ATOMIC_EXIT_CRITICAL(); - -#endif - - return ulReturnValue; -} - - -/*----------------------------- Arithmetic ------------------------------*/ - -/** - * Atomic add - * - * @brief Atomically adds count to the value of the specified pointer points to. - * - * @param[in,out] pAddend Pointer to memory location from where value is to be - * loaded and written back to. - * @param[in] ulCount Value to be added to *pAddend. - * - * @return previous *pAddend value. - */ -static portFORCE_INLINE uint32_t Atomic_Add_u32( - uint32_t volatile * pAddend, - uint32_t ulCount ) -{ -#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 ) - - return __atomic_fetch_add(pAddend, ulCount, __ATOMIC_SEQ_CST); - -#else - - uint32_t ulCurrent; - - ATOMIC_ENTER_CRITICAL(); - - ulCurrent = *pAddend; - - *pAddend += ulCount; - - ATOMIC_EXIT_CRITICAL(); - - return ulCurrent; - -#endif -} - -/** - * Atomic subtract - * - * @brief Atomically subtracts count from the value of the specified pointer - * pointers to. - * - * @param[in,out] pAddend Pointer to memory location from where value is to be - * loaded and written back to. - * @param[in] ulCount Value to be subtract from *pAddend. - * - * @return previous *pAddend value. - */ -static portFORCE_INLINE uint32_t Atomic_Subtract_u32( - uint32_t volatile * pAddend, - uint32_t ulCount ) -{ -#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 ) - - return __atomic_fetch_sub(pAddend, ulCount, __ATOMIC_SEQ_CST); - -#else - - uint32_t ulCurrent; - - ATOMIC_ENTER_CRITICAL(); - - ulCurrent = *pAddend; - - *pAddend -= ulCount; - - ATOMIC_EXIT_CRITICAL(); - - return ulCurrent; - -#endif -} - -/** - * Atomic increment - * - * @brief Atomically increments the value of the specified pointer points to. - * - * @param[in,out] pAddend Pointer to memory location from where value is to be - * loaded and written back to. - * - * @return *pAddend value before increment. - */ -static portFORCE_INLINE uint32_t Atomic_Increment_u32( uint32_t volatile * pAddend ) -{ -#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 ) - - return __atomic_fetch_add(pAddend, 1, __ATOMIC_SEQ_CST); - -#else - - uint32_t ulCurrent; - - ATOMIC_ENTER_CRITICAL(); - - ulCurrent = *pAddend; - - *pAddend += 1; - - ATOMIC_EXIT_CRITICAL(); - - return ulCurrent; - -#endif -} - -/** - * Atomic decrement - * - * @brief Atomically decrements the value of the specified pointer points to - * - * @param[in,out] pAddend Pointer to memory location from where value is to be - * loaded and written back to. - * - * @return *pAddend value before decrement. - */ -static portFORCE_INLINE uint32_t Atomic_Decrement_u32( uint32_t volatile * pAddend ) -{ -#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 ) - - return __atomic_fetch_sub(pAddend, 1, __ATOMIC_SEQ_CST); - -#else - - uint32_t ulCurrent; - - ATOMIC_ENTER_CRITICAL(); - - ulCurrent = *pAddend; - - *pAddend -= 1; - - ATOMIC_EXIT_CRITICAL(); - - return ulCurrent; - -#endif -} - -/*----------------------------- Bitwise Logical ------------------------------*/ - -/** - * Atomic OR - * - * @brief Performs an atomic OR operation on the specified values. - * - * @param [in, out] pDestination Pointer to memory location from where value is - * to be loaded and written back to. - * @param [in] ulValue Value to be ORed with *pDestination. - * - * @return The original value of *pDestination. - */ -static portFORCE_INLINE uint32_t Atomic_OR_u32( - uint32_t volatile * pDestination, - uint32_t ulValue ) -{ -#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 ) - - return __atomic_fetch_or(pDestination, ulValue, __ATOMIC_SEQ_CST); - -#else - - uint32_t ulCurrent; - - ATOMIC_ENTER_CRITICAL(); - - ulCurrent = *pDestination; - - *pDestination |= ulValue; - - ATOMIC_EXIT_CRITICAL(); - - return ulCurrent; - -#endif -} - -/** - * Atomic AND - * - * @brief Performs an atomic AND operation on the specified values. - * - * @param [in, out] pDestination Pointer to memory location from where value is - * to be loaded and written back to. - * @param [in] ulValue Value to be ANDed with *pDestination. - * - * @return The original value of *pDestination. - */ -static portFORCE_INLINE uint32_t Atomic_AND_u32( - uint32_t volatile * pDestination, - uint32_t ulValue ) -{ -#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 ) - - return __atomic_fetch_and(pDestination, ulValue, __ATOMIC_SEQ_CST); - -#else - - uint32_t ulCurrent; - - ATOMIC_ENTER_CRITICAL(); - - ulCurrent = *pDestination; - - *pDestination &= ulValue; - - ATOMIC_EXIT_CRITICAL(); - - return ulCurrent; - -#endif -} - -/** - * Atomic NAND - * - * @brief Performs an atomic NAND operation on the specified values. - * - * @param [in, out] pDestination Pointer to memory location from where value is - * to be loaded and written back to. - * @param [in] ulValue Value to be NANDed with *pDestination. - * - * @return The original value of *pDestination. - */ -static portFORCE_INLINE uint32_t Atomic_NAND_u32( - uint32_t volatile * pDestination, - uint32_t ulValue ) -{ -#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 ) - - return __atomic_fetch_nand(pDestination, ulValue, __ATOMIC_SEQ_CST); - -#else - - uint32_t ulCurrent; - - ATOMIC_ENTER_CRITICAL(); - - ulCurrent = *pDestination; - - *pDestination = ~(ulCurrent & ulValue); - - ATOMIC_EXIT_CRITICAL(); - - return ulCurrent; - -#endif -} - -/** - * Atomic XOR - * - * @brief Performs an atomic XOR operation on the specified values. - * - * @param [in, out] pDestination Pointer to memory location from where value is - * to be loaded and written back to. - * @param [in] ulValue Value to be XORed with *pDestination. - * - * @return The original value of *pDestination. - */ -static portFORCE_INLINE uint32_t Atomic_XOR_u32( - uint32_t volatile * pDestination, - uint32_t ulValue ) -{ -#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 ) - - return __atomic_fetch_xor(pDestination, ulValue, __ATOMIC_SEQ_CST); - -#else - - uint32_t ulCurrent; - - ATOMIC_ENTER_CRITICAL(); - - ulCurrent = *pDestination; - - *pDestination ^= ulValue; - - ATOMIC_EXIT_CRITICAL(); - - return ulCurrent; - -#endif -} - -#ifdef __cplusplus -} -#endif - -#endif /* ATOMIC_H */ 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 deleted file mode 100644 index ff2a21972..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_atomic.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Amazon FreeRTOS Common V1.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_atomic.h - * @brief Chooses the appropriate atomic operations header. - * - * On FreeRTOS, this file chooses the atomic header provided with the FreeRTOS - * kernel. - */ - -#ifndef IOT_ATOMIC_H_ -#define IOT_ATOMIC_H_ - -#include "atomic.h" - -#endif /* ifndef IOT_ATOMIC_H_ */ 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 deleted file mode 100644 index 5e27cf816..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_init.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Amazon FreeRTOS Common V1.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_init.h - * @brief Provides function signatures for common initialization and cleanup of - * this SDK. - */ - -#ifndef IOT_INIT_H_ -#define IOT_INIT_H_ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* Standard includes. */ -#include - -/** - * @brief One-time initialization function for this SDK. - * - * This function initializes common libraries, such as static memory and task - * pool. It must be called once (and only once) before calling any other - * function in this SDK. Calling this function more than once without first - * calling `IotSdk_Cleanup` may result in a crash. - * - * @return `true` if initialization succeeded; `false` otherwise. Logs may be - * printed in case of failure. - * - * @warning No thread-safety guarantees are provided for this function. - */ -bool IotSdk_Init( void ); - -/** - * @brief One-time deinitialization function for all common libraries. - * - * This function frees resources taken in `IotSdk_Init`. No other function - * in this SDK may be called after calling this function unless `IotSdk_Init` - * is called again. - * - * @warning No thread-safety guarantees are provided for this function. - */ -void IotSdk_Cleanup( void ); - -#endif /* IOT_INIT_H_ */ 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 deleted file mode 100644 index dc5ac252c..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_linear_containers.h +++ /dev/null @@ -1,956 +0,0 @@ -/* - * Amazon FreeRTOS Common V1.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_linear_containers.h - * @brief Declares and implements doubly-linked lists and queues. - */ - -#ifndef IOT_LINEAR_CONTAINERS_H_ -#define IOT_LINEAR_CONTAINERS_H_ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* Standard includes. */ -#include -#include -#include - -/** - * @defgroup linear_containers_datatypes_listqueue List and queue - * @brief Structures that represent a list or queue. - */ - -/** - * @ingroup linear_containers_datatypes_listqueue - * @brief Link member placed in structs of a list or queue. - * - * All elements in a list or queue must contain one of these members. The macro - * #IotLink_Container can be used to calculate the starting address of the - * link's container. - */ -typedef struct IotLink -{ - struct IotLink * pPrevious; /**< @brief Pointer to the previous element. */ - struct IotLink * pNext; /**< @brief Pointer to the next element. */ -} IotLink_t; - -/** - * @ingroup linear_containers_datatypes_listqueue - * @brief Represents a doubly-linked list. - */ -typedef IotLink_t IotListDouble_t; - -/** - * @ingroup linear_containers_datatypes_listqueue - * @brief Represents a queue. - */ -typedef IotLink_t IotDeQueue_t; - -/** - * @constantspage{linear_containers,linear containers library} - * - * @section linear_containers_constants_initializers Linear Containers Initializers - * @brief Provides default values for initializing the linear containers data types. - * - * @snippet this define_linear_containers_initializers - * - * All user-facing data types of the linear containers library should be initialized - * using one of the following. - * - * @warning Failure to initialize a linear containers data type with the appropriate - * initializer may result in a runtime error! - * @note The initializers may change at any time in future versions, but their - * names will remain the same. - */ -/* @[define_linear_containers_initializers] */ -#define IOT_LINK_INITIALIZER { 0 } /**< @brief Initializer for an #IotLink_t. */ -#define IOT_LIST_DOUBLE_INITIALIZER IOT_LINK_INITIALIZER /**< @brief Initializer for an #IotListDouble_t. */ -#define IOT_DEQUEUE_INITIALIZER IOT_LINK_INITIALIZER /**< @brief Initializer for an #IotDeQueue_t. */ -/* @[define_linear_containers_initializers] */ - -/** - * @def IotContainers_Assert( expression ) - * @brief Assertion macro for the linear containers library. - * - * Set @ref IOT_CONTAINERS_ENABLE_ASSERTS to `1` to enable assertions in the linear - * containers library. - * - * @param[in] expression Expression to be evaluated. - */ -#if IOT_CONTAINERS_ENABLE_ASSERTS == 1 - #ifndef IotContainers_Assert - #include - #define IotContainers_Assert( expression ) assert( expression ) - #endif -#else - #define IotContainers_Assert( expression ) -#endif - -/** - * @brief Calculates the starting address of a containing struct. - * - * @param[in] type Type of the containing struct. - * @param[in] pLink Pointer to a link member. - * @param[in] linkName Name of the #IotLink_t in the containing struct. - */ -#define IotLink_Container( type, pLink, linkName ) \ - ( ( type * ) ( void * ) ( ( ( uint8_t * ) ( pLink ) ) - offsetof( type, linkName ) ) ) - -/** - * @brief Iterates through all elements of a linear container. - * - * Container elements must not be freed or removed while iterating. - * - * @param[in] pStart The first element to iterate from. - * @param[out] pLink Pointer to a container element. - */ -#define IotContainers_ForEach( pStart, pLink ) \ - for( ( pLink ) = ( pStart )->pNext; \ - ( pLink ) != ( pStart ); \ - ( pLink ) = ( pLink )->pNext ) - -/** - * @functionspage{linear_containers,linear containers library} - * - @functionname{linear_containers_function_link_islinked} - * - @functionname{linear_containers_function_list_double_create} - * - @functionname{linear_containers_function_list_double_count} - * - @functionname{linear_containers_function_list_double_isempty} - * - @functionname{linear_containers_function_list_double_peekhead} - * - @functionname{linear_containers_function_list_double_peektail} - * - @functionname{linear_containers_function_list_double_inserthead} - * - @functionname{linear_containers_function_list_double_inserttail} - * - @functionname{linear_containers_function_list_double_insertbefore} - * - @functionname{linear_containers_function_list_double_insertafter} - * - @functionname{linear_containers_function_list_double_insertsorted} - * - @functionname{linear_containers_function_list_double_remove} - * - @functionname{linear_containers_function_list_double_removehead} - * - @functionname{linear_containers_function_list_double_removetail} - * - @functionname{linear_containers_function_list_double_removeall} - * - @functionname{linear_containers_function_list_double_findfirstmatch} - * - @functionname{linear_containers_function_list_double_removefirstmatch} - * - @functionname{linear_containers_function_list_double_removeallmatches} - * - @functionname{linear_containers_function_queue_create} - * - @functionname{linear_containers_function_queue_count} - * - @functionname{linear_containers_function_queue_isempty} - * - @functionname{linear_containers_function_queue_peekhead} - * - @functionname{linear_containers_function_queue_peektail} - * - @functionname{linear_containers_function_queue_enqueuehead} - * - @functionname{linear_containers_function_queue_dequeuehead} - * - @functionname{linear_containers_function_queue_enqueuetail} - * - @functionname{linear_containers_function_queue_dequeuetail} - * - @functionname{linear_containers_function_queue_remove} - * - @functionname{linear_containers_function_queue_removeall} - * - @functionname{linear_containers_function_queue_removeallmatches} - */ - -/** - * @functionpage{IotLink_IsLinked,linear_containers,link_islinked} - * @functionpage{IotListDouble_Create,linear_containers,list_double_create} - * @functionpage{IotListDouble_Count,linear_containers,list_double_count} - * @functionpage{IotListDouble_IsEmpty,linear_containers,list_double_isempty} - * @functionpage{IotListDouble_PeekHead,linear_containers,list_double_peekhead} - * @functionpage{IotListDouble_PeekTail,linear_containers,list_double_peektail} - * @functionpage{IotListDouble_InsertHead,linear_containers,list_double_inserthead} - * @functionpage{IotListDouble_InsertTail,linear_containers,list_double_inserttail} - * @functionpage{IotListDouble_InsertBefore,linear_containers,list_double_insertbefore} - * @functionpage{IotListDouble_InsertAfter,linear_containers,list_double_insertafter} - * @functionpage{IotListDouble_InsertSorted,linear_containers,list_double_insertsorted} - * @functionpage{IotListDouble_Remove,linear_containers,list_double_remove} - * @functionpage{IotListDouble_RemoveHead,linear_containers,list_double_removehead} - * @functionpage{IotListDouble_RemoveTail,linear_containers,list_double_removetail} - * @functionpage{IotListDouble_RemoveAll,linear_containers,list_double_removeall} - * @functionpage{IotListDouble_FindFirstMatch,linear_containers,list_double_findfirstmatch} - * @functionpage{IotListDouble_RemoveFirstMatch,linear_containers,list_double_removefirstmatch} - * @functionpage{IotListDouble_RemoveAllMatches,linear_containers,list_double_removeallmatches} - * @functionpage{IotDeQueue_Create,linear_containers,queue_create} - * @functionpage{IotDeQueue_Count,linear_containers,queue_count} - * @functionpage{IotDeQueue_IsEmpty,linear_containers,queue_isempty} - * @functionpage{IotDeQueue_PeekHead,linear_containers,queue_peekhead} - * @functionpage{IotDeQueue_PeekTail,linear_containers,queue_peektail} - * @functionpage{IotDeQueue_EnqueueHead,linear_containers,queue_enqueuehead} - * @functionpage{IotDeQueue_DequeueHead,linear_containers,queue_dequeuehead} - * @functionpage{IotDeQueue_EnqueueTail,linear_containers,queue_enqueuetail} - * @functionpage{IotDeQueue_DequeueTail,linear_containers,queue_dequeuetail} - * @functionpage{IotDeQueue_Remove,linear_containers,queue_remove} - * @functionpage{IotDeQueue_RemoveAll,linear_containers,queue_removeall} - * @functionpage{IotDeQueue_RemoveAllMatches,linear_containers,queue_removeallmatches} - */ - -/** - * @brief Check if an #IotLink_t is linked in a list or queue. - * - * @param[in] pLink The link to check. - * - * @return `true` if `pCurrent` is linked in a list or queue; `false` otherwise. - */ -/* @[declare_linear_containers_link_islinked] */ -static inline bool IotLink_IsLinked( const IotLink_t * const pLink ) -/* @[declare_linear_containers_link_islinked] */ -{ - bool isLinked = false; - - if( pLink != NULL ) - { - isLinked = ( pLink->pNext != NULL ) && ( pLink->pPrevious != NULL ); - } - - return isLinked; -} - -/** - * @brief Create a new doubly-linked list. - * - * This function initializes a new doubly-linked list. It must be called on an - * uninitialized #IotListDouble_t before calling any other doubly-linked list - * function. This function must not be called on an already-initialized - * #IotListDouble_t. - * - * This function will not fail. The function @ref linear_containers_function_list_double_removeall - * may be called to destroy a list. - * - * @param[in] pList Pointer to the memory that will hold the new doubly-linked list. - */ -/* @[declare_linear_containers_list_double_create] */ -static inline void IotListDouble_Create( IotListDouble_t * const pList ) -/* @[declare_linear_containers_list_double_create] */ -{ - /* This function must not be called with a NULL parameter. */ - IotContainers_Assert( pList != NULL ); - - /* An empty list is a link pointing to itself. */ - pList->pPrevious = pList; - pList->pNext = pList; -} - -/** - * @brief Return the number of elements contained in an #IotListDouble_t. - * - * @param[in] pList The doubly-linked list with the elements to count. - * - * @return The number of elements in the doubly-linked list. - */ -/* @[declare_linear_containers_list_double_count] */ -static inline size_t IotListDouble_Count( const IotListDouble_t * const pList ) -/* @[declare_linear_containers_list_double_count] */ -{ - size_t count = 0; - - if( pList != NULL ) - { - /* Get the list head. */ - const IotLink_t * pCurrent = pList->pNext; - - /* Iterate through the list to count the elements. */ - while( pCurrent != pList ) - { - count++; - pCurrent = pCurrent->pNext; - } - } - - return count; -} - -/** - * @brief Check if a doubly-linked list is empty. - * - * @param[in] pList The doubly-linked list to check. - * - * @return `true` if the list is empty; `false` otherwise. - */ -/* @[declare_linear_containers_list_double_isempty] */ -static inline bool IotListDouble_IsEmpty( const IotListDouble_t * const pList ) -/* @[declare_linear_containers_list_double_isempty] */ -{ - /* An empty list is NULL link, or a link pointing to itself. */ - return( ( pList == NULL ) || ( pList->pNext == pList ) ); -} - -/** - * @brief Return an #IotLink_t representing the first element in a doubly-linked list - * without removing it. - * - * @param[in] pList The list to peek. - * - * @return Pointer to an #IotLink_t representing the element at the head of the - * list; `NULL` if the list is empty. The macro #IotLink_Container may be used to - * determine the address of the link's container. - */ -/* @[declare_linear_containers_list_double_peekhead] */ -static inline IotLink_t * IotListDouble_PeekHead( const IotListDouble_t * const pList ) -/* @[declare_linear_containers_list_double_peekhead] */ -{ - IotLink_t * pHead = NULL; - - if( pList != NULL ) - { - if( IotListDouble_IsEmpty( pList ) == false ) - { - pHead = pList->pNext; - } - } - - return pHead; -} - -/** - * @brief Return an #IotLink_t representing the last element in a doubly-linked - * list without removing it. - * - * @param[in] pList The list to peek. - * - * @return Pointer to an #IotLink_t representing the element at the tail of the - * list; `NULL` if the list is empty. The macro #IotLink_Container may be used to - * determine the address of the link's container. - */ -/* @[declare_linear_containers_list_double_peektail] */ -static inline IotLink_t * IotListDouble_PeekTail( const IotListDouble_t * const pList ) -/* @[declare_linear_containers_list_double_peektail] */ -{ - IotLink_t * pTail = NULL; - - if( pList != NULL ) - { - if( IotListDouble_IsEmpty( pList ) == false ) - { - pTail = pList->pPrevious; - } - } - - return pTail; -} - -/** - * @brief Insert an element at the head of a doubly-linked list. - * - * @param[in] pList The doubly-linked list that will hold the new element. - * @param[in] pLink Pointer to the new element's link member. - */ -/* @[declare_linear_containers_list_double_inserthead] */ -static inline void IotListDouble_InsertHead( IotListDouble_t * const pList, - IotLink_t * const pLink ) -/* @[declare_linear_containers_list_double_inserthead] */ -{ - /* This function must not be called with NULL parameters. */ - IotContainers_Assert( pList != NULL ); - IotContainers_Assert( pLink != NULL ); - - /* Save current list head. */ - IotLink_t * pHead = pList->pNext; - - /* Place new element before list head. */ - pLink->pNext = pHead; - pLink->pPrevious = pList; - - /* Assign new list head. */ - pHead->pPrevious = pLink; - pList->pNext = pLink; -} - -/** - * @brief Insert an element at the tail of a doubly-linked list. - * - * @param[in] pList The double-linked list that will hold the new element. - * @param[in] pLink Pointer to the new element's link member. - */ -/* @[declare_linear_containers_list_double_inserttail] */ -static inline void IotListDouble_InsertTail( IotListDouble_t * const pList, - IotLink_t * const pLink ) -/* @[declare_linear_containers_list_double_inserttail] */ -{ - /* This function must not be called with NULL parameters. */ - IotContainers_Assert( pList != NULL ); - IotContainers_Assert( pLink != NULL ); - - /* Save current list tail. */ - IotLink_t * pTail = pList->pPrevious; - - pLink->pNext = pList; - pLink->pPrevious = pTail; - - pList->pPrevious = pLink; - pTail->pNext = pLink; -} - -/** - * @brief Insert an element before another element in a doubly-linked list. - * - * @param[in] pElement The new element will be placed before this element. - * @param[in] pLink Pointer to the new element's link member. - */ -/* @[declare_linear_containers_list_double_insertbefore] */ -static inline void IotListDouble_InsertBefore( IotLink_t * const pElement, - IotLink_t * const pLink ) -/* @[declare_linear_containers_list_double_insertbefore] */ -{ - IotListDouble_InsertTail( pElement, pLink ); -} - -/** - * @brief Insert an element after another element in a doubly-linked list. - * - * @param[in] pElement The new element will be placed after this element. - * @param[in] pLink Pointer to the new element's link member. - */ -/* @[declare_linear_containers_list_double_insertafter] */ -static inline void IotListDouble_InsertAfter( IotLink_t * const pElement, - IotLink_t * const pLink ) -/* @[declare_linear_containers_list_double_insertafter] */ -{ - IotListDouble_InsertHead( pElement, pLink ); -} - -/** - * @brief Insert an element in a sorted doubly-linked list. - * - * Places an element into a list by sorting it into order. The function - * `compare` is used to determine where to place the new element. - * - * @param[in] pList The list that will hold the new element. - * @param[in] pLink Pointer to the new element's link member. - * @param[in] compare Determines the order of the list. Returns a negative - * value if its first argument is less than its second argument; returns - * zero if its first argument is equal to its second argument; returns a - * positive value if its first argument is greater than its second argument. - * The parameters to this function are #IotLink_t, so the macro #IotLink_Container - * may be used to determine the address of the link's container. - */ -/* @[declare_linear_containers_list_double_insertsorted] */ -static inline void IotListDouble_InsertSorted( IotListDouble_t * const pList, - IotLink_t * const pLink, - int32_t ( *compare )( const IotLink_t * const, const IotLink_t * const ) ) -/* @[declare_linear_containers_list_double_insertsorted] */ -{ - /* This function must not be called with NULL parameters. */ - IotContainers_Assert( pList != NULL ); - IotContainers_Assert( pLink != NULL ); - IotContainers_Assert( compare != NULL ); - - /* Insert at head for empty list. */ - if( IotListDouble_IsEmpty( pList ) == true ) - { - IotListDouble_InsertHead( pList, pLink ); - } - else - { - bool inserted = false; - IotLink_t * pCurrent = pList->pNext; - - /* Iterate through the list to find the correct position. */ - while( pCurrent != pList ) - { - /* Comparing for '<' preserves the order of insertion. */ - if( compare( pLink, pCurrent ) < 0 ) - { - IotListDouble_InsertBefore( pCurrent, pLink ); - inserted = true; - - break; - } - - pCurrent = pCurrent->pNext; - } - - /* New element is greater than all elements in list. Insert at tail. */ - if( inserted == false ) - { - IotListDouble_InsertTail( pList, pLink ); - } - } -} - -/** - * @brief Remove a single element from a doubly-linked list. - * - * @param[in] pLink The element to remove. - */ -/* @[declare_linear_containers_list_double_remove] */ -static inline void IotListDouble_Remove( IotLink_t * const pLink ) -/* @[declare_linear_containers_list_double_remove] */ -{ - /* This function must not be called with a NULL parameter. */ - IotContainers_Assert( pLink != NULL ); - - /* This function must be called on a linked element. */ - IotContainers_Assert( IotLink_IsLinked( pLink ) == true ); - - pLink->pPrevious->pNext = pLink->pNext; - pLink->pNext->pPrevious = pLink->pPrevious; - pLink->pPrevious = NULL; - pLink->pNext = NULL; -} - -/** - * @brief Remove the element at the head of a doubly-linked list. - * - * @param[in] pList The doubly-linked list that holds the element to remove. - * - * @return Pointer to an #IotLink_t representing the removed list head; `NULL` - * if the list is empty. The macro #IotLink_Container may be used to determine - * the address of the link's container. - */ -/* @[declare_linear_containers_list_double_removehead] */ -static inline IotLink_t * IotListDouble_RemoveHead( IotListDouble_t * const pList ) -/* @[declare_linear_containers_list_double_removehead] */ -{ - IotLink_t * pHead = NULL; - - if( IotListDouble_IsEmpty( pList ) == false ) - { - pHead = pList->pNext; - IotListDouble_Remove( pHead ); - } - - return pHead; -} - -/** - * @brief Remove the element at the tail of a doubly-linked list. - * - * @param[in] pList The doubly-linked list that holds the element to remove. - * - * @return Pointer to an #IotLink_t representing the removed list tail; `NULL` - * if the list is empty. The macro #IotLink_Container may be used to determine - * the address of the link's container. - */ -/* @[declare_linear_containers_list_double_removetail] */ -static inline IotLink_t * IotListDouble_RemoveTail( IotListDouble_t * const pList ) -/* @[declare_linear_containers_list_double_removetail] */ -{ - IotLink_t * pTail = NULL; - - if( IotListDouble_IsEmpty( pList ) == false ) - { - pTail = pList->pPrevious; - IotListDouble_Remove( pTail ); - } - - return pTail; -} - -/** - * @brief Remove all elements in a doubly-linked list. - * - * @param[in] pList The list to empty. - * @param[in] freeElement A function to free memory used by each removed list - * element. Optional; pass `NULL` to ignore. - * @param[in] linkOffset Offset in bytes of a link member in its container, used - * to calculate the pointer to pass to `freeElement`. This value should be calculated - * with the C `offsetof` macro. This parameter is ignored if `freeElement` is `NULL` - * or its value is `0`. - */ -/* @[declare_linear_containers_list_double_removeall] */ -static inline void IotListDouble_RemoveAll( IotListDouble_t * const pList, - void ( *freeElement )( void * ), - size_t linkOffset ) -/* @[declare_linear_containers_list_double_removeall] */ -{ - /* This function must not be called with a NULL pList parameter. */ - IotContainers_Assert( pList != NULL ); - - /* Get the list head. */ - IotLink_t * pCurrent = pList->pNext; - - /* Iterate through the list and remove all elements. */ - while( pCurrent != pList ) - { - /* Save a pointer to the next list element. */ - IotLink_t * pNext = pCurrent->pNext; - - /* Remove and free the current list element. */ - IotListDouble_Remove( pCurrent ); - - if( freeElement != NULL ) - { - freeElement( ( ( uint8_t * ) pCurrent ) - linkOffset ); - } - - /* Move the iterating pointer to the next list element. */ - pCurrent = pNext; - } -} - -/** - * @brief Search a doubly-linked list for the first matching element. - * - * If a match is found, the matching element is not removed from the list. - * See @ref linear_containers_function_list_double_removefirstmatch for the function - * that searches and removes. - * - * @param[in] pList The doubly-linked list to search. - * @param[in] pStartPoint An element in `pList`. Only elements between this one and - * the list tail are checked. Pass `NULL` to search from the beginning of the list. - * @param[in] isMatch Function to determine if an element matches. Pass `NULL` to - * search using the address `pMatch`, i.e. `element == pMatch`. - * @param[in] pMatch If `isMatch` is `NULL`, each element in the list is compared - * to this address to find a match. Otherwise, it is passed as the second argument - * to `isMatch`. - * - * @return Pointer to an #IotLink_t representing the first matched element; `NULL` - * if no match is found. The macro #IotLink_Container may be used to determine the - * address of the link's container. - */ -/* @[declare_linear_containers_list_double_findfirstmatch] */ -static inline IotLink_t * IotListDouble_FindFirstMatch( const IotListDouble_t * const pList, - const IotLink_t * const pStartPoint, - bool ( *isMatch )( const IotLink_t * const, void * ), - void * pMatch ) -/* @[declare_linear_containers_list_double_findfirstmatch] */ -{ - /* The const must be cast away to match this function's return value. Nevertheless, - * this function will respect the const-ness of pStartPoint. */ - IotLink_t * pCurrent = ( IotLink_t * ) pStartPoint; - - /* This function must not be called with a NULL pList parameter. */ - IotContainers_Assert( pList != NULL ); - - /* Search starting from list head if no start point is given. */ - if( pStartPoint == NULL ) - { - pCurrent = pList->pNext; - } - - /* Iterate through the list to search for matches. */ - while( pCurrent != pList ) - { - /* Call isMatch if provided. Otherwise, compare pointers. */ - if( isMatch != NULL ) - { - if( isMatch( pCurrent, pMatch ) == true ) - { - return pCurrent; - } - } - else - { - if( pCurrent == pMatch ) - { - return pCurrent; - } - } - - pCurrent = pCurrent->pNext; - } - - /* No match found, return NULL. */ - return NULL; -} - -/** - * @brief Search a doubly-linked list for the first matching element and remove - * it. - * - * An #IotLink_t may be passed as `pList` to start searching after the head of a - * doubly-linked list. - * - * @param[in] pList The doubly-linked list to search. - * @param[in] pStartPoint An element in `pList`. Only elements between this one and - * the list tail are checked. Pass `NULL` to search from the beginning of the list. - * @param[in] isMatch Function to determine if an element matches. Pass `NULL` to - * search using the address `pMatch`, i.e. `element == pMatch`. - * @param[in] pMatch If `isMatch` is `NULL`, each element in the list is compared - * to this address to find a match. Otherwise, it is passed as the second argument - * to `isMatch`. - * - * @return Pointer to an #IotLink_t representing the matched and removed element; - * `NULL` if no match is found. The macro #IotLink_Container may be used to determine - * the address of the link's container. - */ -/* @[declare_linear_containers_list_double_removefirstmatch] */ -static inline IotLink_t * IotListDouble_RemoveFirstMatch( IotListDouble_t * const pList, - const IotLink_t * const pStartPoint, - bool ( *isMatch )( const IotLink_t *, void * ), - void * pMatch ) -/* @[declare_linear_containers_list_double_removefirstmatch] */ -{ - IotLink_t * pMatchedElement = IotListDouble_FindFirstMatch( pList, - pStartPoint, - isMatch, - pMatch ); - - if( pMatchedElement != NULL ) - { - IotListDouble_Remove( pMatchedElement ); - } - - return pMatchedElement; -} - -/** - * @brief Remove all matching elements from a doubly-linked list. - * - * @param[in] pList The doubly-linked list to search. - * @param[in] isMatch Function to determine if an element matches. Pass `NULL` to - * search using the address `pMatch`, i.e. `element == pMatch`. - * @param[in] pMatch If `isMatch` is `NULL`, each element in the list is compared - * to this address to find a match. Otherwise, it is passed as the second argument - * to `isMatch`. - * @param[in] freeElement A function to free memory used by each removed list - * element. Optional; pass `NULL` to ignore. - * @param[in] linkOffset Offset in bytes of a link member in its container, used - * to calculate the pointer to pass to `freeElement`. This value should be calculated - * with the C `offsetof` macro. This parameter is ignored if `freeElement` is `NULL` - * or its value is `0`. - */ -/* @[declare_linear_containers_list_double_removeallmatches] */ -static inline void IotListDouble_RemoveAllMatches( IotListDouble_t * const pList, - bool ( *isMatch )( const IotLink_t *, void * ), - void * pMatch, - void ( *freeElement )( void * ), - size_t linkOffset ) -/* @[declare_linear_containers_list_double_removeallmatches] */ -{ - IotLink_t * pMatchedElement = NULL, * pNextElement = NULL; - - /* Search the list for all matching elements. */ - do - { - pMatchedElement = IotListDouble_FindFirstMatch( pList, - pMatchedElement, - isMatch, - pMatch ); - - if( pMatchedElement != NULL ) - { - /* Save pointer to next element. */ - pNextElement = pMatchedElement->pNext; - - /* Match found; remove and free. */ - IotListDouble_Remove( pMatchedElement ); - - if( freeElement != NULL ) - { - freeElement( ( ( uint8_t * ) pMatchedElement ) - linkOffset ); - } - - /* Continue search from next element. */ - pMatchedElement = pNextElement; - } - } while( pMatchedElement != NULL ); -} - -/** - * @brief Create a new queue. - * - * This function initializes a new double-ended queue. It must be called on an uninitialized - * #IotDeQueue_t before calling any other queue function. This function must not be - * called on an already-initialized #IotDeQueue_t. - * - * This function will not fail. - * - * @param[in] pQueue Pointer to the memory that will hold the new queue. - */ -/* @[declare_linear_containers_queue_create] */ -static inline void IotDeQueue_Create( IotDeQueue_t * const pQueue ) -/* @[declare_linear_containers_queue_create] */ -{ - IotListDouble_Create( pQueue ); -} - -/** - * @brief Return the number of elements contained in an #IotDeQueue_t. - * - * @param[in] pQueue The queue with the elements to count. - * - * @return The number of items elements in the queue. - */ -/* @[declare_linear_containers_queue_count] */ -static inline size_t IotDeQueue_Count( const IotDeQueue_t * const pQueue ) -/* @[declare_linear_containers_queue_count] */ -{ - return IotListDouble_Count( pQueue ); -} - -/** - * @brief Check if a queue is empty. - * - * @param[in] pQueue The queue to check. - * - * @return `true` if the queue is empty; `false` otherwise. - * - */ -/* @[declare_linear_containers_queue_isempty] */ -static inline bool IotDeQueue_IsEmpty( const IotDeQueue_t * const pQueue ) -/* @[declare_linear_containers_queue_isempty] */ -{ - return IotListDouble_IsEmpty( pQueue ); -} - -/** - * @brief Return an #IotLink_t representing the element at the front of the queue - * without removing it. - * - * @param[in] pQueue The queue to peek. - * - * @return Pointer to an #IotLink_t representing the element at the head of the - * queue; `NULL` if the queue is empty. The macro #IotLink_Container may be used - * to determine the address of the link's container. - */ -/* @[declare_linear_containers_queue_peekhead] */ -static inline IotLink_t * IotDeQueue_PeekHead( const IotDeQueue_t * const pQueue ) -/* @[declare_linear_containers_queue_peekhead] */ -{ - return IotListDouble_PeekHead( pQueue ); -} - -/** - * @brief Return an #IotLink_t representing the element at the back of the queue - * without removing it. - * - * @param[in] pQueue The queue to peek. - * - * @return Pointer to an #IotLink_t representing the element at the head of the - * queue; `NULL` if the queue is empty. The macro #IotLink_Container may be used - * to determine the address of the link's container. - */ -/* @[declare_linear_containers_queue_peektail] */ -static inline IotLink_t * IotDeQueue_PeekTail( const IotDeQueue_t * const pQueue ) -/* @[declare_linear_containers_queue_peektail] */ -{ - return IotListDouble_PeekTail( pQueue ); -} - -/** - * @brief Add an element at the head of the queue. - * - * @param[in] pQueue The queue that will hold the new element. - * @param[in] pLink Pointer to the new element's link member. - */ -/* @[declare_linear_containers_queue_enqueuehead] */ -static inline void IotDeQueue_EnqueueHead( IotDeQueue_t * const pQueue, - IotLink_t * const pLink ) -/* @[declare_linear_containers_queue_enqueuehead] */ -{ - IotListDouble_InsertHead( pQueue, pLink ); -} - -/** - * @brief Remove an element at the head of the queue. - * - * @param[in] pQueue The queue that holds the element to remove. - * - * @return Pointer to an #IotLink_t representing the removed queue element; `NULL` - * if the queue is empty. The macro #IotLink_Container may be used to determine - * the address of the link's container. - */ -/* @[declare_linear_containers_queue_dequeuehead] */ -static inline IotLink_t * IotDeQueue_DequeueHead( IotDeQueue_t * const pQueue ) -/* @[declare_linear_containers_queue_dequeuehead] */ -{ - return IotListDouble_RemoveHead( pQueue ); -} - -/** - * @brief Add an element at the tail of the queue. - * - * @param[in] pQueue The queue that will hold the new element. - * @param[in] pLink Pointer to the new element's link member. - */ -/* @[declare_linear_containers_queue_enqueuetail] */ -static inline void IotDeQueue_EnqueueTail( IotDeQueue_t * const pQueue, - IotLink_t * const pLink ) -/* @[declare_linear_containers_queue_enqueuetail] */ -{ - IotListDouble_InsertTail( pQueue, pLink ); -} - -/** - * @brief Remove an element at the tail of the queue. - * - * @param[in] pQueue The queue that holds the element to remove. - * - * @return Pointer to an #IotLink_t representing the removed queue element; `NULL` - * if the queue is empty. The macro #IotLink_Container may be used to determine - * the address of the link's container. - */ -/* @[declare_linear_containers_queue_dequeuetail] */ -static inline IotLink_t * IotDeQueue_DequeueTail( IotDeQueue_t * const pQueue ) -/* @[declare_linear_containers_queue_dequeuetail] */ -{ - return IotListDouble_RemoveTail( pQueue ); -} - -/** - * @brief Remove a single element from a queue. - * - * @param[in] pLink The element to remove. - */ -/* @[declare_linear_containers_queue_remove] */ -static inline void IotDeQueue_Remove( IotLink_t * const pLink ) -/* @[declare_linear_containers_queue_remove] */ -{ - IotListDouble_Remove( pLink ); -} - -/** - * @brief Remove all elements in a queue. - * - * @param[in] pQueue The queue to empty. - * @param[in] freeElement A function to free memory used by each removed queue - * element. Optional; pass `NULL` to ignore. - * @param[in] linkOffset Offset in bytes of a link member in its container, used - * to calculate the pointer to pass to `freeElement`. This value should be calculated - * with the C `offsetof` macro. This parameter is ignored if `freeElement` is `NULL` - * or its value is `0`. - */ -/* @[declare_linear_containers_queue_removeall] */ -static inline void IotDeQueue_RemoveAll( IotDeQueue_t * const pQueue, - void ( * freeElement )( void * ), - size_t linkOffset ) -/* @[declare_linear_containers_queue_removeall] */ -{ - IotListDouble_RemoveAll( pQueue, freeElement, linkOffset ); -} - -/** - * @brief Remove all matching elements from a queue. - * - * @param[in] pQueue The queue to search. - * @param[in] isMatch Function to determine if an element matches. Pass `NULL` to - * search using the address `pMatch`, i.e. `element == pMatch`. - * @param[in] pMatch If `isMatch` is `NULL`, each element in the queue is compared - * to this address to find a match. Otherwise, it is passed as the second argument - * to `isMatch`. - * @param[in] freeElement A function to free memory used by each removed queue - * element. Optional; pass `NULL` to ignore. - * @param[in] linkOffset Offset in bytes of a link member in its container, used - * to calculate the pointer to pass to `freeElement`. This value should be calculated - * with the C `offsetof` macro. This parameter is ignored if `freeElement` is `NULL` - * or its value is `0`. - */ -/* @[declare_linear_containers_queue_removeallmatches] */ -static inline void IotDeQueue_RemoveAllMatches( IotDeQueue_t * const pQueue, - bool ( * isMatch )( const IotLink_t *, void * ), - void * pMatch, - void ( * freeElement )( void * ), - size_t linkOffset ) -/* @[declare_linear_containers_queue_removeallmatches] */ -{ - IotListDouble_RemoveAllMatches( pQueue, isMatch, pMatch, freeElement, linkOffset ); -} - -#endif /* IOT_LINEAR_CONTAINERS_H_ */ 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 deleted file mode 100644 index ec3d6d164..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_logging_setup.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Amazon FreeRTOS Common V1.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_logging_setup.h - * @brief Defines the logging macro #IotLog. - */ - -#ifndef IOT_LOGGING_SETUP_H_ -#define IOT_LOGGING_SETUP_H_ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* Logging include. Because it's included here, iot_logging.h never needs - * to be included in source. */ -#include "private/iot_logging.h" - -/** - * @functionpage{IotLog,logging,log} - * @functionpage{IotLog_PrintBuffer,logging,printbuffer} - */ - -/** - * @def IotLog( messageLevel, pLogConfig, ... ) - * @brief Logging function for a specific library. In most cases, this is the - * logging function to call. - * - * This function prints a single log message. It is available when @ref - * LIBRARY_LOG_LEVEL is not #IOT_LOG_NONE. Log messages automatically - * include the [log level](@ref logging_constants_levels), [library name] - * (@ref LIBRARY_LOG_NAME), and time. An optional @ref IotLogConfig_t may - * be passed to this function to hide information for a single log message. - * - * The logging library must be set up before this function may be called. See - * @ref logging_setup_use for more information. - * - * This logging function also has the following abbreviated forms that can be used - * when an #IotLogConfig_t isn't needed. - * - * Name | Equivalent to - * ---- | ------------- - * #IotLogError | @code{c} IotLog( IOT_LOG_ERROR, NULL, ... ) @endcode - * #IotLogWarn | @code{c} IotLog( IOT_LOG_WARN, NULL, ... ) @endcode - * #IotLogInfo | @code{c} IotLog( IOT_LOG_INFO, NULL, ... ) @endcode - * #IotLogDebug | @code{c} IotLog( IOT_LOG_DEBUG, NULL, ... ) @endcode - * - * @param[in] messageLevel Log level of this message. Must be one of the - * @ref logging_constants_levels. - * @param[in] pLogConfig Pointer to an #IotLogConfig_t. Optional; pass `NULL` - * to ignore. - * @param[in] ... Message and format specification. - * - * @return No return value. On errors, it prints nothing. - * - * @note This function may be implemented as a macro. - * @see @ref logging_function_generic for the generic (not library-specific) - * logging function. - */ - -/** - * @def IotLog_PrintBuffer( pHeader, pBuffer, bufferSize ) - * @brief Log the contents of buffer as bytes. Only available when @ref - * LIBRARY_LOG_LEVEL is #IOT_LOG_DEBUG. - * - * This function prints the bytes located at a given memory address. It is - * intended for debugging only, and is therefore only available when @ref - * LIBRARY_LOG_LEVEL is #IOT_LOG_DEBUG. - * - * Log messages printed by this function always include the [log level] - * (@ref logging_constants_levels), [library name](@ref LIBRARY_LOG_NAME), - * and time. In addition, this function may print an optional header `pHeader` - * before it prints the contents of the buffer. This function does not have an - * #IotLogConfig_t parameter. - * - * The logging library must be set up before this function may be called. See - * @ref logging_setup_use for more information. - * - * @param[in] pHeader A message to log before the buffer. Optional; pass `NULL` - * to ignore. - * @param[in] pBuffer Pointer to start of buffer. - * @param[in] bufferSize Size of `pBuffer`. - * - * @return No return value. On errors, it prints nothing. - * - * @note This function may be implemented as a macro. - * @note To conserve memory, @ref logging_function_genericprintbuffer (the underlying - * implementation) only allocates enough memory for a single line of output. Therefore, - * in multithreaded systems, its output may appear "fragmented" if other threads are - * logging simultaneously. - * @see @ref logging_function_genericprintbuffer for the generic (not library-specific) - * buffer logging function. - * - * Example - * @code{c} - * const uint8_t pBuffer[] = { 0x00, 0x01, 0x02, 0x03 }; - * - * IotLog_PrintBuffer( "This buffer contains:", - * pBuffer, - * 4 ); - * @endcode - * The code above prints something like the following: - * @code{c} - * [DEBUG][LIB_NAME][2018-01-01 12:00:00] This buffer contains: - * 00 01 02 03 - * @endcode - */ - -/** - * @def IotLogError( ... ) - * @brief Abbreviated logging macro for level #IOT_LOG_ERROR. - * - * Equivalent to: - * @code{c} - * IotLog( IOT_LOG_ERROR, NULL, ... ) - * @endcode - */ - -/** - * @def IotLogWarn( ... ) - * @brief Abbreviated logging macro for level #IOT_LOG_WARN. - * - * Equivalent to: - * @code{c} - * IotLog( IOT_LOG_WARN, NULL, ... ) - * @endcode - */ - -/** - * @def IotLogInfo( ... ) - * @brief Abbreviated logging macro for level #IOT_LOG_INFO. - * - * Equivalent to: - * @code{c} - * IotLog( IOT_LOG_INFO, NULL, ... ) - * @endcode - */ - -/** - * @def IotLogDebug( ... ) - * @brief Abbreviated logging macro for level #IOT_LOG_DEBUG. - * - * Equivalent to: - * @code{c} - * IotLog( IOT_LOG_DEBUG, NULL, ... ) - * @endcode - */ - -/* Check that LIBRARY_LOG_LEVEL is defined and has a valid value. */ -#if !defined( LIBRARY_LOG_LEVEL ) || \ - ( LIBRARY_LOG_LEVEL != IOT_LOG_NONE && \ - LIBRARY_LOG_LEVEL != IOT_LOG_ERROR && \ - LIBRARY_LOG_LEVEL != IOT_LOG_WARN && \ - LIBRARY_LOG_LEVEL != IOT_LOG_INFO && \ - LIBRARY_LOG_LEVEL != IOT_LOG_DEBUG ) - #error "Please define LIBRARY_LOG_LEVEL as either IOT_LOG_NONE, IOT_LOG_ERROR, IOT_LOG_WARN, IOT_LOG_INFO, or IOT_LOG_DEBUG." -/* Check that LIBRARY_LOG_NAME is defined and has a valid value. */ -#elif !defined( LIBRARY_LOG_NAME ) - #error "Please define LIBRARY_LOG_NAME." -#else - /* Define IotLog if the log level is greater than "none". */ - #if LIBRARY_LOG_LEVEL > IOT_LOG_NONE - #define IotLog( messageLevel, pLogConfig, ... ) \ - IotLog_Generic( LIBRARY_LOG_LEVEL, \ - LIBRARY_LOG_NAME, \ - messageLevel, \ - pLogConfig, \ - __VA_ARGS__ ) - - /* Define the abbreviated logging macros. */ - #define IotLogError( ... ) IotLog( IOT_LOG_ERROR, NULL, __VA_ARGS__ ) - #define IotLogWarn( ... ) IotLog( IOT_LOG_WARN, NULL, __VA_ARGS__ ) - #define IotLogInfo( ... ) IotLog( IOT_LOG_INFO, NULL, __VA_ARGS__ ) - #define IotLogDebug( ... ) IotLog( IOT_LOG_DEBUG, NULL, __VA_ARGS__ ) - - /* If log level is DEBUG, enable the function to print buffers. */ - #if LIBRARY_LOG_LEVEL >= IOT_LOG_DEBUG - #define IotLog_PrintBuffer( pHeader, pBuffer, bufferSize ) \ - IotLog_GenericPrintBuffer( LIBRARY_LOG_NAME, \ - pHeader, \ - pBuffer, \ - bufferSize ) - #else - #define IotLog_PrintBuffer( pHeader, pBuffer, bufferSize ) - #endif - /* Remove references to IotLog from the source code if logging is disabled. */ - #else - /* @[declare_logging_log] */ - #define IotLog( messageLevel, pLogConfig, ... ) - /* @[declare_logging_log] */ - /* @[declare_logging_printbuffer] */ - #define IotLog_PrintBuffer( pHeader, pBuffer, bufferSize ) - /* @[declare_logging_printbuffer] */ - #define IotLogError( ... ) - #define IotLogWarn( ... ) - #define IotLogInfo( ... ) - #define IotLogDebug( ... ) - #endif -#endif - -#endif /* ifndef IOT_LOGGING_SETUP_H_ */ 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 deleted file mode 100644 index a91ccf152..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/iot_taskpool.h +++ /dev/null @@ -1,558 +0,0 @@ -/* - * Amazon FreeRTOS Common V1.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_taskpool.h - * @brief User-facing functions of the task pool library. - */ - -#ifndef IOT_TASKPOOL_H_ -#define IOT_TASKPOOL_H_ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* Standard includes. */ -#include -#include -#include - -/* Task pool types. */ -#include "types/iot_taskpool_types.h" - -/*------------------------- Task Pool library functions --------------------------*/ - -/** - * @functionspage{taskpool,task pool library} - * - @functionname{taskpool_function_createsystemtaskpool} - * - @functionname{taskpool_function_getsystemtaskpool} - * - @functionname{taskpool_function_create} - * - @functionname{taskpool_function_destroy} - * - @functionname{taskpool_function_setmaxthreads} - * - @functionname{taskpool_function_createjob} - * - @functionname{taskpool_function_createrecyclablejob} - * - @functionname{taskpool_function_destroyrecyclablejob} - * - @functionname{taskpool_function_recyclejob} - * - @functionname{taskpool_function_schedule} - * - @functionname{taskpool_function_scheduledeferred} - * - @functionname{taskpool_function_getstatus} - * - @functionname{taskpool_function_trycancel} - * - @functionname{taskpool_function_getjobstoragefromhandle} - * - @functionname{taskpool_function_strerror} - */ - -/** - * @functionpage{IotTaskPool_CreateSystemTaskPool,taskpool,createsystemtaskpool} - * @functionpage{IotTaskPool_GetSystemTaskPool,taskpool,getsystemtaskpool} - * @functionpage{IotTaskPool_Create,taskpool,create} - * @functionpage{IotTaskPool_Destroy,taskpool,destroy} - * @functionpage{IotTaskPool_SetMaxThreads,taskpool,setmaxthreads} - * @functionpage{IotTaskPool_CreateJob,taskpool,createjob} - * @functionpage{IotTaskPool_CreateRecyclableJob,taskpool,createrecyclablejob} - * @functionpage{IotTaskPool_DestroyRecyclableJob,taskpool,destroyrecyclablejob} - * @functionpage{IotTaskPool_RecycleJob,taskpool,recyclejob} - * @functionpage{IotTaskPool_Schedule,taskpool,schedule} - * @functionpage{IotTaskPool_ScheduleDeferred,taskpool,scheduledeferred} - * @functionpage{IotTaskPool_GetStatus,taskpool,getstatus} - * @functionpage{IotTaskPool_TryCancel,taskpool,trycancel} - * @functionpage{IotTaskPool_GetJobStorageFromHandle,taskpool,getjobstoragefromhandle} - * @functionpage{IotTaskPool_strerror,taskpool,strerror} - */ - -/** - * @brief Creates the one single instance of the system task pool. - * - * This function should be called once by the application to initialize the one single instance of the system task pool. - * An application should initialize the system task pool early in the boot sequence, before initializing any other library - * and before posting any jobs. Early initialization it typically easy to accomplish by creating the system task pool - * before starting the scheduler. - * - * This function does not allocate memory to hold the task pool data structures and state, but it - * may allocate memory to hold the dependent entities and data structures, e.g. the threads of the task - * pool. The system task pool handle is recoverable for later use by calling @ref IotTaskPool_GetSystemTaskPool or - * the shortcut @ref IOT_SYSTEM_TASKPOOL. - * - * @param[in] pInfo A pointer to the task pool initialization data. - * - * @return One of the following: - * - #IOT_TASKPOOL_SUCCESS - * - #IOT_TASKPOOL_BAD_PARAMETER - * - #IOT_TASKPOOL_NO_MEMORY - * - * @warning This function should be called only once. Calling this function more that once will result in - * undefined behavior. - * - */ -/* @[declare_taskpool_createsystemtaskpool] */ -IotTaskPoolError_t IotTaskPool_CreateSystemTaskPool( const IotTaskPoolInfo_t * const pInfo ); -/* @[declare_taskpool_createsystemtaskpool] */ - -/** - * @brief Retrieves the one and only instance of a system task pool - * - * This function retrieves the system task pool created with @ref IotTaskPool_CreateSystemTaskPool, and it is functionally - * equivalent to using the shortcut @ref IOT_SYSTEM_TASKPOOL. - * - * @return The system task pool handle. - * - * @warning This function should be called after creating the system task pool with @ref IotTaskPool_CreateSystemTaskPool. - * Calling this function before creating the system task pool may return a pointer to an uninitialized task pool, NULL, or otherwise - * fail with undefined behaviour. - * - */ -/* @[declare_taskpool_getsystemtaskpool] */ -IotTaskPool_t IotTaskPool_GetSystemTaskPool( void ); -/* @[declare_taskpool_getsystemtaskpool] */ - -/** - * @brief Creates one instance of a task pool. - * - * This function should be called by the user to initialize one instance of a task - * pool. The task pool instance will be created around the storage pointed to by the `pTaskPool` - * parameter. This function will create the minimum number of threads requested by the user - * through an instance of the #IotTaskPoolInfo_t type specified with the `pInfo` parameter. - * This function does not allocate memory to hold the task pool data structures and state, but it - * may allocates memory to hold the dependent data structures, e.g. the threads of the task - * pool. - * - * @param[in] pInfo A pointer to the task pool initialization data. - * @param[out] pTaskPool A pointer to the task pool handle to be used after initialization. - * The pointer `pTaskPool` will hold a valid handle only if (@ref IotTaskPool_Create) - * completes successfully. - * - * @return One of the following: - * - #IOT_TASKPOOL_SUCCESS - * - #IOT_TASKPOOL_BAD_PARAMETER - * - #IOT_TASKPOOL_NO_MEMORY - * - */ -/* @[declare_taskpool_create] */ -IotTaskPoolError_t IotTaskPool_Create( const IotTaskPoolInfo_t * const pInfo, - IotTaskPool_t * const pTaskPool ); -/* @[declare_taskpool_create] */ - -/** - * @brief Destroys a task pool instance and collects all memory associated with a task pool and its - * satellite data structures. - * - * This function should be called to destroy one instance of a task pool previously created with a call - * to @ref IotTaskPool_Create or @ref IotTaskPool_CreateSystemTaskPool. - * Calling this fuction release all underlying resources. After calling this function, any job scheduled but not yet executed - * will be canceled and destroyed. - * The `taskPool` instance will no longer be valid after this function returns. - * - * @param[in] taskPool A handle to the task pool, e.g. as returned by a call to @ref IotTaskPool_Create or - * @ref IotTaskPool_CreateSystemTaskPool. The `taskPool` instance will no longer be valid after this function returns. - * - * @return One of the following: - * - #IOT_TASKPOOL_SUCCESS - * - #IOT_TASKPOOL_BAD_PARAMETER - * - */ -/* @[declare_taskpool_destroy] */ -IotTaskPoolError_t IotTaskPool_Destroy( IotTaskPool_t taskPool ); -/* @[declare_taskpool_destroy] */ - -/** - * @brief Sets the maximum number of threads for one instance of a task pool. - * - * This function sets the maximum number of threads for the task pool - * pointed to by `taskPool`. - * - * If the number of currently active threads in the task pool is greater than `maxThreads`, this - * function causes the task pool to shrink the number of active threads. - * - * @param[in] taskPool A handle to the task pool that must have been previously initialized with - * a call to @ref IotTaskPool_Create or @ref IotTaskPool_CreateSystemTaskPool. - * @param[in] maxThreads The maximum number of threads for the task pool. - * - * @return One of the following: - * - #IOT_TASKPOOL_SUCCESS - * - #IOT_TASKPOOL_BAD_PARAMETER - * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS - * - */ -/* @[declare_taskpool_setmaxthreads] */ -IotTaskPoolError_t IotTaskPool_SetMaxThreads( IotTaskPool_t taskPool, - uint32_t maxThreads ); -/* @[declare_taskpool_setmaxthreads] */ - -/** - * @brief Creates a job for the task pool around a user-provided storage. - * - * This function may allocate memory to hold the state for a job. - * - * @param[in] userCallback A user-specified callback for the job. - * @param[in] pUserContext A user-specified context for the callback. - * @param[in] pJobStorage The storage for the job data structure. - * @param[out] pJob A pointer to an instance of @ref IotTaskPoolJob_t that will be initialized when this - * function returns successfully. This handle can be used to inspect the job status with - * @ref IotTaskPool_GetStatus or cancel the job with @ref IotTaskPool_TryCancel, etc.... - * - * @return One of the following: - * - #IOT_TASKPOOL_SUCCESS - * - #IOT_TASKPOOL_BAD_PARAMETER - * - * - */ -/* @[declare_taskpool_createjob] */ -IotTaskPoolError_t IotTaskPool_CreateJob( IotTaskPoolRoutine_t userCallback, - void * pUserContext, - IotTaskPoolJobStorage_t * const pJobStorage, - IotTaskPoolJob_t * const pJob ); -/* @[declare_taskpool_createjob] */ - -/** - * brief Creates a job for the task pool by allocating the job dynamically. - * - * A recyclable job does not need to be allocated twice, but it can rather be reused through - * subsequent calls to @ref IotTaskPool_CreateRecyclableJob. - * - * @param[in] taskPool A handle to the task pool for which to create a recyclable job. - * @param[in] userCallback A user-specified callback for the job. - * @param[in] pUserContext A user-specified context for the callback. - * @param[out] pJob A pointer to an instance of @ref IotTaskPoolJob_t that will be initialized when this - * function returns successfully. This handle can be used to inspect the job status with - * @ref IotTaskPool_GetStatus or cancel the job with @ref IotTaskPool_TryCancel, etc.... - * - * @return One of the following: - * - #IOT_TASKPOOL_SUCCESS - * - #IOT_TASKPOOL_BAD_PARAMETER - * - #IOT_TASKPOOL_NO_MEMORY - * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS - * - * @note This function will not allocate memory. //_RB_ Incorrect comment. - * - * @warning A recyclable job should be recycled with a call to @ref IotTaskPool_RecycleJob rather than destroyed. - * - */ -/* @[declare_taskpool_createrecyclablejob] */ -IotTaskPoolError_t IotTaskPool_CreateRecyclableJob( IotTaskPool_t taskPool, - IotTaskPoolRoutine_t userCallback, - void * pUserContext, - IotTaskPoolJob_t * const pJob ); -/* @[declare_taskpool_createrecyclablejob] */ - -/** - * @brief This function un-initializes a job. - * - * This function will destroy a job created with @ref IotTaskPool_CreateRecyclableJob. - * A job should not be destroyed twice. A job that was previously scheduled but has not completed yet should not be destroyed, - * but rather the application should attempt to cancel it first by calling @ref IotTaskPool_TryCancel. - * An attempt to destroy a job that was scheduled but not yet executed or canceled, may result in a - * @ref IOT_TASKPOOL_ILLEGAL_OPERATION error. - * - * @param[in] taskPool A handle to the task pool, e.g. as returned by a call to @ref IotTaskPool_Create or @ref IotTaskPool_CreateSystemTaskPool. - * @param[in] job A handle to a job that was create with a call to @ref IotTaskPool_CreateJob. - * - * @return One of the following: - * - #IOT_TASKPOOL_SUCCESS - * - #IOT_TASKPOOL_BAD_PARAMETER - * - #IOT_TASKPOOL_ILLEGAL_OPERATION - * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS - * - * @warning The task pool will try and prevent destroying jobs that are currently queued for execution, but does - * not enforce strict ordering of operations. It is up to the user to make sure @ref IotTaskPool_DestroyRecyclableJob is not called - * our of order. - * - * @warning Calling this function on job that was not previously created with @ref IotTaskPool_CreateRecyclableJob - * will result in a @ref IOT_TASKPOOL_ILLEGAL_OPERATION error. - * - */ -/* @[declare_taskpool_destroyrecyclablejob] */ -IotTaskPoolError_t IotTaskPool_DestroyRecyclableJob( IotTaskPool_t taskPool, - IotTaskPoolJob_t job ); -/* @[declare_taskpool_destroyrecyclablejob] */ - -/** - * @brief Recycles a job into the task pool job cache. - * - * This function will try and recycle the job into the task pool cache. If the cache is full, - * the job memory is destroyed as if the user called @ref IotTaskPool_DestroyRecyclableJob. The job should be recycled into - * the task pool instance from where it was allocated. - * Failure to do so will yield undefined results. A job should not be recycled twice. A job - * that was previously scheduled but not completed or canceled cannot be safely recycled. An attempt to do so will result - * in an @ref IOT_TASKPOOL_ILLEGAL_OPERATION error. - * - * @param[in] taskPool A handle to the task pool, e.g. as returned by a call to @ref IotTaskPool_Create. - * @param[out] job A pointer to a job that was create with a call to @ref IotTaskPool_CreateJob. - * - * @return One of the following: - * - #IOT_TASKPOOL_SUCCESS - * - #IOT_TASKPOOL_BAD_PARAMETER - * - #IOT_TASKPOOL_ILLEGAL_OPERATION - * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS - * - * @warning The `taskPool` used in this function should be the same - * used to create the job pointed to by `job`, or the results will be undefined. - * - * @warning Attempting to call this function on a statically allocated job will result in @ref IOT_TASKPOOL_ILLEGAL_OPERATION - * error. - * - * @warning This function should be used to recycle a job in the task pool cache when after the job executed. - * Failing to call either this function or @ref IotTaskPool_DestroyRecyclableJob will result is a memory leak. Statically - * allocated jobs do not need to be recycled or destroyed. - * - */ -/* @[declare_taskpool_recyclejob] */ -IotTaskPoolError_t IotTaskPool_RecycleJob( IotTaskPool_t taskPool, - IotTaskPoolJob_t job ); -/* @[declare_taskpool_recyclejob] */ - -/** - * @brief This function schedules a job created with @ref IotTaskPool_CreateJob or @ref IotTaskPool_CreateRecyclableJob - * against the task pool pointed to by `taskPool`. - * - * See @ref taskpool_design for a description of the jobs lifetime and interaction with the threads used in the task pool - * library. - * - * @param[in] taskPool A handle to the task pool that must have been previously initialized with. - * a call to @ref IotTaskPool_Create. - * @param[in] job A job to schedule for execution. This must be first initialized with a call to @ref IotTaskPool_CreateJob. - * @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. - * - * @return One of the following: - * - #IOT_TASKPOOL_SUCCESS - * - #IOT_TASKPOOL_BAD_PARAMETER - * - #IOT_TASKPOOL_ILLEGAL_OPERATION - * - #IOT_TASKPOOL_NO_MEMORY - * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS - * - * - * @note This function will not allocate memory, so it is guaranteed to succeed if the paramters are correct and the task pool - * was correctly initialized, and not yet destroyed. - * - * @warning The `taskPool` used in this function should be the same used to create the job pointed to by `job`, or the - * results will be undefined. - * - * Example - * @code{c} - * // An example of a user context to pass to a callback through a task pool thread. - * typedef struct JobUserContext - * { - * uint32_t counter; - * } JobUserContext_t; - * - * // An example of a user callback to invoke through a task pool thread. - * static void ExecutionCb( IotTaskPool_t taskPool, IotTaskPoolJob_t job, void * context ) - * { - * ( void )taskPool; - * ( void )job; - * - * JobUserContext_t * pUserContext = ( JobUserContext_t * )context; - * - * pUserContext->counter++; - * } - * - * void TaskPoolExample( ) - * { - * JobUserContext_t userContext = { 0 }; - * IotTaskPoolJob_t job; - * IotTaskPool_t taskPool; - * - * // Configure the task pool to hold at least two threads and three at the maximum. - * // Provide proper stack size and priority per the application needs. - * - * const IotTaskPoolInfo_t tpInfo = { .minThreads = 2, .maxThreads = 3, .stackSize = 512, .priority = 0 }; - * - * // Create a task pool. - * IotTaskPool_Create( &tpInfo, &taskPool ); - * - * // Statically allocate one job, schedule it. - * IotTaskPool_CreateJob( &ExecutionCb, &userContext, &job ); - * - * IotTaskPoolError_t errorSchedule = IotTaskPool_Schedule( taskPool, &job, 0 ); - * - * switch ( errorSchedule ) - * { - * case IOT_TASKPOOL_SUCCESS: - * break; - * case IOT_TASKPOOL_BAD_PARAMETER: // Invalid parameters, such as a NULL handle, can trigger this error. - * case IOT_TASKPOOL_ILLEGAL_OPERATION: // Scheduling a job that was previously scheduled or destroyed could trigger this error. - * case IOT_TASKPOOL_NO_MEMORY: // Scheduling a with flag #IOT_TASKPOOL_JOB_HIGH_PRIORITY could trigger this error. - * case IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS: // Scheduling a job after trying to destroy the task pool could trigger this error. - * // ASSERT - * break; - * default: - * // ASSERT - * } - * - * // - * // ... Perform other operations ... - * // - * - * IotTaskPool_Destroy( taskPool ); - * } - * @endcode - */ -/* @[declare_taskpool_schedule] */ -IotTaskPoolError_t IotTaskPool_Schedule( IotTaskPool_t taskPool, - IotTaskPoolJob_t job, - uint32_t flags ); -/* @[declare_taskpool_schedule] */ - -/** - * @brief This function schedules a job created with @ref IotTaskPool_CreateJob against the task pool - * pointed to by `taskPool` to be executed after a user-defined time interval. - * - * See @ref taskpool_design for a description of the jobs lifetime and interaction with the threads used in the task pool - * library. - * - * @param[in] taskPool A handle to the task pool that must have been previously initialized with. - * a call to @ref IotTaskPool_Create. - * @param[in] job A job to schedule for execution. This must be first initialized with a call to @ref IotTaskPool_CreateJob. - * @param[in] timeMs The time in milliseconds to wait before scheduling the job. - * - * @return One of the following: - * - #IOT_TASKPOOL_SUCCESS - * - #IOT_TASKPOOL_BAD_PARAMETER - * - #IOT_TASKPOOL_ILLEGAL_OPERATION - * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS - * - * - * @note This function will not allocate memory. - * - * @warning The `taskPool` used in this function should be the same - * used to create the job pointed to by `job`, or the results will be undefined. - * - */ -/* @[declare_taskpool_scheduledeferred] */ -IotTaskPoolError_t IotTaskPool_ScheduleDeferred( IotTaskPool_t taskPool, - IotTaskPoolJob_t job, - uint32_t timeMs ); -/* @[declare_taskpool_scheduledeferred] */ - -/** - * @brief This function retrieves the current status of a job. - * - * @param[in] taskPool A handle to the task pool that must have been previously initialized with - * a call to @ref IotTaskPool_Create or @ref IotTaskPool_CreateSystemTaskPool. - * @param[in] job The job to cancel. - * @param[out] pStatus The status of the job at the time of cancellation. - * - * @return One of the following: - * - #IOT_TASKPOOL_SUCCESS - * - #IOT_TASKPOOL_BAD_PARAMETER - * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS - * - * @warning This function is not thread safe and the job status returned in `pStatus` may be invalid by the time - * the calling thread has a chance to inspect it. - */ -/* @[declare_taskpool_getstatus] */ -IotTaskPoolError_t IotTaskPool_GetStatus( IotTaskPool_t taskPool, - IotTaskPoolJob_t job, - IotTaskPoolJobStatus_t * const pStatus ); -/* @[declare_taskpool_getstatus] */ - -/** - * @brief This function tries to cancel a job that was previously scheduled with @ref IotTaskPool_Schedule. - * - * A job can be canceled only if it is not yet executing, i.e. if its status is - * @ref IOT_TASKPOOL_STATUS_READY or @ref IOT_TASKPOOL_STATUS_SCHEDULED. Calling - * @ref IotTaskPool_TryCancel on a job whose status is @ref IOT_TASKPOOL_STATUS_COMPLETED, - * or #IOT_TASKPOOL_STATUS_CANCELED will yield a #IOT_TASKPOOL_CANCEL_FAILED return result. - * - * @param[in] taskPool A handle to the task pool that must have been previously initialized with - * a call to @ref IotTaskPool_Create. - * @param[in] job The job to cancel. - * @param[out] pStatus The status of the job at the time of cancellation. - * - * @return One of the following: - * - #IOT_TASKPOOL_SUCCESS - * - #IOT_TASKPOOL_BAD_PARAMETER - * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS - * - #IOT_TASKPOOL_CANCEL_FAILED - * - * @warning The `taskPool` used in this function should be the same - * used to create the job pointed to by `job`, or the results will be undefined. - * - */ -/* @[declare_taskpool_trycancel] */ -IotTaskPoolError_t IotTaskPool_TryCancel( IotTaskPool_t taskPool, - IotTaskPoolJob_t job, - IotTaskPoolJobStatus_t * const pStatus ); -/* @[declare_taskpool_trycancel] */ - -/** - * @brief Returns a pointer to the job storage from an instance of a job handle - * of type @ref IotTaskPoolJob_t. This function is guaranteed to succeed for a - * valid job handle. - * - * @param[in] job The job handle. - * - * @return A pointer to the storage associated with the job handle `job`. - * - * @warning If the `job` handle used is invalid, the results will be undefined. - */ -/* @[declare_taskpool_getjobstoragefromhandle] */ -IotTaskPoolJobStorage_t * IotTaskPool_GetJobStorageFromHandle( IotTaskPoolJob_t job ); -/* @[declare_taskpool_getjobstoragefromhandle] */ - -/** - * @brief Returns a string that describes an @ref IotTaskPoolError_t. - * - * Like the POSIX's `strerror`, this function returns a string describing a - * return code. In this case, the return code is a task pool library error code, - * `status`. - * - * The string returned by this function MUST be treated as read-only: any - * attempt to modify its contents may result in a crash. Therefore, this function - * is limited to usage in logging. - * - * @param[in] status The status to describe. - * - * @return A read-only string that describes `status`. - * - * @warning The string returned by this function must never be modified. - */ -/* @[declare_taskpool_strerror] */ -const char * IotTaskPool_strerror( IotTaskPoolError_t status ); -/* @[declare_taskpool_strerror] */ - -/** - * @brief The maximum number of task pools to be created when using - * a memory pool. - */ -#ifndef IOT_TASKPOOLS -#define IOT_TASKPOOLS ( 4 ) -#endif - -/** - * @brief The maximum number of jobs to cache. - */ -#ifndef IOT_TASKPOOL_JOBS_RECYCLE_LIMIT - #define IOT_TASKPOOL_JOBS_RECYCLE_LIMIT ( 8UL ) -#endif - -/** - * @brief The maximum timeout in milliseconds to wait for a job to be scheduled before waking up a worker thread. - * A worker thread that wakes up as a result of a timeout may exit to allow the task pool to fold back to its - * minimum number of threads. - */ -#ifndef IOT_TASKPOOL_JOB_WAIT_TIMEOUT_MS - #define IOT_TASKPOOL_JOB_WAIT_TIMEOUT_MS ( 60 * 1000UL ) -#endif - -#endif /* ifndef IOT_TASKPOOL_H_ */ 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 deleted file mode 100644 index 805039001..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/private/iot_error.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Amazon FreeRTOS Common V1.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_error.h - * @brief Provides macros for error checking and function cleanup. - * - * The macros in this file are generic. They may be customized by each library - * by setting the library prefix. - */ - -#ifndef IOT_ERROR_H_ -#define IOT_ERROR_H_ - -/* The config header is always included first. */ -#include "iot_config.h" - -/** - * @brief Declare the status variable and an initial value. - * - * This macro should be at the beginning of any functions that use cleanup sections. - * - * @param[in] statusType The type of the status variable for this function. - * @param[in] initialValue The initial value to assign to the status variable. - */ -#define IOT_FUNCTION_ENTRY( statusType, initialValue ) statusType status = initialValue - -/** - * @brief Declares the label that begins a cleanup section. - * - * This macro should be placed at the end of a function and followed by - * #IOT_FUNCTION_CLEANUP_END. - */ -#define IOT_FUNCTION_CLEANUP_BEGIN() iotCleanup: - -/** - * @brief Declares the end of a cleanup section. - * - * This macro should be placed at the end of a function and preceded by - * #IOT_FUNCTION_CLEANUP_BEGIN. - */ -#define IOT_FUNCTION_CLEANUP_END() return status - -/** - * @brief Declares an empty cleanup section. - * - * This macro should be placed at the end of a function to exit on error if no - * cleanup is required. - */ -#define IOT_FUNCTION_EXIT_NO_CLEANUP() IOT_FUNCTION_CLEANUP_BEGIN(); IOT_FUNCTION_CLEANUP_END() - -/** - * @brief Jump to the cleanup section. - */ -#define IOT_GOTO_CLEANUP() goto iotCleanup - -/** - * @brief Assign a value to the status variable and jump to the cleanup section. - * - * @param[in] statusValue The value to assign to the status variable. - */ -#define IOT_SET_AND_GOTO_CLEANUP( statusValue ) { status = ( statusValue ); IOT_GOTO_CLEANUP(); } - -/** - * @brief Jump to the cleanup section if a condition is `false`. - * - * This macro may be used in place of `assert` to exit a function is a condition - * is `false`. - * - * @param[in] condition The condition to check. - */ -#define IOT_GOTO_CLEANUP_IF_FALSE( condition ) { if( ( condition ) == false ) { IOT_GOTO_CLEANUP(); } } - -/** - * @brief Assign a value to the status variable and jump to the cleanup section - * if a condition is `false`. - * - * @param[in] statusValue The value to assign to the status variable. - * @param[in] condition The condition to check. - */ -#define IOT_SET_AND_GOTO_CLEANUP_IF_FALSE( statusValue, condition ) \ - if( ( condition ) == false ) \ - IOT_SET_AND_GOTO_CLEANUP( statusValue ) - -/** - * @brief Check a condition; if `false`, assign the "Bad parameter" status value - * and jump to the cleanup section. - * - * @param[in] libraryPrefix The library prefix of the status variable. - * @param[in] condition The condition to check. - */ -#define IOT_VALIDATE_PARAMETER( libraryPrefix, condition ) \ - IOT_SET_AND_GOTO_CLEANUP_IF_FALSE( libraryPrefix ## _BAD_PARAMETER, condition ) - -#endif /* ifndef IOT_ERROR_H_ */ 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 deleted file mode 100644 index 377dd6985..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/private/iot_logging.h +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Amazon FreeRTOS Common V1.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_logging.h - * @brief Generic logging function header file. - * - * Declares the generic logging function and the log levels. This file never - * needs to be included in source code. The header iot_logging_setup.h should - * be included instead. - * - * @see iot_logging_setup.h - */ - -#ifndef IOT_LOGGING_H_ -#define IOT_LOGGING_H_ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* Standard includes. */ -#include -#include -#include - -/** - * @constantspage{logging,logging library} - * - * @section logging_constants_levels Log levels - * @brief Log levels for the libraries in this SDK. - * - * Each library should specify a log level by setting @ref LIBRARY_LOG_LEVEL. - * All log messages with a level at or below the specified level will be printed - * for that library. - * - * Currently, there are 4 log levels. In the order of lowest to highest, they are: - * - #IOT_LOG_NONE
- * @copybrief IOT_LOG_NONE - * - #IOT_LOG_ERROR
- * @copybrief IOT_LOG_ERROR - * - #IOT_LOG_WARN
- * @copybrief IOT_LOG_WARN - * - #IOT_LOG_INFO
- * @copybrief IOT_LOG_INFO - * - #IOT_LOG_DEBUG
- * @copybrief IOT_LOG_DEBUG - */ - -/** - * @brief No log messages. - * - * Log messages with this level will be silently discarded. When @ref - * LIBRARY_LOG_LEVEL is #IOT_LOG_NONE, logging is disabled and no [logging functions] - * (@ref logging_functions) can be called. - */ -#define IOT_LOG_NONE 0 - -/** - * @brief Only critical, unrecoverable errors. - * - * Log messages with this level will be printed when a library encounters an - * error from which it cannot easily recover. - */ -#define IOT_LOG_ERROR 1 - -/** - * @brief Message about an abnormal but recoverable event. - * - * Log messages with this level will be printed when a library encounters an - * abnormal event that may be indicative of an error. Libraries should continue - * execution after logging a warning. - */ -#define IOT_LOG_WARN 2 - -/** - * @brief A helpful, informational message. - * - * Log messages with this level may indicate the normal status of a library - * function. They should be used to track how far a program has executed. - */ -#define IOT_LOG_INFO 3 - -/** - * @brief Detailed and excessive debug information. - * - * Log messages with this level are intended for developers. They may contain - * excessive information such as internal variables, buffers, or other specific - * information. - */ -#define IOT_LOG_DEBUG 4 - -/** - * @paramstructs{logging,logging} - */ - -/** - * @ingroup logging_datatypes_paramstructs - * @brief Log message configuration struct. - * - * @paramfor @ref logging_function_log, @ref logging_function_generic - * - * By default, log messages print the library name, log level, and a timestring. - * This struct can be passed to @ref logging_function_generic to disable one of - * the above components in the log message. - * - * Example: - * - * @code{c} - * IotLog_Generic( IOT_LOG_DEBUG, "SAMPLE", IOT_LOG_DEBUG, NULL, "Hello world!" ); - * @endcode - * The code above prints the following message: - * @code - * [DEBUG][SAMPLE][2018-01-01 12:00:00] Hello world! - * @endcode - * - * The timestring can be disabled as follows: - * @code - * IotLogConfig_t logConfig = { .hideLogLevel = false, .hideLibraryName = false, .hideTimestring = true}; - * IotLog_Generic( IOT_LOG_DEBUG, "SAMPLE", IOT_LOG_DEBUG, &logConfig, "Hello world!" ); - * @endcode - * The resulting log message will be: - * @code - * [DEBUG][SAMPLE] Hello world! - * @endcode - */ -typedef struct IotLogConfig -{ - bool hideLogLevel; /**< @brief Don't print the log level string for this message. */ - bool hideLibraryName; /**< @brief Don't print the library name for this message. */ - bool hideTimestring; /**< @brief Don't print the timestring for this message. */ -} IotLogConfig_t; - -/** - * @functionspage{logging,logging library} - * - * - @functionname{logging_function_log} - * - @functionname{logging_function_printbuffer} - * - @functionname{logging_function_generic} - * - @functionname{logging_function_genericprintbuffer} - */ - -/** - * @functionpage{IotLog_Generic,logging,generic} - * @functionpage{IotLog_PrintBuffer,logging,genericprintbuffer} - */ - -/** - * @brief Generic logging function that prints a single message. - * - * This function is the generic logging function shared across all libraries. - * The library-specific logging function @ref logging_function_log is implemented - * using this function. Like @ref logging_function_log, this function is only - * available when @ref LIBRARY_LOG_LEVEL is #IOT_LOG_NONE. - * - * In most cases, the library-specific logging function @ref logging_function_log - * should be called instead of this function. - * - * @param[in] libraryLogSetting The log level setting of the library, used to - * determine if the log message should be printed. Must be one of the @ref - * logging_constants_levels. - * @param[in] pLibraryName The library name to print. See @ref LIBRARY_LOG_NAME. - * @param[in] messageLevel The log level of the this message. See @ref LIBRARY_LOG_LEVEL. - * @param[in] pLogConfig Pointer to a #IotLogConfig_t. Optional; pass `NULL` to ignore. - * @param[in] pFormat Format string for the log message. - * @param[in] ... Arguments for format specification. - * - * @return No return value. On errors, it prints nothing. - */ -/* @[declare_logging_generic] */ -void IotLog_Generic( int libraryLogSetting, - const char * const pLibraryName, - int messageLevel, - const IotLogConfig_t * const pLogConfig, - const char * const pFormat, - ... ); -/* @[declare_logging_generic] */ - -/** - * @brief Generic function to log the contents of a buffer as bytes. - * - * This function is the generic buffer logging function shared across all libraries. - * The library-specific buffer logging function @ref logging_function_printbuffer is - * implemented using this function. Like @ref logging_function_printbuffer, this - * function is only available when @ref LIBRARY_LOG_LEVEL is #IOT_LOG_DEBUG. - * - * In most cases, the library-specific buffer logging function @ref - * logging_function_printbuffer should be called instead of this function. - * - * @param[in] pLibraryName The library name to print with the log. See @ref LIBRARY_LOG_NAME. - * @param[in] pHeader A message to print before printing the buffer. - * @param[in] pBuffer The buffer to print. - * @param[in] bufferSize The number of bytes in `pBuffer` to print. - * - * @return No return value. On errors, it prints nothing. - * - * @note To conserve memory, this function only allocates enough memory for a - * single line of output. Therefore, in multithreaded systems, its output may - * appear "fragmented" if other threads are logging simultaneously. - */ -/* @[declare_logging_genericprintbuffer] */ -void IotLog_GenericPrintBuffer( const char * const pLibraryName, - const char * const pHeader, - const uint8_t * const pBuffer, - size_t bufferSize ); -/* @[declare_logging_genericprintbuffer] */ - -#endif /* ifndef IOT_LOGGING_H_ */ 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 deleted file mode 100644 index 76fe2b36d..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/private/iot_static_memory.h +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Amazon FreeRTOS Common V1.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_static_memory.h - * @brief Common functions for managing static buffers. Only used when - * @ref IOT_STATIC_MEMORY_ONLY is `1`. - */ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* The functions in this file should only exist in static memory only mode, hence - * the check for IOT_STATIC_MEMORY_ONLY in the double inclusion guard. */ -#if !defined( IOT_STATIC_MEMORY_H_ ) && ( IOT_STATIC_MEMORY_ONLY == 1 ) -#define IOT_STATIC_MEMORY_H_ - -/* Standard includes. */ -#include -#include -#include - -/** - * @functionspage{static_memory,static memory component} - * - @functionname{static_memory_function_init} - * - @functionname{static_memory_function_cleanup} - * - @functionname{static_memory_function_findfree} - * - @functionname{static_memory_function_returninuse} - * - @functionname{static_memory_function_messagebuffersize} - * - @functionname{static_memory_function_mallocmessagebuffer} - * - @functionname{static_memory_function_freemessagebuffer} - */ - -/*----------------------- Initialization and cleanup ------------------------*/ - -/** - * @functionpage{IotStaticMemory_Init,static_memory,init} - * @functionpage{IotStaticMemory_Cleanup,static_memory,cleanup} - */ - -/** - * @brief One-time initialization function for static memory. - * - * This function performs internal setup of static memory. It must be called - * once (and only once) before calling any other static memory function. - * Calling this function more than once without first calling - * @ref static_memory_function_cleanup may result in a crash. - * - * @return `true` if initialization succeeded; `false` otherwise. - * - * @attention This function is called by `IotSdk_Init` and does not need to be - * called by itself. - * - * @warning No thread-safety guarantees are provided for this function. - * - * @see static_memory_function_cleanup - */ -/* @[declare_static_memory_init] */ -bool IotStaticMemory_Init( void ); -/* @[declare_static_memory_init] */ - -/** - * @brief One-time deinitialization function for static memory. - * - * This function frees resources taken in @ref static_memory_function_init. - * It should be called after to clean up static memory. After this function - * returns, @ref static_memory_function_init must be called again before - * calling any other static memory function. - * - * @attention This function is called by `IotSdk_Cleanup` and does not need - * to be called by itself. - * - * @warning No thread-safety guarantees are provided for this function. - * - * @see static_memory_function_init - */ -/* @[declare_static_memory_cleanup] */ -void IotStaticMemory_Cleanup( void ); -/* @[declare_static_memory_cleanup] */ - -/*------------------------- Buffer allocation and free ----------------------*/ - -/** - * @functionpage{IotStaticMemory_FindFree,static_memory,findfree} - * @functionpage{IotStaticMemory_ReturnInUse,static_memory,returninuse} - */ - -/** - * @brief Find a free buffer using the "in-use" flags. - * - * If a free buffer is found, this function marks the buffer in-use. This function - * is common to the static memory implementation. - * - * @param[in] pInUse The "in-use" flags to search. - * @param[in] limit How many flags to check, i.e. the size of `pInUse`. - * - * @return The index of a free buffer; `-1` if no free buffers are available. - * - * Example: - * @code{c} - * // To use this function, first declare two arrays. One provides the statically-allocated - * // objects, the other provides flags to determine which objects are in-use. - * #define NUMBER_OF_OBJECTS ... - * #define OBJECT_SIZE ... - * static bool _pInUseObjects[ NUMBER_OF_OBJECTS ] = { 0 }; - * static uint8_t _pObjects[ NUMBER_OF_OBJECTS ][ OBJECT_SIZE ] = { { 0 } }; // Placeholder for objects. - * - * // The function to statically allocate objects. Must have the same signature - * // as malloc(). - * void * Iot_MallocObject( size_t size ) - * { - * int32_t freeIndex = -1; - * void * pNewObject = NULL; - * - * // Check that sizes match. - * if( size != OBJECT_SIZE ) - * { - * // Get the index of a free object. - * freeIndex = IotStaticMemory_FindFree( _pInUseMessageBuffers, - * IOT_MESSAGE_BUFFERS ); - * - * if( freeIndex != -1 ) - * { - * pNewBuffer = &( _pMessageBuffers[ freeIndex ][ 0 ] ); - * } - * } - * - * return pNewBuffer; - * } - * @endcode - */ -/* @[declare_static_memory_findfree] */ -int32_t IotStaticMemory_FindFree( bool * pInUse, - size_t limit ); -/* @[declare_static_memory_findfree] */ - -/** - * @brief Return an "in-use" buffer. - * - * This function is common to the static memory implementation. - * - * @param[in] ptr Pointer to the buffer to return. - * @param[in] pPool The pool of buffers that the in-use buffer was allocated from. - * @param[in] pInUse The "in-use" flags for pPool. - * @param[in] limit How many buffers (and flags) to check while searching for ptr. - * @param[in] elementSize The size of a single element in pPool. - * - * Example: - * @code{c} - * // To use this function, first declare two arrays. One provides the statically-allocated - * // objects, the other provides flags to determine which objects are in-use. - * #define NUMBER_OF_OBJECTS ... - * #define OBJECT_SIZE ... - * static bool _pInUseObjects[ NUMBER_OF_OBJECTS ] = { 0 }; - * static uint8_t _pObjects[ NUMBER_OF_OBJECTS ][ OBJECT_SIZE ] = { { 0 } }; // Placeholder for objects. - * - * // The function to free statically-allocated objects. Must have the same signature - * // as free(). - * void Iot_FreeObject( void * ptr ) - * { - * IotStaticMemory_ReturnInUse( ptr, - * _pObjects, - * _pInUseObjects, - * NUMBER_OF_OBJECTS, - * OBJECT_SIZE ); - * } - * @endcode - */ -/* @[declare_static_memory_returninuse] */ -void IotStaticMemory_ReturnInUse( void * ptr, - void * pPool, - bool * pInUse, - size_t limit, - size_t elementSize ); -/* @[declare_static_memory_returninuse] */ - -/*------------------------ Message buffer management ------------------------*/ - -/** - * @functionpage{Iot_MessageBufferSize,static_memory,messagebuffersize} - * @functionpage{Iot_MallocMessageBuffer,static_memory,mallocmessagebuffer} - * @functionpage{Iot_FreeMessageBuffer,static_memory,freemessagebuffer} - */ - -/** - * @brief Get the fixed size of a message buffer. - * - * The size of the message buffers are known at compile time, but it is a [constant] - * (@ref IOT_MESSAGE_BUFFER_SIZE) that may not be visible to all source files. - * This function allows other source files to know the size of a message buffer. - * - * @return The size, in bytes, of a single message buffer. - */ -/* @[declare_static_memory_messagebuffersize] */ -size_t Iot_MessageBufferSize( void ); -/* @[declare_static_memory_messagebuffersize] */ - -/** - * @brief Get an empty message buffer. - * - * This function is the analog of [malloc] - * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html) - * for message buffers. - * - * @param[in] size Requested size for a message buffer. - * - * @return Pointer to the start of a message buffer. If the `size` argument is larger - * than the [fixed size of a message buffer](@ref IOT_MESSAGE_BUFFER_SIZE) - * or no message buffers are available, `NULL` is returned. - */ -/* @[declare_static_memory_mallocmessagebuffer] */ -void * Iot_MallocMessageBuffer( size_t size ); -/* @[declare_static_memory_mallocmessagebuffer] */ - -/** - * @brief Free an in-use message buffer. - * - * This function is the analog of [free] - * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html) - * for message buffers. - * - * @param[in] ptr Pointer to the message buffer to free. - */ -/* @[declare_static_memory_freemessagebuffer] */ -void Iot_FreeMessageBuffer( void * ptr ); -/* @[declare_static_memory_freemessagebuffer] */ - -#endif /* if !defined( IOT_STATIC_MEMORY_H_ ) && ( IOT_STATIC_MEMORY_ONLY == 1 ) */ 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 deleted file mode 100644 index 3779ff958..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/private/iot_taskpool_internal.h +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Amazon FreeRTOS Common V1.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_taskpool_internal.h - * @brief Internal header of task pool library. This header should not be included in - * typical application code. - */ - -#ifndef IOT_TASKPOOL_INTERNAL_H_ -#define IOT_TASKPOOL_INTERNAL_H_ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* Task pool include. */ -#include "private/iot_error.h" -#include "iot_taskpool.h" - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "semphr.h" -#include "timers.h" - -/* Establish a few convenience macros to handle errors in a standard way. */ - -/** - * @brief Every public API return an enumeration value with an undelying value of 0 in case of success. - */ -#define TASKPOOL_SUCCEEDED( x ) ( ( x ) == IOT_TASKPOOL_SUCCESS ) - -/** - * @brief Every public API returns an enumeration value with an undelying value different than 0 in case of success. - */ -#define TASKPOOL_FAILED( x ) ( ( x ) != IOT_TASKPOOL_SUCCESS ) - -/** - * @brief Jump to the cleanup area. - */ -#define TASKPOOL_GOTO_CLEANUP() IOT_GOTO_CLEANUP() - -/** - * @brief Declare the storage for the error status variable. - */ -#define TASKPOOL_FUNCTION_ENTRY( result ) IOT_FUNCTION_ENTRY( IotTaskPoolError_t, result ) - -/** - * @brief Check error and leave in case of failure. - */ -#define TASKPOOL_ON_ERROR_GOTO_CLEANUP( expr ) \ - { if( TASKPOOL_FAILED( status = ( expr ) ) ) { IOT_GOTO_CLEANUP(); } \ - } - -/** - * @brief Exit if an argument is NULL. - */ -#define TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( ptr ) IOT_VALIDATE_PARAMETER( IOT_TASKPOOL, ( ptr != NULL ) ) - -/** - * @brief Exit if an argument is NULL. - */ -#define TASKPOOL_ON_ARG_ERROR_GOTO_CLEANUP( expr ) IOT_VALIDATE_PARAMETER( IOT_TASKPOOL, ( ( expr ) == false ) ) - -/** - * @brief Set error and leave. - */ -#define TASKPOOL_SET_AND_GOTO_CLEANUP( expr ) IOT_SET_AND_GOTO_CLEANUP( expr ) - -/** - * @brief Initialize error and declare start of cleanup area. - */ -#define TASKPOOL_FUNCTION_CLEANUP() IOT_FUNCTION_CLEANUP_BEGIN() - -/** - * @brief Initialize error and declare end of cleanup area. - */ -#define TASKPOOL_FUNCTION_CLEANUP_END() IOT_FUNCTION_CLEANUP_END() - -/** - * @brief Create an empty cleanup area. - */ -#define TASKPOOL_NO_FUNCTION_CLEANUP() IOT_FUNCTION_EXIT_NO_CLEANUP() - -/** - * @brief Does not create a cleanup area. - */ -#define TASKPOOL_NO_FUNCTION_CLEANUP_NOLABEL() return status - -/** - * @def IotTaskPool_Assert( expression ) - * @brief Assertion macro for the Task pool library. - * - * Set @ref IOT_TASKPOOL_ENABLE_ASSERTS to `1` to enable assertions in the Task pool - * library. - * - * @param[in] expression Expression to be evaluated. - */ -#if IOT_TASKPOOL_ENABLE_ASSERTS == 1 - #ifndef IotTaskPool_Assert - #include - #define IotTaskPool_Assert( expression ) assert( expression ) - #endif -#else - #define IotTaskPool_Assert( expression ) -#endif - -/* Configure logs for TASKPOOL functions. */ -#ifdef IOT_LOG_LEVEL_TASKPOOL - #define LIBRARY_LOG_LEVEL IOT_LOG_LEVEL_TASKPOOL -#else - #ifdef IOT_LOG_LEVEL_GLOBAL - #define LIBRARY_LOG_LEVEL IOT_LOG_LEVEL_GLOBAL - #else - #define LIBRARY_LOG_LEVEL IOT_LOG_NONE - #endif -#endif - -#define LIBRARY_LOG_NAME ( "TASKPOOL" ) -#include "iot_logging_setup.h" - -/* - * Provide default values for undefined memory allocation functions based on - * the usage of dynamic memory allocation. - */ -#if IOT_STATIC_MEMORY_ONLY == 1 - #include "private/iot_static_memory.h" - -/** - * @brief Allocate an #_taskPool_t. This function should have the - * same signature as [malloc]. - */ - void * IotTaskPool_MallocTaskPool( size_t size ); - -/** - * @brief Free an #_taskPool_t. This function should have the - * same signature as [malloc]. - */ - void IotTaskPool_FreeTaskPool( void * ptr ); - -/** - * @brief Allocate an #IotTaskPoolJob_t. This function should have the - * same signature as [malloc]. - */ - void * IotTaskPool_MallocJob( size_t size ); - -/** - * @brief Free an #IotTaskPoolJob_t. This function should have the same - * same signature as [malloc]. - * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html). - */ - void IotTaskPool_FreeJob( void * ptr ); - -/** - * @brief Allocate an #_taskPoolTimerEvent_t. This function should have the - * same signature as [malloc]. - */ - void * IotTaskPool_MallocTimerEvent( size_t size ); - -/** - * @brief Free an #_taskPoolTimerEvent_t. This function should have the - * same signature as[ free ]. - */ - void IotTaskPool_FreeTimerEvent( void * ptr ); - -#else /* if IOT_STATIC_MEMORY_ONLY == 1 */ - #include - - #ifndef IotTaskPool_MallocTaskPool - #define IotTaskPool_MallocTaskPool malloc - #endif - - #ifndef IotTaskPool_FreeTaskPool - #define IotTaskPool_FreeTaskPool free - #endif - - #ifndef IotTaskPool_MallocJob - #define IotTaskPool_MallocJob malloc - #endif - - #ifndef IotTaskPool_FreeJob - #define IotTaskPool_FreeJob free - #endif - - #ifndef IotTaskPool_MallocTimerEvent - #define IotTaskPool_MallocTimerEvent malloc - #endif - - #ifndef IotTaskPool_FreeTimerEvent - #define IotTaskPool_FreeTimerEvent free - #endif - -#endif /* if IOT_STATIC_MEMORY_ONLY == 1 */ - -/* ---------------------------------------------------------------------------------------------- */ - -/** - * @cond DOXYGEN_IGNORE - * Doxygen should ignore this section. - * - * A macros to manage task pool memory allocation. - */ -#define IOT_TASK_POOL_INTERNAL_STATIC ( ( uint32_t ) 0x00000001 ) /* Flag to mark a job as user-allocated. */ -/** @endcond */ - -/** - * @brief Task pool jobs cache. - * - * @warning This is a system-level data type that should not be modified or used directly in any application. - * @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. - * - */ -typedef struct _taskPoolCache -{ - IotListDouble_t freeList; /**< @brief A list ot hold cached jobs. */ - - uint32_t freeCount; /**< @brief A counter to track the number of jobs in the cache. */ -} _taskPoolCache_t; - -/** - * @brief The task pool data structure keeps track of the internal state and the signals for the dispatcher threads. - * The task pool is a thread safe data structure. - * - * @warning This is a system-level data type that should not be modified or used directly in any application. - * @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. - * - */ -typedef struct _taskPool -{ - IotDeQueue_t dispatchQueue; /**< @brief The queue for the jobs waiting to be executed. */ - IotListDouble_t timerEventsList; /**< @brief The timeouts queue for all deferred jobs waiting to be executed. */ - _taskPoolCache_t jobsCache; /**< @brief A cache to re-use jobs in order to limit memory allocations. */ - uint32_t activeThreads; /**< @brief The number of threads in the task pool at any given time. */ - int32_t priority; /**< @brief The priority for all task pool threads. */ - SemaphoreHandle_t dispatchSignal; /**< @brief The synchronization object on which threads are waiting for incoming jobs. */ - StaticSemaphore_t dispatchSignalBuffer; /**< @brief The semaphore buffer. */ - StaticSemaphore_t startStopSignalBuffer; /**< @brief The semaphore buffer. */ - TimerHandle_t timer; /**< @brief The timer for deferred jobs. */ - StaticTimer_t timerBuffer; /**< @brief The timer buffer. */ - bool running; /**< @brief A flag to track whether the task pool is operational or should shut down. */ -} _taskPool_t; - -/** - * @brief The job data structure keeps track of the user callback and context, as well as the status of the job. - * - * @warning This is a system-level data type that should not be modified or used directly in any application. - * @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. - * - */ -typedef struct _taskPoolJob -{ - IotLink_t link; /**< @brief The link to insert the job in the dispatch queue. */ - IotTaskPoolRoutine_t userCallback; /**< @brief The user provided callback. */ - void * pUserContext; /**< @brief The user provided context. */ - uint32_t flags; /**< @brief Internal flags. */ - IotTaskPoolJobStatus_t status; /**< @brief The status for the job. */ -} _taskPoolJob_t; - -/** - * @brief Represents an operation that is subject to a timer. - * - * These events are queued per MQTT connection. They are sorted by their - * expiration time. - */ -typedef struct _taskPoolTimerEvent -{ - IotLink_t link; /**< @brief List link member. */ - TickType_t expirationTime; /**< @brief When this event should be processed. */ - IotTaskPoolJob_t job; /**< @brief The task pool job associated with this event. */ -} _taskPoolTimerEvent_t; - -#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 deleted file mode 100644 index a09e8133f..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/include/types/iot_taskpool_types.h +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Amazon FreeRTOS Common V1.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_taskpool_types.h - * @brief Types of the task pool. - */ - -#ifndef IOT_TASKPOOL_TYPES_H_ -#define IOT_TASKPOOL_TYPES_H_ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* Standard includes. */ -#include -#include - -/* Platform types includes. */ -#include "types/iot_platform_types.h" - -/* Linear containers (lists and queues) include. */ -#include "iot_linear_containers.h" - -/*-------------------------- Task pool enumerated types --------------------------*/ - -/** - * @ingroup taskpool_datatypes_enums - * @brief Return codes of [task pool functions](@ref taskpool_functions). - */ -typedef enum IotTaskPoolError -{ - /** - * @brief Task pool operation completed successfully. - * - * Functions that may return this value: - * - @ref taskpool_function_createsystemtaskpool - * - @ref taskpool_function_create - * - @ref taskpool_function_destroy - * - @ref taskpool_function_setmaxthreads - * - @ref taskpool_function_createjob - * - @ref taskpool_function_createrecyclablejob - * - @ref taskpool_function_destroyrecyclablejob - * - @ref taskpool_function_recyclejob - * - @ref taskpool_function_schedule - * - @ref taskpool_function_scheduledeferred - * - @ref taskpool_function_getstatus - * - @ref taskpool_function_trycancel - * - */ - IOT_TASKPOOL_SUCCESS = 0, - - /** - * @brief Task pool operation failed because at least one parameter is invalid. - * - * Functions that may return this value: - * - @ref taskpool_function_createsystemtaskpool - * - @ref taskpool_function_create - * - @ref taskpool_function_destroy - * - @ref taskpool_function_setmaxthreads - * - @ref taskpool_function_createjob - * - @ref taskpool_function_createrecyclablejob - * - @ref taskpool_function_destroyrecyclablejob - * - @ref taskpool_function_recyclejob - * - @ref taskpool_function_schedule - * - @ref taskpool_function_scheduledeferred - * - @ref taskpool_function_getstatus - * - @ref taskpool_function_trycancel - * - */ - IOT_TASKPOOL_BAD_PARAMETER, - - /** - * @brief Task pool operation failed because it is illegal. - * - * Functions that may return this value: - * - @ref taskpool_function_createjob - * - @ref taskpool_function_createrecyclablejob - * - @ref taskpool_function_destroyrecyclablejob - * - @ref taskpool_function_recyclejob - * - @ref taskpool_function_schedule - * - @ref taskpool_function_scheduledeferred - * - @ref taskpool_function_trycancel - * - */ - IOT_TASKPOOL_ILLEGAL_OPERATION, - - /** - * @brief Task pool operation failed because allocating memory failed. - * - * Functions that may return this value: - * - @ref taskpool_function_createsystemtaskpool - * - @ref taskpool_function_create - * - @ref taskpool_function_setmaxthreads - * - @ref taskpool_function_createrecyclablejob - * - @ref taskpool_function_scheduledeferred - * - @ref taskpool_function_getstatus - * - */ - IOT_TASKPOOL_NO_MEMORY, - - /** - * @brief Task pool operation failed because of an invalid parameter. - * - * Functions that may return this value: - * - @ref taskpool_function_setmaxthreads - * - @ref taskpool_function_createrecyclablejob - * - @ref taskpool_function_destroyrecyclablejob - * - @ref taskpool_function_recyclejob - * - @ref taskpool_function_schedule - * - @ref taskpool_function_scheduledeferred - * - @ref taskpool_function_getstatus - * - @ref taskpool_function_trycancel - * - */ - IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS, - - /** - * @brief Task pool cancellation failed. - * - * Functions that may return this value: - * - @ref taskpool_function_trycancel - * - */ - IOT_TASKPOOL_CANCEL_FAILED, -} IotTaskPoolError_t; - -/** - * @enums{taskpool,Task pool library} - */ - -/** - * @ingroup taskpool_datatypes_enums - * @brief Status codes of [task pool Job](@ref IotTaskPoolJob_t). - * - */ -typedef enum IotTaskPoolJobStatus -{ - /** - * @brief Job is ready to be scheduled. - * - */ - IOT_TASKPOOL_STATUS_READY = 0, - - /** - * @brief Job has been queued for execution. - * - */ - IOT_TASKPOOL_STATUS_SCHEDULED, - - /** - * @brief Job has been scheduled for deferred execution. - * - */ - IOT_TASKPOOL_STATUS_DEFERRED, - - /** - * @brief Job is executing. - * - */ - IOT_TASKPOOL_STATUS_COMPLETED, - - /** - * @brief Job has been canceled before executing. - * - */ - IOT_TASKPOOL_STATUS_CANCELED, - - /** - * @brief Job status is undefined. - * - */ - IOT_TASKPOOL_STATUS_UNDEFINED, -} IotTaskPoolJobStatus_t; - -/*------------------------- Task pool types and handles --------------------------*/ - -/** - * @ingroup taskpool_datatypes_handles - * @brief Opaque handle of a Task Pool instance. - * - * This type identifies a Task Pool instance, which is valid after a successful call - * to @ref taskpool_function_createsystemtaskpool or @ref taskpool_function_create. A - * variable of this type is passed as the first - * argument to [Task Pool library functions](@ref taskpool_functions) to identify which - * task pool that function acts on. - * - * A call to @ref taskpool_function_destroy makes a task pool handle invalid. Once - * @ref taskpool_function_destroy returns, the task handle should no longer - * be used. - * - * @initializer{IotTaskPool_t,IOT_TASKPOOL_INITIALIZER} - */ -typedef struct _taskPool * IotTaskPool_t; - -/** - * @ingroup taskpool_datatypes_structs - * @brief The job storage data structure provides the storage for a statically allocated Task Pool Job instance. - * - * @warning This is a system-level data type that should not be modified or used directly in any application. - * @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. - * - */ -typedef struct IotTaskPoolJobStorage -{ - IotLink_t link; /**< @brief Placeholder. */ - void * dummy2; /**< @brief Placeholder. */ - void * dummy3; /**< @brief Placeholder. */ - uint32_t dummy4; /**< @brief Placeholder. */ - IotTaskPoolJobStatus_t status; /**< @brief Placeholder. */ -} IotTaskPoolJobStorage_t; - -/** - * @ingroup taskpool_datatypes_handles - * @brief Opaque handle of a Task Pool Job. - * - * This type identifies a Task Pool Job instance, which is valid after a successful call - * to @ref taskpool_function_createjob or @ref taskpool_function_createrecyclablejob. - * - * A call to @ref taskpool_function_recyclejob or @ref taskpool_function_destroyrecyclablejob makes a - * task pool job handle invalid. Once @ref taskpool_function_recyclejob or - * @ref taskpool_function_destroyrecyclablejob returns, the task job handle should no longer be used. - * - * @initializer{IotTaskPoolJob_t,IOT_TASKPOOL_JOB_INITIALIZER} - * - */ -typedef struct _taskPoolJob * IotTaskPoolJob_t; - -/*------------------------- Task pool parameter structs --------------------------*/ - -/** - * @ingroup taskpool_datatypes_functionpointers - * @brief Callback type for a user callback. - * - * This type identifies the user callback signature to execute a task pool job. This callback will be invoked - * by the task pool threads with the `pUserContext` parameter, as specified by the user when - * calling @ref IotTaskPool_Schedule. - * - */ -typedef void ( * IotTaskPoolRoutine_t )( IotTaskPool_t pTaskPool, - IotTaskPoolJob_t pJob, - void * pUserContext ); - -/** - * @ingroup taskpool_datatypes_paramstructs - * @brief Initialization information to create one task pool instance. - * - * @paramfor @ref taskpool_function_createsystemtaskpool @ref taskpool_function_create. - * - * Passed as an argument to @ref taskpool_function_create. - * - * @initializer{IotTaskPoolInfo_t,IOT_TASKPOOL_INFO_INITIALIZER} - */ -typedef struct IotTaskPoolInfo -{ - /** - * @brief Specifies the operating parameters for a task pool. - * - * @attention #IotTaskPoolInfo_t.minThreads MUST be at least 1. - * #IotTaskPoolInfo_t.maxThreads MUST be greater or equal to #IotTaskPoolInfo_t.minThreads. - * If the minimum number of threads is same as the maximum, then the task pool will not try and grow the - * number of worker threads at run time. - */ - - 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. */ - 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. */ - 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. */ - 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. */ -} IotTaskPoolInfo_t; - -/*------------------------- TASKPOOL defined constants --------------------------*/ - -/** - * @constantspage{taskpool,task pool library} - * - * @section taskpool_constants_initializers Task pool Initializers - * @brief Provides default values for initializing the data types of the task pool library. - * - * @snippet this define_taskpool_initializers - * - * All user-facing data types of the task pool library can be initialized using - * one of the following. - * - * @warning Failure to initialize a task pool data type with the appropriate initializer - * may result in a runtime error! - * @note The initializers may change at any time in future versions, but their - * names will remain the same. - * - * Example - * @code{c} - * - * IotTaskPool_t * pTaskPool; - * - * const IotTaskPoolInfo_t tpInfo = IOT_TASKPOOL_INFO_INITIALIZER_LARGE; - * - * IotTaskPoolError_t error = IotTaskPool_Create( &tpInfo, &pTaskPool ); - * - * // Use the task pool - * // ... - * - * @endcode - * - */ -/* @[define_taskpool_initializers] */ -/** @brief Initializer for a small #IotTaskPoolInfo_t. */ -#define IOT_TASKPOOL_INFO_INITIALIZER_SMALL { .minThreads = 1, .maxThreads = 1, .stackSize = IOT_THREAD_DEFAULT_STACK_SIZE, .priority = IOT_THREAD_DEFAULT_PRIORITY } -/** @brief Initializer for a medium #IotTaskPoolInfo_t. */ -#define IOT_TASKPOOL_INFO_INITIALIZER_MEDIUM { .minThreads = 1, .maxThreads = 2, .stackSize = IOT_THREAD_DEFAULT_STACK_SIZE, .priority = IOT_THREAD_DEFAULT_PRIORITY } -/** @brief Initializer for a large #IotTaskPoolInfo_t. */ -#define IOT_TASKPOOL_INFO_INITIALIZER_LARGE { .minThreads = 2, .maxThreads = 3, .stackSize = IOT_THREAD_DEFAULT_STACK_SIZE, .priority = IOT_THREAD_DEFAULT_PRIORITY } -/** @brief Initializer for a very large #IotTaskPoolInfo_t. */ -#define IOT_TASKPOOL_INFO_INITIALIZER_XLARGE { .minThreads = 2, .maxThreads = 4, .stackSize = IOT_THREAD_DEFAULT_STACK_SIZE, .priority = IOT_THREAD_DEFAULT_PRIORITY } -/** @brief Initializer for a typical #IotTaskPoolInfo_t. */ -#define IOT_TASKPOOL_INFO_INITIALIZER IOT_TASKPOOL_INFO_INITIALIZER_MEDIUM -/** @brief Initializer for a #IotTaskPool_t. */ -#define IOT_TASKPOOL_INITIALIZER NULL -/** @brief Initializer for a #IotTaskPoolJobStorage_t. */ -#define IOT_TASKPOOL_JOB_STORAGE_INITIALIZER { { NULL, NULL }, NULL, NULL, 0, IOT_TASKPOOL_STATUS_UNDEFINED } -/** @brief Initializer for a #IotTaskPoolJob_t. */ -#define IOT_TASKPOOL_JOB_INITIALIZER NULL -/* @[define_taskpool_initializers] */ - -/** - * @brief Flag for scheduling a job to execute immediately, even if the maximum number of threads in the - * task pool was reached already. - * - * @warning This flag may cause the task pool to create a worker to serve the job immediately, and - * therefore using this flag may incur in additional memory usage and potentially fail scheduling the job. - */ -#define IOT_TASKPOOL_JOB_HIGH_PRIORITY ( ( uint32_t ) 0x00000001 ) - -/** - * @brief Allows the use of the system task pool. - * - * @warning The system task pool handle is not valid unless @ref IotTaskPool_CreateSystemTaskPool is - * called before the handle is used. - */ -#define IOT_SYSTEM_TASKPOOL ( NULL ) - -#endif /* ifndef IOT_TASKPOOL_TYPES_H_ */ 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 deleted file mode 100644 index aac8d3181..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/logging/iot_logging.c +++ /dev/null @@ -1,454 +0,0 @@ -/* - * Amazon FreeRTOS Common V1.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_logging.c - * @brief Implementation of logging functions from iot_logging.h - */ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* Standard includes. */ -#include -#include -#include - -/* Platform clock include. */ -#include "platform/iot_clock.h" - -/* Logging includes. */ -#include "private/iot_logging.h" - -/*-----------------------------------------------------------*/ - -/* This implementation assumes the following values for the log level constants. - * Ensure that the values have not been modified. */ -#if IOT_LOG_NONE != 0 - #error "IOT_LOG_NONE must be 0." -#endif -#if IOT_LOG_ERROR != 1 - #error "IOT_LOG_ERROR must be 1." -#endif -#if IOT_LOG_WARN != 2 - #error "IOT_LOG_WARN must be 2." -#endif -#if IOT_LOG_INFO != 3 - #error "IOT_LOG_INFO must be 3." -#endif -#if IOT_LOG_DEBUG != 4 - #error "IOT_LOG_DEBUG must be 4." -#endif - -/** - * @def IotLogging_Puts( message ) - * @brief Function the logging library uses to print a line. - * - * This function can be set by using a define. By default, the standard library - * [puts](http://pubs.opengroup.org/onlinepubs/9699919799/functions/puts.html) - * function is used. - */ -#ifndef IotLogging_Puts - #define IotLogging_Puts puts -#endif - -/* - * Provide default values for undefined memory allocation functions based on - * the usage of dynamic memory allocation. - */ -#if IOT_STATIC_MEMORY_ONLY == 1 - /* Static memory allocation header. */ - #include "private/iot_static_memory.h" - -/** - * @brief Allocate a new logging buffer. This function must have the same - * signature as [malloc](http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html). - */ - #ifndef IotLogging_Malloc - #define IotLogging_Malloc Iot_MallocMessageBuffer - #endif - -/** - * @brief Free a logging buffer. This function must have the same signature - * as [free](http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html). - */ - #ifndef IotLogging_Free - #define IotLogging_Free Iot_FreeMessageBuffer - #endif - -/** - * @brief Get the size of a logging buffer. Statically-allocated buffers - * should all have the same size. - */ - #ifndef IotLogging_StaticBufferSize - #define IotLogging_StaticBufferSize Iot_MessageBufferSize - #endif -#else /* if IOT_STATIC_MEMORY_ONLY == 1 */ - #ifndef IotLogging_Malloc - #include - #define IotLogging_Malloc malloc - #endif - - #ifndef IotLogging_Free - #include - #define IotLogging_Free free - #endif -#endif /* if IOT_STATIC_MEMORY_ONLY == 1 */ - -/** - * @brief A guess of the maximum length of a timestring. - * - * There's no way for this logging library to know the length of a timestring - * before it's generated. Therefore, the logging library will assume a maximum - * length of any timestring it may get. This value should be generous enough - * to accommodate the vast majority of timestrings. - * - * @see @ref platform_clock_function_gettimestring - */ -#define MAX_TIMESTRING_LENGTH ( 64 ) - -/** - * @brief The longest string in #_pLogLevelStrings (below), plus 3 to accommodate - * `[]` and a null-terminator. - */ -#define MAX_LOG_LEVEL_LENGTH ( 8 ) - -/** - * @brief How many bytes @ref logging_function_genericprintbuffer should output on - * each line. - */ -#define BYTES_PER_LINE ( 16 ) - -/*-----------------------------------------------------------*/ - -/** - * @brief Lookup table for log levels. - * - * Converts one of the @ref logging_constants_levels to a string. - */ -static const char * const _pLogLevelStrings[ 5 ] = -{ - "", /* IOT_LOG_NONE */ - "ERROR", /* IOT_LOG_ERROR */ - "WARN ", /* IOT_LOG_WARN */ - "INFO ", /* IOT_LOG_INFO */ - "DEBUG" /* IOT_LOG_DEBUG */ -}; - -/*-----------------------------------------------------------*/ - -#if !defined( IOT_STATIC_MEMORY_ONLY ) || ( IOT_STATIC_MEMORY_ONLY == 0 ) - static bool _reallocLoggingBuffer( void ** pOldBuffer, - size_t newSize, - size_t oldSize ) - { - bool status = false; - - /* Allocate a new, larger buffer. */ - void * pNewBuffer = IotLogging_Malloc( newSize ); - - /* Ensure that memory allocation succeeded. */ - if( pNewBuffer != NULL ) - { - /* Copy the data from the old buffer to the new buffer. */ - ( void ) memcpy( pNewBuffer, *pOldBuffer, oldSize ); - - /* Free the old buffer and update the pointer. */ - IotLogging_Free( *pOldBuffer ); - *pOldBuffer = pNewBuffer; - - status = true; - } - - return status; - } -#endif /* if !defined( IOT_STATIC_MEMORY_ONLY ) || ( IOT_STATIC_MEMORY_ONLY == 0 ) */ - -/*-----------------------------------------------------------*/ - -void IotLog_Generic( int libraryLogSetting, - const char * const pLibraryName, - int messageLevel, - const IotLogConfig_t * const pLogConfig, - const char * const pFormat, - ... ) -{ - int requiredMessageSize = 0; - size_t bufferSize = 0, - bufferPosition = 0, timestringLength = 0; - char * pLoggingBuffer = NULL; - va_list args; - - /* If the library's log level setting is lower than the message level, - * return without doing anything. */ - if( ( messageLevel == 0 ) || ( messageLevel > libraryLogSetting ) ) - { - return; - } - - if( ( pLogConfig == NULL ) || ( pLogConfig->hideLogLevel == false ) ) - { - /* Add length of log level if requested. */ - bufferSize += MAX_LOG_LEVEL_LENGTH; - } - - /* Estimate the amount of buffer needed for this log message. */ - if( ( pLogConfig == NULL ) || ( pLogConfig->hideLibraryName == false ) ) - { - /* Add size of library name if requested. Add 2 to accommodate "[]". */ - bufferSize += strlen( pLibraryName ) + 2; - } - - if( ( pLogConfig == NULL ) || ( pLogConfig->hideTimestring == false ) ) - { - /* Add length of timestring if requested. */ - bufferSize += MAX_TIMESTRING_LENGTH; - } - - /* Add 64 as an initial (arbitrary) guess for the length of the message. */ - bufferSize += 64; - - /* In static memory mode, check that the log message will fit in the a - * static buffer. */ - #if IOT_STATIC_MEMORY_ONLY == 1 - if( bufferSize >= IotLogging_StaticBufferSize() ) - { - /* If the static buffers are likely too small to fit the log message, - * return. */ - return; - } - - /* Otherwise, update the buffer size to the size of a static buffer. */ - bufferSize = IotLogging_StaticBufferSize(); - #endif - - /* Allocate memory for the logging buffer. */ - pLoggingBuffer = ( char * ) IotLogging_Malloc( bufferSize ); - - if( pLoggingBuffer == NULL ) - { - return; - } - - /* Print the message log level if requested. */ - if( ( pLogConfig == NULL ) || ( pLogConfig->hideLogLevel == false ) ) - { - /* Ensure that message level is valid. */ - if( ( messageLevel >= IOT_LOG_NONE ) && ( messageLevel <= IOT_LOG_DEBUG ) ) - { - /* Add the log level string to the logging buffer. */ - requiredMessageSize = snprintf( pLoggingBuffer + bufferPosition, - bufferSize - bufferPosition, - "[%s]", - _pLogLevelStrings[ messageLevel ] ); - - /* Check for encoding errors. */ - if( requiredMessageSize <= 0 ) - { - IotLogging_Free( pLoggingBuffer ); - - return; - } - - /* Update the buffer position. */ - bufferPosition += ( size_t ) requiredMessageSize; - } - } - - /* Print the library name if requested. */ - if( ( pLogConfig == NULL ) || ( pLogConfig->hideLibraryName == false ) ) - { - /* Add the library name to the logging buffer. */ - requiredMessageSize = snprintf( pLoggingBuffer + bufferPosition, - bufferSize - bufferPosition, - "[%s]", - pLibraryName ); - - /* Check for encoding errors. */ - if( requiredMessageSize <= 0 ) - { - IotLogging_Free( pLoggingBuffer ); - - return; - } - - /* Update the buffer position. */ - bufferPosition += ( size_t ) requiredMessageSize; - } - - /* Print the timestring if requested. */ - if( ( pLogConfig == NULL ) || ( pLogConfig->hideTimestring == false ) ) - { - /* Add the opening '[' enclosing the timestring. */ - pLoggingBuffer[ bufferPosition ] = '['; - bufferPosition++; - - /* Generate the timestring and add it to the buffer. */ - if( IotClock_GetTimestring( pLoggingBuffer + bufferPosition, - bufferSize - bufferPosition, - ×tringLength ) == true ) - { - /* If the timestring was successfully generated, add the closing "]". */ - bufferPosition += timestringLength; - pLoggingBuffer[ bufferPosition ] = ']'; - bufferPosition++; - } - else - { - /* Sufficient memory for a timestring should have been allocated. A timestring - * probably failed to generate due to a clock read error; remove the opening '[' - * from the logging buffer. */ - bufferPosition--; - pLoggingBuffer[ bufferPosition ] = '\0'; - } - } - - /* Add a padding space between the last closing ']' and the message, unless - * the logging buffer is empty. */ - if( bufferPosition > 0 ) - { - pLoggingBuffer[ bufferPosition ] = ' '; - bufferPosition++; - } - - va_start( args, pFormat ); - - /* Add the log message to the logging buffer. */ - requiredMessageSize = vsnprintf( pLoggingBuffer + bufferPosition, - bufferSize - bufferPosition, - pFormat, - args ); - - va_end( args ); - - /* If the logging buffer was too small to fit the log message, reallocate - * a larger logging buffer. */ - if( ( size_t ) requiredMessageSize >= bufferSize - bufferPosition ) - { - #if IOT_STATIC_MEMORY_ONLY == 1 - - /* There's no point trying to allocate a larger static buffer. Return - * immediately. */ - IotLogging_Free( pLoggingBuffer ); - - return; - #else - if( _reallocLoggingBuffer( ( void ** ) &pLoggingBuffer, - ( size_t ) requiredMessageSize + bufferPosition + 1, - bufferSize ) == false ) - { - /* If buffer reallocation failed, return. */ - IotLogging_Free( pLoggingBuffer ); - - return; - } - - /* Reallocation successful, update buffer size. */ - bufferSize = ( size_t ) requiredMessageSize + bufferPosition + 1; - - /* Add the log message to the buffer. Now that the buffer has been - * reallocated, this should succeed. */ - va_start( args, pFormat ); - requiredMessageSize = vsnprintf( pLoggingBuffer + bufferPosition, - bufferSize - bufferPosition, - pFormat, - args ); - va_end( args ); - #endif /* if IOT_STATIC_MEMORY_ONLY == 1 */ - } - - /* Check for encoding errors. */ - if( requiredMessageSize <= 0 ) - { - IotLogging_Free( pLoggingBuffer ); - - return; - } - - /* Print the logging buffer to stdout. */ - IotLogging_Puts( pLoggingBuffer ); - - /* Free the logging buffer. */ - IotLogging_Free( pLoggingBuffer ); -} - -/*-----------------------------------------------------------*/ - -void IotLog_GenericPrintBuffer( const char * const pLibraryName, - const char * const pHeader, - const uint8_t * const pBuffer, - size_t bufferSize ) -{ - size_t i = 0, offset = 0; - - /* Allocate memory to hold each line of the log message. Since each byte - * of pBuffer is printed in 4 characters (2 digits, a space, and a null- - * terminator), the size of each line is 4 * BYTES_PER_LINE. */ - char * pMessageBuffer = IotLogging_Malloc( 4 * BYTES_PER_LINE ); - - /* Exit if no memory is available. */ - if( pMessageBuffer == NULL ) - { - return; - } - - /* Print pHeader before printing pBuffer. */ - if( pHeader != NULL ) - { - IotLog_Generic( IOT_LOG_DEBUG, - pLibraryName, - IOT_LOG_DEBUG, - NULL, - pHeader ); - } - - /* Print each byte in pBuffer. */ - for( i = 0; i < bufferSize; i++ ) - { - /* Print a line if BYTES_PER_LINE is reached. But don't print a line - * at the beginning (when i=0). */ - if( ( i % BYTES_PER_LINE == 0 ) && ( i != 0 ) ) - { - IotLogging_Puts( pMessageBuffer ); - - /* Reset offset so that pMessageBuffer is filled from the beginning. */ - offset = 0; - } - - /* Print a single byte into pMessageBuffer. */ - ( void ) snprintf( pMessageBuffer + offset, 4, "%02x ", pBuffer[ i ] ); - - /* Move the offset where the next character is printed. */ - offset += 3; - } - - /* Print the final line of bytes. This line isn't printed by the for-loop above. */ - IotLogging_Puts( pMessageBuffer ); - - /* Free memory used by this function. */ - IotLogging_Free( pMessageBuffer ); -} - -/*-----------------------------------------------------------*/ 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 deleted file mode 100644 index ac08e2271..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/logging/iot_logging_task_dynamic_buffers.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Amazon FreeRTOS Common V1.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" -#include "queue.h" - -/* Logging includes. */ -#include "iot_logging_task.h" - -/* Standard includes. */ -#include -#include -#include - -/* Sanity check all the definitions required by this file are set. */ -#ifndef configPRINT_STRING - #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 ) -#endif - -#ifndef configLOGGING_MAX_MESSAGE_LENGTH - #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. -#endif - -#ifndef configLOGGING_INCLUDE_TIME_AND_TASK_NAME - #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. -#endif - -/* A block time of 0 just means don't block. */ -#define loggingDONT_BLOCK 0 - -/*-----------------------------------------------------------*/ - -/* - * The task that actually performs the print output. Using a separate task - * enables the use of slow output, such as as a UART, without the task that is - * outputting the log message having to wait for the message to be completely - * written. Using a separate task also serializes access to the output port. - * - * The structure of this task is very simple; it blocks on a queue to wait for - * a pointer to a string, sending any received strings to a macro that performs - * the actual output. The macro is port specific, so implemented outside of - * this file. This version uses dynamic memory, so the buffer that contained - * the log message is freed after it has been output. - */ -static void prvLoggingTask( void * pvParameters ); - -/*-----------------------------------------------------------*/ - -/* - * The queue used to pass pointers to log messages from the task that created - * the message to the task that will performs the output. - */ -static QueueHandle_t xQueue = NULL; - -/*-----------------------------------------------------------*/ - -BaseType_t xLoggingTaskInitialize( uint16_t usStackSize, - UBaseType_t uxPriority, - UBaseType_t uxQueueLength ) -{ - BaseType_t xReturn = pdFAIL; - - /* Ensure the logging task has not been created already. */ - if( xQueue == NULL ) - { - /* Create the queue used to pass pointers to strings to the logging task. */ - xQueue = xQueueCreate( uxQueueLength, sizeof( char ** ) ); - - if( xQueue != NULL ) - { - if( xTaskCreate( prvLoggingTask, "Logging", usStackSize, NULL, uxPriority, NULL ) == pdPASS ) - { - xReturn = pdPASS; - } - else - { - /* Could not create the task, so delete the queue again. */ - vQueueDelete( xQueue ); - } - } - } - - return xReturn; -} -/*-----------------------------------------------------------*/ - -static void prvLoggingTask( void * pvParameters ) -{ - char * pcReceivedString = NULL; - - for( ; ; ) - { - /* Block to wait for the next string to print. */ - if( xQueueReceive( xQueue, &pcReceivedString, portMAX_DELAY ) == pdPASS ) - { - configPRINT_STRING( pcReceivedString ); - vPortFree( ( void * ) pcReceivedString ); - } - } -} -/*-----------------------------------------------------------*/ - -/*! - * \brief Formats a string to be printed and sends it - * to the print queue. - * - * Appends the message number, time (in ticks), and task - * that called vLoggingPrintf to the beginning of each - * print statement. - * - */ -void vLoggingPrintf( const char * pcFormat, - ... ) -{ - size_t xLength = 0; - int32_t xLength2 = 0; - va_list args; - char * pcPrintString = NULL; - - /* The queue is created by xLoggingTaskInitialize(). Check - * xLoggingTaskInitialize() has been called. */ - configASSERT( xQueue ); - - /* Allocate a buffer to hold the log message. */ - pcPrintString = pvPortMalloc( configLOGGING_MAX_MESSAGE_LENGTH ); - - if( pcPrintString != NULL ) - { - /* There are a variable number of parameters. */ - va_start( args, pcFormat ); - - if( strcmp( pcFormat, "\n" ) != 0 ) - { - #if ( configLOGGING_INCLUDE_TIME_AND_TASK_NAME == 1 ) - { - const char * pcTaskName; - const char * pcNoTask = "None"; - static BaseType_t xMessageNumber = 0; - - /* Add a time stamp and the name of the calling task to the - * start of the log. */ - if( xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED ) - { - pcTaskName = pcTaskGetName( NULL ); - } - else - { - pcTaskName = pcNoTask; - } - - xLength = snprintf( pcPrintString, configLOGGING_MAX_MESSAGE_LENGTH, "%lu %lu [%s] ", - ( unsigned long ) xMessageNumber++, - ( unsigned long ) xTaskGetTickCount(), - pcTaskName ); - } - #else /* if ( configLOGGING_INCLUDE_TIME_AND_TASK_NAME == 1 ) */ - { - xLength = 0; - } - #endif /* if ( configLOGGING_INCLUDE_TIME_AND_TASK_NAME == 1 ) */ - } - - xLength2 = vsnprintf( pcPrintString + xLength, configLOGGING_MAX_MESSAGE_LENGTH - xLength, pcFormat, args ); - - if( xLength2 < 0 ) - { - /* vsnprintf() failed. Restore the terminating NULL - * character of the first part. Note that the first - * part of the buffer may be empty if the value of - * configLOGGING_INCLUDE_TIME_AND_TASK_NAME is not - * 1 and as a result, the whole buffer may be empty. - * That's the reason we have a check for xLength > 0 - * before sending the buffer to the logging task. - */ - xLength2 = 0; - pcPrintString[ xLength ] = '\0'; - } - - xLength += ( size_t ) xLength2; - va_end( args ); - - /* Only send the buffer to the logging task if it is - * not empty. */ - if( xLength > 0 ) - { - /* Send the string to the logging task for IO. */ - if( xQueueSend( xQueue, &pcPrintString, loggingDONT_BLOCK ) != pdPASS ) - { - /* The buffer was not sent so must be freed again. */ - vPortFree( ( void * ) pcPrintString ); - } - } - else - { - /* The buffer was not sent, so it must be - * freed. */ - vPortFree( ( void * ) pcPrintString ); - } - } -} -/*-----------------------------------------------------------*/ - -void vLoggingPrint( const char * pcMessage ) -{ - char * pcPrintString = NULL; - size_t xLength = 0; - - /* The queue is created by xLoggingTaskInitialize(). Check - * xLoggingTaskInitialize() has been called. */ - configASSERT( xQueue ); - - xLength = strlen( pcMessage ) + 1; - pcPrintString = pvPortMalloc( xLength ); - - if( pcPrintString != NULL ) - { - strncpy( pcPrintString, pcMessage, xLength ); - - /* Send the string to the logging task for IO. */ - if( xQueueSend( xQueue, &pcPrintString, loggingDONT_BLOCK ) != pdPASS ) - { - /* The buffer was not sent so must be freed again. */ - vPortFree( ( void * ) pcPrintString ); - } - } -} 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 deleted file mode 100644 index 568499337..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/common/taskpool/iot_taskpool.c +++ /dev/null @@ -1,1192 +0,0 @@ -/* - * Amazon FreeRTOS Common V1.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ -/** - * @file iot_taskpool.c - * @brief Implements the task pool functions in iot_taskpool.h - */ - - -/* - * The full IoT Task Pool Library has many use cases, including Linux - * development.  Typical FreeRTOS use cases do not require the full - * functionality so an optimised implementation is provided specifically for use - * with FreeRTOS. The optimised version has a fixed number of tasks in the - * pool, each of which uses statically allocated memory to ensure creation of - * the pool is guaranteed (it does not run out of heap space). The constant - * IOT_TASKPOOL_NUMBER_OF_WORKERS sets the number of tasks in the pool. - * - * Unlike the full version, this optimised version: - * + Only supports a single task pool (system task pool) at a time. - * + Does not auto-scale by dynamically adding more tasks if the number of - * + tasks in the pool becomes exhausted.  The number of tasks in the pool - * are fixed at compile time.  See the task pool configuration options for - * more information. - * + Cannot be shut down - it exists for the lifetime of the application. - * - * As such this file does not implement the following API functions: - * + IotTaskPool_GetSystemTaskPool() - * + IotTaskPool_Create() - * + IotTaskPool_Destroy() - * + IotTaskPool_SetMaxThreads() - * - * Users who are interested in the functionality of the full IoT Task Pool - * library can us it in place of this optimised version. - */ - - -/* Kernel includes. */ -#include "FreeRTOS.h" -#include "semphr.h" - -/* IoT libraries includes. */ -#include "iot_config.h" - -/* Standard includes. */ -#include -#include -#include -#include -#include - -#if !defined( configSUPPORT_STATIC_ALLOCATION ) || ( configSUPPORT_STATIC_ALLOCATION != 1 ) - #error configSUPPORT_STATIC_ALLOCATION must be set to 1 in FreeRTOSConfig.h to build this file. -#endif - -/* Task pool internal include. */ -#include "private/iot_taskpool_internal.h" - -/** - * @brief Maximum semaphore value for wait operations. - */ -#define TASKPOOL_MAX_SEM_VALUE 0xFFFF - -/** - * @brief Reschedule delay in milliseconds for deferred jobs. - */ -#define TASKPOOL_JOB_RESCHEDULE_DELAY_MS ( 10ULL ) - -/* ---------------------------------------------------------------------------------- */ - -/** - * Doxygen should ignore this section. - * - * @brief The system task pool handle for all libraries to use. - * User application can use the system task pool as well knowing that the usage will be shared with - * the system libraries as well. The system task pool needs to be initialized before any library is used or - * before any code that posts jobs to the task pool runs. - */ -static _taskPool_t _IotSystemTaskPool = { .dispatchQueue = IOT_DEQUEUE_INITIALIZER }; - -/* -------------- Convenience functions to create/recycle/destroy jobs -------------- */ - -/** - * @brief Initializes one instance of a Task pool cache. - * - * @param[in] pCache The pre-allocated instance of the cache to initialize. - */ -static void _initJobsCache( _taskPoolCache_t * const pCache ); - -/** - * @brief Initialize a job. - * - * @param[in] pJob The job to initialize. - * @param[in] userCallback The user callback for the job. - * @param[in] pUserContext The context tp be passed to the callback. - * @param[in] isStatic A flag to indicate whether the job is statically or synamically allocated. - */ -static void _initializeJob( _taskPoolJob_t * const pJob, - IotTaskPoolRoutine_t userCallback, - void * pUserContext, - bool isStatic ); - -/** - * @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. - * - * @param[in] pCache The instance of the cache to extract the job from. - */ -static _taskPoolJob_t * _fetchOrAllocateJob( _taskPoolCache_t * const pCache ); - -/** - * Recycles one instance of a job into the cache or, if the cache is full, it destroys it. - * - * @param[in] pCache The instance of the cache to recycle the job into. - * @param[in] pJob The job to recycle. - * - */ -static void _recycleJob( _taskPoolCache_t * const pCache, - _taskPoolJob_t * const pJob ); - -/** - * Destroys one instance of a job. - * - * @param[in] pJob The job to destroy. - * - */ -static void _destroyJob( _taskPoolJob_t * const pJob ); - -/* -------------- The worker thread procedure for a task pool thread -------------- */ - -/** - * The procedure for a task pool worker thread. - * - * @param[in] pUserContext The user context. - * - */ -static void _taskPoolWorker( void * pUserContext ); - -/* -------------- Convenience functions to handle timer events -------------- */ - -/** - * Comparer for the time list. - * - * param[in] pTimerEventLink1 The link to the first timer event. - * param[in] pTimerEventLink1 The link to the first timer event. - */ -static int32_t _timerEventCompare( const IotLink_t * const pTimerEventLink1, - const IotLink_t * const pTimerEventLink2 ); - -/** - * Reschedules the timer for handling deferred jobs to the next timeout. - * - * param[in] timer The timer to reschedule. - * param[in] pFirstTimerEvent The timer event that carries the timeout and job inforamtion. - */ -static void _rescheduleDeferredJobsTimer( TimerHandle_t const timer, - _taskPoolTimerEvent_t * const pFirstTimerEvent ); - -/** - * The task pool timer procedure for scheduling deferred jobs. - * - * param[in] timer The timer to handle. - */ -static void _timerCallback( TimerHandle_t xTimer ); - -/* -------------- Convenience functions to create/initialize/destroy the task pool -------------- */ - -/** - * Parameter validation for a task pool initialization. - * - * @param[in] pInfo The initialization information for the task pool. - * - */ -static IotTaskPoolError_t _performTaskPoolParameterValidation( const IotTaskPoolInfo_t * const pInfo ); - -/** - * Initializes a pre-allocated instance of a task pool. - * - * @param[in] pTaskPool The pre-allocated instance of the task pool to initialize. - * - */ -static void _initTaskPoolControlStructures( _taskPool_t * const pTaskPool ); - -/** - * Initializes a pre-allocated instance of a task pool. - * - * @param[in] pInfo The initialization information for the task pool. - * @param[out] pTaskPool A pointer to the task pool data structure to initialize. - * - */ -static IotTaskPoolError_t _createTaskPool( const IotTaskPoolInfo_t * const pInfo, - _taskPool_t * const pTaskPool ); - -/** - * Destroys one instance of a task pool. - * - * @param[in] pTaskPool The task pool to destroy. - * - */ -static void _destroyTaskPool( _taskPool_t * const pTaskPool ); - -/** - * Places a job in the dispatch queue. - * - * @param[in] pTaskPool The task pool to scheduel the job with. - * @param[in] pJob The job to schedule. - * @param[in] flags The job flags. - * - */ -static IotTaskPoolError_t _scheduleInternal( _taskPool_t * const pTaskPool, - _taskPoolJob_t * const pJob ); -/** - * Matches a deferred job in the timer queue with its timer event wrapper. - * - * @param[in] pLink A pointer to the timer event link in the timer queue. - * @param[in] pMatch A pointer to the job to match. - * - */ -static bool _matchJobByPointer( const IotLink_t * const pLink, - void * pMatch ); - -/** - * Tries to cancel a job. - * - * @param[in] pTaskPool The task pool to cancel an operation against. - * @param[in] pJob The job to cancel. - * @param[out] pStatus The status of the job at the time of cancellation. - * - */ -static IotTaskPoolError_t _tryCancelInternal( _taskPool_t * const pTaskPool, - _taskPoolJob_t * const pJob, - IotTaskPoolJobStatus_t * const pStatus ); - -/* ---------------------------------------------------------------------------------------------- */ - -IotTaskPoolError_t IotTaskPool_CreateSystemTaskPool( const IotTaskPoolInfo_t * const pInfo ) -{ - TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS ); - - /* At this time the task pool cannot be created before the scheduler has - started because the function attempts to block on synchronization - primitives (although I'm not sure why). */ - configASSERT( xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED ); - - /* Guard against multiple attempts to create the system task pool in case - this function is called by more than one library initialization routine. */ - if( _IotSystemTaskPool.running == false ) - { - /* Parameter checking. */ - TASKPOOL_ON_ERROR_GOTO_CLEANUP( _performTaskPoolParameterValidation( pInfo ) ); - - /* Create the system task pool pool. */ - TASKPOOL_SET_AND_GOTO_CLEANUP( _createTaskPool( pInfo, &_IotSystemTaskPool ) ); - } - - TASKPOOL_NO_FUNCTION_CLEANUP(); -} -/*-----------------------------------------------------------*/ - -IotTaskPoolError_t IotTaskPool_CreateJob( IotTaskPoolRoutine_t userCallback, - void * pUserContext, - IotTaskPoolJobStorage_t * const pJobStorage, - IotTaskPoolJob_t * const ppJob ) -{ - TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS ); - - /* Parameter checking. */ - TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( userCallback ); - TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pJobStorage ); - TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( ppJob ); - - /* Build a job around the user-provided storage. */ - _initializeJob( ( _taskPoolJob_t * ) pJobStorage, userCallback, pUserContext, true ); - - *ppJob = ( IotTaskPoolJob_t ) pJobStorage; - - TASKPOOL_NO_FUNCTION_CLEANUP(); -} - -/*-----------------------------------------------------------*/ - -IotTaskPoolError_t IotTaskPool_CreateRecyclableJob( IotTaskPool_t taskPoolHandle, - IotTaskPoolRoutine_t userCallback, - void * pUserContext, - IotTaskPoolJob_t * const ppJob ) -{ - TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS ); - - _taskPool_t * const pTaskPool = &_IotSystemTaskPool; - _taskPoolJob_t * pTempJob = NULL; - - /* This lean version of the task pool only supports the task pool created - by this library (the system task pool). NULL means use the system task - pool - no other values are allowed. Use the full implementation of this - library if you want multiple task pools (there is more than one task in - each pool. */ - configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) ); - - /* Avoid compiler warnings about unused parameters if configASSERT() is not - defined. */ - ( void ) taskPoolHandle; - - /* Parameter checking. */ - TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( userCallback ); - TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( ppJob ); - - taskENTER_CRITICAL(); - { - /* Bail out early if this task pool is shutting down. */ - pTempJob = _fetchOrAllocateJob( &pTaskPool->jobsCache ); - } - taskEXIT_CRITICAL(); - - if( pTempJob == NULL ) - { - IotLogInfo( "Failed to allocate a job." ); - - TASKPOOL_SET_AND_GOTO_CLEANUP( IOT_TASKPOOL_NO_MEMORY ); - } - - _initializeJob( pTempJob, userCallback, pUserContext, false ); - - *ppJob = pTempJob; - - TASKPOOL_NO_FUNCTION_CLEANUP(); -} - -/*-----------------------------------------------------------*/ - -IotTaskPoolError_t IotTaskPool_DestroyRecyclableJob( IotTaskPool_t taskPoolHandle, - IotTaskPoolJob_t pJobHandle ) -{ - TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS ); - - _taskPoolJob_t * pJob = ( _taskPoolJob_t * ) pJobHandle; - - /* This lean version of the task pool only supports the task pool created - by this library (the system task pool). NULL means use the system task - pool - no other values are allowed. Use the full implementation of this - library if you want multiple task pools (there is more than one task in - each pool. */ - configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) ); - - /* Avoid compiler warnings about unused parameters if configASSERT() is not - defined. */ - ( void ) taskPoolHandle; - - /* Parameter checking. */ - TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pJobHandle ); - - IotTaskPool_Assert( IotLink_IsLinked( &pJob->link ) == false ); - - _destroyJob( pJob ); - - TASKPOOL_NO_FUNCTION_CLEANUP(); -} - -/*-----------------------------------------------------------*/ - -IotTaskPoolError_t IotTaskPool_RecycleJob( IotTaskPool_t taskPoolHandle, - IotTaskPoolJob_t pJob ) -{ - TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS ); - - _taskPool_t * pTaskPool = ( _taskPool_t * ) &_IotSystemTaskPool; - - /* This lean version of the task pool only supports the task pool created - by this library (the system task pool). NULL means use the system task - pool - no other values are allowed. Use the full implementation of this - library if you want multiple task pools (there is more than one task in - each pool. */ - configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) ); - - /* Ensure unused parameters do not cause compiler warnings in case - configASSERT() is not defined. */ - ( void ) taskPoolHandle; - - TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pJob ); - - taskENTER_CRITICAL(); - { - IotTaskPool_Assert( IotLink_IsLinked( &pJob->link ) == false ); - - _recycleJob( &pTaskPool->jobsCache, pJob ); - } - taskEXIT_CRITICAL(); - - TASKPOOL_NO_FUNCTION_CLEANUP(); -} - -/*-----------------------------------------------------------*/ - -IotTaskPoolError_t IotTaskPool_Schedule( IotTaskPool_t taskPoolHandle, - IotTaskPoolJob_t pJob, - uint32_t flags ) -{ - TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS ); - - _taskPool_t * const pTaskPool = &_IotSystemTaskPool; - - /* Task pool must have been created. */ - configASSERT( pTaskPool->running != false ); - - /* This lean version of the task pool only supports the task pool created - by this library (the system task pool). NULL means use the system task - pool - no other values are allowed. Use the full implementation of this - library if you want multiple task pools (there is more than one task in - each pool. */ - configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) ); - - /* Avoid compiler warnings about unused parameters if configASSERT() is not - defined. */ - ( void ) taskPoolHandle; - - /* Parameter checking. */ - TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pJob ); - TASKPOOL_ON_ARG_ERROR_GOTO_CLEANUP( ( flags != 0UL ) && ( flags != IOT_TASKPOOL_JOB_HIGH_PRIORITY ) ); - - taskENTER_CRITICAL(); //_RB_ Critical section is too long - does the whole thing need to be protected? - { - _scheduleInternal( pTaskPool, pJob ); - } - taskEXIT_CRITICAL(); - - TASKPOOL_NO_FUNCTION_CLEANUP(); -} - -/*-----------------------------------------------------------*/ - -IotTaskPoolError_t IotTaskPool_ScheduleDeferred( IotTaskPool_t taskPoolHandle, - IotTaskPoolJob_t job, - uint32_t timeMs ) -{ - TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS ); - - _taskPool_t * pTaskPool = &_IotSystemTaskPool; - - /* This lean version of the task pool only supports the task pool created - by this library (the system task pool). NULL means use the system task - pool - no other values are allowed. Use the full implementation of this - library if you want multiple task pools (there is more than one task in - each pool. */ - configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) ); - - TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( job ); - - if( timeMs == 0UL ) - { - TASKPOOL_SET_AND_GOTO_CLEANUP( IotTaskPool_Schedule( pTaskPool, job, 0 ) ); - } - - taskENTER_CRITICAL(); - { - _taskPoolTimerEvent_t * pTimerEvent = IotTaskPool_MallocTimerEvent( sizeof( _taskPoolTimerEvent_t ) ); - - if( pTimerEvent == NULL ) - { - taskEXIT_CRITICAL(); - - TASKPOOL_SET_AND_GOTO_CLEANUP( IOT_TASKPOOL_NO_MEMORY ); - } - - IotLink_t * pTimerEventLink; - - TickType_t now = xTaskGetTickCount(); - - pTimerEvent->link.pNext = NULL; - pTimerEvent->link.pPrevious = NULL; - pTimerEvent->expirationTime = now + pdMS_TO_TICKS( timeMs ); - pTimerEvent->job = job; //_RB_ Think up to here can be outside the critical section. - - /* Append the timer event to the timer list. */ - IotListDouble_InsertSorted( &pTaskPool->timerEventsList, &pTimerEvent->link, _timerEventCompare ); - - /* Update the job status to 'scheduled'. */ - job->status = IOT_TASKPOOL_STATUS_DEFERRED; - - /* Peek the first event in the timer event list. There must be at least one, - * since we just inserted it. */ - pTimerEventLink = IotListDouble_PeekHead( &pTaskPool->timerEventsList ); - IotTaskPool_Assert( pTimerEventLink != NULL ); - - /* If the event we inserted is at the front of the queue, then - * we need to reschedule the underlying timer. */ - if( pTimerEventLink == &pTimerEvent->link ) - { - pTimerEvent = IotLink_Container( _taskPoolTimerEvent_t, pTimerEventLink, link ); - - _rescheduleDeferredJobsTimer( pTaskPool->timer, pTimerEvent ); - } - } - taskEXIT_CRITICAL(); - - TASKPOOL_NO_FUNCTION_CLEANUP(); -} - -/*-----------------------------------------------------------*/ - -IotTaskPoolError_t IotTaskPool_GetStatus( IotTaskPool_t taskPoolHandle, - IotTaskPoolJob_t job, - IotTaskPoolJobStatus_t * const pStatus ) -{ - TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS ); - - /* This lean version of the task pool only supports the task pool created - by this library (the system task pool). NULL means use the system task - pool - no other values are allowed. Use the full implementation of this - library if you want multiple task pools (there is more than one task in - each pool. */ - configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) ); - ( void ) taskPoolHandle; - - /* Parameter checking. */ - TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( job ); - TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pStatus ); - *pStatus = IOT_TASKPOOL_STATUS_UNDEFINED; - - taskENTER_CRITICAL(); - { - *pStatus = job->status; - } - taskEXIT_CRITICAL(); - - TASKPOOL_NO_FUNCTION_CLEANUP(); -} - -/*-----------------------------------------------------------*/ - -IotTaskPoolError_t IotTaskPool_TryCancel( IotTaskPool_t taskPoolHandle, - IotTaskPoolJob_t job, - IotTaskPoolJobStatus_t * const pStatus ) -{ - TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS ); - - _taskPool_t * const pTaskPool = &_IotSystemTaskPool; - - /* This lean version of the task pool only supports the task pool created - by this library (the system task pool). NULL means use the system task - pool - no other values are allowed. Use the full implementation of this - library if you want multiple task pools (there is more than one task in - each pool. */ - configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) ); - TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( job ); - - if( pStatus != NULL ) - { - *pStatus = IOT_TASKPOOL_STATUS_UNDEFINED; - } - - taskENTER_CRITICAL(); - { - status = _tryCancelInternal( pTaskPool, job, pStatus ); - } - taskEXIT_CRITICAL(); - - TASKPOOL_NO_FUNCTION_CLEANUP(); -} - -/*-----------------------------------------------------------*/ - -IotTaskPoolJobStorage_t * IotTaskPool_GetJobStorageFromHandle( IotTaskPoolJob_t pJob ) -{ - return ( IotTaskPoolJobStorage_t * ) pJob; -} - -/*-----------------------------------------------------------*/ - -const char * IotTaskPool_strerror( IotTaskPoolError_t status ) -{ - const char * pMessage = NULL; - - switch( status ) - { - case IOT_TASKPOOL_SUCCESS: - pMessage = "SUCCESS"; - break; - - case IOT_TASKPOOL_BAD_PARAMETER: - pMessage = "BAD PARAMETER"; - break; - - case IOT_TASKPOOL_ILLEGAL_OPERATION: - pMessage = "ILLEGAL OPERATION"; - break; - - case IOT_TASKPOOL_NO_MEMORY: - pMessage = "NO MEMORY"; - break; - - case IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS: - pMessage = "SHUTDOWN IN PROGRESS"; - break; - - case IOT_TASKPOOL_CANCEL_FAILED: - pMessage = "CANCEL FAILED"; - break; - - default: - pMessage = "INVALID STATUS"; - break; - } - - return pMessage; -} - -/* ---------------------------------------------------------------------------------------------- */ -/* ---------------------------------------------------------------------------------------------- */ -/* ---------------------------------------------------------------------------------------------- */ - -static IotTaskPoolError_t _performTaskPoolParameterValidation( const IotTaskPoolInfo_t * const pInfo ) -{ - TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS ); - - /* Check input values for consistency. */ - TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pInfo ); - TASKPOOL_ON_ARG_ERROR_GOTO_CLEANUP( pInfo->minThreads > pInfo->maxThreads ); - TASKPOOL_ON_ARG_ERROR_GOTO_CLEANUP( pInfo->minThreads < 1UL ); - TASKPOOL_ON_ARG_ERROR_GOTO_CLEANUP( pInfo->maxThreads < 1UL ); - - TASKPOOL_NO_FUNCTION_CLEANUP(); -} - -static void _initTaskPoolControlStructures( _taskPool_t * const pTaskPool ) -{ - /* Initialize a job data structures that require no de-initialization. - * All other data structures carry a value of 'NULL' before initailization. - */ - IotDeQueue_Create( &pTaskPool->dispatchQueue ); - IotListDouble_Create( &pTaskPool->timerEventsList ); - - _initJobsCache( &pTaskPool->jobsCache ); - - /* Initialize the semaphore for waiting for incoming work. Cannot fail as - statically allocated. */ - pTaskPool->dispatchSignal = xSemaphoreCreateCountingStatic( TASKPOOL_MAX_SEM_VALUE, 0, &pTaskPool->dispatchSignalBuffer ); -} - -static IotTaskPoolError_t _createTaskPool( const IotTaskPoolInfo_t * const pInfo, - _taskPool_t * const pTaskPool ) -{ - TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS ); - - /* Static TCB structures and arrays to be used by statically allocated - worker tasks. */ - static StaticTask_t workerTaskTCBs[ IOT_TASKPOOL_NUMBER_OF_WORKERS ]; - static StackType_t workerTaskStacks[ IOT_TASKPOOL_NUMBER_OF_WORKERS ][ IOT_TASKPOOL_WORKER_STACK_SIZE_BYTES / sizeof( portSTACK_TYPE ) ]; - - /* Static structure to hold te software timer. */ - static StaticTimer_t staticTimer; - - uint32_t threadsCreated = 0; /* Although initialised before use removing the initialiser here results in compiler warnings. */ - char taskName[ 10 ]; - - /* Check input values for consistency. */ - TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pTaskPool ); - - /* Zero out all data structures. */ - memset( ( void * ) pTaskPool, 0x00, sizeof( _taskPool_t ) ); - - /* Initialize all internal data structure prior to creating all threads. */ - _initTaskPoolControlStructures( pTaskPool ); - - /* Create the timer for a new connection. */ - pTaskPool->timer = xTimerCreateStatic( NULL, /* Text name for the timer, only used for debugging. */ - portMAX_DELAY, /* Timer period in ticks. */ - pdFALSE, /* pdFALSE means its a one-shot timer. */ - ( void * ) pTaskPool, /* Parameter passed into callback. */ - _timerCallback, /* Callback that executes when the timer expires. */ - &staticTimer ); /* Static storage for the timer's data structure. */ - - /* The task pool will initialize the minimum number of threads requested by the user upon start. - Note this tailored version of the task pool does not autoscale, but fixes the number of tasks - in the pool to the originally specified minimum, and the specified maximum value is ignored. */ - /* Create the minimum number of threads specified by the user, and if one fails shutdown and return error. */ - for( threadsCreated = 0; threadsCreated < pInfo->minThreads; ) - { - /* Generate a unique name for the task. */ - snprintf( taskName, sizeof( taskName ), "pool%d", ( int ) threadsCreated ); - - xTaskCreateStatic( _taskPoolWorker, /* Function that implements the task. */ - taskName, /* Text name for the task, used for debugging only. */ - IOT_TASKPOOL_WORKER_STACK_SIZE_BYTES / sizeof( portSTACK_TYPE ), /* xTaskCreate() expects the stack size to be specified in words. */ - pTaskPool, /* Parameter passed into the task. */ - pInfo->priority, /* Priority at which the task starts running. */ - &( workerTaskStacks[ threadsCreated ][ 0 ] ), /* Pointer to static storage for the task's stack. */ - &( workerTaskTCBs[ threadsCreated ] ) ); /* Pointer to static storage for te task's TCB. */ - - /* Upon successful thread creation, increase the number of active threads. */ - pTaskPool->activeThreads++; - ++threadsCreated; - } - pTaskPool->running = true; - - TASKPOOL_FUNCTION_CLEANUP(); - - TASKPOOL_FUNCTION_CLEANUP_END(); -} - -/*-----------------------------------------------------------*/ - -static void _destroyTaskPool( _taskPool_t * const pTaskPool ) -{ - if( pTaskPool->timer != NULL ) - { - xTimerDelete( pTaskPool->timer, 0 ); - } -} - -/* ---------------------------------------------------------------------------------------------- */ - -static void _taskPoolWorker( void * pUserContext ) -{ - IotTaskPool_Assert( pUserContext != NULL ); - - IotTaskPoolRoutine_t userCallback = NULL; - - /* Extract pTaskPool pointer from context. */ - _taskPool_t * pTaskPool = ( _taskPool_t * ) pUserContext; - - /* OUTER LOOP: it controls the lifetime of the worker thread. */ - for( ;; ) - { - IotLink_t * pFirst = NULL; - _taskPoolJob_t * pJob = NULL; - - /* Wait on incoming notifications... */ - configASSERT( pTaskPool->dispatchSignal ); - xSemaphoreTake( pTaskPool->dispatchSignal, portMAX_DELAY ); - - /* Acquire the lock to check for incoming notifications. */ - taskENTER_CRITICAL(); - { - /* Dequeue the first job in FIFO order. */ - pFirst = IotDeQueue_DequeueHead( &pTaskPool->dispatchQueue ); - - /* If there is indeed a job, then update status under lock, and release the lock before processing the job. */ - if( pFirst != NULL ) - { - /* Extract the job from its link. */ - pJob = IotLink_Container( _taskPoolJob_t, pFirst, link ); - - /* Update status to 'executing'. */ - pJob->status = IOT_TASKPOOL_STATUS_COMPLETED; /*_RB_ Should this be 'executing'? */ - userCallback = pJob->userCallback; - } - } - taskEXIT_CRITICAL(); - - /* INNER LOOP: it controls the execution of jobs: the exit condition is the lack of a job to execute. */ - while( pJob != NULL ) - { - /* Process the job by invoking the associated callback with the user context. - * This task pool thread will not be available until the user callback returns. - */ - { - IotTaskPool_Assert( IotLink_IsLinked( &pJob->link ) == false ); - IotTaskPool_Assert( userCallback != NULL ); - - userCallback( pTaskPool, pJob, pJob->pUserContext ); - - /* This job is finished, clear its pointer. */ - pJob = NULL; - userCallback = NULL; - } - - /* Acquire the lock before updating the job status. */ - taskENTER_CRITICAL(); - { - /* Try and dequeue the next job in the dispatch queue. */ - IotLink_t * pItem = NULL; - - /* Dequeue the next job from the dispatch queue. */ - pItem = IotDeQueue_DequeueHead( &pTaskPool->dispatchQueue ); - - /* If there is no job left in the dispatch queue, update the worker status and leave. */ - if( pItem == NULL ) - { - taskEXIT_CRITICAL(); - - /* Abandon the INNER LOOP. Execution will transfer back to the OUTER LOOP condition. */ - break; - } - else - { - pJob = IotLink_Container( _taskPoolJob_t, pItem, link ); - - userCallback = pJob->userCallback; - } - - pJob->status = IOT_TASKPOOL_STATUS_COMPLETED; - } - taskEXIT_CRITICAL(); - } - } -} - -/* ---------------------------------------------------------------------------------------------- */ - -static void _initJobsCache( _taskPoolCache_t * const pCache ) -{ - IotDeQueue_Create( &pCache->freeList ); - - pCache->freeCount = 0; -} - -/*-----------------------------------------------------------*/ - -static void _initializeJob( _taskPoolJob_t * const pJob, - IotTaskPoolRoutine_t userCallback, - void * pUserContext, - bool isStatic ) -{ - pJob->link.pNext = NULL; - pJob->link.pPrevious = NULL; - pJob->userCallback = userCallback; - pJob->pUserContext = pUserContext; - - if( isStatic ) - { - pJob->flags = IOT_TASK_POOL_INTERNAL_STATIC; - pJob->status = IOT_TASKPOOL_STATUS_READY; - } - else - { - pJob->status = IOT_TASKPOOL_STATUS_READY; - } -} - -static _taskPoolJob_t * _fetchOrAllocateJob( _taskPoolCache_t * const pCache ) -{ - _taskPoolJob_t * pJob = NULL; - IotLink_t * pLink = IotListDouble_RemoveHead( &( pCache->freeList ) ); - - if( pLink != NULL ) - { - pJob = IotLink_Container( _taskPoolJob_t, pLink, link ); - } - - /* If there is no available job in the cache, then allocate one. */ - if( pJob == NULL ) - { - pJob = ( _taskPoolJob_t * ) IotTaskPool_MallocJob( sizeof( _taskPoolJob_t ) ); - - if( pJob != NULL ) - { - memset( pJob, 0x00, sizeof( _taskPoolJob_t ) ); - } - else - { - /* Log allocation failure for troubleshooting purposes. */ - IotLogInfo( "Failed to allocate job." ); - } - } - /* If there was a job in the cache, then make sure we keep the counters up-to-date. */ - else - { - IotTaskPool_Assert( pCache->freeCount > 0 ); - - pCache->freeCount--; - } - - return pJob; -} - -/*-----------------------------------------------------------*/ - -static void _recycleJob( _taskPoolCache_t * const pCache, - _taskPoolJob_t * const pJob ) -{ - /* We should never try and recycling a job that is linked into some queue. */ - IotTaskPool_Assert( IotLink_IsLinked( &pJob->link ) == false );//_RB_ Seems to be duplicate of test before this is called. - - /* We will recycle the job if there is space in the cache. */ - if( pCache->freeCount < IOT_TASKPOOL_JOBS_RECYCLE_LIMIT ) - { - /* Destroy user data, for added safety&security. */ - pJob->userCallback = NULL; - pJob->pUserContext = NULL; - - /* Reset the status for added debuggability. */ - pJob->status = IOT_TASKPOOL_STATUS_UNDEFINED; - - IotListDouble_InsertTail( &pCache->freeList, &pJob->link ); - - pCache->freeCount++; - - IotTaskPool_Assert( pCache->freeCount >= 1 ); - } - else - { - _destroyJob( pJob ); - } -} - -/*-----------------------------------------------------------*/ - -static void _destroyJob( _taskPoolJob_t * const pJob ) -{ - /* Destroy user data, for added safety & security. */ - pJob->userCallback = NULL; - pJob->pUserContext = NULL; - - /* Reset the status for added debuggability. */ - pJob->status = IOT_TASKPOOL_STATUS_UNDEFINED; - - /* Only dispose of dynamically allocated jobs. */ - if( ( pJob->flags & IOT_TASK_POOL_INTERNAL_STATIC ) == 0UL ) - { - IotTaskPool_FreeJob( pJob ); - } -} - -/* ---------------------------------------------------------------------------------------------- */ - -static IotTaskPoolError_t _scheduleInternal( _taskPool_t * const pTaskPool, - _taskPoolJob_t * const pJob ) -{ - TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS ); - - /* Update the job status to 'scheduled'. */ - pJob->status = IOT_TASKPOOL_STATUS_SCHEDULED; - - /* Append the job to the dispatch queue. */ - IotDeQueue_EnqueueTail( &pTaskPool->dispatchQueue, &pJob->link ); - - /* Signal a worker to pick up the job. */ - xSemaphoreGive( pTaskPool->dispatchSignal ); - - TASKPOOL_NO_FUNCTION_CLEANUP_NOLABEL(); -} - -/*-----------------------------------------------------------*/ - -static bool _matchJobByPointer( const IotLink_t * const pLink, - void * pMatch ) -{ - const _taskPoolJob_t * const pJob = ( _taskPoolJob_t * ) pMatch; - - const _taskPoolTimerEvent_t * const pTimerEvent = IotLink_Container( _taskPoolTimerEvent_t, pLink, link ); - - if( pJob == pTimerEvent->job ) - { - return true; - } - - return false; -} - -/*-----------------------------------------------------------*/ - -static IotTaskPoolError_t _tryCancelInternal( _taskPool_t * const pTaskPool, - _taskPoolJob_t * const pJob, - IotTaskPoolJobStatus_t * const pStatus ) -{ - TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS ); - - bool cancelable = false; - - /* We can only cancel jobs that are either 'ready' (waiting to be scheduled). 'deferred', or 'scheduled'. */ - - IotTaskPoolJobStatus_t currentStatus = pJob->status; - - switch( currentStatus ) - { - case IOT_TASKPOOL_STATUS_READY: - case IOT_TASKPOOL_STATUS_DEFERRED: - case IOT_TASKPOOL_STATUS_SCHEDULED: - case IOT_TASKPOOL_STATUS_CANCELED: - cancelable = true; - break; - - case IOT_TASKPOOL_STATUS_COMPLETED: - /* Log message for debug purposes. */ - IotLogWarn( "Attempt to cancel a job that is already executing, or canceled." ); - break; - - default: - /* Log message for debug purposes purposes. */ - IotLogError( "Attempt to cancel a job with an undefined state." ); - break; - } - - /* Update the returned status to the current status of the job. */ - if( pStatus != NULL ) - { - *pStatus = currentStatus; - } - - if( cancelable == false ) - { - TASKPOOL_SET_AND_GOTO_CLEANUP( IOT_TASKPOOL_CANCEL_FAILED ); - } - else - { - /* Update the status of the job. */ - pJob->status = IOT_TASKPOOL_STATUS_CANCELED; - - /* If the job is cancelable and its current status is 'scheduled' then unlink it from the dispatch - * queue and signal any waiting threads. */ - if( currentStatus == IOT_TASKPOOL_STATUS_SCHEDULED ) - { - /* A scheduled work items must be in the dispatch queue. */ - IotTaskPool_Assert( IotLink_IsLinked( &pJob->link ) ); - - IotDeQueue_Remove( &pJob->link ); - } - - /* If the job current status is 'deferred' then the job has to be pending - * in the timeouts queue. */ - else if( currentStatus == IOT_TASKPOOL_STATUS_DEFERRED ) - { - /* Find the timer event associated with the current job. There MUST be one, hence assert if not. */ - IotLink_t * pTimerEventLink = IotListDouble_FindFirstMatch( &pTaskPool->timerEventsList, NULL, _matchJobByPointer, pJob ); - IotTaskPool_Assert( pTimerEventLink != NULL ); - - if( pTimerEventLink != NULL ) - { - bool shouldReschedule = false; - - /* If the job being canceled was at the head of the timeouts queue, then we need to reschedule the timer - * with the next job timeout */ - IotLink_t * pHeadLink = IotListDouble_PeekHead( &pTaskPool->timerEventsList ); - - if( pHeadLink == pTimerEventLink ) - { - shouldReschedule = true; - } - - /* Remove the timer event associated with the canceled job and free the associated memory. */ - IotListDouble_Remove( pTimerEventLink ); - IotTaskPool_FreeTimerEvent( IotLink_Container( _taskPoolTimerEvent_t, pTimerEventLink, link ) ); - - if( shouldReschedule ) - { - IotLink_t * pNextTimerEventLink = IotListDouble_PeekHead( &pTaskPool->timerEventsList ); - - if( pNextTimerEventLink != NULL ) - { - _rescheduleDeferredJobsTimer( pTaskPool->timer, IotLink_Container( _taskPoolTimerEvent_t, pNextTimerEventLink, link ) ); - } - } - } - } - else - { - /* A cancelable job status should be either 'scheduled' or 'deferrred'. */ - IotTaskPool_Assert( ( currentStatus == IOT_TASKPOOL_STATUS_READY ) || ( currentStatus == IOT_TASKPOOL_STATUS_CANCELED ) ); - } - } - - TASKPOOL_NO_FUNCTION_CLEANUP(); -} - -/*-----------------------------------------------------------*/ - -static int32_t _timerEventCompare( const IotLink_t * const pTimerEventLink1, - const IotLink_t * const pTimerEventLink2 ) -{ - const _taskPoolTimerEvent_t * const pTimerEvent1 = IotLink_Container( _taskPoolTimerEvent_t, - pTimerEventLink1, - link ); - const _taskPoolTimerEvent_t * const pTimerEvent2 = IotLink_Container( _taskPoolTimerEvent_t, - pTimerEventLink2, - link ); - - if( pTimerEvent1->expirationTime < pTimerEvent2->expirationTime ) - { - return -1; - } - - if( pTimerEvent1->expirationTime > pTimerEvent2->expirationTime ) - { - return 1; - } - - return 0; -} - -/*-----------------------------------------------------------*/ - -static void _rescheduleDeferredJobsTimer( TimerHandle_t const timer, - _taskPoolTimerEvent_t * const pFirstTimerEvent ) -{ - uint64_t delta = 0; - TickType_t now = xTaskGetTickCount(); - - if( pFirstTimerEvent->expirationTime > now ) - { - delta = pFirstTimerEvent->expirationTime - now; - } - - if( delta < TASKPOOL_JOB_RESCHEDULE_DELAY_MS ) - { - delta = TASKPOOL_JOB_RESCHEDULE_DELAY_MS; /* The job will be late... */ - } - - IotTaskPool_Assert( delta > 0 ); - - if( xTimerChangePeriod( timer, ( uint32_t ) delta, portMAX_DELAY ) == pdFAIL ) - { - IotLogWarn( "Failed to re-arm timer for task pool" ); - } -} - -/*-----------------------------------------------------------*/ - -static void _timerCallback( TimerHandle_t xTimer ) -{ - _taskPool_t * pTaskPool = pvTimerGetTimerID( xTimer ); - - IotTaskPool_Assert( pTaskPool ); - - _taskPoolTimerEvent_t * pTimerEvent = NULL; - - IotLogDebug( "Timer thread started for task pool %p.", pTaskPool ); - - /* Attempt to lock the timer mutex. Return immediately if the mutex cannot be locked. - * If this mutex cannot be locked it means that another thread is manipulating the - * timeouts list, and will reset the timer to fire again, although it will be late. - */ - taskENTER_CRITICAL(); //_RB_ Critical section is too long. - { - /* Dispatch all deferred job whose timer expired, then reset the timer for the next - * job down the line. */ - for( ; ; ) - { - /* Peek the first event in the timer event list. */ - IotLink_t * pLink = IotListDouble_PeekHead( &pTaskPool->timerEventsList ); - - /* Check if the timer misfired for any reason. */ - if( pLink != NULL ) - { - /* Record the current time. */ - TickType_t now = xTaskGetTickCount(); - - /* Extract the job from its envelope. */ - pTimerEvent = IotLink_Container( _taskPoolTimerEvent_t, pLink, link ); - - /* Check if the first event should be processed now. */ - if( pTimerEvent->expirationTime <= now ) - { - /* Remove the timer event for immediate processing. */ - IotListDouble_Remove( &( pTimerEvent->link ) ); - } - else - { - /* The first element in the timer queue shouldn't be processed yet. - * Arm the timer for when it should be processed and leave altogether. */ - _rescheduleDeferredJobsTimer( pTaskPool->timer, pTimerEvent ); - - break; - } - } - /* If there are no timer events to process, terminate this thread. */ - else - { - IotLogDebug( "No further timer events to process. Exiting timer thread." ); - - break; - } - - IotLogDebug( "Scheduling job from timer event." ); - - /* Queue the job associated with the received timer event. */ - ( void ) _scheduleInternal( pTaskPool, pTimerEvent->job ); - - /* Free the timer event. */ - IotTaskPool_FreeTimerEvent( pTimerEvent ); - } - } - taskEXIT_CRITICAL(); -} diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/directories.txt b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/directories.txt deleted file mode 100644 index 5492b0944..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/directories.txt +++ /dev/null @@ -1,7 +0,0 @@ -+ mqtt -Contains the implementation of the MQTT library. - -+ common -Contains the implementation of utility functions used by other IoT libraries. - -Further libraries will be rolled out soon. 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 deleted file mode 100644 index dad106a68..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt.h +++ /dev/null @@ -1,823 +0,0 @@ -/* - * Amazon FreeRTOS MQTT V2.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_mqtt.h - * @brief User-facing functions of the MQTT 3.1.1 library. - */ - -#ifndef IOT_MQTT_H_ -#define IOT_MQTT_H_ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* MQTT types include. */ -#include "types/iot_mqtt_types.h" - -/*------------------------- MQTT library functions --------------------------*/ - -/** - * @functionspage{mqtt,MQTT library} - * - @functionname{mqtt_function_init} - * - @functionname{mqtt_function_cleanup} - * - @functionname{mqtt_function_receivecallback} - * - @functionname{mqtt_function_connect} - * - @functionname{mqtt_function_disconnect} - * - @functionname{mqtt_function_subscribe} - * - @functionname{mqtt_function_timedsubscribe} - * - @functionname{mqtt_function_unsubscribe} - * - @functionname{mqtt_function_timedunsubscribe} - * - @functionname{mqtt_function_publish} - * - @functionname{mqtt_function_timedpublish} - * - @functionname{mqtt_function_wait} - * - @functionname{mqtt_function_strerror} - * - @functionname{mqtt_function_operationtype} - * - @functionname{mqtt_function_issubscribed} - */ - -/** - * @functionpage{IotMqtt_Init,mqtt,init} - * @functionpage{IotMqtt_Cleanup,mqtt,cleanup} - * @functionpage{IotMqtt_ReceiveCallback,mqtt,receivecallback} - * @functionpage{IotMqtt_Connect,mqtt,connect} - * @functionpage{IotMqtt_Disconnect,mqtt,disconnect} - * @functionpage{IotMqtt_Subscribe,mqtt,subscribe} - * @functionpage{IotMqtt_TimedSubscribe,mqtt,timedsubscribe} - * @functionpage{IotMqtt_Unsubscribe,mqtt,unsubscribe} - * @functionpage{IotMqtt_TimedUnsubscribe,mqtt,timedunsubscribe} - * @functionpage{IotMqtt_Publish,mqtt,publish} - * @functionpage{IotMqtt_TimedPublish,mqtt,timedpublish} - * @functionpage{IotMqtt_Wait,mqtt,wait} - * @functionpage{IotMqtt_strerror,mqtt,strerror} - * @functionpage{IotMqtt_OperationType,mqtt,operationtype} - * @functionpage{IotMqtt_IsSubscribed,mqtt,issubscribed} - */ - -/** - * @brief One-time initialization function for the MQTT library. - * - * This function performs setup of the MQTT library. It must be called - * once (and only once) before calling any other MQTT function. Calling this - * function more than once without first calling @ref mqtt_function_cleanup - * may result in a crash. - * - * @return One of the following: - * - #IOT_MQTT_SUCCESS - * - #IOT_MQTT_INIT_FAILED - * - * @warning No thread-safety guarantees are provided for this function. - * - * @see @ref mqtt_function_cleanup - */ -/* @[declare_mqtt_init] */ -IotMqttError_t IotMqtt_Init( void ); -/* @[declare_mqtt_init] */ - -/** - * @brief One-time deinitialization function for the MQTT library. - * - * This function frees resources taken in @ref mqtt_function_init. It should be - * called after [closing all MQTT connections](@ref mqtt_function_disconnect) to - * clean up the MQTT library. After this function returns, @ref mqtt_function_init - * must be called again before calling any other MQTT function. - * - * @warning No thread-safety guarantees are provided for this function. Do not - * call this function if any MQTT connections are open! - * - * @see @ref mqtt_function_init - */ -/* @[declare_mqtt_cleanup] */ -void IotMqtt_Cleanup( void ); -/* @[declare_mqtt_cleanup] */ - -/** - * @brief Network receive callback for the MQTT library. - * - * This function should be called by the system whenever data is available for - * the MQTT library. - * - * @param[in] pNetworkConnection The network connection associated with the MQTT - * connection, passed by the network stack. - * @param[in] pReceiveContext A pointer to the MQTT connection handle for which - * the packet was received. - */ -/* @[declare_mqtt_receivecallback] */ -void IotMqtt_ReceiveCallback( void * pNetworkConnection, - void * pReceiveContext ); -/* @[declare_mqtt_receivecallback] */ - -/** - * @brief Establish a new MQTT connection. - * - * This function opens a connection between a new MQTT client and an MQTT server - * (also called a broker). MQTT connections are established on top of transport - * layer protocols (such as TCP/IP), and optionally, application layer security - * protocols (such as TLS). The MQTT packet that establishes a connection is called - * the MQTT CONNECT packet. After @ref mqtt_function_init, this function must be - * called before any other MQTT library function. - * - * If [pConnectInfo->cleanSession](@ref IotMqttConnectInfo_t.cleanSession) is `true`, - * this function establishes a clean MQTT session. Subscriptions and unacknowledged - * PUBLISH messages will be discarded when the connection is closed. - * - * If [pConnectInfo->cleanSession](@ref IotMqttConnectInfo_t.cleanSession) is `false`, - * this function establishes (or re-establishes) a persistent MQTT session. The parameters - * [pConnectInfo->pPreviousSubscriptions](@ref IotMqttConnectInfo_t.pPreviousSubscriptions) - * and [pConnectInfo->previousSubscriptionCount](@ref IotMqttConnectInfo_t.previousSubscriptionCount) - * may be used to restore subscriptions present in a re-established persistent session. - * Any restored subscriptions MUST have been present in the persistent session; - * this function does not send an MQTT SUBSCRIBE packet! - * - * This MQTT library is network agnostic, meaning it has no knowledge of the - * underlying network protocol carrying the MQTT packets. It interacts with the - * network through a network abstraction layer, allowing it to be used with many - * different network stacks. The network abstraction layer is established - * per-connection, allowing every #IotMqttConnection_t to use a different network - * stack. The parameter `pNetworkInterface` sets up the network abstraction layer - * for an MQTT connection; see the documentation on #IotMqttNetworkInfo_t for details - * on its members. - * - * The `pConnectInfo` parameter provides the contents of the MQTT CONNECT packet. - * Most members [are defined by the MQTT spec.](@ref IotMqttConnectInfo_t). The - * [pConnectInfo->pWillInfo](@ref IotMqttConnectInfo_t.pWillInfo) member provides - * information on a Last Will and Testament (LWT) message to be published if the - * MQTT connection is closed without [sending a DISCONNECT packet] - * (@ref mqtt_function_disconnect). Unlike other PUBLISH - * messages, a LWT message payload is limited to 65535 bytes in length. Additionally, - * the retry [interval](@ref IotMqttPublishInfo_t.retryMs) and [limit] - * (@ref IotMqttPublishInfo_t.retryLimit) members of #IotMqttPublishInfo_t - * are ignored for LWT messages. The LWT message is optional; `pWillInfo` may be NULL. - * - * Unlike @ref mqtt_function_publish, @ref mqtt_function_subscribe, and - * @ref mqtt_function_unsubscribe, this function is always blocking. Additionally, - * because the MQTT connection acknowledgement packet (CONNACK packet) does not - * contain any information on which CONNECT packet it acknowledges, only one - * CONNECT operation may be in progress at any time. This means that parallel - * threads making calls to @ref mqtt_function_connect will be serialized to send - * their CONNECT packets one-by-one. - * - * @param[in] pNetworkInfo Information on the transport-layer network connection - * to use with the MQTT connection. - * @param[in] pConnectInfo MQTT connection setup parameters. - * @param[in] timeoutMs If the MQTT server does not accept the connection within - * this timeout, this function returns #IOT_MQTT_TIMEOUT. - * @param[out] pMqttConnection Set to a newly-initialized MQTT connection handle - * if this function succeeds. - * - * @return One of the following: - * - #IOT_MQTT_SUCCESS - * - #IOT_MQTT_BAD_PARAMETER - * - #IOT_MQTT_NO_MEMORY - * - #IOT_MQTT_NETWORK_ERROR - * - #IOT_MQTT_SCHEDULING_ERROR - * - #IOT_MQTT_BAD_RESPONSE - * - #IOT_MQTT_TIMEOUT - * - #IOT_MQTT_SERVER_REFUSED - * - * Example - * @code{c} - * // An initialized and connected network connection. - * IotNetworkConnection_t pNetworkConnection; - * - * // Parameters to MQTT connect. - * IotMqttConnection_t mqttConnection = IOT_MQTT_CONNECTION_INITIALIZER; - * IotMqttNetworkInfo_t networkInfo = IOT_MQTT_NETWORK_INFO_INITIALIZER; - * IotMqttConnectInfo_t connectInfo = IOT_MQTT_CONNECT_INFO_INITIALIZER; - * IotMqttPublishInfo_t willInfo = IOT_MQTT_PUBLISH_INFO_INITIALIZER; - * - * // Example network abstraction types. - * IotNetworkServerInfo_t serverInfo = { ... }; - * IotNetworkCredentialInfo_t credentialInfo = { ... }; - * IotNetworkInterface_t networkInterface = { ... }; - * - * // Example using a generic network implementation. - * networkInfo.createNetworkConnection = true; - * networkInfo.pNetworkServerInfo = &serverInfo; - * networkInfo.pNetworkCredentialInfo = &credentialInfo; - * networkInfo.pNetworkInterface = &networkInterface; - * - * // Set the members of the connection info (password and username not used). - * connectInfo.cleanSession = true; - * connectInfo.keepAliveSeconds = 30; - * connectInfo.pClientIdentifier = "uniqueclientidentifier"; - * connectInfo.clientIdentifierLength = 22; - * - * // Set the members of the will info (retain and retry not used). - * willInfo.qos = IOT_MQTT_QOS_1; - * willInfo.pTopicName = "will/topic/name"; - * willInfo.topicNameLength = 15; - * willInfo.pPayload = "MQTT client unexpectedly disconnected."; - * willInfo.payloadLength = 38; - * - * // Set the pointer to the will info. - * connectInfo.pWillInfo = &willInfo; - * - * // Call CONNECT with a 5 second block time. Should return - * // IOT_MQTT_SUCCESS when successful. - * IotMqttError_t result = IotMqtt_Connect( &networkInfo, - * &connectInfo, - * 5000, - * &mqttConnection ); - * - * if( result == IOT_MQTT_SUCCESS ) - * { - * // Do something with the MQTT connection... - * - * // Clean up and close the MQTT connection once it's no longer needed. - * IotMqtt_Disconnect( mqttConnection, 0 ); - * } - * @endcode - */ -/* @[declare_mqtt_connect] */ -IotMqttError_t IotMqtt_Connect( const IotMqttNetworkInfo_t * pNetworkInfo, - const IotMqttConnectInfo_t * pConnectInfo, - uint32_t timeoutMs, - IotMqttConnection_t * const pMqttConnection ); -/* @[declare_mqtt_connect] */ - -/** - * @brief Closes an MQTT connection and frees resources. - * - * This function closes an MQTT connection and should only be called once - * the MQTT connection is no longer needed. Its exact behavior depends on the - * `flags` parameter. - * - * Normally, `flags` should be `0`. This gracefully shuts down an MQTT - * connection by sending an MQTT DISCONNECT packet. Any [network close function] - * (@ref IotNetworkInterface_t::close) provided [when the connection was established] - * (@ref mqtt_function_connect) will also be called. Note that because the MQTT server - * will not acknowledge a DISCONNECT packet, the client has no way of knowing if - * the server received the DISCONNECT packet. In the case where the DISCONNECT - * packet is lost in transport, any Last Will and Testament (LWT) message established - * with the connection may be published. However, if the DISCONNECT reaches the - * MQTT server, the LWT message will be discarded and not published. - * - * Should the underlying network connection become unusable, this function should - * be called with `flags` set to #IOT_MQTT_FLAG_CLEANUP_ONLY. In this case, no - * DISCONNECT packet will be sent, though the [network close function](@ref IotNetworkInterface_t::close) - * will still be called. This function will only free the resources used by the MQTT - * connection; it still must be called even if the network is offline to avoid leaking - * resources. - * - * Once this function is called, its parameter `mqttConnection` should no longer - * be used. - * - * @param[in] mqttConnection The MQTT connection to close and clean up. - * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags. - */ -/* @[declare_mqtt_disconnect] */ -void IotMqtt_Disconnect( IotMqttConnection_t mqttConnection, - uint32_t flags ); -/* @[declare_mqtt_disconnect] */ - -/** - * @brief Subscribes to the given array of topic filters and receive an asynchronous - * notification when the subscribe completes. - * - * This function transmits an MQTT SUBSCRIBE packet to the server. A SUBSCRIBE - * packet notifies the server to send any matching PUBLISH messages to this client. - * A single SUBSCRIBE packet may carry more than one topic filter, hence the - * parameters to this function include an array of [subscriptions] - * (@ref IotMqttSubscription_t). - * - * An MQTT subscription has two pieces: - * 1. The subscription topic filter registered with the MQTT server. The MQTT - * SUBSCRIBE packet sent from this client to server notifies the server to send - * messages matching the given topic filters to this client. - * 2. The [callback function](@ref IotMqttCallbackInfo_t.function) that this - * client will invoke when an incoming message is received. The callback function - * notifies applications of an incoming PUBLISH message. - * - * The helper function @ref mqtt_function_issubscribed can be used to check if a - * [callback function](@ref IotMqttCallbackInfo_t.function) is registered for - * a particular topic filter. - * - * To modify an already-registered subscription callback, call this function with - * a new `pSubscriptionList`. Any topic filters in `pSubscriptionList` that already - * have a registered callback will be replaced with the new values in `pSubscriptionList`. - * - * @attention QoS 2 subscriptions are currently unsupported. Only 0 or 1 are valid - * for subscription QoS. - * - * @param[in] mqttConnection The MQTT connection to use for the subscription. - * @param[in] pSubscriptionList Pointer to the first element in the array of - * subscriptions. - * @param[in] subscriptionCount The number of elements in pSubscriptionList. - * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags. - * @param[in] pCallbackInfo Asynchronous notification of this function's completion. - * @param[out] pSubscribeOperation Set to a handle by which this operation may be - * referenced after this function returns. This reference is invalidated once - * the subscription operation completes. - * - * @return This function will return #IOT_MQTT_STATUS_PENDING upon success. - * @return Upon completion of the subscription (either through an - * #IotMqttCallbackInfo_t or @ref mqtt_function_wait), the status will be one of: - * - #IOT_MQTT_SUCCESS - * - #IOT_MQTT_NETWORK_ERROR - * - #IOT_MQTT_SCHEDULING_ERROR - * - #IOT_MQTT_BAD_RESPONSE - * - #IOT_MQTT_SERVER_REFUSED - * @return If this function fails before queuing a subscribe operation, it will return - * one of: - * - #IOT_MQTT_BAD_PARAMETER - * - #IOT_MQTT_NO_MEMORY - * - * @see @ref mqtt_function_timedsubscribe for a blocking variant of this function. - * @see @ref mqtt_function_unsubscribe for the function that removes subscriptions. - * - * Example - * @code{c} - * #define NUMBER_OF_SUBSCRIPTIONS ... - * - * // Subscription callback function. - * void subscriptionCallback( void * pArgument, IotMqttCallbackParam_t * pPublish ); - * - * // An initialized and connected MQTT connection. - * IotMqttConnection_t mqttConnection; - * - * // Subscription information. - * pSubscriptions[ NUMBER_OF_SUBSCRIPTIONS ] = { IOT_MQTT_SUBSCRIPTION_INITIALIZER }; - * IotMqttOperation_t lastOperation = IOT_MQTT_OPERATION_INITIALIZER; - * - * // Set the subscription information. - * for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ ) - * { - * pSubscriptions[ i ].qos = IOT_MQTT_QOS_1; - * pSubscriptions[ i ].pTopicFilter = "some/topic/filter"; - * pSubscriptions[ i ].topicLength = ( uint16_t ) strlen( pSubscriptions[ i ].pTopicFilter ); - * pSubscriptions[ i ].callback.function = subscriptionCallback; - * } - * - * IotMqttError_t result = IotMqtt_Subscribe( mqttConnection, - * pSubscriptions, - * NUMBER_OF_SUBSCRIPTIONS, - * IOT_MQTT_FLAG_WAITABLE, - * NULL, - * &lastOperation ); - * - * // Subscribe returns IOT_MQTT_STATUS_PENDING when successful. Wait up to - * // 5 seconds for the operation to complete. - * if( result == IOT_MQTT_STATUS_PENDING ) - * { - * result = IotMqtt_Wait( subscriptionRef, 5000 ); - * } - * - * // Check that the subscriptions were successful. - * if( result == IOT_MQTT_SUCCESS ) - * { - * // Wait for messages on the subscription topic filters... - * - * // Unsubscribe once the subscriptions are no longer needed. - * result = IotMqtt_Unsubscribe( mqttConnection, - * pSubscriptions, - * NUMBER_OF_SUBSCRIPTIONS, - * IOT_MQTT_FLAG_WAITABLE, - * NULL, - * &lastOperation ); - * - * // UNSUBSCRIBE returns IOT_MQTT_STATUS_PENDING when successful. - * // Wait up to 5 seconds for the operation to complete. - * if( result == IOT_MQTT_STATUS_PENDING ) - * { - * result = IotMqtt_Wait( lastOperation, 5000 ); - * } - * } - * // Check which subscriptions were rejected by the server. - * else if( result == IOT_MQTT_SERVER_REFUSED ) - * { - * for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ ) - * { - * if( IotMqtt_IsSubscribed( mqttConnection, - * pSubscriptions[ i ].pTopicFilter, - * pSubscriptions[ i ].topicFilterLength, - * NULL ) == false ) - * { - * // This subscription was rejected. - * } - * } - * } - * @endcode - */ -/* @[declare_mqtt_subscribe] */ -IotMqttError_t IotMqtt_Subscribe( IotMqttConnection_t mqttConnection, - const IotMqttSubscription_t * pSubscriptionList, - size_t subscriptionCount, - uint32_t flags, - const IotMqttCallbackInfo_t * pCallbackInfo, - IotMqttOperation_t * const pSubscribeOperation ); -/* @[declare_mqtt_subscribe] */ - -/** - * @brief Subscribes to the given array of topic filters with a timeout. - * - * This function transmits an MQTT SUBSCRIBE packet to the server, then waits for - * a server response to the packet. Internally, this function is a call to @ref - * mqtt_function_subscribe followed by @ref mqtt_function_wait. See @ref - * mqtt_function_subscribe for more information about the MQTT SUBSCRIBE operation. - * - * @attention QoS 2 subscriptions are currently unsupported. Only 0 or 1 are valid - * for subscription QoS. - * - * @param[in] mqttConnection The MQTT connection to use for the subscription. - * @param[in] pSubscriptionList Pointer to the first element in the array of - * subscriptions. - * @param[in] subscriptionCount The number of elements in pSubscriptionList. - * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags. - * Currently, flags are ignored by this function; this parameter is for - * future-compatibility. - * @param[in] timeoutMs If the MQTT server does not acknowledge the subscriptions within - * this timeout, this function returns #IOT_MQTT_TIMEOUT. - * - * @return One of the following: - * - #IOT_MQTT_SUCCESS - * - #IOT_MQTT_BAD_PARAMETER - * - #IOT_MQTT_NO_MEMORY - * - #IOT_MQTT_NETWORK_ERROR - * - #IOT_MQTT_SCHEDULING_ERROR - * - #IOT_MQTT_BAD_RESPONSE - * - #IOT_MQTT_TIMEOUT - * - #IOT_MQTT_SERVER_REFUSED - */ -/* @[declare_mqtt_timedsubscribe] */ -IotMqttError_t IotMqtt_TimedSubscribe( IotMqttConnection_t mqttConnection, - const IotMqttSubscription_t * pSubscriptionList, - size_t subscriptionCount, - uint32_t flags, - uint32_t timeoutMs ); -/* @[declare_mqtt_timedsubscribe] */ - -/** - * @brief Unsubscribes from the given array of topic filters and receive an asynchronous - * notification when the unsubscribe completes. - * - * This function transmits an MQTT UNSUBSCRIBE packet to the server. An UNSUBSCRIBE - * packet removes registered topic filters from the server. After unsubscribing, - * the server will no longer send messages on these topic filters to the client. - * - * Corresponding [subscription callback functions](@ref IotMqttCallbackInfo_t.function) - * are also removed from the MQTT connection. These subscription callback functions - * will be removed even if the MQTT UNSUBSCRIBE packet fails to send. - * - * @param[in] mqttConnection The MQTT connection used for the subscription. - * @param[in] pSubscriptionList Pointer to the first element in the array of - * subscriptions. - * @param[in] subscriptionCount The number of elements in pSubscriptionList. - * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags. - * @param[in] pCallbackInfo Asynchronous notification of this function's completion. - * @param[out] pUnsubscribeOperation Set to a handle by which this operation may be - * referenced after this function returns. This reference is invalidated once - * the unsubscribe operation completes. - * - * @return This function will return #IOT_MQTT_STATUS_PENDING upon success. - * @return Upon completion of the unsubscribe (either through an - * #IotMqttCallbackInfo_t or @ref mqtt_function_wait), the status will be one of: - * - #IOT_MQTT_SUCCESS - * - #IOT_MQTT_NETWORK_ERROR - * - #IOT_MQTT_SCHEDULING_ERROR - * - #IOT_MQTT_BAD_RESPONSE - * @return If this function fails before queuing an unsubscribe operation, it will return - * one of: - * - #IOT_MQTT_BAD_PARAMETER - * - #IOT_MQTT_NO_MEMORY - * - * @see @ref mqtt_function_timedsubscribe for a blocking variant of this function. - * @see @ref mqtt_function_subscribe for the function that adds subscriptions. - */ -/* @[declare_mqtt_unsubscribe] */ -IotMqttError_t IotMqtt_Unsubscribe( IotMqttConnection_t mqttConnection, - const IotMqttSubscription_t * pSubscriptionList, - size_t subscriptionCount, - uint32_t flags, - const IotMqttCallbackInfo_t * pCallbackInfo, - IotMqttOperation_t * const pUnsubscribeOperation ); -/* @[declare_mqtt_unsubscribe] */ - -/** - * @brief Unsubscribes from a given array of topic filters with a timeout. - * - * This function transmits an MQTT UNSUBSCRIBE packet to the server, then waits - * for a server response to the packet. Internally, this function is a call to - * @ref mqtt_function_unsubscribe followed by @ref mqtt_function_wait. See @ref - * mqtt_function_unsubscribe for more information about the MQTT UNSUBSCRIBE - * operation. - * - * @param[in] mqttConnection The MQTT connection used for the subscription. - * @param[in] pSubscriptionList Pointer to the first element in the array of - * subscriptions. - * @param[in] subscriptionCount The number of elements in pSubscriptionList. - * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags. - * Currently, flags are ignored by this function; this parameter is for - * future-compatibility. - * @param[in] timeoutMs If the MQTT server does not acknowledge the UNSUBSCRIBE within - * this timeout, this function returns #IOT_MQTT_TIMEOUT. - * - * @return One of the following: - * - #IOT_MQTT_SUCCESS - * - #IOT_MQTT_BAD_PARAMETER - * - #IOT_MQTT_NO_MEMORY - * - #IOT_MQTT_NETWORK_ERROR - * - #IOT_MQTT_SCHEDULING_ERROR - * - #IOT_MQTT_BAD_RESPONSE - */ -/* @[declare_mqtt_timedunsubscribe] */ -IotMqttError_t IotMqtt_TimedUnsubscribe( IotMqttConnection_t mqttConnection, - const IotMqttSubscription_t * pSubscriptionList, - size_t subscriptionCount, - uint32_t flags, - uint32_t timeoutMs ); -/* @[declare_mqtt_timedunsubscribe] */ - -/** - * @brief Publishes a message to the given topic name and receive an asynchronous - * notification when the publish completes. - * - * This function transmits an MQTT PUBLISH packet to the server. A PUBLISH packet - * contains a payload and a topic name. Any clients with a subscription on a - * topic filter matching the PUBLISH topic name will receive a copy of the - * PUBLISH packet from the server. - * - * If a PUBLISH packet fails to reach the server and it is not a QoS 0 message, - * it will be retransmitted. See #IotMqttPublishInfo_t for a description - * of the retransmission strategy. - * - * @attention QoS 2 messages are currently unsupported. Only 0 or 1 are valid - * for message QoS. - * - * @param[in] mqttConnection The MQTT connection to use for the publish. - * @param[in] pPublishInfo MQTT publish parameters. - * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags. - * @param[in] pCallbackInfo Asynchronous notification of this function's completion. - * @param[out] pPublishOperation Set to a handle by which this operation may be - * referenced after this function returns. This reference is invalidated once - * the publish operation completes. - * - * @return This function will return #IOT_MQTT_STATUS_PENDING upon success for - * QoS 1 publishes. For a QoS 0 publish it returns #IOT_MQTT_SUCCESS upon - * success. - * @return Upon completion of a QoS 1 publish (either through an - * #IotMqttCallbackInfo_t or @ref mqtt_function_wait), the status will be one of: - * - #IOT_MQTT_SUCCESS - * - #IOT_MQTT_NETWORK_ERROR - * - #IOT_MQTT_SCHEDULING_ERROR - * - #IOT_MQTT_BAD_RESPONSE - * - #IOT_MQTT_RETRY_NO_RESPONSE (if [pPublishInfo->retryMs](@ref IotMqttPublishInfo_t.retryMs) - * and [pPublishInfo->retryLimit](@ref IotMqttPublishInfo_t.retryLimit) were set). - * @return If this function fails before queuing an publish operation (regardless - * of QoS), it will return one of: - * - #IOT_MQTT_BAD_PARAMETER - * - #IOT_MQTT_NO_MEMORY - * - * @note The parameters `pCallbackInfo` and `pPublishOperation` should only be used for QoS - * 1 publishes. For QoS 0, they should both be `NULL`. - * - * @see @ref mqtt_function_timedpublish for a blocking variant of this function. - * - * Example - * @code{c} - * // An initialized and connected MQTT connection. - * IotMqttConnection_t mqttConnection; - * - * // Publish information. - * IotMqttPublishInfo_t publishInfo = IOT_MQTT_PUBLISH_INFO_INITIALIZER; - * - * // Set the publish information. QoS 0 example (retain not used): - * publishInfo.qos = IOT_MQTT_QOS_0; - * publishInfo.pTopicName = "some/topic/name"; - * publishInfo.topicNameLength = 15; - * publishInfo.pPayload = "payload"; - * publishInfo.payloadLength = 8; - * - * // QoS 0 publish should return IOT_MQTT_SUCCESS upon success. - * IotMqttError_t qos0Result = IotMqtt_Publish( mqttConnection, - * &publishInfo, - * 0, - * NULL, - * NULL ); - * - * // QoS 1 with retry example (using same topic name and payload as QoS 0 example): - * IotMqttOperation_t qos1Operation = IOT_MQTT_OPERATION_INITIALIZER; - * publishInfo.qos = IOT_MQTT_QOS_1; - * publishInfo.retryMs = 1000; // Retry if no response is received in 1 second. - * publishInfo.retryLimit = 5; // Retry up to 5 times. - * - * // QoS 1 publish should return IOT_MQTT_STATUS_PENDING upon success. - * IotMqttError_t qos1Result = IotMqtt_Publish( mqttConnection, - * &publishInfo, - * IOT_MQTT_FLAG_WAITABLE, - * NULL, - * &qos1Operation ); - * - * // Wait up to 5 seconds for the publish to complete. - * if( qos1Result == IOT_MQTT_STATUS_PENDING ) - * { - * qos1Result = IotMqtt_Wait( qos1Operation, 5000 ); - * } - * @endcode - */ -/* @[declare_mqtt_publish] */ -IotMqttError_t IotMqtt_Publish( IotMqttConnection_t mqttConnection, - const IotMqttPublishInfo_t * pPublishInfo, - uint32_t flags, - const IotMqttCallbackInfo_t * pCallbackInfo, - IotMqttOperation_t * const pPublishOperation ); -/* @[declare_mqtt_publish] */ - -/** - * @brief Publish a message to the given topic name with a timeout. - * - * This function transmits an MQTT PUBLISH packet to the server, then waits for - * a server response to the packet. Internally, this function is a call to @ref - * mqtt_function_publish followed by @ref mqtt_function_wait. See @ref - * mqtt_function_publish for more information about the MQTT PUBLISH operation. - * - * @attention QoS 2 messages are currently unsupported. Only 0 or 1 are valid - * for message QoS. - * - * @param[in] mqttConnection The MQTT connection to use for the publish. - * @param[in] pPublishInfo MQTT publish parameters. - * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags. - * Currently, flags are ignored by this function; this parameter is for - * future-compatibility. - * @param[in] timeoutMs If the MQTT server does not acknowledge a QoS 1 PUBLISH - * within this timeout, this function returns #IOT_MQTT_TIMEOUT. This parameter - * is ignored for QoS 0 PUBLISH messages. - * - * @return One of the following: - * - #IOT_MQTT_SUCCESS - * - #IOT_MQTT_BAD_PARAMETER - * - #IOT_MQTT_NO_MEMORY - * - #IOT_MQTT_NETWORK_ERROR - * - #IOT_MQTT_SCHEDULING_ERROR - * - #IOT_MQTT_BAD_RESPONSE - * - #IOT_MQTT_RETRY_NO_RESPONSE (if [pPublishInfo->retryMs](@ref IotMqttPublishInfo_t.retryMs) - * and [pPublishInfo->retryLimit](@ref IotMqttPublishInfo_t.retryLimit) were set). - */ -/* @[declare_mqtt_timedpublish] */ -IotMqttError_t IotMqtt_TimedPublish( IotMqttConnection_t mqttConnection, - const IotMqttPublishInfo_t * pPublishInfo, - uint32_t flags, - uint32_t timeoutMs ); -/* @[declare_mqtt_timedpublish] */ - -/** - * @brief Waits for an operation to complete. - * - * This function blocks to wait for a [subscribe](@ref mqtt_function_subscribe), - * [unsubscribe](@ref mqtt_function_unsubscribe), or [publish] - * (@ref mqtt_function_publish) to complete. These operations are by default - * asynchronous; the function calls queue an operation for processing, and a - * callback is invoked once the operation is complete. - * - * To use this function, the flag #IOT_MQTT_FLAG_WAITABLE must have been - * set in the operation's function call. Additionally, this function must always - * be called with any waitable operation to clean up resources. - * - * Regardless of its return value, this function always clean up resources used - * by the waitable operation. This means `reference` is invalidated as soon as - * this function returns, even if it returns #IOT_MQTT_TIMEOUT or another error. - * - * @param[in] operation Reference to the operation to wait for. The flag - * #IOT_MQTT_FLAG_WAITABLE must have been set for this operation. - * @param[in] timeoutMs How long to wait before returning #IOT_MQTT_TIMEOUT. - * - * @return The return value of this function depends on the MQTT operation associated - * with `reference`. See #IotMqttError_t for possible return values. - * - * Example - * @code{c} - * // Operation reference and timeout. - * IotMqttOperation_t publishOperation = IOT_MQTT_OPERATION_INITIALIZER; - * uint32_t timeoutMs = 5000; // 5 seconds - * - * // MQTT operation to wait for. - * IotMqttError_t result = IotMqtt_Publish( mqttConnection, - * &publishInfo, - * IOT_MQTT_FLAG_WAITABLE, - * NULL, - * &publishOperation ); - * - * // Publish should have returned IOT_MQTT_STATUS_PENDING. The call to wait - * // returns once the result of the publish is available or the timeout expires. - * if( result == IOT_MQTT_STATUS_PENDING ) - * { - * result = IotMqtt_Wait( publishOperation, timeoutMs ); - * - * // After the call to wait, the result of the publish is known - * // (not IOT_MQTT_STATUS_PENDING). - * assert( result != IOT_MQTT_STATUS_PENDING ); - * } - * @endcode - */ -/* @[declare_mqtt_wait] */ -IotMqttError_t IotMqtt_Wait( IotMqttOperation_t operation, - uint32_t timeoutMs ); -/* @[declare_mqtt_wait] */ - -/*-------------------------- MQTT helper functions --------------------------*/ - -/** - * @brief Returns a string that describes an #IotMqttError_t. - * - * Like the POSIX's `strerror`, this function returns a string describing a - * return code. In this case, the return code is an MQTT library error code, - * `status`. - * - * The string returned by this function MUST be treated as read-only: any - * attempt to modify its contents may result in a crash. Therefore, this function - * is limited to usage in logging. - * - * @param[in] status The status to describe. - * - * @return A read-only string that describes `status`. - * - * @warning The string returned by this function must never be modified. - */ -/* @[declare_mqtt_strerror] */ -const char * IotMqtt_strerror( IotMqttError_t status ); -/* @[declare_mqtt_strerror] */ - -/** - * @brief Returns a string that describes an #IotMqttOperationType_t. - * - * This function returns a string describing an MQTT operation type, `operation`. - * - * The string returned by this function MUST be treated as read-only: any - * attempt to modify its contents may result in a crash. Therefore, this function - * is limited to usage in logging. - * - * @param[in] operation The operation to describe. - * - * @return A read-only string that describes `operation`. - * - * @warning The string returned by this function must never be modified. - */ -/* @[declare_mqtt_operationtype] */ -const char * IotMqtt_OperationType( IotMqttOperationType_t operation ); -/* @[declare_mqtt_operationtype] */ - -/** - * @brief Check if an MQTT connection has a subscription for a topic filter. - * - * This function checks whether an MQTT connection `mqttConnection` has a - * subscription callback registered for a topic filter `pTopicFilter`. If a - * subscription callback is found, its details are copied into the output parameter - * `pCurrentSubscription`. This subscription callback will be invoked for incoming - * PUBLISH messages on `pTopicFilter`. - * - * The check for a matching subscription is only performed client-side; - * therefore, this function should not be relied upon for perfect accuracy. For - * example, this function may return an incorrect result if the MQTT server - * crashes and drops subscriptions without informing the client. - * - * Note that an MQTT connection's subscriptions might change between the time this - * function checks the subscription list and its caller tests the return value. - * This function certainly should not be used concurrently with any pending SUBSCRIBE - * or UNSUBSCRIBE operations. - * - * One suitable use of this function is to check which subscriptions were rejected - * if @ref mqtt_function_subscribe returns #IOT_MQTT_SERVER_REFUSED; that return - * code only means that at least one subscription was rejected. - * - * @param[in] mqttConnection The MQTT connection to check. - * @param[in] pTopicFilter The topic filter to check. - * @param[in] topicFilterLength Length of `pTopicFilter`. - * @param[out] pCurrentSubscription If a subscription is found, its details are - * copied here. This output parameter is only valid if this function returns `true`. - * Pass `NULL` to ignore. - * - * @return `true` if a subscription was found; `false` otherwise. - * - * @note The subscription QoS is not stored by the MQTT library; therefore, - * `pCurrentSubscription->qos` will always be set to #IOT_MQTT_QOS_0. - */ -/* @[declare_mqtt_issubscribed] */ -bool IotMqtt_IsSubscribed( IotMqttConnection_t mqttConnection, - const char * pTopicFilter, - uint16_t topicFilterLength, - IotMqttSubscription_t * const pCurrentSubscription ); -/* @[declare_mqtt_issubscribed] */ - -#endif /* ifndef IOT_MQTT_H_ */ 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 deleted file mode 100644 index fbaaeb7fb..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt_agent.h +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Amazon FreeRTOS MQTT V2.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_mqtt_agent.h - * @brief MQTT Agent Interface. - */ - -#ifndef _AWS_MQTT_AGENT_H_ -#define _AWS_MQTT_AGENT_H_ - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" - -/* MQTT lib includes. */ -#include "iot_mqtt_lib.h" - -/* Library initialization definition include */ -#include "iot_lib_init.h" - -/** - * @brief Opaque handle to represent an MQTT client. - * - * The MQTT library is capable of creating multiple MQTT clients, maximum number of which - * is controlled by mqttconfigMAX_BROKERS macro. Each client is identified by an opaque - * handle which is returned by the MQTT_AGENT_Create API call and later used in all - * the subsequent API calls. - */ -typedef void * MQTTAgentHandle_t; - -/** - * @brief Return codes. - * - * Each API returns a value of this type. - */ -typedef enum -{ - eMQTTAgentSuccess, /**< The operation was successful. */ - eMQTTAgentFailure, /**< The operation failed. */ - eMQTTAgentTimeout, /**< The operation timed out. */ - eMQTTAgentAPICalledFromCallback /**< The MQTT agent APIs must not be called from MQTT callbacks as callbacks run - * in the context of MQTT agent task and therefore can result in deadlock. This - * error code is returned if any MQTT agent API is invoked from any callback. */ -} MQTTAgentReturnCode_t; - -/** - * @brief Various events reported by the library in the callback. - * - * The user can register an optional callback with the MQTT library to - * get notified of various events including Publish messages received - * from the broker. This enum identifies the event received in the - * callback. - */ -typedef enum -{ - eMQTTAgentPublish, /**< A Publish message was received from the broker. */ - eMQTTAgentDisconnect /**< The connection to the broker got disconnected. */ -} MQTTAgentEvent_t; - -/** - * @brief Passed by the library in the callback to inform the user of various events. - * - * If the user has registered a callback to get notified of various events, a pointer - * to this structure is passed in the callback function. - * @see MQTTAgentEvent_t. - */ -typedef struct MQTTAgentCallbackParams -{ - MQTTAgentEvent_t xMQTTEvent; /**< Type of the event received. */ - /* This union is here for future support. */ - union - { - MQTTPublishData_t xPublishData; /**< Publish data. Meaningful only in case of eMQTTAgentPublish event. */ - } u; -} MQTTAgentCallbackParams_t; - -/** - * @brief Signature of the callback registered by the user to get notified of various events. - * - * The user can register an optional callback to get notified of various events. - * - * @param[in] pvUserData The user data as provided in the connect parameters while connecting. - * @param[in] pxCallbackParams The event and related data. - * - * @return The return value is ignored in all other cases except publish (i.e. eMQTTAgentPublish - * event): - * 1. If pdTRUE is returned - The ownership of the buffer passed in the callback (xBuffer - * in MQTTPublishData_t) lies with the user. - * 2. If pdFALSE is returned - The ownership of the buffer passed in the callback (xBuffer - * in MQTTPublishData_t) remains with the library and it is recycled as soon as - * the callback returns.
- * The user should take the ownership of the buffer containing the received message from the - * broker by returning pdTRUE from the callback if the user wants to use the buffer after - * the callback is over. The user should return the buffer whenever done by calling the - * MQTT_AGENT_ReturnBuffer API. - * - * @see MQTTAgentCallbackParams_t. - */ -typedef BaseType_t ( * MQTTAgentCallback_t )( void * pvUserData, - const MQTTAgentCallbackParams_t * const pxCallbackParams ); - -/** - * @brief Flags for the MQTT agent connect params. - */ -#define mqttagentURL_IS_IP_ADDRESS 0x00000001 /**< Set this bit in xFlags if the provided URL is an IP address. */ -#define mqttagentREQUIRE_TLS 0x00000002 /**< Set this bit in xFlags to use TLS. */ -#define mqttagentUSE_AWS_IOT_ALPN_443 0x00000004 /**< Set this bit in xFlags to use AWS IoT support for MQTT over TLS port 443. */ - -/** - * @brief Parameters passed to the MQTT_AGENT_Connect API. - */ -typedef struct MQTTAgentConnectParams -{ - const char * pcURL; /**< The URL of the MQTT broker to connect to. */ - BaseType_t xFlags; /**< Flags to control the behavior of MQTT connect. */ - BaseType_t xURLIsIPAddress; /**< Deprecated. Set the mqttagentURL_IS_IP_ADDRESS bit in xFlags instead. */ - 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. */ - const uint8_t * pucClientId; /**< Client Identifier of the MQTT client. It should be unique per broker. */ - uint16_t usClientIdLength; /**< The length of the client Id. */ - BaseType_t xSecuredConnection; /**< Deprecated. Set the mqttagentREQUIRE_TLS bit in xFlags instead. */ - void * pvUserData; /**< User data supplied back as it is in the callback. Can be NULL. */ - MQTTAgentCallback_t pxCallback; /**< Callback used to report various events. In addition to other events, this callback is invoked for the publish - * messages received on the topics for which the user has not registered any subscription callback. Can be NULL. */ - 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. */ - uint32_t ulCertificateSize; /**< Size of certificate used for secure connection. */ -} MQTTAgentConnectParams_t; - -/** - * @brief Parameters passed to the MQTT_AGENT_Subscribe API. - */ -typedef struct MQTTAgentSubscribeParams -{ - const uint8_t * pucTopic; /**< The topic to subscribe to. This can be a topic filter containing wild cards as permitted by the MQTT protocol. */ - uint16_t usTopicLength; /**< The length of the topic. */ - MQTTQoS_t xQoS; /**< Requested Quality of Service. */ - #if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) - void * pvPublishCallbackContext; /**< Passed as it is in the publish callback. Can be NULL. */ - MQTTPublishCallback_t pxPublishCallback; /**< Callback function to be called whenever a publish message is received on this topic or on a topic which matches this - * topic filter. If a publish message is received on a topic which matches more than one topic filters, the order in which - * the callbacks are invoked is undefined. This can be NULL if the user does not want to register a topic specific callback, - * in which case the generic callback ( if registered during connect ) is invoked. */ - #endif /* mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT */ -} MQTTAgentSubscribeParams_t; - -/** - * @brief Parameters passed to the MQTT_AGENT_Unsubscribe API. - */ -typedef struct MQTTAgentUnsubscribeParams -{ - const uint8_t * pucTopic; /**< The topic to unsubscribe from. */ - uint16_t usTopicLength; /**< The length of the topic. */ -} MQTTAgentUnsubscribeParams_t; - -/** - * @brief Parameters passed to the MQTT_AGENT_Publish API. - */ -typedef struct MQTTAgentPublishParams -{ - const uint8_t * pucTopic; /**< The topic string on which the message should be published. */ - uint16_t usTopicLength; /**< The length of the topic. */ - MQTTQoS_t xQoS; /**< Quality of Service (qos). */ - 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. */ - uint32_t ulDataLength; /**< Length of the data. */ -} MQTTAgentPublishParams_t; - -/** - * @brief MQTT library Init function. - * - * This function does general initialization and setup. It must be called once - * and only once before calling any other function. - * - * @return pdPASS if everything succeeds, pdFAIL otherwise. - */ -lib_initDECLARE_LIB_INIT( MQTT_AGENT_Init ); - -/** - * @brief Creates a new MQTT client. - * - * The MQTT library is capable of creating multiple MQTT clients, maximum number of which - * is controlled by mqttconfigMAX_BROKERS macro. If mqttconfigMAX_BROKERS clients are already - * in use, this function will fail immediately. Otherwise a new client is setup and the handle - * to the created client is returned in the pxMQTTHandle parameter which should be used in all - * the subsequent API calls. Note that the returned handled is only valid if the return value - * of the API is eMQTTAgentSuccess. - * - * @param[out] pxMQTTHandle Output parameter to return the opaque client handle. - * - * @return eMQTTAgentSuccess if a new client is successfully created, otherwise an error code - * explaining the reason of the failure is returned. - */ -MQTTAgentReturnCode_t MQTT_AGENT_Create( MQTTAgentHandle_t * const pxMQTTHandle ); - -/** - * @brief Deletes the already created MQTT client. - * - * This function just frees up the internal resources and does not disconnect. The user must - * call MQTT_AGENT_Disconnect API to make sure that the client is disconnected before - * deleting it. - * - * @param[in] xMQTTHandle The opaque handle as returned from MQTT_AGENT_Create. - * - * @return eMQTTAgentSuccess if the client is successfully deleted, otherwise an - * error code explaining the reason of the failure is returned. - */ -MQTTAgentReturnCode_t MQTT_AGENT_Delete( MQTTAgentHandle_t xMQTTHandle ); - -/** - * @brief Establishes a connection with the MQTT broker. - * - * @note This function alters the calling task's notification state and value. If xTimeoutTicks - * is short the calling task's notification state and value may be updated after MQTT_AGENT_Connect() - * has returned. - * - * @param[in] xMQTTHandle The opaque handle as returned from MQTT_AGENT_Create. - * @param[in] pxConnectParams Connect parameters. - * @param[in] xTimeoutTicks Maximum time in ticks after which the operation should fail. Use pdMS_TO_TICKS - * macro to convert milliseconds to ticks. - * - * @return eMQTTAgentSuccess if the connect operation succeeds, otherwise an error code explaining the - * reason of the failure is returned. - */ -MQTTAgentReturnCode_t MQTT_AGENT_Connect( MQTTAgentHandle_t xMQTTHandle, - const MQTTAgentConnectParams_t * const pxConnectParams, - TickType_t xTimeoutTicks ); - -/** - * @brief Disconnects the connection with the MQTT broker. - * - * @note This function alters the calling task's notification state and value. If xTimeoutTicks - * is short the calling task's notification state and value may be updated after MQTT_AGENT_Disconnect() - * has returned. - * - * @param[in] xMQTTHandle The opaque handle as returned from MQTT_AGENT_Create. - * @param[in] xTimeoutTicks Maximum time in ticks after which the operation should fail. Use pdMS_TO_TICKS - * macro to convert milliseconds to ticks. - * - * @return eMQTTAgentSuccess if the disconnect operation succeeds, otherwise an error code explaining - * the reason of the failure is returned. - */ -MQTTAgentReturnCode_t MQTT_AGENT_Disconnect( MQTTAgentHandle_t xMQTTHandle, - TickType_t xTimeoutTicks ); - -/** - * @brief Subscribes to a given topic. - * - * @note This function alters the calling task's notification state and value. If xTimeoutTicks - * is short the calling task's notification state and value may be updated after MQTT_AGENT_Subscribe() - * has returned. - * - * Whenever a publish message is received on a topic, the registered callbacks are invoked - * in the following order: - * * If we have an exact matching entry in the subscription manager, the corresponding - * callback is invoked. - * * Then the wild card topic filters are checked for match and the corresponding callbacks - * are invoked for the ones which match the topic. - * - * @note If a publish message is received on a topic which matches more than one topic - * filters, the order in which the registered callbacks are invoked is undefined. - * - * @warning If the user takes the ownership of the MQTT buffer by returning eMQTTTrue from the - * callback, no further callbacks are invoked. The user should make sure not to take the ownership - * of the MQTT buffer if they want all the callbacks to get invoked. For example: - * * Subscriptions: a/b/c, a/b/#, a/b/+ - * * Publish message received on topic: a/b/c --> First the callback corresponding to a/b/c - * subscription is invoked. Then the callbacks for topic filters a/b/# and a/b/+ are invoked - * in no particular order. If the user decides to take the ownership of the MQTT buffer in - * any of the callback by returning eMQTTTrue, no further callbacks are invoked. - * - * @param[in] xMQTTHandle The opaque handle as returned from MQTT_AGENT_Create. - * @param[in] pxSubscribeParams Subscribe parameters. - * @param[in] xTimeoutTicks Maximum time in ticks after which the operation should fail. Use pdMS_TO_TICKS - * macro to convert milliseconds to ticks. - * - * @return eMQTTAgentSuccess if the subscribe operation succeeds, otherwise an error code explaining - * the reason of the failure is returned. - */ -MQTTAgentReturnCode_t MQTT_AGENT_Subscribe( MQTTAgentHandle_t xMQTTHandle, - const MQTTAgentSubscribeParams_t * const pxSubscribeParams, - TickType_t xTimeoutTicks ); - -/** - * @brief Unsubscribes from a given topic. - * - * @note This function alters the calling task's notification state and value. If xTimeoutTicks - * is short the calling task's notification state and value may be updated after MQTT_AGENT_Unsubscribe() - * has returned. - * - * @param[in] xMQTTHandle The opaque handle as returned from MQTT_AGENT_Create. - * @param[in] pxUnsubscribeParams Unsubscribe parameters. - * @param[in] xTimeoutTicks Maximum time in ticks after which the operation should fail. Use pdMS_TO_TICKS - * macro to convert milliseconds to ticks. - * - * @return eMQTTAgentSuccess if the unsubscribe operation succeeds, otherwise an error code explaining - * the reason of the failure is returned. - */ -MQTTAgentReturnCode_t MQTT_AGENT_Unsubscribe( MQTTAgentHandle_t xMQTTHandle, - const MQTTAgentUnsubscribeParams_t * const pxUnsubscribeParams, - TickType_t xTimeoutTicks ); - -/** - * @brief Publishes a message to a given topic. - * - * @note This function alters the calling task's notification state and value. If xTimeoutTicks - * is short the calling task's notification state and value may be updated after MQTT_AGENT_Publish() - * has returned. - * - * @param[in] xMQTTHandle The opaque handle as returned from MQTT_AGENT_Create. - * @param[in] pxPublishParams Publish parameters. - * @param[in] xTimeoutTicks Maximum time in ticks after which the operation should fail. Use pdMS_TO_TICKS - * macro to convert milliseconds to ticks. - * - * @return eMQTTAgentSuccess if the publish operation succeeds, otherwise an error code explaining - * the reason of the failure is returned. - */ -MQTTAgentReturnCode_t MQTT_AGENT_Publish( MQTTAgentHandle_t xMQTTHandle, - const MQTTAgentPublishParams_t * const pxPublishParams, - TickType_t xTimeoutTicks ); - -/** - * @brief Returns the buffer provided in the publish callback. - * - * When a publish message is received from the broker, the buffer containing the message - * is returned in the user supplied callback (xBuffer in MQTTPublishData_t) and the user - * can take the ownership by returning pdTRUE from the callback. The user should later - * return the buffer whenever done by calling the MQTT_AGENT_ReturnBuffer API. - * - * @param[in] xMQTTHandle The opaque handle as returned from MQTT_AGENT_Create. - * @param[in] xBufferHandle The buffer to return. - * - * @return eMQTTAgentSuccess if the return buffer operation succeeds, otherwise an error - * code explaining the reason of the failure is returned. - */ -MQTTAgentReturnCode_t MQTT_AGENT_ReturnBuffer( MQTTAgentHandle_t xMQTTHandle, - MQTTBufferHandle_t xBufferHandle ); - -#endif /* _AWS_MQTT_AGENT_H_ */ 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 deleted file mode 100644 index 1ac77800d..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt_agent_config_defaults.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Amazon FreeRTOS MQTT V2.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_mqtt_agent_config_defaults.h - * @brief MQTT agent default config options. - * - * Ensures that the config options for MQTT agent are set to sensible - * default values if the user does not provide one. - */ - -#ifndef _AWS_MQTT_AGENT_CONFIG_DEFAULTS_H_ -#define _AWS_MQTT_AGENT_CONFIG_DEFAULTS_H_ - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" - -/** - * @brief Controls whether or not to report usage metrics to the - * AWS IoT broker. - * - * If mqttconfigENABLE_METRICS is set to 1, a string containing - * metric information will be included in the "username" field of - * the MQTT connect messages. - */ -#ifndef mqttconfigENABLE_METRICS - #define mqttconfigENABLE_METRICS ( 1 ) -#endif - -/** - * @brief The maximum time interval in seconds allowed to elapse between 2 consecutive - * control packets. - */ -#ifndef mqttconfigKEEP_ALIVE_INTERVAL_SECONDS - #define mqttconfigKEEP_ALIVE_INTERVAL_SECONDS ( 1200 ) -#endif - -/** - * @brief Defines the frequency at which the client should send Keep Alive messages. - * - * Even though the maximum time allowed between 2 consecutive control packets - * is defined by the mqttconfigKEEP_ALIVE_INTERVAL_SECONDS macro, the user - * can and should send Keep Alive messages at a slightly faster rate to ensure - * that the connection is not closed by the server because of network delays. - * This macro defines the interval of inactivity after which a keep alive messages - * is sent. - */ -#ifndef mqttconfigKEEP_ALIVE_ACTUAL_INTERVAL_TICKS - #define mqttconfigKEEP_ALIVE_ACTUAL_INTERVAL_TICKS ( 5000 ) -#endif - -/** - * @brief The maximum interval in ticks to wait for PINGRESP. - * - * If PINGRESP is not received within this much time after sending PINGREQ, - * the client assumes that the PINGREQ timed out. - */ -#ifndef mqttconfigKEEP_ALIVE_TIMEOUT_TICKS - #define mqttconfigKEEP_ALIVE_TIMEOUT_TICKS ( 1000 ) -#endif - -/** - * @brief The maximum time in ticks for which the MQTT task is permitted to block. - * - * The MQTT task blocks until the user initiates any action or until it receives - * any data from the broker. This macro controls the maximum time the MQTT task can - * block. It should be set to a small number for the platforms which do not have any - * mechanism to wake up the MQTT task whenever data is received on a connected socket. - * This ensures that the MQTT task keeps waking up frequently and processes the publish - * messages received from the broker, if any. - * - * If the platform's secure_sockets layer supports SOCKETS_SO_WAKEUP_CALLBACK i.e. - * the MQTT task can wake up whenever data is received on a connected socket, this - * value should be set to maximum value: - * #define #define mqttconfigMQTT_TASK_MAX_BLOCK_TICKS ( ~( ( uint32_t ) 0 ) ) - * - * If the platform's secure_sockets layer does not support SOCKETS_SO_WAKEUP_CALLBACK - * i.e. the MQTT task cannot wake up whenever data is received on a connected socket, - * this value should be set to a small number: - * #define mqttconfigMQTT_TASK_MAX_BLOCK_TICKS ( 100 ) - */ -#ifndef mqttconfigMQTT_TASK_MAX_BLOCK_TICKS - #error "mqttconfigMQTT_TASK_MAX_BLOCK_TICKS must be defined in iot_mqtt_agent_config.h." -#endif - -/** - * @defgroup MQTTTask MQTT task configuration parameters. - */ -/** @{ */ -#ifndef mqttconfigMQTT_TASK_STACK_DEPTH - #define mqttconfigMQTT_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 4 ) -#endif - -#ifndef mqttconfigMQTT_TASK_PRIORITY - #define mqttconfigMQTT_TASK_PRIORITY ( tskIDLE_PRIORITY ) -#endif -/** @} */ - -/** - * @brief Maximum number of MQTT clients that can exist simultaneously. - */ -#ifndef mqttconfigMAX_BROKERS - #define mqttconfigMAX_BROKERS ( 1 ) -#endif - -/** - * @brief Maximum number of parallel operations per client. - */ -#ifndef mqttconfigMAX_PARALLEL_OPS - #define mqttconfigMAX_PARALLEL_OPS ( 5 ) -#endif - -/** - * @brief Time in milliseconds after which the TCP send operation should timeout. - */ -#ifndef mqttconfigTCP_SEND_TIMEOUT_MS - #define mqttconfigTCP_SEND_TIMEOUT_MS ( 2000 ) -#endif - -/** - * @brief Length of the buffer used to receive data. - */ -#ifndef mqttconfigRX_BUFFER_SIZE - #define mqttconfigRX_BUFFER_SIZE ( 1024 ) -#endif - -/** - * @defgroup BufferPoolInterface The functions used by the MQTT client to get and return buffers. - * - * The MQTT client needs buffers for both transmitting and receiving messages. - * Whenever it needs a buffer, it invokes mqttconfigGET_FREE_BUFFER_FXN function to get - * a buffer and after it is done it invokes mqttconfigRETURN_BUFFER_FXN to return the - * buffer. By default, BUFFERPOOL_GetFreeBuffer and BUFFERPOOL_ReturnBuffer functions are - * used to get and return buffers from the central buffer pool. The user can change the - * buffer management functions for MQTT client by defining mqttconfigGET_FREE_BUFFER_FXN - * and mqttconfigRETURN_BUFFER_FXN macros. The user should implement the two functions - * having signatures same as BUFFERPOOL_GetFreeBuffer and BUFFERPOOL_ReturnBuffer and then - * define the macros in BufferPoolConfig.h: - * @code - * uint8_t* UserDefined_GetFreeBuffer( uint32_t *pulBufferLength ); - * void UserDefined_ReturnBuffer( uint8_t * const pucBuffer ); - * - * #define mqttconfigGET_FREE_BUFFER_FXN UserDefined_GetFreeBuffer - * #define mqttconfigRETURN_BUFFER_FXN UserDefined_ReturnBuffer - * @endcode - */ -/** @{ */ -#ifndef mqttconfigGET_FREE_BUFFER_FXN - #define mqttconfigGET_FREE_BUFFER_FXN BUFFERPOOL_GetFreeBuffer -#endif - -#ifndef mqttconfigRETURN_BUFFER_FXN - #define mqttconfigRETURN_BUFFER_FXN BUFFERPOOL_ReturnBuffer -#endif -/** @} */ - -#endif /* _AWS_MQTT_AGENT_CONFIG_DEFAULTS_H_ */ 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 deleted file mode 100644 index 08bcd41d4..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt_config_defaults.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Amazon FreeRTOS MQTT V2.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_mqtt_config_defaults.h - * @brief MQTT default config options. - * - * Ensures that the config options for MQTT are set to sensible default - * values if the user does not provide one. - */ - -#ifndef _AWS_MQTT_CONFIG_DEFAULTS_H_ -#define _AWS_MQTT_CONFIG_DEFAULTS_H_ - -/** - * @brief Enable subscription management. - * - * Subscription management allows the user to register per subscription - * callback. - */ -#ifndef mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT - #define mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT ( 1 ) -#endif - -/** - * @brief Maximum length of the topic which can be stored in subscription - * manager. - * - * If the user has enabled subscription management (by defining the macro - * mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT to 1), then this macro must be defined - * to accommodate the maximum length topic which the user is going to subscribe. - * The subscribe operation will fail if the user tries to subscribe to a topic - * of length more than the maximum specified here. - */ -#ifndef mqttconfigSUBSCRIPTION_MANAGER_MAX_TOPIC_LENGTH - #define mqttconfigSUBSCRIPTION_MANAGER_MAX_TOPIC_LENGTH ( 128 ) -#endif - -/** - * @brief Maximum number of subscriptions which can be stored in subscription - * manager. - * - * If the user has enabled subscription management (by defining the macro - * mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT to 1), then this macro must be defined - * to the maximum number of topics which the user is going to subscribe - * simultaneously. The subscribe operation will fail is the user tries to - * subscribe to more topics than the maximum specified here. - */ -#ifndef mqttconfigSUBSCRIPTION_MANAGER_MAX_SUBSCRIPTIONS - #define mqttconfigSUBSCRIPTION_MANAGER_MAX_SUBSCRIPTIONS ( 8 ) -#endif - -/** - * @brief Define mqttconfigASSERT to enable asserts. - * - * mqttconfigASSERT should be defined to match the semantics of standard - * C assert() macro i.e. an assertion should trigger if the parameter - * passed is zero. If the standard C assert is available, the user might - * do the following: - * @code - * #define mqttconfigASSERT( x ) assert( x ) - * @endcode - * - * Otherwise, a user can choose to implement a function which should be - * called when an assertion triggers and then define the mqttconfigASSERT - * to that function: - * @code - * extern void vAssertCalled( const char *pcFile, uint32_t ulLine ); - * #define mqttconfigASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ ) - * @endcode - */ -#ifndef mqttconfigASSERT - #define mqttconfigASSERT( x ) -#endif - -/** - * @brief Define mqttconfigENABLE_DEBUG_LOGS macro to 1 for enabling debug logs. - * - * If you choose to enable debug logs, the following function must be implemented - * which is called to print logs: - * @code - * void vLoggingPrintf( const char *pcFormatString, ... ); - * @endcode - */ -#if ( mqttconfigENABLE_DEBUG_LOGS == 1 ) - extern void vLoggingPrintf( const char * pcFormatString, - ... ); - #define mqttconfigDEBUG_LOG( x ) vLoggingPrintf x -#else - #define mqttconfigDEBUG_LOG( x ) -#endif - -#endif /* _AWS_MQTT_CONFIG_DEFAULTS_H_ */ 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 deleted file mode 100644 index ae3e2638e..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt_lib.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Amazon FreeRTOS MQTT V2.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_mqtt_lib.h - * @brief MQTT Core Library interface. - */ - -#ifndef _AWS_MQTT_LIB_H_ -#define _AWS_MQTT_LIB_H_ - -/* This ifndef enables the core MQTT library to be used without - * providing MQTTConfig.h. All the config values in this case are - * taken from MQTTConfigDefaults.h. */ -#ifndef mqttDO_NOT_USE_CUSTOM_CONFIG - #include "aws_mqtt_config.h" -#endif -#include "iot_mqtt_config_defaults.h" - -#include "iot_doubly_linked_list.h" - - /** - * @brief Opaque handle to represent an MQTT buffer. - */ -typedef void * MQTTBufferHandle_t; - -/** - * @brief Boolean type. - */ -typedef enum -{ - eMQTTFalse = 0, /**< Boolean False. */ - eMQTTTrue = 1 /**< Boolean True. */ -} MQTTBool_t; - -/** - * @brief Quality of Service (qos). - */ -typedef enum -{ - eMQTTQoS0 = 0, /**< Quality of Service 0 - Fire and Forget. No ACK. */ - eMQTTQoS1 = 1, /**< Quality of Service 1 - Wait till ACK or Timeout. */ - eMQTTQoS2 = 2 /**< Quality of Service 2 - Not supported. */ -} MQTTQoS_t; - -/** - * @brief The data sent by the MQTT library in the user supplied callback - * when a publish message from the broker is received. - */ -typedef struct MQTTPublishData -{ - MQTTQoS_t xQos; /**< Quality of Service (qos). */ - const uint8_t * pucTopic; /**< The topic on which the message is received. */ - uint16_t usTopicLength; /**< Length of the topic. */ - const void * pvData; /**< The received message. */ - uint32_t ulDataLength; /**< Length of the message. */ - MQTTBufferHandle_t xBuffer; /**< The buffer containing the whole MQTT message. Both pcTopic and pvData are pointers to the locations in this buffer. */ -} MQTTPublishData_t; - -/** - * @brief Signature of the user supplied topic specific publish callback which gets called - * whenever a publish message is received on the topic this callback is registered for. - * - * The user can choose to register this optional topic specific callback while subscribing to - * a topic. Whenever a publish message is received on the topic, this callback is invoked. If - * the user chooses not to enable subscription management or chooses not to register a topic - * specific callback, the generic callback supplied during Init is invoked. - * - * @param[in] pvPublishCallbackContext The callback context as supplied by the user in the - * subscribe parameters. - * @param[in] pxPublishData The publish data. - * - * @return The return value is interpreted as follows: - * 1. If eMQTTTrue is returned - the ownership of the buffer passed in the callback (xBuffer - * in MQTTPublishData_t) lies with the user. - * 2. If eMQTTFalse is returned - the ownership of the buffer passed in the callback (xBuffer - * in MQTTPublishData_t) remains with the library and it is recycled as soon as the callback - * returns.
- * The user should take the ownership of the buffer containing the received message from the - * broker by returning eMQTTTrue from the callback if the user wants to use the buffer after - * the callback is over. The user should return the buffer whenever done by calling the - * MQTT_ReturnBuffer API. - */ -#if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) - - typedef MQTTBool_t ( * MQTTPublishCallback_t )( void * pvPublishCallbackContext, - const MQTTPublishData_t * const pxPublishData ); - -#endif /* mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT */ - -#endif /* _AWS_MQTT_LIB_H_ */ 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 deleted file mode 100644 index c4bea3105..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/types/iot_mqtt_types.h +++ /dev/null @@ -1,1087 +0,0 @@ -/* - * Amazon FreeRTOS MQTT V2.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_mqtt_types.h - * @brief Types of the MQTT library. - */ - -#ifndef IOT_MQTT_TYPES_H_ -#define IOT_MQTT_TYPES_H_ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* Standard includes. */ -#include -#include -#include - -/* Type includes. */ -#include "types/iot_platform_types.h" -#include "types/iot_taskpool_types.h" - -/* Platform network include. */ -#include "platform/iot_network.h" - -/*---------------------------- MQTT handle types ----------------------------*/ - -/** - * @handles{mqtt,MQTT library} - */ - -/** - * @ingroup mqtt_datatypes_handles - * @brief Opaque handle of an MQTT connection. - * - * This type identifies an MQTT connection, which is valid after a successful call - * to @ref mqtt_function_connect. A variable of this type is passed as the first - * argument to [MQTT library functions](@ref mqtt_functions) to identify which - * connection that function acts on. - * - * A call to @ref mqtt_function_disconnect makes a connection handle invalid. Once - * @ref mqtt_function_disconnect returns, the connection handle should no longer - * be used. - * - * @initializer{IotMqttConnection_t,IOT_MQTT_CONNECTION_INITIALIZER} - */ -typedef struct _mqttConnection * IotMqttConnection_t; - -/** - * @ingroup mqtt_datatypes_handles - * @brief Opaque handle that references an in-progress MQTT operation. - * - * Set as an output parameter of @ref mqtt_function_publish, @ref mqtt_function_subscribe, - * and @ref mqtt_function_unsubscribe. These functions queue an MQTT operation; the result - * of the operation is unknown until a response from the MQTT server is received. Therefore, - * this handle serves as a reference to MQTT operations awaiting MQTT server response. - * - * This reference will be valid from the successful return of @ref mqtt_function_publish, - * @ref mqtt_function_subscribe, or @ref mqtt_function_unsubscribe. The reference becomes - * invalid once the [completion callback](@ref IotMqttCallbackInfo_t) is invoked, or - * @ref mqtt_function_wait returns. - * - * @initializer{IotMqttOperation_t,IOT_MQTT_OPERATION_INITIALIZER} - * - * @see @ref mqtt_function_wait and #IOT_MQTT_FLAG_WAITABLE for waiting on a reference. - * #IotMqttCallbackInfo_t and #IotMqttCallbackParam_t for an asynchronous notification - * of completion. - */ -typedef struct _mqttOperation * IotMqttOperation_t; - -/*-------------------------- MQTT enumerated types --------------------------*/ - -/** - * @enums{mqtt,MQTT library} - */ - -/** - * @ingroup mqtt_datatypes_enums - * @brief Return codes of [MQTT functions](@ref mqtt_functions). - * - * The function @ref mqtt_function_strerror can be used to get a return code's - * description. - */ -typedef enum IotMqttError -{ - /** - * @brief MQTT operation completed successfully. - * - * Functions that may return this value: - * - @ref mqtt_function_connect - * - @ref mqtt_function_publish with QoS 0 parameter - * - @ref mqtt_function_wait - * - @ref mqtt_function_timedsubscribe - * - @ref mqtt_function_timedunsubscribe - * - @ref mqtt_function_timedpublish - * - * Will also be the value of an operation completion callback's - * #IotMqttCallbackParam_t.result when successful. - */ - IOT_MQTT_SUCCESS = 0, - - /** - * @brief MQTT operation queued, awaiting result. - * - * Functions that may return this value: - * - @ref mqtt_function_subscribe - * - @ref mqtt_function_unsubscribe - * - @ref mqtt_function_publish with QoS 1 parameter - */ - IOT_MQTT_STATUS_PENDING, - - /** - * @brief Initialization failed. - * - * Functions that may return this value: - * - @ref mqtt_function_init - */ - IOT_MQTT_INIT_FAILED, - - /** - * @brief At least one parameter is invalid. - * - * Functions that may return this value: - * - @ref mqtt_function_connect - * - @ref mqtt_function_subscribe and @ref mqtt_function_timedsubscribe - * - @ref mqtt_function_unsubscribe and @ref mqtt_function_timedunsubscribe - * - @ref mqtt_function_publish and @ref mqtt_function_timedpublish - * - @ref mqtt_function_wait - */ - IOT_MQTT_BAD_PARAMETER, - - /** - * @brief MQTT operation failed because of memory allocation failure. - * - * Functions that may return this value: - * - @ref mqtt_function_connect - * - @ref mqtt_function_subscribe and @ref mqtt_function_timedsubscribe - * - @ref mqtt_function_unsubscribe and @ref mqtt_function_timedunsubscribe - * - @ref mqtt_function_publish and @ref mqtt_function_timedpublish - */ - IOT_MQTT_NO_MEMORY, - - /** - * @brief MQTT operation failed because the network was unusable. - * - * This return value may indicate that the network is disconnected. - * - * Functions that may return this value: - * - @ref mqtt_function_connect - * - @ref mqtt_function_wait - * - @ref mqtt_function_timedsubscribe - * - @ref mqtt_function_timedunsubscribe - * - @ref mqtt_function_timedpublish - * - * May also be the value of an operation completion callback's - * #IotMqttCallbackParam_t.result. - */ - IOT_MQTT_NETWORK_ERROR, - - /** - * @brief MQTT operation could not be scheduled, i.e. enqueued for sending. - * - * Functions that may return this value: - * - @ref mqtt_function_connect - * - @ref mqtt_function_subscribe and @ref mqtt_function_timedsubscribe - * - @ref mqtt_function_unsubscribe and @ref mqtt_function_timedunsubscribe - * - @ref mqtt_function_publish and @ref mqtt_function_timedpublish - */ - IOT_MQTT_SCHEDULING_ERROR, - - /** - * @brief MQTT response packet received from the network is malformed. - * - * Functions that may return this value: - * - @ref mqtt_function_connect - * - @ref mqtt_function_wait - * - @ref mqtt_function_timedsubscribe - * - @ref mqtt_function_timedunsubscribe - * - @ref mqtt_function_timedpublish - * - * May also be the value of an operation completion callback's - * #IotMqttCallbackParam_t.result. - * - * @note If this value is received, the network connection has been closed. - */ - IOT_MQTT_BAD_RESPONSE, - - /** - * @brief A blocking MQTT operation timed out. - * - * Functions that may return this value: - * - @ref mqtt_function_connect - * - @ref mqtt_function_wait - * - @ref mqtt_function_timedsubscribe - * - @ref mqtt_function_timedunsubscribe - * - @ref mqtt_function_timedpublish - */ - IOT_MQTT_TIMEOUT, - - /** - * @brief A CONNECT or at least one subscription was refused by the server. - * - * Functions that may return this value: - * - @ref mqtt_function_connect - * - @ref mqtt_function_wait, but only when its #IotMqttOperation_t parameter - * is associated with a SUBSCRIBE operation. - * - @ref mqtt_function_timedsubscribe - * - * May also be the value of an operation completion callback's - * #IotMqttCallbackParam_t.result for a SUBSCRIBE. - * - * @note If this value is returned and multiple subscriptions were passed to - * @ref mqtt_function_subscribe (or @ref mqtt_function_timedsubscribe), it's - * still possible that some of the subscriptions succeeded. This value only - * signifies that AT LEAST ONE subscription was rejected. The function @ref - * mqtt_function_issubscribed can be used to determine which subscriptions - * were accepted or rejected. - */ - IOT_MQTT_SERVER_REFUSED, - - /** - * @brief A QoS 1 PUBLISH received no response and [the retry limit] - * (#IotMqttPublishInfo_t.retryLimit) was reached. - * - * Functions that may return this value: - * - @ref mqtt_function_wait, but only when its #IotMqttOperation_t parameter - * is associated with a QoS 1 PUBLISH operation - * - @ref mqtt_function_timedpublish - * - * May also be the value of an operation completion callback's - * #IotMqttCallbackParam_t.result for a QoS 1 PUBLISH. - */ - IOT_MQTT_RETRY_NO_RESPONSE -} IotMqttError_t; - -/** - * @ingroup mqtt_datatypes_enums - * @brief Types of MQTT operations. - * - * The function @ref mqtt_function_operationtype can be used to get an operation - * type's description. - */ -typedef enum IotMqttOperationType -{ - IOT_MQTT_CONNECT, /**< Client-to-server CONNECT. */ - IOT_MQTT_PUBLISH_TO_SERVER, /**< Client-to-server PUBLISH. */ - IOT_MQTT_PUBACK, /**< Client-to-server PUBACK. */ - IOT_MQTT_SUBSCRIBE, /**< Client-to-server SUBSCRIBE. */ - IOT_MQTT_UNSUBSCRIBE, /**< Client-to-server UNSUBSCRIBE. */ - IOT_MQTT_PINGREQ, /**< Client-to-server PINGREQ. */ - IOT_MQTT_DISCONNECT /**< Client-to-server DISCONNECT. */ -} IotMqttOperationType_t; - -/** - * @ingroup mqtt_datatypes_enums - * @brief Quality of service levels for MQTT PUBLISH messages. - * - * All MQTT PUBLISH messages, including Last Will and Testament and messages - * received on subscription filters, have an associated Quality of Service, - * which defines any delivery guarantees for that message. - * - QoS 0 messages will be delivered at most once. This is a "best effort" - * transmission with no retransmissions. - * - QoS 1 messages will be delivered at least once. See #IotMqttPublishInfo_t - * for the retransmission strategy this library uses to redeliver messages - * assumed to be lost. - * - * @attention QoS 2 is not supported by this library and should not be used. - */ -typedef enum IotMqttQos -{ - IOT_MQTT_QOS_0 = 0, /**< Delivery at most once. */ - IOT_MQTT_QOS_1 = 1, /**< Delivery at least once. See #IotMqttPublishInfo_t for client-side retry strategy. */ - IOT_MQTT_QOS_2 = 2 /**< Delivery exactly once. Unsupported, but enumerated for completeness. */ -} IotMqttQos_t; - -/** - * @ingroup mqtt_datatypes_enums - * @brief The reason that an MQTT connection (and its associated network connection) - * was disconnected. - * - * When an MQTT connection is closed, its associated [disconnect callback] - * (@ref IotMqttNetworkInfo_t::disconnectCallback) will be invoked. This type - * is passed inside of an #IotMqttCallbackParam_t to provide a reason for the - * disconnect. - */ -typedef enum IotMqttDisconnectReason -{ - IOT_MQTT_DISCONNECT_CALLED, /**< @ref mqtt_function_disconnect was invoked. */ - IOT_MQTT_BAD_PACKET_RECEIVED, /**< An invalid packet was received from the network. */ - IOT_MQTT_KEEP_ALIVE_TIMEOUT /**< Keep-alive response was not received within @ref IOT_MQTT_RESPONSE_WAIT_MS. */ -} IotMqttDisconnectReason_t; - -/*------------------------- MQTT parameter structs --------------------------*/ - -/** - * @paramstructs{mqtt,MQTT} - */ - -/** - * @ingroup mqtt_datatypes_paramstructs - * @brief Information on a PUBLISH message. - * - * @paramfor @ref mqtt_function_connect, @ref mqtt_function_publish - * - * Passed to @ref mqtt_function_publish as the message to publish and @ref - * mqtt_function_connect as the Last Will and Testament (LWT) message. - * - * @initializer{IotMqttPublishInfo_t,IOT_MQTT_PUBLISH_INFO_INITIALIZER} - * - * #IotMqttPublishInfo_t.retryMs and #IotMqttPublishInfo_t.retryLimit are only - * relevant to QoS 1 PUBLISH messages. They are ignored for QoS 0 PUBLISH - * messages and LWT messages. These members control retransmissions of QoS 1 - * messages under the following rules: - * - Retransmission is disabled when #IotMqttPublishInfo_t.retryLimit is 0. - * After sending the PUBLISH, the library will wait indefinitely for a PUBACK. - * - If #IotMqttPublishInfo_t.retryLimit is greater than 0, then QoS 1 publishes - * that do not receive a PUBACK within #IotMqttPublishInfo_t.retryMs will be - * retransmitted, up to #IotMqttPublishInfo_t.retryLimit times. - * - * Retransmission follows a truncated exponential backoff strategy. The constant - * @ref IOT_MQTT_RETRY_MS_CEILING controls the maximum time between retransmissions. - * - * After #IotMqttPublishInfo_t.retryLimit retransmissions are sent, the MQTT - * library will wait @ref IOT_MQTT_RESPONSE_WAIT_MS before a final check - * for a PUBACK. If no PUBACK was received within this time, the QoS 1 PUBLISH - * fails with the code #IOT_MQTT_RETRY_NO_RESPONSE. - * - * @note The lengths of the strings in this struct should not include the NULL - * terminator. Strings in this struct do not need to be NULL-terminated. - * - * @note The AWS IoT MQTT server does not support the DUP bit. When - * [using this library with the AWS IoT MQTT server](@ref IotMqttConnectInfo_t.awsIotMqttMode), - * retransmissions will instead be sent with a new packet identifier in the PUBLISH - * packet. This is a nonstandard workaround. Note that this workaround has some - * flaws, including the following: - * - The previous packet identifier is forgotten, so if a PUBACK arrives for that - * packet identifier, it will be ignored. On an exceptionally busy network, this - * may cause excessive retransmissions when too many PUBACKS arrive after the - * PUBLISH packet identifier is changed. However, the exponential backoff - * retransmission strategy should mitigate this problem. - * - Log messages will be printed using the new packet identifier; the old packet - * identifier is not saved. - * - * Example - * - * Consider a situation where - * - @ref IOT_MQTT_RETRY_MS_CEILING is 60000 - * - #IotMqttPublishInfo_t.retryMs is 2000 - * - #IotMqttPublishInfo_t.retryLimit is 20 - * - * A PUBLISH message will be retransmitted at the following times after the initial - * transmission if no PUBACK is received: - * - 2000 ms (2000 ms after previous transmission) - * - 6000 ms (4000 ms after previous transmission) - * - 14000 ms (8000 ms after previous transmission) - * - 30000 ms (16000 ms after previous transmission) - * - 62000 ms (32000 ms after previous transmission) - * - 122000 ms, 182000 ms, 242000 ms... (every 60000 ms until 20 transmissions have been sent) - * - * After the 20th retransmission, the MQTT library will wait - * @ref IOT_MQTT_RESPONSE_WAIT_MS before checking a final time for a PUBACK. - */ -typedef struct IotMqttPublishInfo -{ - IotMqttQos_t qos; /**< @brief QoS of message. Must be 0 or 1. */ - bool retain; /**< @brief MQTT message retain flag. */ - - const char * pTopicName; /**< @brief Topic name of PUBLISH. */ - uint16_t topicNameLength; /**< @brief Length of #IotMqttPublishInfo_t.pTopicName. */ - - const void * pPayload; /**< @brief Payload of PUBLISH. */ - size_t payloadLength; /**< @brief Length of #IotMqttPublishInfo_t.pPayload. For LWT messages, this is limited to 65535. */ - - uint32_t retryMs; /**< @brief If no response is received within this time, the message is retransmitted. */ - uint32_t retryLimit; /**< @brief How many times to attempt retransmission. */ -} IotMqttPublishInfo_t; - -/** - * @ingroup mqtt_datatypes_paramstructs - * @brief Parameter to an MQTT callback function. - * - * @paramfor MQTT callback functions - * - * The MQTT library passes this struct to registered callback whenever an - * operation completes, a message is received on a topic filter, or an MQTT - * connection is disconnected. - * - * The members of this struct are different based on the callback trigger. If the - * callback function was triggered for completed operation, the `operation` - * member is valid. Otherwise, if the callback was triggered because of a - * server-to-client PUBLISH, the `message` member is valid. Finally, if the callback - * was triggered because of a disconnect, the `disconnectReason` member is valid. - * - * For an incoming PUBLISH, the `message.pTopicFilter` parameter provides the - * subscription topic filter that matched the topic name in the PUBLISH. Because - * topic filters may use MQTT wildcards, the topic filter may be different from the - * topic name. This pointer must be treated as read-only; the topic filter must not - * be modified. Additionally, the topic filter may go out of scope as soon as the - * callback function returns, so it must be copied if it is needed at a later time. - * - * @attention Any pointers in this callback parameter may be freed as soon as - * the [callback function](@ref IotMqttCallbackInfo_t.function) returns. - * Therefore, data must be copied if it is needed after the callback function - * returns. - * @attention The MQTT library may set strings that are not NULL-terminated. - * - * @see #IotMqttCallbackInfo_t for the signature of a callback function. - */ -typedef struct IotMqttCallbackParam -{ - /** - * @brief The MQTT connection associated with this completed operation, - * incoming PUBLISH, or disconnect. - * - * [MQTT API functions](@ref mqtt_functions) are safe to call from a callback - * for completed operations or incoming PUBLISH messages. However, blocking - * function calls (including @ref mqtt_function_wait) are not recommended - * (though still safe). Do not call any API functions from a disconnect - * callback. - */ - IotMqttConnection_t mqttConnection; - - union - { - /* Valid for completed operations. */ - struct - { - IotMqttOperationType_t type; /**< @brief Type of operation that completed. */ - IotMqttOperation_t reference; /**< @brief Reference to the operation that completed. */ - IotMqttError_t result; /**< @brief Result of operation, e.g. succeeded or failed. */ - } operation; - - /* Valid for incoming PUBLISH messages. */ - struct - { - const char * pTopicFilter; /**< @brief Topic filter that matched the message. */ - uint16_t topicFilterLength; /**< @brief Length of `pTopicFilter`. */ - IotMqttPublishInfo_t info; /**< @brief PUBLISH message received from the server. */ - } message; - - /* Valid when a connection is disconnected. */ - IotMqttDisconnectReason_t disconnectReason; /**< @brief Why the MQTT connection was disconnected. */ - } u; /**< @brief Valid member depends on callback type. */ -} IotMqttCallbackParam_t; - -/** - * @ingroup mqtt_datatypes_paramstructs - * @brief Information on a user-provided MQTT callback function. - * - * @paramfor @ref mqtt_function_subscribe, @ref mqtt_function_unsubscribe, - * and @ref mqtt_function_publish. Cannot be used with #IOT_MQTT_FLAG_WAITABLE. - * - * Provides a function to be invoked when an operation completes or when a - * server-to-client PUBLISH is received. - * - * @initializer{IotMqttCallbackInfo_t,IOT_MQTT_CALLBACK_INFO_INITIALIZER} - * - * Below is an example for receiving an asynchronous notification on operation - * completion. See @ref mqtt_function_subscribe for an example of using this struct - * with for incoming PUBLISH messages. - * - * @code{c} - * // Operation completion callback. - * void operationComplete( void * pArgument, IotMqttCallbackParam_t * pOperation ); - * - * // Callback information. - * IotMqttCallbackInfo_t callbackInfo = IOT_MQTT_CALLBACK_INFO_INITIALIZER; - * callbackInfo.function = operationComplete; - * - * // Operation to wait for. - * IotMqttError_t result = IotMqtt_Publish( &mqttConnection, - * &publishInfo, - * 0, - * &callbackInfo, - * &reference ); - * - * // Publish should have returned IOT_MQTT_STATUS_PENDING. Once a response - * // is received, operationComplete is executed with the actual status passed - * // in pOperation. - * @endcode - */ -typedef struct IotMqttCallbackInfo -{ - void * pCallbackContext; /**< @brief The first parameter to pass to the callback function to provide context. */ - - /** - * @brief User-provided callback function signature. - * - * @param[in] void * #IotMqttCallbackInfo_t.pCallbackContext - * @param[in] IotMqttCallbackParam_t * Details on the outcome of the MQTT operation - * or an incoming MQTT PUBLISH. - * - * @see #IotMqttCallbackParam_t for more information on the second parameter. - */ - void ( * function )( void *, - IotMqttCallbackParam_t * ); -} IotMqttCallbackInfo_t; - -/** - * @ingroup mqtt_datatypes_paramstructs - * @brief Information on an MQTT subscription. - * - * @paramfor @ref mqtt_function_subscribe, @ref mqtt_function_unsubscribe - * - * An array of these is passed to @ref mqtt_function_subscribe and @ref - * mqtt_function_unsubscribe. However, #IotMqttSubscription_t.callback and - * and #IotMqttSubscription_t.qos are ignored by @ref mqtt_function_unsubscribe. - * - * @initializer{IotMqttSubscription_t,IOT_MQTT_SUBSCRIPTION_INITIALIZER} - * - * @note The lengths of the strings in this struct should not include the NULL - * terminator. Strings in this struct do not need to be NULL-terminated. - * @see #IotMqttCallbackInfo_t for details on setting a callback function. - */ -typedef struct IotMqttSubscription -{ - /** - * @brief QoS of messages delivered on subscription. - * - * Must be `0` or `1`. Ignored by @ref mqtt_function_unsubscribe. - */ - IotMqttQos_t qos; - - const char * pTopicFilter; /**< @brief Topic filter of subscription. */ - uint16_t topicFilterLength; /**< @brief Length of #IotMqttSubscription_t.pTopicFilter. */ - - /** - * @brief Callback to invoke when a message is received. - * - * See #IotMqttCallbackInfo_t. Ignored by @ref mqtt_function_unsubscribe. - */ - IotMqttCallbackInfo_t callback; -} IotMqttSubscription_t; - -/** - * @ingroup mqtt_datatypes_paramstructs - * @brief Information on a new MQTT connection. - * - * @paramfor @ref mqtt_function_connect - * - * Passed as an argument to @ref mqtt_function_connect. Most members of this struct - * correspond to the content of an [MQTT CONNECT packet.] - * (http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/csprd02/mqtt-v3.1.1-csprd02.html#_Toc385349764) - * - * @initializer{IotMqttConnectInfo_t,IOT_MQTT_CONNECT_INFO_INITIALIZER} - * - * @note The lengths of the strings in this struct should not include the NULL - * terminator. Strings in this struct do not need to be NULL-terminated. - */ -typedef struct IotMqttConnectInfo -{ - /** - * @brief Specifies if this MQTT connection is to an AWS IoT MQTT server. - * - * The AWS IoT MQTT broker [differs somewhat from the MQTT specification.] - * (https://docs.aws.amazon.com/iot/latest/developerguide/mqtt.html) - * When this member is `true`, the MQTT library will accommodate these - * differences. This setting should be `false` when communicating with a - * fully-compliant MQTT broker. - * - * @attention This setting MUST be `true` when using the AWS IoT MQTT - * server; it MUST be `false` otherwise. - * @note Currently, @ref IOT_MQTT_CONNECT_INFO_INITIALIZER sets this - * this member to `true`. - */ - bool awsIotMqttMode; - - /** - * @brief Whether this connection is a clean session. - * - * MQTT servers can maintain and topic filter subscriptions and unacknowledged - * PUBLISH messages. These form part of an MQTT session, which is identified by - * the [client identifier](@ref IotMqttConnectInfo_t.pClientIdentifier). - * - * Setting this value to `true` establishes a clean session, which causes - * the MQTT server to discard any previous session data for a client identifier. - * When the client disconnects, the server discards all session data. If this - * value is `true`, #IotMqttConnectInfo_t.pPreviousSubscriptions and - * #IotMqttConnectInfo_t.previousSubscriptionCount are ignored. - * - * Setting this value to `false` does one of the following: - * - If no previous session exists, the MQTT server will create a new - * persistent session. The server may maintain subscriptions and - * unacknowledged PUBLISH messages after a client disconnects, to be restored - * once the same client identifier reconnects. - * - If a previous session exists, the MQTT server restores all of the session's - * subscriptions for the client identifier and may immediately transmit any - * unacknowledged PUBLISH packets to the client. - * - * When a client with a persistent session disconnects, the MQTT server - * continues to maintain all subscriptions and unacknowledged PUBLISH messages. - * The client must also remember the session subscriptions to restore them - * upon reconnecting. #IotMqttConnectInfo_t.pPreviousSubscriptions and - * #IotMqttConnectInfo_t.previousSubscriptionCount are used to restore a - * previous session's subscriptions client-side. - */ - bool cleanSession; - - /** - * @brief An array of MQTT subscriptions present in a previous session, if any. - * - * Pointer to the start of an array of subscriptions present a previous session, - * if any. These subscriptions will be immediately restored upon reconnecting. - * - * This member is ignored if it is `NULL` or #IotMqttConnectInfo_t.cleanSession - * is `true`. If this member is not `NULL`, #IotMqttConnectInfo_t.previousSubscriptionCount - * must be nonzero. - */ - const IotMqttSubscription_t * pPreviousSubscriptions; - - /** - * @brief The number of MQTT subscriptions present in a previous session, if any. - * - * Number of subscriptions contained in the array - * #IotMqttConnectInfo_t.pPreviousSubscriptions. - * - * This value is ignored if #IotMqttConnectInfo_t.pPreviousSubscriptions - * is `NULL` or #IotMqttConnectInfo_t.cleanSession is `true`. If - * #IotMqttConnectInfo_t.pPreviousSubscriptions is not `NULL`, this value - * must be nonzero. - */ - size_t previousSubscriptionCount; - - /** - * @brief A message to publish if the new MQTT connection is unexpectedly closed. - * - * A Last Will and Testament (LWT) message may be published if this connection is - * closed without sending an MQTT DISCONNECT packet. This pointer should be set to - * an #IotMqttPublishInfo_t representing any LWT message to publish. If an LWT - * is not needed, this member must be set to `NULL`. - * - * Unlike other PUBLISH messages, an LWT message is limited to 65535 bytes in - * length. Additionally, [pWillInfo->retryMs](@ref IotMqttPublishInfo_t.retryMs) - * and [pWillInfo->retryLimit](@ref IotMqttPublishInfo_t.retryLimit) will - * be ignored. - */ - const IotMqttPublishInfo_t * pWillInfo; - - uint16_t keepAliveSeconds; /**< @brief Period of keep-alive messages. Set to 0 to disable keep-alive. */ - - const char * pClientIdentifier; /**< @brief MQTT client identifier. */ - uint16_t clientIdentifierLength; /**< @brief Length of #IotMqttConnectInfo_t.pClientIdentifier. */ - - /* These credentials are not used by AWS IoT and may be ignored if - * awsIotMqttMode is true. */ - const char * pUserName; /**< @brief Username for MQTT connection. */ - uint16_t userNameLength; /**< @brief Length of #IotMqttConnectInfo_t.pUserName. */ - const char * pPassword; /**< @brief Password for MQTT connection. */ - uint16_t passwordLength; /**< @brief Length of #IotMqttConnectInfo_t.pPassword. */ -} IotMqttConnectInfo_t; - -#if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 - -/** - * @cond DOXYGEN_IGNORE - * Doxygen should ignore this section. - * - * Forward declaration of the internal MQTT packet structure. - */ - struct _mqttPacket; -/** @endcond */ - -/** - * @ingroup mqtt_datatypes_paramstructs - * @brief Function pointers for MQTT packet serializer overrides. - * - * These function pointers allow the MQTT serialization and deserialization functions - * to be overridden for an MQTT connection. The compile-time setting - * @ref IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES must be `1` to enable this functionality. - * See the #IotMqttSerializer_t::serialize and #IotMqttSerializer_t::deserialize - * members for a list of functions that can be overridden. In addition, the functions - * for freeing packets and determining the packet type can also be overridden. If - * @ref IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES is `1`, the serializer initialization and - * cleanup functions may be extended. See documentation of - * @ref IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES for more information. - * - * If any function pointers that are `NULL`, then the default implementation of that - * function will be used. - */ - typedef struct IotMqttSerializer - { - /** - * @brief Get the MQTT packet type from a stream of bytes off the network. - * - * @param[in] pNetworkConnection Reference to the network connection. - * @param[in] pNetworkInterface Function pointers used to interact with the - * network. - * - * Default implementation: #_IotMqtt_GetPacketType - */ - uint8_t ( * getPacketType )( void * /* pNetworkConnection */, - const IotNetworkInterface_t * /* pNetworkInterface */ ); - - /** - * @brief Get the remaining length from a stream of bytes off the network. - * - * @param[in] pNetworkConnection Reference to the network connection. - * @param[in] pNetworkInterface Function pointers used to interact with the - * network. - * - * Default implementation: #_IotMqtt_GetRemainingLength - */ - size_t ( * getRemainingLength )( void * pNetworkConnection, - const IotNetworkInterface_t * pNetworkInterface ); - - /** - * @brief Free a packet generated by the serializer. - * - * This function pointer must be set if any other serializer override is set. - * @param[in] uint8_t* The packet to free. - * - * Default implementation: #_IotMqtt_FreePacket - */ - void ( * freePacket )( uint8_t * /* pPacket */ ); - - struct - { - /** - * @brief CONNECT packet serializer function. - * @param[in] IotMqttConnectInfo_t* User-provided CONNECT information. - * @param[out] uint8_t** Where the CONNECT packet is written. - * @param[out] size_t* Size of the CONNECT packet. - * - * Default implementation: #_IotMqtt_SerializeConnect - */ - IotMqttError_t ( * connect )( const IotMqttConnectInfo_t * /* pConnectInfo */, - uint8_t ** /* pConnectPacket */, - size_t * /* pPacketSize */ ); - - /** - * @brief PUBLISH packet serializer function. - * @param[in] IotMqttPublishInfo_t* User-provided PUBLISH information. - * @param[out] uint8_t** Where the PUBLISH packet is written. - * @param[out] size_t* Size of the PUBLISH packet. - * @param[out] uint16_t* The packet identifier generated for this PUBLISH. - * @param[out] uint8_t** Where the high byte of the packet identifier - * is written. - * - * Default implementation: #_IotMqtt_SerializePublish - */ - IotMqttError_t ( * publish )( const IotMqttPublishInfo_t * /* pPublishInfo */, - uint8_t ** /* pPublishPacket */, - size_t * /* pPacketSize */, - uint16_t * /* pPacketIdentifier */, - uint8_t ** /* pPacketIdentifierHigh */ ); - - /** - * @brief Set the `DUP` bit in a QoS `1` PUBLISH packet. - * @param[in] uint8_t* Pointer to the PUBLISH packet to modify. - * @param[in] uint8_t* The high byte of any packet identifier to modify. - * @param[out] uint16_t* New packet identifier (AWS IoT MQTT mode only). - * - * Default implementation: #_IotMqtt_PublishSetDup - */ - void ( *publishSetDup )( uint8_t * /* pPublishPacket */, - uint8_t * /* pPacketIdentifierHigh */, - uint16_t * /* pNewPacketIdentifier */ ); - - /** - * @brief PUBACK packet serializer function. - * @param[in] uint16_t The packet identifier to place in PUBACK. - * @param[out] uint8_t** Where the PUBACK packet is written. - * @param[out] size_t* Size of the PUBACK packet. - * - * Default implementation: #_IotMqtt_SerializePuback - */ - IotMqttError_t ( * puback )( uint16_t /* packetIdentifier */, - uint8_t ** /* pPubackPacket */, - size_t * /* pPacketSize */ ); - - /** - * @brief SUBSCRIBE packet serializer function. - * @param[in] IotMqttSubscription_t* User-provided array of subscriptions. - * @param[in] size_t Number of elements in the subscription array. - * @param[out] uint8_t** Where the SUBSCRIBE packet is written. - * @param[out] size_t* Size of the SUBSCRIBE packet. - * @param[out] uint16_t* The packet identifier generated for this SUBSCRIBE. - * - * Default implementation: #_IotMqtt_SerializeSubscribe - */ - IotMqttError_t ( * subscribe )( const IotMqttSubscription_t * /* pSubscriptionList */, - size_t /* subscriptionCount */, - uint8_t ** /* pSubscribePacket */, - size_t * /* pPacketSize */, - uint16_t * /* pPacketIdentifier */ ); - - /** - * @brief UNSUBSCRIBE packet serializer function. - * @param[in] IotMqttSubscription_t* User-provided array of subscriptions to remove. - * @param[in] size_t Number of elements in the subscription array. - * @param[out] uint8_t** Where the UNSUBSCRIBE packet is written. - * @param[out] size_t* Size of the UNSUBSCRIBE packet. - * @param[out] uint16_t* The packet identifier generated for this UNSUBSCRIBE. - * - * Default implementation: #_IotMqtt_SerializeUnsubscribe - */ - IotMqttError_t ( * unsubscribe )( const IotMqttSubscription_t * /* pSubscriptionList */, - size_t /* subscriptionCount */, - uint8_t ** /* pUnsubscribePacket */, - size_t * /* pPacketSize */, - uint16_t * /* pPacketIdentifier */ ); - - /** - * @brief PINGREQ packet serializer function. - * @param[out] uint8_t** Where the PINGREQ packet is written. - * @param[out] size_t* Size of the PINGREQ packet. - * - * Default implementation: #_IotMqtt_SerializePingreq - */ - IotMqttError_t ( * pingreq )( uint8_t ** /* pPingreqPacket */, - size_t * /* pPacketSize */ ); - - /** - * @brief DISCONNECT packet serializer function. - * @param[out] uint8_t** Where the DISCONNECT packet is written. - * @param[out] size_t* Size of the DISCONNECT packet. - * - * Default implementation: #_IotMqtt_SerializeDisconnect - */ - IotMqttError_t ( * disconnect )( uint8_t ** /* pDisconnectPacket */, - size_t * /* pPacketSize */ ); - } serialize; /**< @brief Overrides the packet serialization functions for a single connection. */ - - struct - { - /** - * @brief CONNACK packet deserializer function. - * @param[in,out] _mqttPacket* Pointer to an MQTT packet struct representing a CONNACK. - * - * Default implementation: #_IotMqtt_DeserializeConnack - */ - IotMqttError_t ( * connack )( struct _mqttPacket * /* pConnack */ ); - - /** - * @brief PUBLISH packet deserializer function. - * @param[in,out] _mqttPacket* Pointer to an MQTT packet struct representing a PUBLISH. - * - * Default implementation: #_IotMqtt_DeserializePublish - */ - IotMqttError_t ( * publish )( struct _mqttPacket * /* pPublish */ ); - - /** - * @brief PUBACK packet deserializer function. - * @param[in,out] _mqttPacket* Pointer to an MQTT packet struct representing a PUBACK. - * - * Default implementation: #_IotMqtt_DeserializePuback - */ - IotMqttError_t ( * puback )( struct _mqttPacket * pPuback ); - - /** - * @brief SUBACK packet deserializer function. - * @param[in,out] _mqttPacket* Pointer to an MQTT packet struct representing a SUBACK. - * - * Default implementation: #_IotMqtt_DeserializeSuback - */ - IotMqttError_t ( * suback )( struct _mqttPacket * /* pSuback */ ); - - /** - * @brief UNSUBACK packet deserializer function. - * @param[in,out] _mqttPacket* Pointer to an MQTT packet struct representing an UNSUBACK. - * - * Default implementation: #_IotMqtt_DeserializeUnsuback - */ - IotMqttError_t ( * unsuback )( struct _mqttPacket * /* pUnsuback */ ); - - /** - * @brief PINGRESP packet deserializer function. - * @param[in,out] _mqttPacket* Pointer to an MQTT packet struct representing a PINGRESP. - * - * Default implementation: #_IotMqtt_DeserializePingresp - */ - IotMqttError_t ( * pingresp )( struct _mqttPacket * /* pPingresp */ ); - } deserialize; /**< @brief Overrides the packet deserialization functions for a single connection. */ - } IotMqttSerializer_t; -#else /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */ - -/* When MQTT packet serializer overrides are disabled, this struct is an - * incomplete type. */ - typedef struct IotMqttSerializer IotMqttSerializer_t; - -#endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */ - -/** - * @ingroup mqtt_datatypes_paramstructs - * @brief Infomation on the transport-layer network connection for the new MQTT - * connection. - * - * @paramfor @ref mqtt_function_connect - * - * The MQTT library needs to be able to send and receive data over a network. - * This struct provides an interface for interacting with the network. - * - * @initializer{IotMqttNetworkInfo_t,IOT_MQTT_NETWORK_INFO_INITIALIZER} - */ -typedef struct IotMqttNetworkInfo -{ - /** - * @brief Whether a new network connection should be created. - * - * When this value is `true`, a new transport-layer network connection will - * be created along with the MQTT connection. #IotMqttNetworkInfo_t::pNetworkServerInfo - * and #IotMqttNetworkInfo_t::pNetworkCredentialInfo are valid when this value - * is `true`. - * - * When this value is `false`, the MQTT connection will use a transport-layer - * network connection that has already been established. The MQTT library will - * still set the appropriate receive callback even if the network connection - * has been established. - * #IotMqttNetworkInfo_t::pNetworkConnection, which represents an established - * network connection, is valid when this value is `false`. - */ - bool createNetworkConnection; - - union - { - struct - { - /** - * @brief Information on the MQTT server, passed as `pConnectionInfo` to - * #IotNetworkInterface_t::create. - * - * This member is opaque to the MQTT library. It is passed to the network - * interface when creating a new network connection. It is only valid when - * #IotMqttNetworkInfo_t::createNetworkConnection is `true`. - */ - void * pNetworkServerInfo; - - /** - * @brief Credentials for the MQTT server, passed as `pCredentialInfo` to - * #IotNetworkInterface_t::create. - * - * This member is opaque to the MQTT library. It is passed to the network - * interface when creating a new network connection. It is only valid when - * #IotMqttNetworkInfo_t::createNetworkConnection is `true`. - */ - void * pNetworkCredentialInfo; - } setup; - - /** - * @brief An established transport-layer network connection. - * - * This member is opaque to the MQTT library. It is passed to the network - * interface to reference an established network connection. It is only - * valid when #IotMqttNetworkInfo_t::createNetworkConnection is `false`. - */ - void * pNetworkConnection; - } u /**< @brief Valid member depends of IotMqttNetworkInfo_t.createNetworkConnection. */; - - /** - * @brief The network functions used by the new MQTT connection. - * - * @attention The function pointers of the network interface must remain valid - * for the lifetime of the MQTT connection. - */ - const IotNetworkInterface_t * pNetworkInterface; - - /** - * @brief A callback function to invoke when this MQTT connection is disconnected. - */ - IotMqttCallbackInfo_t disconnectCallback; - - #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 - - /** - * @brief MQTT packet serializer overrides used by the new MQTT connection. - * - * @attention The function pointers of the MQTT serializer overrides must - * remain valid for the lifetime of the MQTT connection. - */ - const IotMqttSerializer_t * pMqttSerializer; - #endif -} IotMqttNetworkInfo_t; - -/*------------------------- MQTT defined constants --------------------------*/ - -/** - * @constantspage{mqtt,MQTT library} - * - * @section mqtt_constants_initializers MQTT Initializers - * @brief Provides default values for the data types of the MQTT library. - * - * @snippet this define_mqtt_initializers - * - * All user-facing data types of the MQTT library should be initialized using - * one of the following. - * - * @warning Failing to initialize an MQTT data type with the appropriate initializer - * may result in undefined behavior! - * @note The initializers may change at any time in future versions, but their - * names will remain the same. - * - * Example - * @code{c} - * IotMqttNetworkInfo_t networkInfo = IOT_MQTT_NETWORK_INFO_INITIALIZER; - * IotMqttSerializer_t serializer = IOT_MQTT_SERIALIZER_INITIALIZER; - * IotMqttConnectInfo_t connectInfo = IOT_MQTT_CONNECT_INFO_INITIALIZER; - * IotMqttPublishInfo_t publishInfo = IOT_MQTT_PUBLISH_INFO_INITIALIZER; - * IotMqttSubscription_t subscription = IOT_MQTT_SUBSCRIPTION_INITIALIZER; - * IotMqttCallbackInfo_t callbackInfo = IOT_MQTT_CALLBACK_INFO_INITIALIZER; - * IotMqttConnection_t connection = IOT_MQTT_CONNECTION_INITIALIZER; - * IotMqttOperation_t operation = IOT_MQTT_OPERATION_INITIALIZER; - * @endcode - * - * @section mqtt_constants_flags MQTT Function Flags - * @brief Flags that modify the behavior of MQTT library functions. - * - #IOT_MQTT_FLAG_WAITABLE
- * @copybrief IOT_MQTT_FLAG_WAITABLE - * - #IOT_MQTT_FLAG_CLEANUP_ONLY
- * @copybrief IOT_MQTT_FLAG_CLEANUP_ONLY - * - * Flags should be bitwise-ORed with each other to change the behavior of - * @ref mqtt_function_subscribe, @ref mqtt_function_unsubscribe, - * @ref mqtt_function_publish, or @ref mqtt_function_disconnect. - * - * @note The values of the flags may change at any time in future versions, but - * their names will remain the same. Additionally, flags that may be used together - * will be bitwise-exclusive of each other. - */ - -/* @[define_mqtt_initializers] */ -/** @brief Initializer for #IotMqttNetworkInfo_t. */ -#define IOT_MQTT_NETWORK_INFO_INITIALIZER { .createNetworkConnection = true } -/** @brief Initializer for #IotMqttSerializer_t. */ -#define IOT_MQTT_SERIALIZER_INITIALIZER { 0 } -/** @brief Initializer for #IotMqttConnectInfo_t. */ -#define IOT_MQTT_CONNECT_INFO_INITIALIZER { .cleanSession = true } -/** @brief Initializer for #IotMqttPublishInfo_t. */ -#define IOT_MQTT_PUBLISH_INFO_INITIALIZER { .qos = IOT_MQTT_QOS_0 } -/** @brief Initializer for #IotMqttSubscription_t. */ -#define IOT_MQTT_SUBSCRIPTION_INITIALIZER { .qos = IOT_MQTT_QOS_0 } -/** @brief Initializer for #IotMqttCallbackInfo_t. */ -#define IOT_MQTT_CALLBACK_INFO_INITIALIZER { 0 } -/** @brief Initializer for #IotMqttConnection_t. */ -#define IOT_MQTT_CONNECTION_INITIALIZER NULL -/** @brief Initializer for #IotMqttOperation_t. */ -#define IOT_MQTT_OPERATION_INITIALIZER NULL -/* @[define_mqtt_initializers] */ - -/** - * @brief Allows the use of @ref mqtt_function_wait for blocking until completion. - * - * This flag is always valid for @ref mqtt_function_subscribe and - * @ref mqtt_function_unsubscribe. If passed to @ref mqtt_function_publish, - * the parameter [pPublishInfo->qos](@ref IotMqttPublishInfo_t.qos) must not be `0`. - * - * An #IotMqttOperation_t MUST be provided if this flag is set. Additionally, an - * #IotMqttCallbackInfo_t MUST NOT be provided. - * - * @note If this flag is set, @ref mqtt_function_wait MUST be called to clean up - * resources. - */ -#define IOT_MQTT_FLAG_WAITABLE ( 0x00000001 ) - -/** - * @brief Causes @ref mqtt_function_disconnect to only free memory and not send - * an MQTT DISCONNECT packet. - * - * This flag is only valid for @ref mqtt_function_disconnect. It should be passed - * to @ref mqtt_function_disconnect if the network goes offline or is otherwise - * unusable. - */ -#define IOT_MQTT_FLAG_CLEANUP_ONLY ( 0x00000001 ) - -#endif /* ifndef IOT_MQTT_TYPES_H_ */ 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 deleted file mode 100644 index 143b44297..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_ble_mqtt_serialize.c +++ /dev/null @@ -1,1528 +0,0 @@ -/* - * Amazon FreeRTOS MQTT V2.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file aws_mqtt_lib_ble.c - * @brief MQTT library for BLE. - */ -/* The config header is always included first. */ -#include "iot_config.h" - -/* Standard includes. */ -#include -#include - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" - -#include "iot_ble_config.h" - - -/* MQTT internal includes. */ -#include "platform/iot_threads.h" -#include "iot_serializer.h" -#include "platform/iot_network_ble.h" -#include "iot_ble_data_transfer.h" -#include "iot_ble_mqtt_serialize.h" -#include "private/iot_mqtt_internal.h" - -#define _INVALID_MQTT_PACKET_TYPE ( 0xF0 ) - - -#define _IS_VALID_SERIALIZER_RET( ret, pSerializerBuf ) \ - ( ( ret == IOT_SERIALIZER_SUCCESS ) || \ - ( ( !pSerializerBuf ) && ( ret == IOT_SERIALIZER_BUFFER_TOO_SMALL ) ) ) - -#define _NUM_CONNECT_PARMAS ( 4 ) -#define _NUM_DEFAULT_PUBLISH_PARMAS ( 4 ) -#define _NUM_PUBACK_PARMAS ( 2 ) -#define _NUM_SUBACK_PARAMS ( 4 ) -#define _NUM_UNSUBACK_PARAMS ( 3 ) -#define _NUM_DISCONNECT_PARAMS ( 1 ) -#define _NUM_PINGREQUEST_PARAMS ( 1 ) - -const IotMqttSerializer_t IotBleMqttSerializer = { - .serialize.connect = IotBleMqtt_SerializeConnect, - .serialize.publish = IotBleMqtt_SerializePublish, - .serialize.publishSetDup = IotBleMqtt_PublishSetDup, - .serialize.puback = IotBleMqtt_SerializePuback, - .serialize.subscribe = IotBleMqtt_SerializeSubscribe, - .serialize.unsubscribe = IotBleMqtt_SerializeUnsubscribe, - .serialize.pingreq = IotBleMqtt_SerializePingreq, - .serialize.disconnect = IotBleMqtt_SerializeDisconnect, - .freePacket = IotBleMqtt_FreePacket, - .getPacketType = IotBleMqtt_GetPacketType, - .getRemainingLength = IotBleMqtt_GetRemainingLength, - .deserialize.connack = IotBleMqtt_DeserializeConnack, - .deserialize.publish = IotBleMqtt_DeserializePublish, - .deserialize.puback = IotBleMqtt_DeserializePuback, - .deserialize.suback = IotBleMqtt_DeserializeSuback, - .deserialize.unsuback = IotBleMqtt_DeserializeUnsuback, - .deserialize.pingresp = IotBleMqtt_DeserializePingresp -}; - -/** - * @brief Guards access to the packet identifier counter. - * - * Each packet should have a unique packet identifier. This mutex ensures that only - * one thread at a time may read the global packet identifer. - */ - - -/** - * @brief Generates a monotonically increasing identifier used in MQTT message - * - * @return Identifier for the MQTT message - */ -static uint16_t _nextPacketIdentifier( void ); - - -static inline uint16_t _getNumPublishParams( const IotMqttPublishInfo_t * const pPublish ) -{ - return ( pPublish->qos > 0 ) ? ( _NUM_DEFAULT_PUBLISH_PARMAS + 1 ) : _NUM_DEFAULT_PUBLISH_PARMAS; -} - -static IotSerializerError_t _serializeConnect( const IotMqttConnectInfo_t * const pConnectInfo, - uint8_t* const pBuffer, - size_t* const pSize ); -static IotSerializerError_t _serializePublish( const IotMqttPublishInfo_t * const pPublishInfo, - uint8_t * pBuffer, - size_t * pSize, - uint16_t packetIdentifier ); -static IotSerializerError_t _serializePubAck( uint16_t packetIdentifier, - uint8_t * pBuffer, - size_t * pSize ); - - - -static IotSerializerError_t _serializeSubscribe( const IotMqttSubscription_t * const pSubscriptionList, - size_t subscriptionCount, - uint8_t * const pBuffer, - size_t * const pSize, - uint16_t packetIdentifier ); - -static IotSerializerError_t _serializeUnSubscribe( const IotMqttSubscription_t * const pSubscriptionList, - size_t subscriptionCount, - uint8_t * const pBuffer, - size_t * const pSize, - uint16_t packetIdentifier ); - -static IotSerializerError_t _serializeDisconnect( uint8_t * const pBuffer, - size_t * const pSize ); - - -static IotSerializerError_t _serializePingRequest( uint8_t * const pBuffer, - size_t * const pSize ); - -#if LIBRARY_LOG_LEVEL > AWS_IOT_LOG_NONE - -/** - * @brief If logging is enabled, define a log configuration that only prints the log - * string. This is used when printing out details of deserialized MQTT packets. - */ -static const IotLogConfig_t _logHideAll = -{ - .hideLibraryName = true, - .hideLogLevel = true, - .hideTimestring = true -}; -#endif - - -static IotMutex_t _packetIdentifierMutex; - - -/* Declaration of snprintf. The header stdio.h is not included because it - * includes conflicting symbols on some platforms. */ -extern int snprintf( char * s, - size_t n, - const char * format, - ... ); - -/*-----------------------------------------------------------*/ - -static uint16_t _nextPacketIdentifier( void ) -{ - static uint16_t nextPacketIdentifier = 1; - uint16_t newPacketIdentifier = 0; - - /* Lock the packet identifier mutex so that only one thread may read and - * modify nextPacketIdentifier. */ - IotMutex_Lock( &_packetIdentifierMutex ); - - /* Read the next packet identifier. */ - newPacketIdentifier = nextPacketIdentifier; - - /* The next packet identifier will be greater by 2. This prevents packet - * identifiers from ever being 0, which is not allowed by MQTT 3.1.1. Packet - * identifiers will follow the sequence 1,3,5...65535,1,3,5... */ - nextPacketIdentifier = ( uint16_t ) ( nextPacketIdentifier + ( ( uint16_t ) 2 ) ); - - /* Unlock the packet identifier mutex. */ - IotMutex_Unlock( &_packetIdentifierMutex ); - - return newPacketIdentifier; -} - -static IotSerializerError_t _serializeConnect( const IotMqttConnectInfo_t * const pConnectInfo, - uint8_t* const pBuffer, - size_t* const pSize ) -{ - IotSerializerError_t error = IOT_SERIALIZER_SUCCESS; - IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM ; - IotSerializerEncoderObject_t connectMap = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP; - IotSerializerScalarData_t data = { 0 }; - - error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize ); - if( error == IOT_SERIALIZER_SUCCESS ) - { - - error = IOT_BLE_MESG_ENCODER.openContainer( - &encoderObj, - &connectMap, - _NUM_CONNECT_PARMAS ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT; - data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_CONNECT; - error = IOT_BLE_MESG_ENCODER.appendKeyValue( &connectMap, IOT_BLE_MQTT_MSG_TYPE, data ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - data.type = IOT_SERIALIZER_SCALAR_TEXT_STRING; - data.value.u.string.pString = ( uint8_t * ) pConnectInfo->pClientIdentifier; - data.value.u.string.length = pConnectInfo->clientIdentifierLength; - error = IOT_BLE_MESG_ENCODER.appendKeyValue( &connectMap, IOT_BLE_MQTT_CLIENT_ID, data ); - } - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - data.type = IOT_SERIALIZER_SCALAR_TEXT_STRING; - data.value.u.string.pString = ( uint8_t * ) clientcredentialMQTT_BROKER_ENDPOINT; - data.value.u.string.length = strlen( clientcredentialMQTT_BROKER_ENDPOINT ); - error = IOT_BLE_MESG_ENCODER.appendKeyValue( &connectMap, IOT_BLE_MQTT_BROKER_EP, data ); - } - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - data.type = IOT_SERIALIZER_SCALAR_BOOL; - data.value.u.booleanValue = pConnectInfo->cleanSession; - error = IOT_BLE_MESG_ENCODER.appendKeyValue( &connectMap, IOT_BLE_MQTT_CLEAN_SESSION, data ); - } - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &connectMap ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - if( pBuffer == NULL ) - { - *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj ); - } - else - { - *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer ); - } - - IOT_BLE_MESG_ENCODER.destroy( &encoderObj ); - error = IOT_SERIALIZER_SUCCESS; - - } - - return error; -} - -static IotSerializerError_t _serializePublish( const IotMqttPublishInfo_t * const pPublishInfo, - uint8_t * pBuffer, - size_t * pSize, - uint16_t packetIdentifier ) -{ - IotSerializerError_t error = IOT_SERIALIZER_SUCCESS; - IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM ; - IotSerializerEncoderObject_t publishMap = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP; - IotSerializerScalarData_t data = { 0 }; - uint16_t numPublishParams = _getNumPublishParams( pPublishInfo ); - - error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize ); - - if( error == IOT_SERIALIZER_SUCCESS ) - { - - - error = IOT_BLE_MESG_ENCODER.openContainer( - &encoderObj, - &publishMap, - numPublishParams ); - } - - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT; - data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_PUBLISH; - error = IOT_BLE_MESG_ENCODER.appendKeyValue( &publishMap, IOT_BLE_MQTT_MSG_TYPE, data ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - data.type = IOT_SERIALIZER_SCALAR_TEXT_STRING; - data.value.u.string.pString = ( uint8_t * ) pPublishInfo->pTopicName; - data.value.u.string.length = pPublishInfo->topicNameLength; - error = IOT_BLE_MESG_ENCODER.appendKeyValue( &publishMap, IOT_BLE_MQTT_TOPIC, data ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - - data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT; - data.value.u.signedInt = pPublishInfo->qos; - error = IOT_BLE_MESG_ENCODER.appendKeyValue( &publishMap, IOT_BLE_MQTT_QOS, data ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - data.type = IOT_SERIALIZER_SCALAR_BYTE_STRING; - data.value.u.string.pString = ( uint8_t * ) pPublishInfo->pPayload; - data.value.u.string.length = pPublishInfo->payloadLength; - error = IOT_BLE_MESG_ENCODER.appendKeyValue( &publishMap, IOT_BLE_MQTT_PAYLOAD, data ); - } - - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - if( pPublishInfo->qos != 0 ) - { - data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT; - data.value.u.signedInt = packetIdentifier; - error = IOT_BLE_MESG_ENCODER.appendKeyValue( &publishMap, IOT_BLE_MQTT_MESSAGE_ID, data ); - - } - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - - error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &publishMap ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - if( pBuffer == NULL ) - { - *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj ); - - } - else - { - *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer ); - } - IOT_BLE_MESG_ENCODER.destroy( &encoderObj ); - error = IOT_SERIALIZER_SUCCESS; - } - - - return error; -} - -static IotSerializerError_t _serializePubAck( uint16_t packetIdentifier, - uint8_t * pBuffer, - size_t * pSize ) - -{ - IotSerializerError_t error = IOT_SERIALIZER_SUCCESS; - IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM ; - IotSerializerEncoderObject_t pubAckMap = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP; - IotSerializerScalarData_t data = { 0 }; - - error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize ); - - if( error == IOT_SERIALIZER_SUCCESS ) - { - - error = IOT_BLE_MESG_ENCODER.openContainer( - &encoderObj, - &pubAckMap, - _NUM_PUBACK_PARMAS ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT; - data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_PUBACK; - error = IOT_BLE_MESG_ENCODER.appendKeyValue( &pubAckMap, IOT_BLE_MQTT_MSG_TYPE, data ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT; - data.value.u.signedInt = packetIdentifier; - error = IOT_BLE_MESG_ENCODER.appendKeyValue( &pubAckMap, IOT_BLE_MQTT_MESSAGE_ID, data ); - } - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &pubAckMap ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - if( pBuffer == NULL ) - { - *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj ); - } - else - { - *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer ); - } - IOT_BLE_MESG_ENCODER.destroy( &encoderObj ); - error = IOT_SERIALIZER_SUCCESS; - } - - return error; -} - - -static IotSerializerError_t _serializeSubscribe( const IotMqttSubscription_t * const pSubscriptionList, - size_t subscriptionCount, - uint8_t * const pBuffer, - size_t * const pSize, - uint16_t packetIdentifier ) -{ - IotSerializerError_t error = IOT_SERIALIZER_SUCCESS; - IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM ; - IotSerializerEncoderObject_t subscribeMap = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP; - IotSerializerEncoderObject_t subscriptionArray = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_ARRAY; - IotSerializerScalarData_t data = { 0 }; - uint16_t idx; - - error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize ); - - if( error == IOT_SERIALIZER_SUCCESS ) - { - error = IOT_BLE_MESG_ENCODER.openContainer( - &encoderObj, - &subscribeMap, - _NUM_SUBACK_PARAMS ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT; - data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_SUBSCRIBE; - error = IOT_BLE_MESG_ENCODER.appendKeyValue( &subscribeMap, IOT_BLE_MQTT_MSG_TYPE, data ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - - error = IOT_BLE_MESG_ENCODER.openContainerWithKey( - &subscribeMap, - IOT_BLE_MQTT_TOPIC_LIST, - &subscriptionArray, - subscriptionCount ); - } - - for( idx = 0; idx < subscriptionCount; idx++ ) - { - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - data.type = IOT_SERIALIZER_SCALAR_TEXT_STRING; - data.value.u.string.pString = ( uint8_t * ) pSubscriptionList[ idx ].pTopicFilter; - data.value.u.string.length = pSubscriptionList[ idx ].topicFilterLength; - error = IOT_BLE_MESG_ENCODER.append( &subscriptionArray, data ); - } - else - { - break; - } - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - error = IOT_BLE_MESG_ENCODER.closeContainer( &subscribeMap, &subscriptionArray ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - - error = IOT_BLE_MESG_ENCODER.openContainerWithKey( - &subscribeMap, - IOT_BLE_MQTT_QOS_LIST, - &subscriptionArray, - subscriptionCount ); - } - - - for( idx = 0; idx < subscriptionCount; idx++ ) - { - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - - data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT; - data.value.u.signedInt = pSubscriptionList[ idx ].qos; - error = IOT_BLE_MESG_ENCODER.append( &subscriptionArray, data ); - } - else - { - break; - } - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - error = IOT_BLE_MESG_ENCODER.closeContainer( &subscribeMap, &subscriptionArray ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - - data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT; - data.value.u.signedInt = packetIdentifier; - error = IOT_BLE_MESG_ENCODER.appendKeyValue( &subscribeMap, IOT_BLE_MQTT_MESSAGE_ID, data ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &subscribeMap ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - if( pBuffer == NULL ) - { - *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj ); - } - else - { - *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer ); - } - - IOT_BLE_MESG_ENCODER.destroy( &encoderObj ); - error = IOT_SERIALIZER_SUCCESS; - } - return error; -} - -static IotSerializerError_t _serializeUnSubscribe( const IotMqttSubscription_t * const pSubscriptionList, - size_t subscriptionCount, - uint8_t * const pBuffer, - size_t * const pSize, - uint16_t packetIdentifier ) -{ - IotSerializerError_t error = IOT_SERIALIZER_SUCCESS; - IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM; - IotSerializerEncoderObject_t subscribeMap = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP; - IotSerializerEncoderObject_t subscriptionArray = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_ARRAY; - IotSerializerScalarData_t data = { 0 }; - uint16_t idx; - - error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize ); - - if( error == IOT_SERIALIZER_SUCCESS ) - { - - error = IOT_BLE_MESG_ENCODER.openContainer( - &encoderObj, - &subscribeMap, - _NUM_UNSUBACK_PARAMS ); - } - - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT; - data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_UNSUBSCRIBE; - error = IOT_BLE_MESG_ENCODER.appendKeyValue( &subscribeMap, IOT_BLE_MQTT_MSG_TYPE, data ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - error = IOT_BLE_MESG_ENCODER.openContainerWithKey ( - &subscribeMap, - IOT_BLE_MQTT_TOPIC_LIST, - &subscriptionArray, - subscriptionCount ); - } - - for( idx = 0; idx < subscriptionCount; idx++ ) - { - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - data.type = IOT_SERIALIZER_SCALAR_TEXT_STRING; - data.value.u.string.pString = ( uint8_t * ) pSubscriptionList[ idx ].pTopicFilter; - data.value.u.string.length = pSubscriptionList[ idx ].topicFilterLength; - error = IOT_BLE_MESG_ENCODER.append( &subscriptionArray, data ); - } - else - { - break; - } - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - error = IOT_BLE_MESG_ENCODER.closeContainer( &subscribeMap, &subscriptionArray ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT; - data.value.u.signedInt = packetIdentifier; - error = IOT_BLE_MESG_ENCODER.appendKeyValue( &subscribeMap, IOT_BLE_MQTT_MESSAGE_ID, data ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &subscribeMap ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - if( pBuffer == NULL ) - { - *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj ); - - } - else - { - *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer ); - } - IOT_BLE_MESG_ENCODER.destroy( &encoderObj ); - error = IOT_SERIALIZER_SUCCESS; - } - - return error; -} - -static IotSerializerError_t _serializeDisconnect( uint8_t * const pBuffer, - size_t * const pSize ) -{ - IotSerializerError_t error = IOT_SERIALIZER_SUCCESS; - IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM; - IotSerializerEncoderObject_t disconnectMap = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP; - IotSerializerScalarData_t data = { 0 }; - - error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize ); - - if( error == IOT_SERIALIZER_SUCCESS ) - { - error = IOT_BLE_MESG_ENCODER.openContainer( - &encoderObj, - &disconnectMap, - _NUM_DISCONNECT_PARAMS ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT; - data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_DISCONNECT; - error = IOT_BLE_MESG_ENCODER.appendKeyValue( &disconnectMap, IOT_BLE_MQTT_MSG_TYPE, data ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &disconnectMap ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - if( pBuffer == NULL ) - { - *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj ); - } - else - { - *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer ); - } - IOT_BLE_MESG_ENCODER.destroy( &encoderObj ); - error = IOT_SERIALIZER_SUCCESS; - } - - return error; -} - -static IotSerializerError_t _serializePingRequest( uint8_t * const pBuffer, - size_t * const pSize ) -{ - IotSerializerError_t error = IOT_SERIALIZER_SUCCESS; - IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM; - IotSerializerEncoderObject_t pingRequest = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP; - IotSerializerScalarData_t data = { 0 }; - - error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize ); - - if( error == IOT_SERIALIZER_SUCCESS ) - { - error = IOT_BLE_MESG_ENCODER.openContainer( - &encoderObj, - &pingRequest, - _NUM_PINGREQUEST_PARAMS ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT; - data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_PINGREQ; - error = IOT_BLE_MESG_ENCODER.appendKeyValue( &pingRequest, IOT_BLE_MQTT_MSG_TYPE, data ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &pingRequest ); - } - - if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) ) - { - if( pBuffer == NULL ) - { - *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj ); - } - else - { - *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer ); - } - IOT_BLE_MESG_ENCODER.destroy( &encoderObj ); - error = IOT_SERIALIZER_SUCCESS; - } - - return error; -} - - -bool IotBleMqtt_InitSerialize( void ) -{ - /* Create the packet identifier mutex. */ - return IotMutex_Create( &_packetIdentifierMutex, false ); -} - -void IotBleMqtt_CleanupSerialize( void ) -{ - /* Destroy the packet identifier mutex */ - IotMutex_Destroy( &_packetIdentifierMutex ); -} - - -IotMqttError_t IotBleMqtt_SerializeConnect( const IotMqttConnectInfo_t * const pConnectInfo, - uint8_t ** const pConnectPacket, - size_t * const pPacketSize ) -{ - uint8_t * pBuffer = NULL; - size_t bufLen = 0; - IotSerializerError_t error; - IotMqttError_t ret = IOT_MQTT_SUCCESS; - - - error = _serializeConnect( pConnectInfo, NULL, &bufLen ); - if( error != IOT_SERIALIZER_SUCCESS ) - { - IotLogError( "Failed to find length of serialized CONNECT message, error = %d", error ); - ret = IOT_MQTT_BAD_PARAMETER; - } - - if( ret == IOT_MQTT_SUCCESS ) - { - - pBuffer = IotMqtt_MallocMessage( bufLen ); - - /* If Memory cannot be allocated log an error and return */ - if( pBuffer == NULL ) - { - IotLogError( "Failed to allocate memory for CONNECT packet." ); - ret = IOT_MQTT_NO_MEMORY; - } - } - - if( ret == IOT_MQTT_SUCCESS ) - { - error = _serializeConnect( pConnectInfo, pBuffer, &bufLen ); - if( error != IOT_SERIALIZER_SUCCESS ) - { - IotLogError( "Failed to serialize CONNECT message, error = %d", error ); - ret = IOT_MQTT_BAD_PARAMETER; - } - } - - if( ret == IOT_MQTT_SUCCESS ) - { - *pConnectPacket = pBuffer; - *pPacketSize = bufLen; - } - else - { - *pConnectPacket = NULL; - *pPacketSize = 0; - if( pBuffer != NULL ) - { - IotMqtt_FreeMessage( pBuffer ); - } - } - - return ret; -} - -IotMqttError_t IotBleMqtt_DeserializeConnack( _mqttPacket_t * pConnack ) -{ - - IotSerializerDecoderObject_t decoderObj = { 0 }, decoderValue = { 0 }; - IotSerializerError_t error; - IotMqttError_t ret = IOT_MQTT_SUCCESS; - int64_t respCode = 0L; - - error = IOT_BLE_MESG_DECODER.init( &decoderObj, ( uint8_t * ) pConnack->pRemainingData, pConnack->remainingLength ); - if( ( error != IOT_SERIALIZER_SUCCESS ) - || ( decoderObj.type != IOT_SERIALIZER_CONTAINER_MAP ) ) - { - IotLogError( "Malformed CONNACK, decoding the packet failed, decoder error = %d, type: %d", error, decoderObj.type ); - ret = IOT_MQTT_BAD_RESPONSE; - } - - - if( ret == IOT_MQTT_SUCCESS ) - { - - error = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_STATUS, &decoderValue ); - if ( ( error != IOT_SERIALIZER_SUCCESS ) || - ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) ) - { - IotLogError( "Invalid CONNACK, response code decode failed, error = %d, decoded value type = %d", error, decoderValue.type ); - ret = IOT_MQTT_BAD_RESPONSE; - } - else - { - - respCode = decoderValue.u.value.u.signedInt; - if( ( respCode != IOT_BLE_MQTT_STATUS_CONNECTING ) - && ( respCode != IOT_BLE_MQTT_STATUS_CONNECTED ) ) - { - ret = IOT_MQTT_SERVER_REFUSED; - } - } - } - - IOT_BLE_MESG_DECODER.destroy( &decoderObj ); - - return ret; -} - -IotMqttError_t IotBleMqtt_SerializePublish( const IotMqttPublishInfo_t * const pPublishInfo, - uint8_t ** const pPublishPacket, - size_t * const pPacketSize, - uint16_t * const pPacketIdentifier, - uint8_t ** pPacketIdentifierHigh ) -{ - - uint8_t * pBuffer = NULL; - size_t bufLen = 0; - uint16_t usPacketIdentifier = 0; - IotSerializerError_t error; - IotMqttError_t ret = IOT_MQTT_SUCCESS; - - (void)pPacketIdentifierHigh; - - if( pPublishInfo->qos != 0 ) - { - usPacketIdentifier = _nextPacketIdentifier(); - } - - error = _serializePublish( pPublishInfo, NULL, &bufLen, usPacketIdentifier ); - if( error != IOT_SERIALIZER_SUCCESS ) - { - IotLogError( "Failed to find size of serialized PUBLISH message, error = %d", error ); - ret = IOT_MQTT_BAD_PARAMETER; - } - - if( ret == IOT_MQTT_SUCCESS ) - { - - pBuffer = IotMqtt_MallocMessage( bufLen ); - /* If Memory cannot be allocated log an error and return */ - if( pBuffer == NULL ) - { - IotLogError( "Failed to allocate memory for PUBLISH packet." ); - ret = IOT_MQTT_NO_MEMORY; - } - } - - if( ret == IOT_MQTT_SUCCESS ) - { - - error = _serializePublish( pPublishInfo, pBuffer, &bufLen, usPacketIdentifier ); - if( error != IOT_SERIALIZER_SUCCESS ) - { - IotLogError( "Failed to serialize PUBLISH message, error = %d", error ); - ret = IOT_MQTT_BAD_PARAMETER; - } - } - - if( ret == IOT_MQTT_SUCCESS ) - { - *pPublishPacket = pBuffer; - *pPacketSize = bufLen; - *pPacketIdentifier = usPacketIdentifier; - } - else - { - if( pBuffer != NULL ) - { - IotMqtt_FreeMessage( pBuffer ); - } - *pPublishPacket = NULL; - *pPacketSize = 0; - } - - return ret; -} - -void IotBleMqtt_PublishSetDup( uint8_t * const pPublishPacket, uint8_t * pPacketIdentifierHigh, uint16_t * const pNewPacketIdentifier ) -{ - /** TODO: Currently DUP flag is not supported by BLE SDKs **/ -} - -IotMqttError_t IotBleMqtt_DeserializePublish( _mqttPacket_t * pPublish ) -{ - - IotSerializerDecoderObject_t decoderObj = { 0 }, decoderValue = { 0 }; - IotSerializerError_t xSerializerRet; - IotMqttError_t ret = IOT_MQTT_SUCCESS; - - xSerializerRet = IOT_BLE_MESG_DECODER.init( &decoderObj, ( uint8_t * ) pPublish->pRemainingData, pPublish->remainingLength ); - if ( (xSerializerRet != IOT_SERIALIZER_SUCCESS ) || - ( decoderObj.type != IOT_SERIALIZER_CONTAINER_MAP ) ) - { - - IotLogError( "Decoding PUBLISH packet failed, decoder error = %d, object type = %d", xSerializerRet, decoderObj.type ); - ret = IOT_MQTT_BAD_RESPONSE; - } - - if( ret == IOT_MQTT_SUCCESS ) - { - xSerializerRet = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_QOS, &decoderValue ); - if ( ( xSerializerRet != IOT_SERIALIZER_SUCCESS ) || - ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) ) - { - IotLogError( "QOS Value decode failed, error = %d, decoded value type = %d", xSerializerRet, decoderValue.type ); - ret = IOT_MQTT_BAD_RESPONSE; - } - else - { - pPublish->u.pIncomingPublish->u.publish.publishInfo.qos = decoderValue.u.value.u.signedInt; - } - } - - if( ret == IOT_MQTT_SUCCESS ) - { - decoderValue.u.value.u.string.pString = NULL; - decoderValue.u.value.u.string.length = 0; - xSerializerRet = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_TOPIC, &decoderValue ); - - if( ( xSerializerRet != IOT_SERIALIZER_SUCCESS ) || - ( decoderValue.type != IOT_SERIALIZER_SCALAR_TEXT_STRING ) ) - { - IotLogError( "Topic value decode failed, error = %d", xSerializerRet ); - ret = IOT_MQTT_BAD_RESPONSE; - } - else - { - pPublish->u.pIncomingPublish->u.publish.publishInfo.pTopicName = ( const char* ) decoderValue.u.value.u.string.pString; - pPublish->u.pIncomingPublish->u.publish.publishInfo.topicNameLength = decoderValue.u.value.u.string.length; - } - } - - if( ret == IOT_MQTT_SUCCESS ) - { - decoderValue.u.value.u.string.pString = NULL; - decoderValue.u.value.u.string.length = 0; - xSerializerRet = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_PAYLOAD, &decoderValue ); - - if( ( xSerializerRet != IOT_SERIALIZER_SUCCESS ) || - ( decoderValue.type != IOT_SERIALIZER_SCALAR_BYTE_STRING ) ) - { - IotLogError( "Payload value decode failed, error = %d", xSerializerRet ); - ret = IOT_MQTT_BAD_RESPONSE; - } - else - { - pPublish->u.pIncomingPublish->u.publish.publishInfo.pPayload = ( const char* ) decoderValue.u.value.u.string.pString; - pPublish->u.pIncomingPublish->u.publish.publishInfo.payloadLength = decoderValue.u.value.u.string.length; - } - } - - if( ret == IOT_MQTT_SUCCESS ) - { - if( pPublish->u.pIncomingPublish->u.publish.publishInfo.qos != 0 ) - { - xSerializerRet = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_MESSAGE_ID, &decoderValue ); - if ( ( xSerializerRet != IOT_SERIALIZER_SUCCESS ) || - ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) ) - { - IotLogError( "Message identifier decode failed, error = %d, decoded value type = %d", xSerializerRet, decoderValue.type ); - ret = IOT_MQTT_BAD_RESPONSE; - } - else - { - pPublish->packetIdentifier = ( uint16_t ) decoderValue.u.value.u.signedInt; - } - } - } - - if( ret == IOT_MQTT_SUCCESS ) - { - pPublish->u.pIncomingPublish->u.publish.publishInfo.retain = false; - } - - IOT_BLE_MESG_DECODER.destroy( &decoderObj ); - - return ret; -} - -IotMqttError_t IotBleMqtt_SerializePuback( uint16_t packetIdentifier, - uint8_t ** const pPubackPacket, - size_t * const pPacketSize ) -{ - uint8_t * pBuffer = NULL; - size_t bufLen = 0; - IotSerializerError_t error; - IotMqttError_t ret = IOT_MQTT_SUCCESS; - - error = _serializePubAck( packetIdentifier, NULL, &bufLen ); - - if( error != IOT_SERIALIZER_SUCCESS ) - { - IotLogError( "Failed to find size of serialized PUBACK message, error = %d", error ); - ret = IOT_MQTT_BAD_PARAMETER; - } - - - if( ret == IOT_MQTT_SUCCESS ) - { - pBuffer = IotMqtt_MallocMessage( bufLen ); - - /* If Memory cannot be allocated log an error and return */ - if( pBuffer == NULL ) - { - IotLogError( "Failed to allocate memory for PUBACK packet, packet identifier = %d", packetIdentifier ); - ret = IOT_MQTT_NO_MEMORY; - } - } - - - if( ret == IOT_MQTT_SUCCESS ) - { - error = _serializePubAck( packetIdentifier, pBuffer, &bufLen ); - - if( error != IOT_SERIALIZER_SUCCESS ) - { - IotLogError( "Failed to find size of serialized PUBACK message, error = %d", error ); - ret = IOT_MQTT_BAD_PARAMETER; - } - } - - - if( ret == IOT_MQTT_SUCCESS ) - { - *pPubackPacket = pBuffer; - *pPacketSize = bufLen; - } - else - { - if( pBuffer != NULL ) - { - IotMqtt_FreeMessage( pBuffer ); - } - - *pPubackPacket = NULL; - *pPacketSize = 0; - } - - return ret; - -} - -IotMqttError_t IotBleMqtt_DeserializePuback( _mqttPacket_t * pPuback ) -{ - - IotSerializerDecoderObject_t decoderObj = { 0 }, decoderValue = { 0 }; - IotSerializerError_t error; - IotMqttError_t ret = IOT_MQTT_SUCCESS; - - error = IOT_BLE_MESG_DECODER.init( &decoderObj, ( uint8_t * ) pPuback->pRemainingData, pPuback->remainingLength ); - - if ( ( error != IOT_SERIALIZER_SUCCESS ) - || ( decoderObj.type != IOT_SERIALIZER_CONTAINER_MAP ) ) - { - IotLogError( "Malformed PUBACK, decoding the packet failed, decoder error = %d, object type: %d", error, decoderObj.type ); - ret = IOT_MQTT_BAD_RESPONSE; - } - - - if( ret == IOT_MQTT_SUCCESS ) - { - - error = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_MESSAGE_ID, &decoderValue ); - - if ( ( error != IOT_SERIALIZER_SUCCESS ) || - ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) ) - { - IotLogError( "Message ID decode failed, error = %d, decoded value type = %d", error, decoderValue.type ); - ret = IOT_MQTT_BAD_RESPONSE; - } - else - { - pPuback->packetIdentifier = ( uint16_t ) decoderValue.u.value.u.signedInt; - } - } - - IOT_BLE_MESG_DECODER.destroy( &decoderObj ); - - return ret; - -} - -IotMqttError_t IotBleMqtt_SerializeSubscribe( const IotMqttSubscription_t * const pSubscriptionList, - size_t subscriptionCount, - uint8_t ** const pSubscribePacket, - size_t * const pPacketSize, - uint16_t * const pPacketIdentifier ) -{ - uint8_t * pBuffer = NULL; - size_t bufLen = 0; - uint16_t usPacketIdentifier = 0; - IotSerializerError_t error; - IotMqttError_t ret = IOT_MQTT_SUCCESS; - - usPacketIdentifier = _nextPacketIdentifier(); - - error = _serializeSubscribe( pSubscriptionList, subscriptionCount, NULL, &bufLen, usPacketIdentifier ); - if( error != IOT_SERIALIZER_SUCCESS ) - { - IotLogError( "Failed to find serialized length of SUBSCRIBE message, error = %d", error ); - ret = IOT_MQTT_BAD_PARAMETER; - } - - if( ret == IOT_MQTT_SUCCESS ) - { - pBuffer = IotMqtt_MallocMessage( bufLen ); - - /* If Memory cannot be allocated log an error and return */ - if( pBuffer == NULL ) - { - IotLogError( "Failed to allocate memory for SUBSCRIBE message." ); - ret = IOT_MQTT_NO_MEMORY; - } - } - - if( ret == IOT_MQTT_SUCCESS ) - { - error = _serializeSubscribe( pSubscriptionList, subscriptionCount, pBuffer, &bufLen, usPacketIdentifier ); - if( error != IOT_SERIALIZER_SUCCESS ) - { - IotLogError( "Failed to serialize SUBSCRIBE message, error = %d", error ); - ret = IOT_MQTT_BAD_PARAMETER; - } - } - - if( ret == IOT_MQTT_SUCCESS ) - { - *pSubscribePacket = pBuffer; - *pPacketSize = bufLen; - *pPacketIdentifier = usPacketIdentifier; - } - else - { - if( pBuffer != NULL ) - { - IotMqtt_FreeMessage( pBuffer ); - } - - *pSubscribePacket = NULL; - *pPacketSize = 0; - } - - return ret; -} - -IotMqttError_t IotBleMqtt_DeserializeSuback( _mqttPacket_t * pSuback ) -{ - - IotSerializerDecoderObject_t decoderObj = { 0 }, decoderValue = { 0 }; - IotSerializerError_t error; - int64_t subscriptionStatus; - IotMqttError_t ret = IOT_MQTT_SUCCESS; - - error = IOT_BLE_MESG_DECODER.init( &decoderObj, ( uint8_t * ) pSuback->pRemainingData, pSuback->remainingLength ); - - if ( ( error != IOT_SERIALIZER_SUCCESS ) - || ( decoderObj.type != IOT_SERIALIZER_CONTAINER_MAP ) ) - { - IotLogError( "Malformed SUBACK, decoding the packet failed, decoder error = %d, type: %d", error, decoderObj.type ); - ret = IOT_MQTT_BAD_RESPONSE; - } - - if( ret == IOT_MQTT_SUCCESS ) - { - - error = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_MESSAGE_ID, &decoderValue ); - if ( ( error != IOT_SERIALIZER_SUCCESS ) || - ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) ) - { - IotLogError( "Message ID decode failed, error = %d, decoded value type = %d", error, decoderValue.type ); - ret = IOT_MQTT_BAD_RESPONSE; - } - else - { - pSuback->packetIdentifier = ( uint16_t ) decoderValue.u.value.u.signedInt; - } - } - - if( ret == IOT_MQTT_SUCCESS ) - { - error = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_STATUS, &decoderValue ); - if ( ( error != IOT_SERIALIZER_SUCCESS ) || - ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) ) - { - IotLogError( "Status code decode failed, error = %d, decoded value type = %d", error, decoderValue.type ); - ret = IOT_MQTT_BAD_RESPONSE; - } - else - { - subscriptionStatus = ( uint16_t ) decoderValue.u.value.u.signedInt; - switch( subscriptionStatus ) - { - case 0x00: - case 0x01: - case 0x02: - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "Topic accepted, max QoS %hhu.", subscriptionStatus ); - ret = IOT_MQTT_SUCCESS; - break; - case 0x80: - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "Topic refused." ); - - /* Remove a rejected subscription from the subscription manager. */ - _IotMqtt_RemoveSubscriptionByPacket( - pSuback->u.pMqttConnection, - pSuback->packetIdentifier, - 0 ); - ret = IOT_MQTT_SERVER_REFUSED; - break; - default: - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "Bad SUBSCRIBE status %hhu.", subscriptionStatus ); - - ret = IOT_MQTT_BAD_RESPONSE; - break; - } - } - - } - - IOT_BLE_MESG_DECODER.destroy( &decoderObj ); - - return ret; -} - -IotMqttError_t IotBleMqtt_SerializeUnsubscribe( const IotMqttSubscription_t * const pSubscriptionList, - size_t subscriptionCount, - uint8_t ** const pUnsubscribePacket, - size_t * const pPacketSize, - uint16_t * const pPacketIdentifier ) -{ - - uint8_t * pBuffer = NULL; - size_t bufLen = 0; - uint16_t usPacketIdentifier = 0; - IotSerializerError_t error; - IotMqttError_t ret = IOT_MQTT_SUCCESS; - - usPacketIdentifier = _nextPacketIdentifier(); - - error = _serializeUnSubscribe( pSubscriptionList, subscriptionCount, NULL, &bufLen, usPacketIdentifier ); - if( error != IOT_SERIALIZER_SUCCESS ) - { - IotLogError( "Failed to find serialized length of UNSUBSCRIBE message, error = %d", error ); - ret = IOT_MQTT_BAD_PARAMETER; - } - - if( ret == IOT_MQTT_SUCCESS ) - { - pBuffer = IotMqtt_MallocMessage( bufLen ); - - /* If Memory cannot be allocated log an error and return */ - if( pBuffer == NULL ) - { - IotLogError( "Failed to allocate memory for UNSUBSCRIBE message." ); - ret = IOT_MQTT_NO_MEMORY; - } - } - - if( ret == IOT_MQTT_SUCCESS ) - { - error = _serializeUnSubscribe( pSubscriptionList, subscriptionCount, pBuffer, &bufLen, usPacketIdentifier ); - if( error != IOT_SERIALIZER_SUCCESS ) - { - IotLogError( "Failed to serialize UNSUBSCRIBE message, error = %d", error ); - ret = IOT_MQTT_BAD_PARAMETER; - } - } - - if( ret == IOT_MQTT_SUCCESS ) - { - *pUnsubscribePacket = pBuffer; - *pPacketSize = bufLen; - *pPacketIdentifier = usPacketIdentifier; - } - else - { - if( pBuffer != NULL ) - { - IotMqtt_FreeMessage( pBuffer ); - } - - *pUnsubscribePacket = NULL; - *pPacketSize = 0; - } - - return ret; -} - -IotMqttError_t IotBleMqtt_DeserializeUnsuback( _mqttPacket_t * pUnsuback ) -{ - IotSerializerDecoderObject_t decoderObj = { 0 }, decoderValue = { 0 }; - IotSerializerError_t error; - IotMqttError_t ret = IOT_MQTT_SUCCESS; - - error = IOT_BLE_MESG_DECODER.init( &decoderObj, ( uint8_t * ) pUnsuback->pRemainingData, pUnsuback->remainingLength ); - if( ( error != IOT_SERIALIZER_SUCCESS ) - || ( decoderObj.type != IOT_SERIALIZER_CONTAINER_MAP ) ) - { - IotLogError( "Malformed UNSUBACK, decoding the packet failed, decoder error = %d, type:%d ", error, decoderObj.type ); - ret = IOT_MQTT_BAD_RESPONSE; - } - - if( ret == IOT_MQTT_SUCCESS ) - { - error = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_MESSAGE_ID, &decoderValue ); - if ( ( error != IOT_SERIALIZER_SUCCESS ) || - ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) ) - { - IotLogError( "UNSUBACK Message identifier decode failed, error = %d, decoded value type = %d", error, decoderValue.type ); - ret = IOT_MQTT_BAD_RESPONSE; - - } - else - { - pUnsuback->packetIdentifier = ( uint16_t ) decoderValue.u.value.u.signedInt; - } - } - - IOT_BLE_MESG_DECODER.destroy( &decoderObj ); - - return IOT_MQTT_SUCCESS; -} - -IotMqttError_t IotBleMqtt_SerializeDisconnect( uint8_t ** const pDisconnectPacket, - size_t * const pPacketSize ) -{ - uint8_t *pBuffer = NULL; - size_t bufLen = 0; - IotSerializerError_t error; - IotMqttError_t ret = IOT_MQTT_SUCCESS; - - error = _serializeDisconnect( NULL, &bufLen); - if( error != IOT_SERIALIZER_SUCCESS ) - { - IotLogError( "Failed to find serialized length of DISCONNECT message, error = %d", error ); - ret = IOT_MQTT_BAD_PARAMETER; - } - - if( ret == IOT_MQTT_SUCCESS ) - { - pBuffer = IotMqtt_MallocMessage( bufLen ); - - /* If Memory cannot be allocated log an error and return */ - if( pBuffer == NULL ) - { - IotLogError( "Failed to allocate memory for DISCONNECT message." ); - ret = IOT_MQTT_NO_MEMORY; - } - } - - - if( ret == IOT_MQTT_SUCCESS ) - { - error = _serializeDisconnect( pBuffer, &bufLen ); - if( error != IOT_SERIALIZER_SUCCESS ) - { - IotLogError( "Failed to serialize DISCONNECT message, error = %d", error ); - ret = IOT_MQTT_BAD_PARAMETER; - } - } - - if( ret == IOT_MQTT_SUCCESS ) - { - *pDisconnectPacket = pBuffer; - *pPacketSize = bufLen; - } - else - { - if( pBuffer != NULL ) - { - IotMqtt_FreeMessage( pBuffer ); - } - - *pDisconnectPacket = NULL; - *pPacketSize = 0; - } - - return ret; -} - -size_t IotBleMqtt_GetRemainingLength ( void * pNetworkConnection, - const IotNetworkInterface_t * pNetworkInterface ) -{ - const uint8_t *pBuffer; - size_t length; - - IotBleDataTransfer_PeekReceiveBuffer( *( IotBleDataTransferChannel_t ** ) ( pNetworkConnection ), &pBuffer, &length ); - - return length; -} - - -uint8_t IotBleMqtt_GetPacketType( void * pNetworkConnection, const IotNetworkInterface_t * pNetworkInterface ) -{ - - IotSerializerDecoderObject_t decoderObj = { 0 }, decoderValue = { 0 }; - IotSerializerError_t error; - uint8_t value = 0xFF, packetType = _INVALID_MQTT_PACKET_TYPE; - const uint8_t *pBuffer; - size_t length; - - IotBleDataTransfer_PeekReceiveBuffer( *( IotBleDataTransferChannel_t ** ) ( pNetworkConnection ), &pBuffer, &length ); - - error = IOT_BLE_MESG_DECODER.init( &decoderObj, pBuffer, length ); - - if( ( error == IOT_SERIALIZER_SUCCESS ) - && ( decoderObj.type == IOT_SERIALIZER_CONTAINER_MAP ) ) - { - - error = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_MSG_TYPE, &decoderValue ); - - if ( ( error == IOT_SERIALIZER_SUCCESS ) && - ( decoderValue.type == IOT_SERIALIZER_SCALAR_SIGNED_INT ) ) - { - value = ( uint16_t ) decoderValue.u.value.u.signedInt; - - /** Left shift by 4 bits as MQTT library expects packet type to be upper 4 bits **/ - packetType = value << 4; - } - else - { - IotLogError( "Packet type decode failed, error = %d, decoded value type = %d", error, decoderValue.type ); - } - } - else - { - IotLogError( "Decoding the packet failed, decoder error = %d, type = %d", error, decoderObj.type ); - } - - IOT_BLE_MESG_DECODER.destroy( &decoderObj ); - - return packetType; -} - -IotMqttError_t IotBleMqtt_SerializePingreq( uint8_t ** const pPingreqPacket, - size_t * const pPacketSize ) -{ - uint8_t *pBuffer = NULL; - size_t bufLen = 0; - IotSerializerError_t error; - IotMqttError_t ret = IOT_MQTT_SUCCESS; - - error = _serializePingRequest( NULL, &bufLen); - if( error != IOT_SERIALIZER_SUCCESS ) - { - IotLogError( "Failed to find serialized length of DISCONNECT message, error = %d", error ); - ret = IOT_MQTT_BAD_PARAMETER; - } - - if( ret == IOT_MQTT_SUCCESS ) - { - pBuffer = IotMqtt_MallocMessage( bufLen ); - - /* If Memory cannot be allocated log an error and return */ - if( pBuffer == NULL ) - { - IotLogError( "Failed to allocate memory for DISCONNECT message." ); - ret = IOT_MQTT_NO_MEMORY; - } - } - - if( ret == IOT_MQTT_SUCCESS ) - { - error = _serializePingRequest( pBuffer, &bufLen ); - if( error != IOT_SERIALIZER_SUCCESS ) - { - IotLogError( "Failed to serialize DISCONNECT message, error = %d", error ); - ret = IOT_MQTT_BAD_PARAMETER; - } - } - - if( ret == IOT_MQTT_SUCCESS ) - { - *pPingreqPacket = pBuffer; - *pPacketSize = bufLen; - } - else - { - if( pBuffer != NULL ) - { - IotMqtt_FreeMessage( pBuffer ); - } - - *pPingreqPacket = NULL; - *pPacketSize = 0; - } - - return ret; - -} - -IotMqttError_t IotBleMqtt_DeserializePingresp( _mqttPacket_t * pPingresp ) -{ - /* Ping Response for BLE contains only packet type field in CBOR, which is already decoded - in IotBleMqtt_GetPacketType() function. Returning IOT_MQTT_SUCCESS. */ - return IOT_MQTT_SUCCESS; -} - -void IotBleMqtt_FreePacket( uint8_t * pPacket ) -{ - IotMqtt_FreeMessage( pPacket ); -} 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 deleted file mode 100644 index 9a73b2587..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_agent.c +++ /dev/null @@ -1,794 +0,0 @@ -/* - * Amazon FreeRTOS MQTT V2.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_mqtt_agent.c - * @brief MQTT Agent implementation. Provides backwards compatibility between - * MQTT v2 and MQTT v1. - */ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* Standard includes. */ -#include - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "semphr.h" - -/* MQTT v1 includes. */ -#include "iot_mqtt_agent.h" -#include "iot_mqtt_agent_config.h" -#include "iot_mqtt_agent_config_defaults.h" - -/* MQTT v2 include. */ -#include "iot_mqtt.h" - -/* Platform network include. */ -#include "platform/iot_network_freertos.h" - -/*-----------------------------------------------------------*/ - -/** - * @brief Converts FreeRTOS ticks to milliseconds. - */ -#define mqttTICKS_TO_MS( xTicks ) ( xTicks * 1000 / configTICK_RATE_HZ ) - -/*-----------------------------------------------------------*/ - -/** - * @brief Stores data to convert between the MQTT v1 subscription callback - * and the MQTT v2 subscription callback. - */ -#if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) - typedef struct MQTTCallback - { - BaseType_t xInUse; /**< Whether this instance is in-use. */ - MQTTPublishCallback_t xFunction; /**< MQTT v1 callback function. */ - void * pvParameter; /**< Parameter to xFunction. */ - - uint16_t usTopicFilterLength; /**< Length of pcTopicFilter. */ - char pcTopicFilter[ mqttconfigSUBSCRIPTION_MANAGER_MAX_TOPIC_LENGTH ]; /**< Topic filter. */ - } MQTTCallback_t; -#endif - -/** - * @brief Stores data on an active MQTT connection. - */ -typedef struct MQTTConnection -{ - IotMqttConnection_t xMQTTConnection; /**< MQTT v2 connection handle. */ - MQTTAgentCallback_t pxCallback; /**< MQTT v1 global callback. */ - void * pvUserData; /**< Parameter to pxCallback. */ - StaticSemaphore_t xConnectionMutex; /**< Protects from concurrent accesses. */ - #if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) - MQTTCallback_t xCallbacks /**< Conversion table of MQTT v1 to MQTT v2 subscription callbacks. */ - [ mqttconfigSUBSCRIPTION_MANAGER_MAX_SUBSCRIPTIONS ]; - #endif -} MQTTConnection_t; - -/*-----------------------------------------------------------*/ - -/** - * @brief Convert an MQTT v2 return code to an MQTT v1 return code. - * - * @param[in] xMqttStatus The MQTT v2 return code. - * - * @return An equivalent MQTT v1 return code. - */ -static inline MQTTAgentReturnCode_t prvConvertReturnCode( IotMqttError_t xMqttStatus ); - -/** - * @brief Wraps an MQTT v1 publish callback. - * - * @param[in] pvParameter The MQTT connection. - * @param[in] pxPublish Information about the incoming publish. - */ -static void prvPublishCallbackWrapper( void * pvParameter, - IotMqttCallbackParam_t * const pxPublish ); - -/** - * @brief Wraps an MQTT v1 disconnect callback. - * - * @param[in] pvCallbackContext The MQTT connection. - * @param[in] pxDisconnect Information about the disconnect. - */ -static void prvDisconnectCallbackWrapper( void * pvParameter, - IotMqttCallbackParam_t * pxDisconnect ); - -#if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) - -/** - * @brief Store an MQTT v1 callback in the conversion table. - * - * @param[in] pxConnection Where to store the callback. - * @param[in] pcTopicFilter Topic filter to store. - * @param[in] usTopicFilterLength Length of pcTopicFilter. - * @param[in] xCallback MQTT v1 callback to store. - * @param[in] pvParameter Parameter to xCallback. - * - * @return pdPASS if the callback was successfully stored; pdFAIL otherwise. - */ - static BaseType_t prvStoreCallback( MQTTConnection_t * const pxConnection, - const char * const pcTopicFilter, - uint16_t usTopicFilterLength, - MQTTPublishCallback_t xCallback, - void * pvParameter ); - -/** - * @brief Search the callback conversion table for the given topic filter. - * - * @param[in] pxConnection The connection containing the conversion table. - * @param[in] pcTopicFilter The topic filter to search for. - * @param[in] usTopicFilterLength The length of pcTopicFilter. - * - * @return A pointer to the callback entry if found; NULL otherwise. - * @note This function should be called with pxConnection->xConnectionMutex - * locked. - */ - static MQTTCallback_t * prvFindCallback( MQTTConnection_t * const pxConnection, - const char * const pcTopicFilter, - uint16_t usTopicFilterLength ); - -/** - * @brief Remove a topic filter from the callback conversion table. - * - * @param[in] pxConnection The connection containing the conversion table. - * @param[in] pcTopicFilter The topic filter to remove. - * @param[in] usTopicFilterLength The length of pcTopic. - */ - static void prvRemoveCallback( MQTTConnection_t * const pxConnection, - const char * const pcTopicFilter, - uint16_t usTopicFilterLength ); -#endif /* if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) */ - -/*-----------------------------------------------------------*/ - -/** - * @brief The number of available MQTT brokers, controlled by the constant - * mqttconfigMAX_BROKERS; - */ -static UBaseType_t uxAvailableBrokers = mqttconfigMAX_BROKERS; - -/*-----------------------------------------------------------*/ - -static inline MQTTAgentReturnCode_t prvConvertReturnCode( IotMqttError_t xMqttStatus ) -{ - MQTTAgentReturnCode_t xStatus = eMQTTAgentSuccess; - - switch( xMqttStatus ) - { - case IOT_MQTT_SUCCESS: - case IOT_MQTT_STATUS_PENDING: - xStatus = eMQTTAgentSuccess; - break; - - case IOT_MQTT_TIMEOUT: - xStatus = eMQTTAgentTimeout; - break; - - default: - xStatus = eMQTTAgentFailure; - break; - } - - return xStatus; -} - -/*-----------------------------------------------------------*/ - -static void prvPublishCallbackWrapper( void * pvParameter, - IotMqttCallbackParam_t * const pxPublish ) -{ - BaseType_t xStatus = pdPASS; - size_t xBufferSize = 0; - uint8_t * pucMqttBuffer = NULL; - MQTTBool_t xCallbackReturn = eMQTTFalse; - MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) pvParameter; - MQTTAgentCallbackParams_t xPublishData = { .xMQTTEvent = eMQTTAgentPublish }; - - /* Calculate the size of the MQTT buffer that must be allocated. */ - if( xStatus == pdPASS ) - { - xBufferSize = pxPublish->u.message.info.topicNameLength + - pxPublish->u.message.info.payloadLength; - - /* Check for overflow. */ - if( ( xBufferSize < pxPublish->u.message.info.topicNameLength ) || - ( xBufferSize < pxPublish->u.message.info.payloadLength ) ) - { - mqttconfigDEBUG_LOG( ( "Incoming PUBLISH message and topic name length too large.\r\n" ) ); - xStatus = pdFAIL; - } - } - - /* Allocate an MQTT buffer for the callback. */ - if( xStatus == pdPASS ) - { - pucMqttBuffer = pvPortMalloc( xBufferSize ); - - if( pucMqttBuffer == NULL ) - { - mqttconfigDEBUG_LOG( ( "Failed to allocate memory for MQTT buffer.\r\n" ) ); - xStatus = pdFAIL; - } - else - { - /* Copy the topic name and payload. The topic name and payload must be - * copied in case the user decides to take ownership of the MQTT buffer. - * The original buffer containing the MQTT topic name and payload may - * contain further unprocessed packets and must remain property of the - * MQTT library. Therefore, the topic name and payload are copied into - * another buffer for the user. */ - ( void ) memcpy( pucMqttBuffer, - pxPublish->u.message.info.pTopicName, - pxPublish->u.message.info.topicNameLength ); - ( void ) memcpy( pucMqttBuffer + pxPublish->u.message.info.topicNameLength, - pxPublish->u.message.info.pPayload, - pxPublish->u.message.info.payloadLength ); - - /* Set the members of the callback parameter. */ - xPublishData.xMQTTEvent = eMQTTAgentPublish; - xPublishData.u.xPublishData.pucTopic = pucMqttBuffer; - xPublishData.u.xPublishData.usTopicLength = pxPublish->u.message.info.topicNameLength; - xPublishData.u.xPublishData.pvData = pucMqttBuffer + pxPublish->u.message.info.topicNameLength; - xPublishData.u.xPublishData.ulDataLength = ( uint32_t ) pxPublish->u.message.info.payloadLength; - xPublishData.u.xPublishData.xQos = ( MQTTQoS_t ) pxPublish->u.message.info.qos; - xPublishData.u.xPublishData.xBuffer = pucMqttBuffer; - } - } - - if( xStatus == pdPASS ) - { - #if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) - /* When subscription management is enabled, search for a matching subscription. */ - MQTTCallback_t * pxCallbackEntry = prvFindCallback( pxConnection, - pxPublish->u.message.pTopicFilter, - pxPublish->u.message.topicFilterLength ); - - /* Check if a matching MQTT v1 subscription was found. */ - if( pxCallbackEntry != NULL ) - { - /* Invoke the topic-specific callback if it exists. */ - if( pxCallbackEntry->xFunction != NULL ) - { - xCallbackReturn = pxCallbackEntry->xFunction( pxCallbackEntry->pvParameter, - &( xPublishData.u.xPublishData ) ); - } - else - { - /* Otherwise, invoke the global callback. */ - if( pxConnection->pxCallback != NULL ) - { - xCallbackReturn = ( MQTTBool_t ) pxConnection->pxCallback( pxConnection->pvUserData, - &xPublishData ); - } - } - } - #else /* if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) */ - - /* When subscription management is disabled, invoke the global callback - * if one exists. */ - - /* When subscription management is disabled, the topic filter must be "#". */ - mqttconfigASSERT( *( xPublish.message.pTopicFilter ) == '#' ); - mqttconfigASSERT( xPublish.message.topicFilterLength == 1 ); - - if( pxConnection->pxCallback != NULL ) - { - xCallbackReturn = ( MQTTBool_t ) pxConnection->pxCallback( pxConnection->pvUserData, - &xPublishData ); - } - #endif /* if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) */ - } - - /* Free the MQTT buffer if the user did not take ownership of it. */ - if( ( xCallbackReturn == eMQTTFalse ) && ( pucMqttBuffer != NULL ) ) - { - vPortFree( pucMqttBuffer ); - } -} - -/*-----------------------------------------------------------*/ - -static void prvDisconnectCallbackWrapper( void * pvParameter, - IotMqttCallbackParam_t * pxDisconnect ) -{ - MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) pvParameter; - MQTTAgentCallbackParams_t xCallbackParams = { .xMQTTEvent = eMQTTAgentDisconnect }; - - ( void ) pxDisconnect; - - /* This function should only be called if a callback was set. */ - mqttconfigASSERT( pxConnection->pxCallback != NULL ); - - /* Invoke the MQTT v1 callback. Ignore the return value. */ - pxConnection->pxCallback( pxConnection->pvUserData, - &xCallbackParams ); -} - -/*-----------------------------------------------------------*/ - -#if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) - static BaseType_t prvStoreCallback( MQTTConnection_t * const pxConnection, - const char * const pcTopicFilter, - uint16_t usTopicFilterLength, - MQTTPublishCallback_t xCallback, - void * pvParameter ) - { - MQTTCallback_t * pxCallback = NULL; - BaseType_t xStatus = pdFAIL, i = 0; - - /* Prevent other tasks from modifying stored callbacks while this function - * runs. */ - if( xSemaphoreTake( ( QueueHandle_t ) &( pxConnection->xConnectionMutex ), - portMAX_DELAY ) == pdTRUE ) - { - /* Check if the topic filter already has an entry. */ - pxCallback = prvFindCallback( pxConnection, pcTopicFilter, usTopicFilterLength ); - - if( pxCallback == NULL ) - { - /* If no entry was found, find a free entry. */ - for( i = 0; i < mqttconfigSUBSCRIPTION_MANAGER_MAX_SUBSCRIPTIONS; i++ ) - { - if( pxConnection->xCallbacks[ i ].xInUse == pdFALSE ) - { - pxConnection->xCallbacks[ i ].xInUse = pdTRUE; - pxCallback = &( pxConnection->xCallbacks[ i ] ); - break; - } - } - } - - /* Set the members of the callback entry. */ - if( i < mqttconfigSUBSCRIPTION_MANAGER_MAX_SUBSCRIPTIONS ) - { - pxCallback->pvParameter = pvParameter; - pxCallback->usTopicFilterLength = usTopicFilterLength; - pxCallback->xFunction = xCallback; - ( void ) strncpy( pxCallback->pcTopicFilter, pcTopicFilter, usTopicFilterLength ); - xStatus = pdPASS; - } - - ( void ) xSemaphoreGive( ( QueueHandle_t ) &( pxConnection->xConnectionMutex ) ); - } - - return xStatus; - } - -/*-----------------------------------------------------------*/ - - static MQTTCallback_t * prvFindCallback( MQTTConnection_t * const pxConnection, - const char * const pcTopicFilter, - uint16_t usTopicFilterLength ) - { - BaseType_t i = 0; - MQTTCallback_t * pxResult = NULL; - - /* Search the callback conversion table for the topic filter. */ - for( i = 0; i < mqttconfigSUBSCRIPTION_MANAGER_MAX_SUBSCRIPTIONS; i++ ) - { - if( ( pxConnection->xCallbacks[ i ].usTopicFilterLength == usTopicFilterLength ) && - ( strncmp( pxConnection->xCallbacks[ i ].pcTopicFilter, - pcTopicFilter, - usTopicFilterLength ) == 0 ) ) - { - pxResult = &( pxConnection->xCallbacks[ i ] ); - break; - } - } - - return pxResult; - } - -/*-----------------------------------------------------------*/ - - static void prvRemoveCallback( MQTTConnection_t * const pxConnection, - const char * const pcTopicFilter, - uint16_t usTopicFilterLength ) - { - MQTTCallback_t * pxCallback = NULL; - - /* Prevent other tasks from modifying stored callbacks while this function - * runs. */ - if( xSemaphoreTake( ( QueueHandle_t ) &( pxConnection->xConnectionMutex ), - portMAX_DELAY ) == pdTRUE ) - { - /* Find the given topic filter. */ - pxCallback = prvFindCallback( pxConnection, pcTopicFilter, usTopicFilterLength ); - - if( pxCallback != NULL ) - { - /* Clear the callback entry. */ - mqttconfigASSERT( pxCallback->xInUse == pdTRUE ); - ( void ) memset( pxCallback, 0x00, sizeof( MQTTCallback_t ) ); - } - - ( void ) xSemaphoreGive( ( QueueHandle_t ) &( pxConnection->xConnectionMutex ) ); - } - } -#endif /* if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) */ - -/*-----------------------------------------------------------*/ - -IotMqttConnection_t MQTT_AGENT_Getv2Connection( MQTTAgentHandle_t xMQTTHandle ) -{ - MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) xMQTTHandle; - - return pxConnection->xMQTTConnection; -} - -/*-----------------------------------------------------------*/ - -BaseType_t MQTT_AGENT_Init( void ) -{ - BaseType_t xStatus = pdFALSE; - - /* Call the initialization function of MQTT v2. */ - if( IotMqtt_Init() == IOT_MQTT_SUCCESS ) - { - xStatus = pdTRUE; - } - - return xStatus; -} - -/*-----------------------------------------------------------*/ - -MQTTAgentReturnCode_t MQTT_AGENT_Create( MQTTAgentHandle_t * const pxMQTTHandle ) -{ - MQTTConnection_t * pxNewConnection = NULL; - MQTTAgentReturnCode_t xStatus = eMQTTAgentSuccess; - - /* Check how many brokers are available; fail if all brokers are in use. */ - taskENTER_CRITICAL(); - { - if( uxAvailableBrokers == 0 ) - { - xStatus = eMQTTAgentFailure; - } - else - { - uxAvailableBrokers--; - mqttconfigASSERT( uxAvailableBrokers <= mqttconfigMAX_BROKERS ); - } - } - taskEXIT_CRITICAL(); - - /* Allocate memory for an MQTT connection. */ - if( xStatus == eMQTTAgentSuccess ) - { - pxNewConnection = pvPortMalloc( sizeof( MQTTConnection_t ) ); - - if( pxNewConnection == NULL ) - { - xStatus = eMQTTAgentFailure; - - taskENTER_CRITICAL(); - { - uxAvailableBrokers++; - mqttconfigASSERT( uxAvailableBrokers <= mqttconfigMAX_BROKERS ); - } - taskEXIT_CRITICAL(); - } - else - { - ( void ) memset( pxNewConnection, 0x00, sizeof( MQTTConnection_t ) ); - pxNewConnection->xMQTTConnection = IOT_MQTT_CONNECTION_INITIALIZER; - } - } - - /* Create the connection mutex and set the output parameter. */ - if( xStatus == eMQTTAgentSuccess ) - { - ( void ) xSemaphoreCreateMutexStatic( &( pxNewConnection->xConnectionMutex ) ); - *pxMQTTHandle = ( MQTTAgentHandle_t ) pxNewConnection; - } - - return xStatus; -} - -/*-----------------------------------------------------------*/ - -MQTTAgentReturnCode_t MQTT_AGENT_Delete( MQTTAgentHandle_t xMQTTHandle ) -{ - MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) xMQTTHandle; - - /* Clean up any allocated MQTT or network resources. */ - if( pxConnection->xMQTTConnection != IOT_MQTT_CONNECTION_INITIALIZER ) - { - IotMqtt_Disconnect( pxConnection->xMQTTConnection, IOT_MQTT_FLAG_CLEANUP_ONLY ); - pxConnection->xMQTTConnection = IOT_MQTT_CONNECTION_INITIALIZER; - } - - /* Free memory used by the MQTT connection. */ - vPortFree( pxConnection ); - - /* Increment the number of available brokers. */ - taskENTER_CRITICAL(); - { - uxAvailableBrokers++; - mqttconfigASSERT( uxAvailableBrokers <= mqttconfigMAX_BROKERS ); - } - taskEXIT_CRITICAL(); - - return eMQTTAgentSuccess; -} - -/*-----------------------------------------------------------*/ - -MQTTAgentReturnCode_t MQTT_AGENT_Connect( MQTTAgentHandle_t xMQTTHandle, - const MQTTAgentConnectParams_t * const pxConnectParams, - TickType_t xTimeoutTicks ) -{ - MQTTAgentReturnCode_t xStatus = eMQTTAgentSuccess; - IotMqttError_t xMqttStatus = IOT_MQTT_STATUS_PENDING; - MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) xMQTTHandle; - IotNetworkServerInfo_t xServerInfo = { 0 }; - IotNetworkCredentials_t xCredentials = AWS_IOT_NETWORK_CREDENTIALS_AFR_INITIALIZER, * pxCredentials = NULL; - IotMqttNetworkInfo_t xNetworkInfo = IOT_MQTT_NETWORK_INFO_INITIALIZER; - IotMqttConnectInfo_t xMqttConnectInfo = IOT_MQTT_CONNECT_INFO_INITIALIZER; - - /* Copy the global callback and parameter. */ - pxConnection->pxCallback = pxConnectParams->pxCallback; - pxConnection->pvUserData = pxConnectParams->pvUserData; - - /* Set the TLS info for a secured connection. */ - if( ( pxConnectParams->xSecuredConnection == pdTRUE ) || - ( ( pxConnectParams->xFlags & mqttagentREQUIRE_TLS ) == mqttagentREQUIRE_TLS ) ) - { - pxCredentials = &xCredentials; - - /* Set the server certificate. Other credentials are set by the initializer. */ - xCredentials.pRootCa = pxConnectParams->pcCertificate; - xCredentials.rootCaSize = ( size_t ) pxConnectParams->ulCertificateSize; - - /* Disable ALPN if requested. */ - if( ( pxConnectParams->xFlags & mqttagentUSE_AWS_IOT_ALPN_443 ) == 0 ) - { - xCredentials.pAlpnProtos = NULL; - } - - /* Disable SNI if requested. */ - if( ( pxConnectParams->xURLIsIPAddress == pdTRUE ) || - ( ( pxConnectParams->xFlags & mqttagentURL_IS_IP_ADDRESS ) == mqttagentURL_IS_IP_ADDRESS ) ) - { - xCredentials.disableSni = true; - } - } - - /* Set the server info. */ - xServerInfo.pHostName = pxConnectParams->pcURL; - xServerInfo.port = pxConnectParams->usPort; - - /* Set the members of the network info. */ - xNetworkInfo.createNetworkConnection = true; - xNetworkInfo.u.setup.pNetworkServerInfo = &xServerInfo; - xNetworkInfo.u.setup.pNetworkCredentialInfo = pxCredentials; - xNetworkInfo.pNetworkInterface = IOT_NETWORK_INTERFACE_AFR; - - if( pxConnectParams->pxCallback != NULL ) - { - xNetworkInfo.disconnectCallback.function = prvDisconnectCallbackWrapper; - xNetworkInfo.disconnectCallback.pCallbackContext = pxConnection; - } - - /* Set the members of the MQTT connect info. */ - xMqttConnectInfo.awsIotMqttMode = true; - xMqttConnectInfo.cleanSession = true; - xMqttConnectInfo.pClientIdentifier = ( const char * ) ( pxConnectParams->pucClientId ); - xMqttConnectInfo.clientIdentifierLength = pxConnectParams->usClientIdLength; - xMqttConnectInfo.keepAliveSeconds = mqttconfigKEEP_ALIVE_INTERVAL_SECONDS; - - /* Call MQTT v2's CONNECT function. */ - xMqttStatus = IotMqtt_Connect( &xNetworkInfo, - &xMqttConnectInfo, - mqttTICKS_TO_MS( xTimeoutTicks ), - &( pxConnection->xMQTTConnection ) ); - xStatus = prvConvertReturnCode( xMqttStatus ); - - /* Add a subscription to "#" to support the global callback when subscription - * manager is disabled. */ - #if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 0 ) - IotMqttSubscription_t xGlobalSubscription = IOT_MQTT_SUBSCRIPTION_INITIALIZER; - IotMqttReference_t xGlobalSubscriptionRef = IOT_MQTT_REFERENCE_INITIALIZER; - - if( xStatus == eMQTTAgentSuccess ) - { - xGlobalSubscription.pTopicFilter = "#"; - xGlobalSubscription.topicFilterLength = 1; - xGlobalSubscription.qos = 0; - xGlobalSubscription.callback.param1 = pxConnection; - xGlobalSubscription.callback.function = prvPublishCallbackWrapper; - - xMqttStatus = IotMqtt_Subscribe( pxConnection->xMQTTConnection, - &xGlobalSubscription, - 1, - IOT_MQTT_FLAG_WAITABLE, - NULL, - &xGlobalSubscriptionRef ); - xStatus = prvConvertReturnCode( xMqttStatus ); - } - - /* Wait for the subscription to "#" to complete. */ - if( xStatus == eMQTTAgentSuccess ) - { - xMqttStatus = IotMqtt_Wait( xGlobalSubscriptionRef, - mqttTICKS_TO_MS( xTimeoutTicks ) ); - xStatus = prvConvertReturnCode( xMqttStatus ); - } - #endif /* if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) */ - - return xStatus; -} - -/*-----------------------------------------------------------*/ - -MQTTAgentReturnCode_t MQTT_AGENT_Disconnect( MQTTAgentHandle_t xMQTTHandle, - TickType_t xTimeoutTicks ) -{ - MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) xMQTTHandle; - - /* MQTT v2's DISCONNECT function does not have a timeout argument. */ - ( void ) xTimeoutTicks; - - /* Check that the connection is established. */ - if( pxConnection->xMQTTConnection != IOT_MQTT_CONNECTION_INITIALIZER ) - { - /* Call MQTT v2's DISCONNECT function. */ - IotMqtt_Disconnect( pxConnection->xMQTTConnection, - 0 ); - pxConnection->xMQTTConnection = IOT_MQTT_CONNECTION_INITIALIZER; - } - - return eMQTTAgentSuccess; -} - -/*-----------------------------------------------------------*/ - -MQTTAgentReturnCode_t MQTT_AGENT_Subscribe( MQTTAgentHandle_t xMQTTHandle, - const MQTTAgentSubscribeParams_t * const pxSubscribeParams, - TickType_t xTimeoutTicks ) -{ - MQTTAgentReturnCode_t xStatus = eMQTTAgentSuccess; - IotMqttError_t xMqttStatus = IOT_MQTT_STATUS_PENDING; - MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) xMQTTHandle; - IotMqttSubscription_t xSubscription = IOT_MQTT_SUBSCRIPTION_INITIALIZER; - - /* Store the topic filter if subscription management is enabled. */ - #if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) - /* Check topic filter length. */ - if( pxSubscribeParams->usTopicLength > mqttconfigSUBSCRIPTION_MANAGER_MAX_TOPIC_LENGTH ) - { - xStatus = eMQTTAgentFailure; - } - - /* Store the subscription. */ - if( prvStoreCallback( pxConnection, - ( const char * ) pxSubscribeParams->pucTopic, - pxSubscribeParams->usTopicLength, - pxSubscribeParams->pxPublishCallback, - pxSubscribeParams->pvPublishCallbackContext ) == pdFAIL ) - { - xStatus = eMQTTAgentFailure; - } - #endif /* if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) */ - - /* Call MQTT v2 blocking SUBSCRIBE function. */ - if( xStatus == eMQTTAgentSuccess ) - { - /* Set the members of the MQTT subscription. */ - xSubscription.pTopicFilter = ( const char * ) ( pxSubscribeParams->pucTopic ); - xSubscription.topicFilterLength = pxSubscribeParams->usTopicLength; - xSubscription.qos = ( IotMqttQos_t ) pxSubscribeParams->xQoS; - xSubscription.callback.pCallbackContext = pxConnection; - xSubscription.callback.function = prvPublishCallbackWrapper; - - xMqttStatus = IotMqtt_TimedSubscribe( pxConnection->xMQTTConnection, - &xSubscription, - 1, - 0, - mqttTICKS_TO_MS( xTimeoutTicks ) ); - xStatus = prvConvertReturnCode( xMqttStatus ); - } - - return xStatus; -} - -/*-----------------------------------------------------------*/ - -MQTTAgentReturnCode_t MQTT_AGENT_Unsubscribe( MQTTAgentHandle_t xMQTTHandle, - const MQTTAgentUnsubscribeParams_t * const pxUnsubscribeParams, - TickType_t xTimeoutTicks ) -{ - IotMqttError_t xMqttStatus = IOT_MQTT_STATUS_PENDING; - MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) xMQTTHandle; - IotMqttSubscription_t xSubscription = IOT_MQTT_SUBSCRIPTION_INITIALIZER; - - /* Remove any subscription callback that may be registered. */ - #if ( mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT == 1 ) - prvRemoveCallback( pxConnection, - ( const char * ) ( pxUnsubscribeParams->pucTopic ), - pxUnsubscribeParams->usTopicLength ); - #endif - - /* Set the members of the subscription to remove. */ - xSubscription.pTopicFilter = ( const char * ) ( pxUnsubscribeParams->pucTopic ); - xSubscription.topicFilterLength = pxUnsubscribeParams->usTopicLength; - xSubscription.callback.pCallbackContext = pxConnection; - xSubscription.callback.function = prvPublishCallbackWrapper; - - /* Call MQTT v2 blocking UNSUBSCRIBE function. */ - xMqttStatus = IotMqtt_TimedUnsubscribe( pxConnection->xMQTTConnection, - &xSubscription, - 1, - 0, - mqttTICKS_TO_MS( xTimeoutTicks ) ); - - return prvConvertReturnCode( xMqttStatus ); -} - -/*-----------------------------------------------------------*/ - -MQTTAgentReturnCode_t MQTT_AGENT_Publish( MQTTAgentHandle_t xMQTTHandle, - const MQTTAgentPublishParams_t * const pxPublishParams, - TickType_t xTimeoutTicks ) -{ - IotMqttError_t xMqttStatus = IOT_MQTT_STATUS_PENDING; - MQTTConnection_t * pxConnection = ( MQTTConnection_t * ) xMQTTHandle; - IotMqttPublishInfo_t xPublishInfo = IOT_MQTT_PUBLISH_INFO_INITIALIZER; - - /* Set the members of the publish info. */ - xPublishInfo.pTopicName = ( const char * ) pxPublishParams->pucTopic; - xPublishInfo.topicNameLength = pxPublishParams->usTopicLength; - xPublishInfo.qos = ( IotMqttQos_t ) pxPublishParams->xQoS; - xPublishInfo.pPayload = ( const void * ) pxPublishParams->pvData; - xPublishInfo.payloadLength = pxPublishParams->ulDataLength; - - /* Call the MQTT v2 blocking PUBLISH function. */ - xMqttStatus = IotMqtt_TimedPublish( pxConnection->xMQTTConnection, - &xPublishInfo, - 0, - mqttTICKS_TO_MS( xTimeoutTicks ) ); - - return prvConvertReturnCode( xMqttStatus ); -} - -/*-----------------------------------------------------------*/ - -MQTTAgentReturnCode_t MQTT_AGENT_ReturnBuffer( MQTTAgentHandle_t xMQTTHandle, - MQTTBufferHandle_t xBufferHandle ) -{ - ( void ) xMQTTHandle; - - /* Free the MQTT buffer. */ - vPortFree( xBufferHandle ); - - return eMQTTAgentSuccess; -} - -/*-----------------------------------------------------------*/ 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 deleted file mode 100644 index 0d6a259ed..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_api.c +++ /dev/null @@ -1,2035 +0,0 @@ -/* - * Amazon FreeRTOS MQTT V2.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_mqtt_api.c - * @brief Implements most user-facing functions of the MQTT library. - */ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* Standard includes. */ -#include - -/* Error handling include. */ -#include "private/iot_error.h" - -/* MQTT internal include. */ -#include "private/iot_mqtt_internal.h" - -/* Platform layer includes. */ -#include "platform/iot_clock.h" -#include "platform/iot_threads.h" - -/* Validate MQTT configuration settings. */ -#if IOT_MQTT_ENABLE_ASSERTS != 0 && IOT_MQTT_ENABLE_ASSERTS != 1 - #error "IOT_MQTT_ENABLE_ASSERTS must be 0 or 1." -#endif -#if IOT_MQTT_ENABLE_METRICS != 0 && IOT_MQTT_ENABLE_METRICS != 1 - #error "IOT_MQTT_ENABLE_METRICS must be 0 or 1." -#endif -#if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES != 0 && IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES != 1 - #error "IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES must be 0 or 1." -#endif -#if IOT_MQTT_RESPONSE_WAIT_MS <= 0 - #error "IOT_MQTT_RESPONSE_WAIT_MS cannot be 0 or negative." -#endif -#if IOT_MQTT_RETRY_MS_CEILING <= 0 - #error "IOT_MQTT_RETRY_MS_CEILING cannot be 0 or negative." -#endif - -/*-----------------------------------------------------------*/ - -/** - * @brief Set the unsubscribed flag of an MQTT subscription. - * - * @param[in] pSubscriptionLink Pointer to the link member of an #_mqttSubscription_t. - * @param[in] pMatch Not used. - * - * @return Always returns `true`. - */ -static bool _mqttSubscription_setUnsubscribe( const IotLink_t * pSubscriptionLink, - void * pMatch ); - -/** - * @brief Destroy an MQTT subscription if its reference count is 0. - * - * @param[in] pData The subscription to destroy. This parameter is of type - * `void*` for compatibility with [free] - * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html). - */ -static void _mqttSubscription_tryDestroy( void * pData ); - -/** - * @brief Decrement the reference count of an MQTT operation and attempt to - * destroy it. - * - * @param[in] pData The operation data to destroy. This parameter is of type - * `void*` for compatibility with [free] - * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html). - */ -static void _mqttOperation_tryDestroy( void * pData ); - -/** - * @brief Initialize the keep-alive operation for an MQTT connection. - * - * @param[in] pNetworkInfo User-provided network information for the new - * connection. - * @param[in] keepAliveSeconds User-provided keep-alive interval. - * @param[out] pMqttConnection The MQTT connection associated with the keep-alive. - * - * @return `true` if the keep-alive job was successfully created; `false` otherwise. - */ -static bool _createKeepAliveOperation( const IotMqttNetworkInfo_t * pNetworkInfo, - uint16_t keepAliveSeconds, - _mqttConnection_t * pMqttConnection ); - -/** - * @brief Creates a new MQTT connection and initializes its members. - * - * @param[in] awsIotMqttMode Specifies if this connection is to an AWS IoT MQTT server. - * @param[in] pNetworkInfo User-provided network information for the new - * connection. - * @param[in] keepAliveSeconds User-provided keep-alive interval for the new connection. - * - * @return Pointer to a newly-created MQTT connection; `NULL` on failure. - */ -static _mqttConnection_t * _createMqttConnection( bool awsIotMqttMode, - const IotMqttNetworkInfo_t * pNetworkInfo, - uint16_t keepAliveSeconds ); - -/** - * @brief Destroys the members of an MQTT connection. - * - * @param[in] pMqttConnection Which connection to destroy. - */ -static void _destroyMqttConnection( _mqttConnection_t * pMqttConnection ); - -/** - * @brief The common component of both @ref mqtt_function_subscribe and @ref - * mqtt_function_unsubscribe. - * - * See @ref mqtt_function_subscribe or @ref mqtt_function_unsubscribe for a - * description of the parameters and return values. - */ -static IotMqttError_t _subscriptionCommon( IotMqttOperationType_t operation, - IotMqttConnection_t mqttConnection, - const IotMqttSubscription_t * pSubscriptionList, - size_t subscriptionCount, - uint32_t flags, - const IotMqttCallbackInfo_t * pCallbackInfo, - IotMqttOperation_t * const pOperationReference ); - -/*-----------------------------------------------------------*/ - -static bool _mqttSubscription_setUnsubscribe( const IotLink_t * pSubscriptionLink, - void * pMatch ) -{ - /* Because this function is called from a container function, the given link - * must never be NULL. */ - IotMqtt_Assert( pSubscriptionLink != NULL ); - - _mqttSubscription_t * pSubscription = IotLink_Container( _mqttSubscription_t, - pSubscriptionLink, - link ); - - /* Silence warnings about unused parameters. */ - ( void ) pMatch; - - /* Set the unsubscribed flag. */ - pSubscription->unsubscribed = true; - - return true; -} - -/*-----------------------------------------------------------*/ - -static void _mqttSubscription_tryDestroy( void * pData ) -{ - _mqttSubscription_t * pSubscription = ( _mqttSubscription_t * ) pData; - - /* Reference count must not be negative. */ - IotMqtt_Assert( pSubscription->references >= 0 ); - - /* Unsubscribed flag should be set. */ - IotMqtt_Assert( pSubscription->unsubscribed == true ); - - /* Free the subscription if it has no references. */ - if( pSubscription->references == 0 ) - { - IotMqtt_FreeSubscription( pSubscription ); - } - else - { - EMPTY_ELSE_MARKER; - } -} - -/*-----------------------------------------------------------*/ - -static void _mqttOperation_tryDestroy( void * pData ) -{ - _mqttOperation_t * pOperation = ( _mqttOperation_t * ) pData; - IotTaskPoolError_t taskPoolStatus = IOT_TASKPOOL_SUCCESS; - - /* Incoming PUBLISH operations may always be freed. */ - if( pOperation->incomingPublish == true ) - { - /* Cancel the incoming PUBLISH operation's job. */ - taskPoolStatus = IotTaskPool_TryCancel( IOT_SYSTEM_TASKPOOL, - pOperation->job, - NULL ); - - /* If the operation's job was not canceled, it must be already executing. - * Any other return value is invalid. */ - IotMqtt_Assert( ( taskPoolStatus == IOT_TASKPOOL_SUCCESS ) || - ( taskPoolStatus == IOT_TASKPOOL_CANCEL_FAILED ) ); - - /* Check if the incoming PUBLISH job was canceled. */ - if( taskPoolStatus == IOT_TASKPOOL_SUCCESS ) - { - /* Job was canceled. Process incoming PUBLISH now to clean up. */ - _IotMqtt_ProcessIncomingPublish( IOT_SYSTEM_TASKPOOL, - pOperation->job, - pOperation ); - } - else - { - /* The executing job will process the PUBLISH, so nothing is done here. */ - EMPTY_ELSE_MARKER; - } - } - else - { - /* Decrement reference count and destroy operation if possible. */ - if( _IotMqtt_DecrementOperationReferences( pOperation, true ) == true ) - { - _IotMqtt_DestroyOperation( pOperation ); - } - else - { - EMPTY_ELSE_MARKER; - } - } -} - -/*-----------------------------------------------------------*/ - -static bool _createKeepAliveOperation( const IotMqttNetworkInfo_t * pNetworkInfo, - uint16_t keepAliveSeconds, - _mqttConnection_t * pMqttConnection ) -{ - bool status = true; - IotMqttError_t serializeStatus = IOT_MQTT_SUCCESS; - IotTaskPoolError_t jobStatus = IOT_TASKPOOL_SUCCESS; - - /* Network information is not used when MQTT packet serializers are disabled. */ - ( void ) pNetworkInfo; - - /* Default PINGREQ serializer function. */ - IotMqttError_t ( * serializePingreq )( uint8_t **, - size_t * ) = _IotMqtt_SerializePingreq; - - /* Set PINGREQ operation members. */ - pMqttConnection->pingreq.u.operation.type = IOT_MQTT_PINGREQ; - - /* Convert the keep-alive interval to milliseconds. */ - pMqttConnection->pingreq.u.operation.periodic.ping.keepAliveMs = keepAliveSeconds * 1000; - pMqttConnection->pingreq.u.operation.periodic.ping.nextPeriodMs = keepAliveSeconds * 1000; - - /* Choose a PINGREQ serializer function. */ - #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 - if( pNetworkInfo->pMqttSerializer != NULL ) - { - if( pNetworkInfo->pMqttSerializer->serialize.pingreq != NULL ) - { - serializePingreq = pNetworkInfo->pMqttSerializer->serialize.pingreq; - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */ - - /* Generate a PINGREQ packet. */ - serializeStatus = serializePingreq( &( pMqttConnection->pingreq.u.operation.pMqttPacket ), - &( pMqttConnection->pingreq.u.operation.packetSize ) ); - - if( serializeStatus != IOT_MQTT_SUCCESS ) - { - IotLogError( "Failed to allocate PINGREQ packet for new connection." ); - - status = false; - } - else - { - /* Create the task pool job that processes keep-alive. */ - jobStatus = IotTaskPool_CreateJob( _IotMqtt_ProcessKeepAlive, - pMqttConnection, - &( pMqttConnection->pingreq.jobStorage ), - &( pMqttConnection->pingreq.job ) ); - - /* Task pool job creation for a pre-allocated job should never fail. - * Abort the program if it does. */ - if( jobStatus != IOT_TASKPOOL_SUCCESS ) - { - IotLogError( "Failed to create keep-alive job for new connection." ); - - IotMqtt_Assert( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Keep-alive references its MQTT connection, so increment reference. */ - ( pMqttConnection->references )++; - } - - return status; -} - -/*-----------------------------------------------------------*/ - -static _mqttConnection_t * _createMqttConnection( bool awsIotMqttMode, - const IotMqttNetworkInfo_t * pNetworkInfo, - uint16_t keepAliveSeconds ) -{ - IOT_FUNCTION_ENTRY( bool, true ); - _mqttConnection_t * pMqttConnection = NULL; - bool referencesMutexCreated = false, subscriptionMutexCreated = false; - - /* Allocate memory for the new MQTT connection. */ - pMqttConnection = IotMqtt_MallocConnection( sizeof( _mqttConnection_t ) ); - - if( pMqttConnection == NULL ) - { - IotLogError( "Failed to allocate memory for new connection." ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - /* Clear the MQTT connection, then copy the MQTT server mode, network - * interface, and disconnect callback. */ - ( void ) memset( pMqttConnection, 0x00, sizeof( _mqttConnection_t ) ); - pMqttConnection->awsIotMqttMode = awsIotMqttMode; - pMqttConnection->pNetworkInterface = pNetworkInfo->pNetworkInterface; - pMqttConnection->disconnectCallback = pNetworkInfo->disconnectCallback; - - /* Start a new MQTT connection with a reference count of 1. */ - pMqttConnection->references = 1; - } - - /* Create the references mutex for a new connection. It is a recursive mutex. */ - referencesMutexCreated = IotMutex_Create( &( pMqttConnection->referencesMutex ), true ); - - if( referencesMutexCreated == false ) - { - IotLogError( "Failed to create references mutex for new connection." ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Create the subscription mutex for a new connection. */ - subscriptionMutexCreated = IotMutex_Create( &( pMqttConnection->subscriptionMutex ), false ); - - if( subscriptionMutexCreated == false ) - { - IotLogError( "Failed to create subscription mutex for new connection." ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Create the new connection's subscription and operation lists. */ - IotListDouble_Create( &( pMqttConnection->subscriptionList ) ); - IotListDouble_Create( &( pMqttConnection->pendingProcessing ) ); - IotListDouble_Create( &( pMqttConnection->pendingResponse ) ); - - /* AWS IoT service limits set minimum and maximum values for keep-alive interval. - * Adjust the user-provided keep-alive interval based on these requirements. */ - if( awsIotMqttMode == true ) - { - if( keepAliveSeconds < AWS_IOT_MQTT_SERVER_MIN_KEEPALIVE ) - { - keepAliveSeconds = AWS_IOT_MQTT_SERVER_MIN_KEEPALIVE; - } - else if( keepAliveSeconds > AWS_IOT_MQTT_SERVER_MAX_KEEPALIVE ) - { - keepAliveSeconds = AWS_IOT_MQTT_SERVER_MAX_KEEPALIVE; - } - else if( keepAliveSeconds == 0 ) - { - keepAliveSeconds = AWS_IOT_MQTT_SERVER_MAX_KEEPALIVE; - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check if keep-alive is active for this connection. */ - if( keepAliveSeconds != 0 ) - { - if( _createKeepAliveOperation( pNetworkInfo, - keepAliveSeconds, - pMqttConnection ) == false ) - { - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Clean up mutexes and connection if this function failed. */ - IOT_FUNCTION_CLEANUP_BEGIN(); - - if( status == false ) - { - if( subscriptionMutexCreated == true ) - { - IotMutex_Destroy( &( pMqttConnection->subscriptionMutex ) ); - } - else - { - EMPTY_ELSE_MARKER; - } - - if( referencesMutexCreated == true ) - { - IotMutex_Destroy( &( pMqttConnection->referencesMutex ) ); - } - else - { - EMPTY_ELSE_MARKER; - } - - if( pMqttConnection != NULL ) - { - IotMqtt_FreeConnection( pMqttConnection ); - pMqttConnection = NULL; - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - return pMqttConnection; -} - -/*-----------------------------------------------------------*/ - -static void _destroyMqttConnection( _mqttConnection_t * pMqttConnection ) -{ - IotNetworkError_t networkStatus = IOT_NETWORK_SUCCESS; - - /* Default free packet function. */ - void (* freePacket)( uint8_t * ) = _IotMqtt_FreePacket; - - /* Clean up keep-alive if still allocated. */ - if( pMqttConnection->pingreq.u.operation.periodic.ping.keepAliveMs != 0 ) - { - IotLogDebug( "(MQTT connection %p) Cleaning up keep-alive.", pMqttConnection ); - - /* Choose a function to free the packet. */ - #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 - if( pMqttConnection->pSerializer != NULL ) - { - if( pMqttConnection->pSerializer->freePacket != NULL ) - { - freePacket = pMqttConnection->pSerializer->freePacket; - } - } - #endif - - freePacket( pMqttConnection->pingreq.u.operation.pMqttPacket ); - - /* Clear data about the keep-alive. */ - pMqttConnection->pingreq.u.operation.periodic.ping.keepAliveMs = 0; - pMqttConnection->pingreq.u.operation.pMqttPacket = NULL; - pMqttConnection->pingreq.u.operation.packetSize = 0; - - /* Decrement reference count. */ - pMqttConnection->references--; - } - else - { - EMPTY_ELSE_MARKER; - } - - /* A connection to be destroyed should have no keep-alive and at most 1 - * reference. */ - IotMqtt_Assert( pMqttConnection->references <= 1 ); - IotMqtt_Assert( pMqttConnection->pingreq.u.operation.periodic.ping.keepAliveMs == 0 ); - IotMqtt_Assert( pMqttConnection->pingreq.u.operation.pMqttPacket == NULL ); - IotMqtt_Assert( pMqttConnection->pingreq.u.operation.packetSize == 0 ); - - /* Remove all subscriptions. */ - IotMutex_Lock( &( pMqttConnection->subscriptionMutex ) ); - IotListDouble_RemoveAllMatches( &( pMqttConnection->subscriptionList ), - _mqttSubscription_setUnsubscribe, - NULL, - _mqttSubscription_tryDestroy, - offsetof( _mqttSubscription_t, link ) ); - IotMutex_Unlock( &( pMqttConnection->subscriptionMutex ) ); - - /* Destroy an owned network connection. */ - if( pMqttConnection->ownNetworkConnection == true ) - { - networkStatus = pMqttConnection->pNetworkInterface->destroy( pMqttConnection->pNetworkConnection ); - - if( networkStatus != IOT_NETWORK_SUCCESS ) - { - IotLogWarn( "(MQTT connection %p) Failed to destroy network connection.", - pMqttConnection ); - } - else - { - IotLogInfo( "(MQTT connection %p) Network connection destroyed.", - pMqttConnection ); - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Destroy mutexes. */ - IotMutex_Destroy( &( pMqttConnection->referencesMutex ) ); - IotMutex_Destroy( &( pMqttConnection->subscriptionMutex ) ); - - IotLogDebug( "(MQTT connection %p) Connection destroyed.", pMqttConnection ); - - /* Free connection. */ - IotMqtt_FreeConnection( pMqttConnection ); -} - -/*-----------------------------------------------------------*/ - -static IotMqttError_t _subscriptionCommon( IotMqttOperationType_t operation, - IotMqttConnection_t mqttConnection, - const IotMqttSubscription_t * pSubscriptionList, - size_t subscriptionCount, - uint32_t flags, - const IotMqttCallbackInfo_t * pCallbackInfo, - IotMqttOperation_t * const pOperationReference ) -{ - IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS ); - _mqttOperation_t * pSubscriptionOperation = NULL; - - /* Subscription serializer function. */ - IotMqttError_t ( * serializeSubscription )( const IotMqttSubscription_t *, - size_t, - uint8_t **, - size_t *, - uint16_t * ) = NULL; - - /* This function should only be called for subscribe or unsubscribe. */ - IotMqtt_Assert( ( operation == IOT_MQTT_SUBSCRIBE ) || - ( operation == IOT_MQTT_UNSUBSCRIBE ) ); - - /* Check that all elements in the subscription list are valid. */ - if( _IotMqtt_ValidateSubscriptionList( operation, - mqttConnection->awsIotMqttMode, - pSubscriptionList, - subscriptionCount ) == false ) - { - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check that a reference pointer is provided for a waitable operation. */ - if( ( flags & IOT_MQTT_FLAG_WAITABLE ) == IOT_MQTT_FLAG_WAITABLE ) - { - if( pOperationReference == NULL ) - { - IotLogError( "Reference must be provided for a waitable %s.", - IotMqtt_OperationType( operation ) ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Choose a subscription serialize function. */ - if( operation == IOT_MQTT_SUBSCRIBE ) - { - serializeSubscription = _IotMqtt_SerializeSubscribe; - - #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 - if( mqttConnection->pSerializer != NULL ) - { - if( mqttConnection->pSerializer->serialize.subscribe != NULL ) - { - serializeSubscription = mqttConnection->pSerializer->serialize.subscribe; - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */ - } - else - { - serializeSubscription = _IotMqtt_SerializeUnsubscribe; - - #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 - if( mqttConnection->pSerializer != NULL ) - { - if( mqttConnection->pSerializer->serialize.unsubscribe != NULL ) - { - serializeSubscription = mqttConnection->pSerializer->serialize.unsubscribe; - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */ - } - - /* Remove the MQTT subscription list for an UNSUBSCRIBE. */ - if( operation == IOT_MQTT_UNSUBSCRIBE ) - { - _IotMqtt_RemoveSubscriptionByTopicFilter( mqttConnection, - pSubscriptionList, - subscriptionCount ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Create a subscription operation. */ - status = _IotMqtt_CreateOperation( mqttConnection, - flags, - pCallbackInfo, - &pSubscriptionOperation ); - - if( status != IOT_MQTT_SUCCESS ) - { - IOT_GOTO_CLEANUP(); - } - - /* Check the subscription operation data and set the operation type. */ - IotMqtt_Assert( pSubscriptionOperation->u.operation.status == IOT_MQTT_STATUS_PENDING ); - IotMqtt_Assert( pSubscriptionOperation->u.operation.periodic.retry.limit == 0 ); - pSubscriptionOperation->u.operation.type = operation; - - /* Generate a subscription packet from the subscription list. */ - status = serializeSubscription( pSubscriptionList, - subscriptionCount, - &( pSubscriptionOperation->u.operation.pMqttPacket ), - &( pSubscriptionOperation->u.operation.packetSize ), - &( pSubscriptionOperation->u.operation.packetIdentifier ) ); - - if( status != IOT_MQTT_SUCCESS ) - { - IOT_GOTO_CLEANUP(); - } - - /* Check the serialized MQTT packet. */ - IotMqtt_Assert( pSubscriptionOperation->u.operation.pMqttPacket != NULL ); - IotMqtt_Assert( pSubscriptionOperation->u.operation.packetSize > 0 ); - - /* Add the subscription list for a SUBSCRIBE. */ - if( operation == IOT_MQTT_SUBSCRIBE ) - { - status = _IotMqtt_AddSubscriptions( mqttConnection, - pSubscriptionOperation->u.operation.packetIdentifier, - pSubscriptionList, - subscriptionCount ); - - if( status != IOT_MQTT_SUCCESS ) - { - IOT_GOTO_CLEANUP(); - } - } - - /* Set the reference, if provided. */ - if( pOperationReference != NULL ) - { - *pOperationReference = pSubscriptionOperation; - } - - /* Schedule the subscription operation for network transmission. */ - status = _IotMqtt_ScheduleOperation( pSubscriptionOperation, - _IotMqtt_ProcessSend, - 0 ); - - if( status != IOT_MQTT_SUCCESS ) - { - IotLogError( "(MQTT connection %p) Failed to schedule %s for sending.", - mqttConnection, - IotMqtt_OperationType( operation ) ); - - if( operation == IOT_MQTT_SUBSCRIBE ) - { - _IotMqtt_RemoveSubscriptionByPacket( mqttConnection, - pSubscriptionOperation->u.operation.packetIdentifier, - -1 ); - } - - /* Clear the previously set (and now invalid) reference. */ - if( pOperationReference != NULL ) - { - *pOperationReference = IOT_MQTT_OPERATION_INITIALIZER; - } - - IOT_GOTO_CLEANUP(); - } - - /* Clean up if this function failed. */ - IOT_FUNCTION_CLEANUP_BEGIN(); - - if( status != IOT_MQTT_SUCCESS ) - { - if( pSubscriptionOperation != NULL ) - { - _IotMqtt_DestroyOperation( pSubscriptionOperation ); - } - } - else - { - status = IOT_MQTT_STATUS_PENDING; - - IotLogInfo( "(MQTT connection %p) %s operation scheduled.", - mqttConnection, - IotMqtt_OperationType( operation ) ); - } - - IOT_FUNCTION_CLEANUP_END(); -} - -/*-----------------------------------------------------------*/ - -bool _IotMqtt_IncrementConnectionReferences( _mqttConnection_t * pMqttConnection ) -{ - bool disconnected = false; - - /* Lock the mutex protecting the reference count. */ - IotMutex_Lock( &( pMqttConnection->referencesMutex ) ); - - /* Reference count must not be negative. */ - IotMqtt_Assert( pMqttConnection->references >= 0 ); - - /* Read connection status. */ - disconnected = pMqttConnection->disconnected; - - /* Increment the connection's reference count if it is not disconnected. */ - if( disconnected == false ) - { - ( pMqttConnection->references )++; - IotLogDebug( "(MQTT connection %p) Reference count changed from %ld to %ld.", - pMqttConnection, - ( long int ) pMqttConnection->references - 1, - ( long int ) pMqttConnection->references ); - } - else - { - IotLogWarn( "(MQTT connection %p) Attempt to use closed connection.", pMqttConnection ); - } - - IotMutex_Unlock( &( pMqttConnection->referencesMutex ) ); - - return( disconnected == false ); -} - -/*-----------------------------------------------------------*/ - -void _IotMqtt_DecrementConnectionReferences( _mqttConnection_t * pMqttConnection ) -{ - bool destroyConnection = false; - - /* Lock the mutex protecting the reference count. */ - IotMutex_Lock( &( pMqttConnection->referencesMutex ) ); - - /* Decrement reference count. It must not be negative. */ - ( pMqttConnection->references )--; - IotMqtt_Assert( pMqttConnection->references >= 0 ); - - IotLogDebug( "(MQTT connection %p) Reference count changed from %ld to %ld.", - pMqttConnection, - ( long int ) pMqttConnection->references + 1, - ( long int ) pMqttConnection->references ); - - /* Check if this connection may be destroyed. */ - if( pMqttConnection->references == 0 ) - { - destroyConnection = true; - } - else - { - EMPTY_ELSE_MARKER; - } - - IotMutex_Unlock( &( pMqttConnection->referencesMutex ) ); - - /* Destroy an unreferenced MQTT connection. */ - if( destroyConnection == true ) - { - IotLogDebug( "(MQTT connection %p) Connection will be destroyed now.", - pMqttConnection ); - _destroyMqttConnection( pMqttConnection ); - } - else - { - EMPTY_ELSE_MARKER; - } -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t IotMqtt_Init( void ) -{ - IotMqttError_t status = IOT_MQTT_SUCCESS; - - /* Call any additional serializer initialization function if serializer - * overrides are enabled. */ - #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 - #ifdef _IotMqtt_InitSerializeAdditional - if( _IotMqtt_InitSerializeAdditional() == false ) - { - status = IOT_MQTT_INIT_FAILED; - } - else - { - EMPTY_ELSE_MARKER; - } - #endif - #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */ - - /* Log initialization status. */ - if( status != IOT_MQTT_SUCCESS ) - { - IotLogError( "Failed to initialize MQTT library serializer. " ); - } - else - { - IotLogInfo( "MQTT library successfully initialized." ); - } - - return status; -} - -/*-----------------------------------------------------------*/ - -void IotMqtt_Cleanup( void ) -{ - /* Call any additional serializer cleanup initialization function if serializer - * overrides are enabled. */ - #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 - #ifdef _IotMqtt_CleanupSerializeAdditional - _IotMqtt_CleanupSerializeAdditional(); - #endif - #endif - - IotLogInfo( "MQTT library cleanup done." ); -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t IotMqtt_Connect( const IotMqttNetworkInfo_t * pNetworkInfo, - const IotMqttConnectInfo_t * pConnectInfo, - uint32_t timeoutMs, - IotMqttConnection_t * const pMqttConnection ) -{ - IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS ); - bool networkCreated = false, ownNetworkConnection = false; - IotNetworkError_t networkStatus = IOT_NETWORK_SUCCESS; - IotTaskPoolError_t taskPoolStatus = IOT_TASKPOOL_SUCCESS; - void * pNetworkConnection = NULL; - _mqttOperation_t * pOperation = NULL; - _mqttConnection_t * pNewMqttConnection = NULL; - - /* Default CONNECT serializer function. */ - IotMqttError_t ( * serializeConnect )( const IotMqttConnectInfo_t *, - uint8_t **, - size_t * ) = _IotMqtt_SerializeConnect; - - /* Network info must not be NULL. */ - if( pNetworkInfo == NULL ) - { - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Validate network interface and connect info. */ - if( _IotMqtt_ValidateConnect( pConnectInfo ) == false ) - { - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* If will info is provided, check that it is valid. */ - if( pConnectInfo->pWillInfo != NULL ) - { - if( _IotMqtt_ValidatePublish( pConnectInfo->awsIotMqttMode, - pConnectInfo->pWillInfo ) == false ) - { - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER ); - } - else if( pConnectInfo->pWillInfo->payloadLength > UINT16_MAX ) - { - /* Will message payloads cannot be larger than 65535. This restriction - * applies only to will messages, and not normal PUBLISH messages. */ - IotLogError( "Will payload cannot be larger than 65535." ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* If previous subscriptions are provided, check that they are valid. */ - if( pConnectInfo->cleanSession == false ) - { - if( pConnectInfo->pPreviousSubscriptions != NULL ) - { - if( _IotMqtt_ValidateSubscriptionList( IOT_MQTT_SUBSCRIBE, - pConnectInfo->awsIotMqttMode, - pConnectInfo->pPreviousSubscriptions, - pConnectInfo->previousSubscriptionCount ) == false ) - { - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Create a new MQTT connection if requested. Otherwise, copy the existing - * network connection. */ - if( pNetworkInfo->createNetworkConnection == true ) - { - networkStatus = pNetworkInfo->pNetworkInterface->create( pNetworkInfo->u.setup.pNetworkServerInfo, - pNetworkInfo->u.setup.pNetworkCredentialInfo, - &pNetworkConnection ); - - if( networkStatus == IOT_NETWORK_SUCCESS ) - { - networkCreated = true; - - /* This MQTT connection owns the network connection it created and - * should destroy it on cleanup. */ - ownNetworkConnection = true; - } - else - { - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NETWORK_ERROR ); - } - } - else - { - pNetworkConnection = pNetworkInfo->u.pNetworkConnection; - networkCreated = true; - } - - IotLogInfo( "Establishing new MQTT connection." ); - - /* Initialize a new MQTT connection object. */ - pNewMqttConnection = _createMqttConnection( pConnectInfo->awsIotMqttMode, - pNetworkInfo, - pConnectInfo->keepAliveSeconds ); - - if( pNewMqttConnection == NULL ) - { - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NO_MEMORY ); - } - else - { - /* Set the network connection associated with the MQTT connection. */ - pNewMqttConnection->pNetworkConnection = pNetworkConnection; - pNewMqttConnection->ownNetworkConnection = ownNetworkConnection; - - /* Set the MQTT packet serializer overrides. */ - #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 - pNewMqttConnection->pSerializer = pNetworkInfo->pMqttSerializer; - #endif - } - - /* Set the MQTT receive callback. */ - networkStatus = pNewMqttConnection->pNetworkInterface->setReceiveCallback( pNetworkConnection, - IotMqtt_ReceiveCallback, - pNewMqttConnection ); - - if( networkStatus != IOT_NETWORK_SUCCESS ) - { - IotLogError( "Failed to set MQTT network receive callback." ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NETWORK_ERROR ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Create a CONNECT operation. */ - status = _IotMqtt_CreateOperation( pNewMqttConnection, - IOT_MQTT_FLAG_WAITABLE, - NULL, - &pOperation ); - - if( status != IOT_MQTT_SUCCESS ) - { - IOT_GOTO_CLEANUP(); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Ensure the members set by operation creation and serialization - * are appropriate for a blocking CONNECT. */ - IotMqtt_Assert( pOperation->u.operation.status == IOT_MQTT_STATUS_PENDING ); - IotMqtt_Assert( ( pOperation->u.operation.flags & IOT_MQTT_FLAG_WAITABLE ) - == IOT_MQTT_FLAG_WAITABLE ); - IotMqtt_Assert( pOperation->u.operation.periodic.retry.limit == 0 ); - - /* Set the operation type. */ - pOperation->u.operation.type = IOT_MQTT_CONNECT; - - /* Add previous session subscriptions. */ - if( pConnectInfo->pPreviousSubscriptions != NULL ) - { - /* Previous subscription count should have been validated as nonzero. */ - IotMqtt_Assert( pConnectInfo->previousSubscriptionCount > 0 ); - - status = _IotMqtt_AddSubscriptions( pNewMqttConnection, - 2, - pConnectInfo->pPreviousSubscriptions, - pConnectInfo->previousSubscriptionCount ); - - if( status != IOT_MQTT_SUCCESS ) - { - IOT_GOTO_CLEANUP(); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Choose a CONNECT serializer function. */ - #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 - if( pNewMqttConnection->pSerializer != NULL ) - { - if( pNewMqttConnection->pSerializer->serialize.connect != NULL ) - { - serializeConnect = pNewMqttConnection->pSerializer->serialize.connect; - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */ - - /* Convert the connect info and will info objects to an MQTT CONNECT packet. */ - status = serializeConnect( pConnectInfo, - &( pOperation->u.operation.pMqttPacket ), - &( pOperation->u.operation.packetSize ) ); - - if( status != IOT_MQTT_SUCCESS ) - { - IOT_GOTO_CLEANUP(); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check the serialized MQTT packet. */ - IotMqtt_Assert( pOperation->u.operation.pMqttPacket != NULL ); - IotMqtt_Assert( pOperation->u.operation.packetSize > 0 ); - - /* Add the CONNECT operation to the send queue for network transmission. */ - status = _IotMqtt_ScheduleOperation( pOperation, - _IotMqtt_ProcessSend, - 0 ); - - if( status != IOT_MQTT_SUCCESS ) - { - IotLogError( "Failed to enqueue CONNECT for sending." ); - } - else - { - /* Wait for the CONNECT operation to complete, i.e. wait for CONNACK. */ - status = IotMqtt_Wait( pOperation, - timeoutMs ); - - /* The call to wait cleans up the CONNECT operation, so set the pointer - * to NULL. */ - pOperation = NULL; - } - - /* When a connection is successfully established, schedule keep-alive job. */ - if( status == IOT_MQTT_SUCCESS ) - { - /* Check if a keep-alive job should be scheduled. */ - if( pNewMqttConnection->pingreq.u.operation.periodic.ping.keepAliveMs != 0 ) - { - IotLogDebug( "Scheduling first MQTT keep-alive job." ); - - taskPoolStatus = IotTaskPool_ScheduleDeferred( IOT_SYSTEM_TASKPOOL, - pNewMqttConnection->pingreq.job, - pNewMqttConnection->pingreq.u.operation.periodic.ping.nextPeriodMs ); - - if( taskPoolStatus != IOT_TASKPOOL_SUCCESS ) - { - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_SCHEDULING_ERROR ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - IOT_FUNCTION_CLEANUP_BEGIN(); - - if( status != IOT_MQTT_SUCCESS ) - { - IotLogError( "Failed to establish new MQTT connection, error %s.", - IotMqtt_strerror( status ) ); - - /* The network connection must be closed if it was created. */ - if( networkCreated == true ) - { - networkStatus = pNetworkInfo->pNetworkInterface->close( pNetworkConnection ); - - if( networkStatus != IOT_NETWORK_SUCCESS ) - { - IotLogWarn( "Failed to close network connection." ); - } - else - { - IotLogInfo( "Network connection closed on error." ); - } - } - else - { - EMPTY_ELSE_MARKER; - } - - if( pOperation != NULL ) - { - _IotMqtt_DestroyOperation( pOperation ); - } - else - { - EMPTY_ELSE_MARKER; - } - - if( pNewMqttConnection != NULL ) - { - _destroyMqttConnection( pNewMqttConnection ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - IotLogInfo( "New MQTT connection %p established.", pMqttConnection ); - - /* Set the output parameter. */ - *pMqttConnection = pNewMqttConnection; - } - - IOT_FUNCTION_CLEANUP_END(); -} - -/*-----------------------------------------------------------*/ - -void IotMqtt_Disconnect( IotMqttConnection_t mqttConnection, - uint32_t flags ) -{ - bool disconnected = false; - IotMqttError_t status = IOT_MQTT_STATUS_PENDING; - _mqttOperation_t * pOperation = NULL; - - IotLogInfo( "(MQTT connection %p) Disconnecting connection.", mqttConnection ); - - /* Read the connection status. */ - IotMutex_Lock( &( mqttConnection->referencesMutex ) ); - disconnected = mqttConnection->disconnected; - IotMutex_Unlock( &( mqttConnection->referencesMutex ) ); - - /* Only send a DISCONNECT packet if the connection is active and the "cleanup only" - * flag is not set. */ - if( disconnected == false ) - { - if( ( flags & IOT_MQTT_FLAG_CLEANUP_ONLY ) == 0 ) - { - /* Create a DISCONNECT operation. This function blocks until the DISCONNECT - * packet is sent, so it sets IOT_MQTT_FLAG_WAITABLE. */ - status = _IotMqtt_CreateOperation( mqttConnection, - IOT_MQTT_FLAG_WAITABLE, - NULL, - &pOperation ); - - if( status == IOT_MQTT_SUCCESS ) - { - /* Ensure that the members set by operation creation and serialization - * are appropriate for a blocking DISCONNECT. */ - IotMqtt_Assert( pOperation->u.operation.status == IOT_MQTT_STATUS_PENDING ); - IotMqtt_Assert( ( pOperation->u.operation.flags & IOT_MQTT_FLAG_WAITABLE ) - == IOT_MQTT_FLAG_WAITABLE ); - IotMqtt_Assert( pOperation->u.operation.periodic.retry.limit == 0 ); - - /* Set the operation type. */ - pOperation->u.operation.type = IOT_MQTT_DISCONNECT; - - /* Choose a disconnect serializer. */ - IotMqttError_t ( * serializeDisconnect )( uint8_t **, - size_t * ) = _IotMqtt_SerializeDisconnect; - - #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 - if( mqttConnection->pSerializer != NULL ) - { - if( mqttConnection->pSerializer->serialize.disconnect != NULL ) - { - serializeDisconnect = mqttConnection->pSerializer->serialize.disconnect; - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */ - - /* Generate a DISCONNECT packet. */ - status = serializeDisconnect( &( pOperation->u.operation.pMqttPacket ), - &( pOperation->u.operation.packetSize ) ); - } - else - { - EMPTY_ELSE_MARKER; - } - - if( status == IOT_MQTT_SUCCESS ) - { - /* Check the serialized MQTT packet. */ - IotMqtt_Assert( pOperation->u.operation.pMqttPacket != NULL ); - IotMqtt_Assert( pOperation->u.operation.packetSize > 0 ); - - /* Schedule the DISCONNECT operation for network transmission. */ - if( _IotMqtt_ScheduleOperation( pOperation, - _IotMqtt_ProcessSend, - 0 ) != IOT_MQTT_SUCCESS ) - { - IotLogWarn( "(MQTT connection %p) Failed to schedule DISCONNECT for sending.", - mqttConnection ); - _IotMqtt_DestroyOperation( pOperation ); - } - else - { - /* Wait a short time for the DISCONNECT packet to be transmitted. */ - status = IotMqtt_Wait( pOperation, - IOT_MQTT_RESPONSE_WAIT_MS ); - - /* A wait on DISCONNECT should only ever return SUCCESS, TIMEOUT, - * or NETWORK ERROR. */ - if( status == IOT_MQTT_SUCCESS ) - { - IotLogInfo( "(MQTT connection %p) Connection disconnected.", mqttConnection ); - } - else - { - IotMqtt_Assert( ( status == IOT_MQTT_TIMEOUT ) || - ( status == IOT_MQTT_NETWORK_ERROR ) ); - - IotLogWarn( "(MQTT connection %p) DISCONNECT not sent, error %s.", - mqttConnection, - IotMqtt_strerror( status ) ); - } - } - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Close the underlying network connection. This also cleans up keep-alive. */ - _IotMqtt_CloseNetworkConnection( IOT_MQTT_DISCONNECT_CALLED, - mqttConnection ); - - /* Check if the connection may be destroyed. */ - IotMutex_Lock( &( mqttConnection->referencesMutex ) ); - - /* At this point, the connection should be marked disconnected. */ - IotMqtt_Assert( mqttConnection->disconnected == true ); - - /* Attempt cancel and destroy each operation in the connection's lists. */ - IotListDouble_RemoveAll( &( mqttConnection->pendingProcessing ), - _mqttOperation_tryDestroy, - offsetof( _mqttOperation_t, link ) ); - - IotListDouble_RemoveAll( &( mqttConnection->pendingResponse ), - _mqttOperation_tryDestroy, - offsetof( _mqttOperation_t, link ) ); - - IotMutex_Unlock( &( mqttConnection->referencesMutex ) ); - - /* Decrement the connection reference count and destroy it if possible. */ - _IotMqtt_DecrementConnectionReferences( mqttConnection ); -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t IotMqtt_Subscribe( IotMqttConnection_t mqttConnection, - const IotMqttSubscription_t * pSubscriptionList, - size_t subscriptionCount, - uint32_t flags, - const IotMqttCallbackInfo_t * pCallbackInfo, - IotMqttOperation_t * const pSubscribeOperation ) -{ - return _subscriptionCommon( IOT_MQTT_SUBSCRIBE, - mqttConnection, - pSubscriptionList, - subscriptionCount, - flags, - pCallbackInfo, - pSubscribeOperation ); -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t IotMqtt_TimedSubscribe( IotMqttConnection_t mqttConnection, - const IotMqttSubscription_t * pSubscriptionList, - size_t subscriptionCount, - uint32_t flags, - uint32_t timeoutMs ) -{ - IotMqttError_t status = IOT_MQTT_STATUS_PENDING; - IotMqttOperation_t subscribeOperation = IOT_MQTT_OPERATION_INITIALIZER; - - /* Flags are not used, but the parameter is present for future compatibility. */ - ( void ) flags; - - /* Call the asynchronous SUBSCRIBE function. */ - status = IotMqtt_Subscribe( mqttConnection, - pSubscriptionList, - subscriptionCount, - IOT_MQTT_FLAG_WAITABLE, - NULL, - &subscribeOperation ); - - /* Wait for the SUBSCRIBE operation to complete. */ - if( status == IOT_MQTT_STATUS_PENDING ) - { - status = IotMqtt_Wait( subscribeOperation, timeoutMs ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Ensure that a status was set. */ - IotMqtt_Assert( status != IOT_MQTT_STATUS_PENDING ); - - return status; -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t IotMqtt_Unsubscribe( IotMqttConnection_t mqttConnection, - const IotMqttSubscription_t * pSubscriptionList, - size_t subscriptionCount, - uint32_t flags, - const IotMqttCallbackInfo_t * pCallbackInfo, - IotMqttOperation_t * const pUnsubscribeOperation ) -{ - return _subscriptionCommon( IOT_MQTT_UNSUBSCRIBE, - mqttConnection, - pSubscriptionList, - subscriptionCount, - flags, - pCallbackInfo, - pUnsubscribeOperation ); -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t IotMqtt_TimedUnsubscribe( IotMqttConnection_t mqttConnection, - const IotMqttSubscription_t * pSubscriptionList, - size_t subscriptionCount, - uint32_t flags, - uint32_t timeoutMs ) -{ - IotMqttError_t status = IOT_MQTT_STATUS_PENDING; - IotMqttOperation_t unsubscribeOperation = IOT_MQTT_OPERATION_INITIALIZER; - - /* Flags are not used, but the parameter is present for future compatibility. */ - ( void ) flags; - - /* Call the asynchronous UNSUBSCRIBE function. */ - status = IotMqtt_Unsubscribe( mqttConnection, - pSubscriptionList, - subscriptionCount, - IOT_MQTT_FLAG_WAITABLE, - NULL, - &unsubscribeOperation ); - - /* Wait for the UNSUBSCRIBE operation to complete. */ - if( status == IOT_MQTT_STATUS_PENDING ) - { - status = IotMqtt_Wait( unsubscribeOperation, timeoutMs ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Ensure that a status was set. */ - IotMqtt_Assert( status != IOT_MQTT_STATUS_PENDING ); - - return status; -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t IotMqtt_Publish( IotMqttConnection_t mqttConnection, - const IotMqttPublishInfo_t * pPublishInfo, - uint32_t flags, - const IotMqttCallbackInfo_t * pCallbackInfo, - IotMqttOperation_t * const pPublishOperation ) -{ - IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS ); - _mqttOperation_t * pOperation = NULL; - uint8_t ** pPacketIdentifierHigh = NULL; - - /* Default PUBLISH serializer function. */ - IotMqttError_t ( * serializePublish )( const IotMqttPublishInfo_t *, - uint8_t **, - size_t *, - uint16_t *, - uint8_t ** ) = _IotMqtt_SerializePublish; - - /* Check that the PUBLISH information is valid. */ - if( _IotMqtt_ValidatePublish( mqttConnection->awsIotMqttMode, - pPublishInfo ) == false ) - { - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check that no notification is requested for a QoS 0 publish. */ - if( pPublishInfo->qos == IOT_MQTT_QOS_0 ) - { - if( pCallbackInfo != NULL ) - { - IotLogError( "QoS 0 PUBLISH should not have notification parameters set." ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER ); - } - else if( ( flags & IOT_MQTT_FLAG_WAITABLE ) != 0 ) - { - IotLogError( "QoS 0 PUBLISH should not have notification parameters set." ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER ); - } - else - { - EMPTY_ELSE_MARKER; - } - - if( pPublishOperation != NULL ) - { - IotLogWarn( "Ignoring reference parameter for QoS 0 publish." ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check that a reference pointer is provided for a waitable operation. */ - if( ( flags & IOT_MQTT_FLAG_WAITABLE ) == IOT_MQTT_FLAG_WAITABLE ) - { - if( pPublishOperation == NULL ) - { - IotLogError( "Reference must be provided for a waitable PUBLISH." ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Create a PUBLISH operation. */ - status = _IotMqtt_CreateOperation( mqttConnection, - flags, - pCallbackInfo, - &pOperation ); - - if( status != IOT_MQTT_SUCCESS ) - { - IOT_GOTO_CLEANUP(); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check the PUBLISH operation data and set the operation type. */ - IotMqtt_Assert( pOperation->u.operation.status == IOT_MQTT_STATUS_PENDING ); - pOperation->u.operation.type = IOT_MQTT_PUBLISH_TO_SERVER; - - /* Choose a PUBLISH serializer function. */ - #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 - if( mqttConnection->pSerializer != NULL ) - { - if( mqttConnection->pSerializer->serialize.publish != NULL ) - { - serializePublish = mqttConnection->pSerializer->serialize.publish; - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */ - - /* In AWS IoT MQTT mode, a pointer to the packet identifier must be saved. */ - if( mqttConnection->awsIotMqttMode == true ) - { - pPacketIdentifierHigh = &( pOperation->u.operation.pPacketIdentifierHigh ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Generate a PUBLISH packet from pPublishInfo. */ - status = serializePublish( pPublishInfo, - &( pOperation->u.operation.pMqttPacket ), - &( pOperation->u.operation.packetSize ), - &( pOperation->u.operation.packetIdentifier ), - pPacketIdentifierHigh ); - - if( status != IOT_MQTT_SUCCESS ) - { - IOT_GOTO_CLEANUP(); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check the serialized MQTT packet. */ - IotMqtt_Assert( pOperation->u.operation.pMqttPacket != NULL ); - IotMqtt_Assert( pOperation->u.operation.packetSize > 0 ); - - /* Initialize PUBLISH retry if retryLimit is set. */ - if( pPublishInfo->retryLimit > 0 ) - { - /* A QoS 0 PUBLISH may not be retried. */ - if( pPublishInfo->qos != IOT_MQTT_QOS_0 ) - { - pOperation->u.operation.periodic.retry.limit = pPublishInfo->retryLimit; - pOperation->u.operation.periodic.retry.nextPeriodMs = pPublishInfo->retryMs; - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Set the reference, if provided. */ - if( pPublishInfo->qos != IOT_MQTT_QOS_0 ) - { - if( pPublishOperation != NULL ) - { - *pPublishOperation = pOperation; - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Add the PUBLISH operation to the send queue for network transmission. */ - status = _IotMqtt_ScheduleOperation( pOperation, - _IotMqtt_ProcessSend, - 0 ); - - if( status != IOT_MQTT_SUCCESS ) - { - IotLogError( "(MQTT connection %p) Failed to enqueue PUBLISH for sending.", - mqttConnection ); - - /* Clear the previously set (and now invalid) reference. */ - if( pPublishInfo->qos != IOT_MQTT_QOS_0 ) - { - if( pPublishOperation != NULL ) - { - *pPublishOperation = IOT_MQTT_OPERATION_INITIALIZER; - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - IOT_GOTO_CLEANUP(); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Clean up the PUBLISH operation if this function fails. Otherwise, set the - * appropriate return code based on QoS. */ - IOT_FUNCTION_CLEANUP_BEGIN(); - - if( status != IOT_MQTT_SUCCESS ) - { - if( pOperation != NULL ) - { - _IotMqtt_DestroyOperation( pOperation ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - if( pPublishInfo->qos > IOT_MQTT_QOS_0 ) - { - status = IOT_MQTT_STATUS_PENDING; - } - else - { - EMPTY_ELSE_MARKER; - } - - IotLogInfo( "(MQTT connection %p) MQTT PUBLISH operation queued.", - mqttConnection ); - } - - IOT_FUNCTION_CLEANUP_END(); -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t IotMqtt_TimedPublish( IotMqttConnection_t mqttConnection, - const IotMqttPublishInfo_t * pPublishInfo, - uint32_t flags, - uint32_t timeoutMs ) -{ - IotMqttError_t status = IOT_MQTT_STATUS_PENDING; - IotMqttOperation_t publishOperation = IOT_MQTT_OPERATION_INITIALIZER, - * pPublishOperation = NULL; - - /* Clear the flags. */ - flags = 0; - - /* Set the waitable flag and reference for QoS 1 PUBLISH. */ - if( pPublishInfo->qos == IOT_MQTT_QOS_1 ) - { - flags = IOT_MQTT_FLAG_WAITABLE; - pPublishOperation = &publishOperation; - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Call the asynchronous PUBLISH function. */ - status = IotMqtt_Publish( mqttConnection, - pPublishInfo, - flags, - NULL, - pPublishOperation ); - - /* Wait for a queued QoS 1 PUBLISH to complete. */ - if( pPublishInfo->qos == IOT_MQTT_QOS_1 ) - { - if( status == IOT_MQTT_STATUS_PENDING ) - { - status = IotMqtt_Wait( publishOperation, timeoutMs ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - return status; -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t IotMqtt_Wait( IotMqttOperation_t operation, - uint32_t timeoutMs ) -{ - IotMqttError_t status = IOT_MQTT_SUCCESS; - _mqttConnection_t * pMqttConnection = operation->pMqttConnection; - - /* Validate the given operation reference. */ - if( _IotMqtt_ValidateOperation( operation ) == false ) - { - status = IOT_MQTT_BAD_PARAMETER; - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check the MQTT connection status. */ - if( status == IOT_MQTT_SUCCESS ) - { - IotMutex_Lock( &( pMqttConnection->referencesMutex ) ); - - if( pMqttConnection->disconnected == true ) - { - IotLogError( "(MQTT connection %p, %s operation %p) MQTT connection is closed. " - "Operation cannot be waited on.", - pMqttConnection, - IotMqtt_OperationType( operation->u.operation.type ), - operation ); - - status = IOT_MQTT_NETWORK_ERROR; - } - else - { - IotLogInfo( "(MQTT connection %p, %s operation %p) Waiting for operation completion.", - pMqttConnection, - IotMqtt_OperationType( operation->u.operation.type ), - operation ); - } - - IotMutex_Unlock( &( pMqttConnection->referencesMutex ) ); - - /* Only wait on an operation if the MQTT connection is active. */ - if( status == IOT_MQTT_SUCCESS ) - { - if( IotSemaphore_TimedWait( &( operation->u.operation.notify.waitSemaphore ), - timeoutMs ) == false ) - { - status = IOT_MQTT_TIMEOUT; - - /* Attempt to cancel the job of the timed out operation. */ - ( void ) _IotMqtt_DecrementOperationReferences( operation, true ); - - /* Clean up lingering subscriptions from a timed-out SUBSCRIBE. */ - if( operation->u.operation.type == IOT_MQTT_SUBSCRIBE ) - { - IotLogDebug( "(MQTT connection %p, SUBSCRIBE operation %p) Cleaning up" - " subscriptions of timed-out SUBSCRIBE.", - pMqttConnection, - operation ); - - _IotMqtt_RemoveSubscriptionByPacket( pMqttConnection, - operation->u.operation.packetIdentifier, - -1 ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - /* Retrieve the status of the completed operation. */ - status = operation->u.operation.status; - } - - IotLogInfo( "(MQTT connection %p, %s operation %p) Wait complete with result %s.", - pMqttConnection, - IotMqtt_OperationType( operation->u.operation.type ), - operation, - IotMqtt_strerror( status ) ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Wait is finished; decrement operation reference count. */ - if( _IotMqtt_DecrementOperationReferences( operation, false ) == true ) - { - _IotMqtt_DestroyOperation( operation ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - return status; -} - -/*-----------------------------------------------------------*/ - -const char * IotMqtt_strerror( IotMqttError_t status ) -{ - const char * pMessage = NULL; - - switch( status ) - { - case IOT_MQTT_SUCCESS: - pMessage = "SUCCESS"; - break; - - case IOT_MQTT_STATUS_PENDING: - pMessage = "PENDING"; - break; - - case IOT_MQTT_INIT_FAILED: - pMessage = "INITIALIZATION FAILED"; - break; - - case IOT_MQTT_BAD_PARAMETER: - pMessage = "BAD PARAMETER"; - break; - - case IOT_MQTT_NO_MEMORY: - pMessage = "NO MEMORY"; - break; - - case IOT_MQTT_NETWORK_ERROR: - pMessage = "NETWORK ERROR"; - break; - - case IOT_MQTT_SCHEDULING_ERROR: - pMessage = "SCHEDULING ERROR"; - break; - - case IOT_MQTT_BAD_RESPONSE: - pMessage = "BAD RESPONSE RECEIVED"; - break; - - case IOT_MQTT_TIMEOUT: - pMessage = "TIMEOUT"; - break; - - case IOT_MQTT_SERVER_REFUSED: - pMessage = "SERVER REFUSED"; - break; - - case IOT_MQTT_RETRY_NO_RESPONSE: - pMessage = "NO RESPONSE"; - break; - - default: - pMessage = "INVALID STATUS"; - break; - } - - return pMessage; -} - -/*-----------------------------------------------------------*/ - -const char * IotMqtt_OperationType( IotMqttOperationType_t operation ) -{ - const char * pMessage = NULL; - - switch( operation ) - { - case IOT_MQTT_CONNECT: - pMessage = "CONNECT"; - break; - - case IOT_MQTT_PUBLISH_TO_SERVER: - pMessage = "PUBLISH"; - break; - - case IOT_MQTT_PUBACK: - pMessage = "PUBACK"; - break; - - case IOT_MQTT_SUBSCRIBE: - pMessage = "SUBSCRIBE"; - break; - - case IOT_MQTT_UNSUBSCRIBE: - pMessage = "UNSUBSCRIBE"; - break; - - case IOT_MQTT_PINGREQ: - pMessage = "PINGREQ"; - break; - - case IOT_MQTT_DISCONNECT: - pMessage = "DISCONNECT"; - break; - - default: - pMessage = "INVALID OPERATION"; - break; - } - - return pMessage; -} - -/*-----------------------------------------------------------*/ - -/* Provide access to internal functions and variables if testing. */ -#if IOT_BUILD_TESTS == 1 - #include "iot_test_access_mqtt_api.c" -#endif diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_network.c b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_network.c deleted file mode 100644 index 42843d28c..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_network.c +++ /dev/null @@ -1,986 +0,0 @@ -/* - * Amazon FreeRTOS MQTT V2.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_mqtt_network.c - * @brief Implements functions involving transport layer connections. - */ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* Standard includes. */ -#include - -/* Error handling include. */ -#include "private/iot_error.h" - -/* MQTT internal include. */ -#include "private/iot_mqtt_internal.h" - -/* Platform layer includes. */ -#include "platform/iot_threads.h" - -/* Atomics include. */ -#include "iot_atomic.h" - -/*-----------------------------------------------------------*/ - -/** - * @brief Check if an incoming packet type is valid. - * - * @param[in] packetType The packet type to check. - * - * @return `true` if the packet type is valid; `false` otherwise. - */ -static bool _incomingPacketValid( uint8_t packetType ); - -/** - * @brief Get an incoming MQTT packet from the network. - * - * @param[in] pNetworkConnection Network connection to use for receive, which - * may be different from the network connection associated with the MQTT connection. - * @param[in] pMqttConnection The associated MQTT connection. - * @param[out] pIncomingPacket Output parameter for the incoming packet. - * - * @return #IOT_MQTT_SUCCESS, #IOT_MQTT_NO_MEMORY or #IOT_MQTT_BAD_RESPONSE. - */ -static IotMqttError_t _getIncomingPacket( void * pNetworkConnection, - const _mqttConnection_t * pMqttConnection, - _mqttPacket_t * pIncomingPacket ); - -/** - * @brief Deserialize a packet received from the network. - * - * @param[in] pMqttConnection The associated MQTT connection. - * @param[in] pIncomingPacket The packet received from the network. - * - * @return #IOT_MQTT_SUCCESS, #IOT_MQTT_NO_MEMORY, #IOT_MQTT_NETWORK_ERROR, - * #IOT_MQTT_SCHEDULING_ERROR, #IOT_MQTT_BAD_RESPONSE, or #IOT_MQTT_SERVER_REFUSED. - */ -static IotMqttError_t _deserializeIncomingPacket( _mqttConnection_t * pMqttConnection, - _mqttPacket_t * pIncomingPacket ); - -/** - * @brief Send a PUBACK for a received QoS 1 PUBLISH packet. - * - * @param[in] pMqttConnection Which connection the PUBACK should be sent over. - * @param[in] packetIdentifier Which packet identifier to include in PUBACK. - */ -static void _sendPuback( _mqttConnection_t * pMqttConnection, - uint16_t packetIdentifier ); - -/** - * @brief Flush a packet from the stream of incoming data. - * - * This function is called when memory for a packet cannot be allocated. The - * packet is flushed from the stream of incoming data so that the next packet - * may be read. - * - * @param[in] pNetworkConnection Network connection to use for receive, which - * may be different from the network connection associated with the MQTT connection. - * @param[in] pMqttConnection The associated MQTT connection. - * @param[in] length The length of the packet to flush. - */ -static void _flushPacket( void * pNetworkConnection, - const _mqttConnection_t * pMqttConnection, - size_t length ); - -/*-----------------------------------------------------------*/ - -static bool _incomingPacketValid( uint8_t packetType ) -{ - bool status = true; - - /* Check packet type. Mask out lower bits to ignore flags. */ - switch( packetType & 0xf0 ) - { - /* Valid incoming packet types. */ - case MQTT_PACKET_TYPE_CONNACK: - case MQTT_PACKET_TYPE_PUBLISH: - case MQTT_PACKET_TYPE_PUBACK: - case MQTT_PACKET_TYPE_SUBACK: - case MQTT_PACKET_TYPE_UNSUBACK: - case MQTT_PACKET_TYPE_PINGRESP: - break; - - /* Any other packet type is invalid. */ - default: - status = false; - break; - } - - return status; -} - -/*-----------------------------------------------------------*/ - -static IotMqttError_t _getIncomingPacket( void * pNetworkConnection, - const _mqttConnection_t * pMqttConnection, - _mqttPacket_t * pIncomingPacket ) -{ - IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS ); - size_t dataBytesRead = 0; - - /* Default functions for retrieving packet type and length. */ - uint8_t ( * getPacketType )( void *, - const IotNetworkInterface_t * ) = _IotMqtt_GetPacketType; - size_t ( * getRemainingLength )( void *, - const IotNetworkInterface_t * ) = _IotMqtt_GetRemainingLength; - - /* No buffer for remaining data should be allocated. */ - IotMqtt_Assert( pIncomingPacket->pRemainingData == NULL ); - IotMqtt_Assert( pIncomingPacket->remainingLength == 0 ); - - /* Choose packet type and length functions. */ - #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 - if( pMqttConnection->pSerializer != NULL ) - { - if( pMqttConnection->pSerializer->getPacketType != NULL ) - { - getPacketType = pMqttConnection->pSerializer->getPacketType; - } - else - { - EMPTY_ELSE_MARKER; - } - - if( pMqttConnection->pSerializer->getRemainingLength != NULL ) - { - getRemainingLength = pMqttConnection->pSerializer->getRemainingLength; - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */ - - /* Read the packet type, which is the first byte available. */ - pIncomingPacket->type = getPacketType( pNetworkConnection, - pMqttConnection->pNetworkInterface ); - - /* Check that the incoming packet type is valid. */ - if( _incomingPacketValid( pIncomingPacket->type ) == false ) - { - IotLogError( "(MQTT connection %p) Unknown packet type %02x received.", - pMqttConnection, - pIncomingPacket->type ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Read the remaining length. */ - pIncomingPacket->remainingLength = getRemainingLength( pNetworkConnection, - pMqttConnection->pNetworkInterface ); - - if( pIncomingPacket->remainingLength == MQTT_REMAINING_LENGTH_INVALID ) - { - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Allocate a buffer for the remaining data and read the data. */ - if( pIncomingPacket->remainingLength > 0 ) - { - pIncomingPacket->pRemainingData = IotMqtt_MallocMessage( pIncomingPacket->remainingLength ); - - if( pIncomingPacket->pRemainingData == NULL ) - { - IotLogError( "(MQTT connection %p) Failed to allocate buffer of length " - "%lu for incoming packet type %lu.", - pMqttConnection, - ( unsigned long ) pIncomingPacket->remainingLength, - ( unsigned long ) pIncomingPacket->type ); - - _flushPacket( pNetworkConnection, pMqttConnection, pIncomingPacket->remainingLength ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NO_MEMORY ); - } - else - { - EMPTY_ELSE_MARKER; - } - - dataBytesRead = pMqttConnection->pNetworkInterface->receive( pNetworkConnection, - pIncomingPacket->pRemainingData, - pIncomingPacket->remainingLength ); - - if( dataBytesRead != pIncomingPacket->remainingLength ) - { - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Clean up on error. */ - IOT_FUNCTION_CLEANUP_BEGIN(); - - if( status != IOT_MQTT_SUCCESS ) - { - if( pIncomingPacket->pRemainingData != NULL ) - { - IotMqtt_FreeMessage( pIncomingPacket->pRemainingData ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - IOT_FUNCTION_CLEANUP_END(); -} - -/*-----------------------------------------------------------*/ - -static IotMqttError_t _deserializeIncomingPacket( _mqttConnection_t * pMqttConnection, - _mqttPacket_t * pIncomingPacket ) -{ - IotMqttError_t status = IOT_MQTT_STATUS_PENDING; - _mqttOperation_t * pOperation = NULL; - - /* Deserializer function. */ - IotMqttError_t ( * deserialize )( _mqttPacket_t * ) = NULL; - - /* A buffer for remaining data must be allocated if remaining length is not 0. */ - IotMqtt_Assert( ( pIncomingPacket->remainingLength > 0 ) == - ( pIncomingPacket->pRemainingData != NULL ) ); - - /* Only valid packets should be given to this function. */ - IotMqtt_Assert( _incomingPacketValid( pIncomingPacket->type ) == true ); - - /* Mask out the low bits of packet type to ignore flags. */ - switch( ( pIncomingPacket->type & 0xf0 ) ) - { - case MQTT_PACKET_TYPE_CONNACK: - IotLogDebug( "(MQTT connection %p) CONNACK in data stream.", pMqttConnection ); - - /* Choose CONNACK deserializer. */ - deserialize = _IotMqtt_DeserializeConnack; - - #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 - if( pMqttConnection->pSerializer != NULL ) - { - if( pMqttConnection->pSerializer->deserialize.connack != NULL ) - { - deserialize = pMqttConnection->pSerializer->deserialize.connack; - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */ - - /* Deserialize CONNACK and notify of result. */ - status = deserialize( pIncomingPacket ); - pOperation = _IotMqtt_FindOperation( pMqttConnection, - IOT_MQTT_CONNECT, - NULL ); - - if( pOperation != NULL ) - { - pOperation->u.operation.status = status; - _IotMqtt_Notify( pOperation ); - } - else - { - EMPTY_ELSE_MARKER; - } - - break; - - case MQTT_PACKET_TYPE_PUBLISH: - IotLogDebug( "(MQTT connection %p) PUBLISH in data stream.", pMqttConnection ); - - /* Allocate memory to handle the incoming PUBLISH. */ - pOperation = IotMqtt_MallocOperation( sizeof( _mqttOperation_t ) ); - - if( pOperation == NULL ) - { - IotLogWarn( "Failed to allocate memory for incoming PUBLISH." ); - status = IOT_MQTT_NO_MEMORY; - - break; - } - else - { - /* Set the members of the incoming PUBLISH operation. */ - ( void ) memset( pOperation, 0x00, sizeof( _mqttOperation_t ) ); - pOperation->incomingPublish = true; - pOperation->pMqttConnection = pMqttConnection; - pIncomingPacket->u.pIncomingPublish = pOperation; - } - - /* Choose a PUBLISH deserializer. */ - deserialize = _IotMqtt_DeserializePublish; - - #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 - if( pMqttConnection->pSerializer != NULL ) - { - if( pMqttConnection->pSerializer->deserialize.publish != NULL ) - { - deserialize = pMqttConnection->pSerializer->deserialize.publish; - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */ - - /* Deserialize incoming PUBLISH. */ - status = deserialize( pIncomingPacket ); - - if( status == IOT_MQTT_SUCCESS ) - { - /* Send a PUBACK for QoS 1 PUBLISH. */ - if( pOperation->u.publish.publishInfo.qos == IOT_MQTT_QOS_1 ) - { - _sendPuback( pMqttConnection, pIncomingPacket->packetIdentifier ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Transfer ownership of the received MQTT packet to the PUBLISH operation. */ - pOperation->u.publish.pReceivedData = pIncomingPacket->pRemainingData; - pIncomingPacket->pRemainingData = NULL; - - /* Add the PUBLISH to the list of operations pending processing. */ - IotMutex_Lock( &( pMqttConnection->referencesMutex ) ); - IotListDouble_InsertHead( &( pMqttConnection->pendingProcessing ), - &( pOperation->link ) ); - IotMutex_Unlock( &( pMqttConnection->referencesMutex ) ); - - /* Increment the MQTT connection reference count before scheduling an - * incoming PUBLISH. */ - if( _IotMqtt_IncrementConnectionReferences( pMqttConnection ) == true ) - { - /* Schedule PUBLISH for callback invocation. */ - status = _IotMqtt_ScheduleOperation( pOperation, _IotMqtt_ProcessIncomingPublish, 0 ); - } - else - { - status = IOT_MQTT_NETWORK_ERROR; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Free PUBLISH operation on error. */ - if( status != IOT_MQTT_SUCCESS ) - { - /* Check ownership of the received MQTT packet. */ - if( pOperation->u.publish.pReceivedData != NULL ) - { - /* Retrieve the pointer MQTT packet pointer so it may be freed later. */ - IotMqtt_Assert( pIncomingPacket->pRemainingData == NULL ); - pIncomingPacket->pRemainingData = ( uint8_t * ) pOperation->u.publish.pReceivedData; - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Remove operation from pending processing list. */ - IotMutex_Lock( &( pMqttConnection->referencesMutex ) ); - - if( IotLink_IsLinked( &( pOperation->link ) ) == true ) - { - IotListDouble_Remove( &( pOperation->link ) ); - } - else - { - EMPTY_ELSE_MARKER; - } - - IotMutex_Unlock( &( pMqttConnection->referencesMutex ) ); - - IotMqtt_Assert( pOperation != NULL ); - IotMqtt_FreeOperation( pOperation ); - } - else - { - EMPTY_ELSE_MARKER; - } - - break; - - case MQTT_PACKET_TYPE_PUBACK: - IotLogDebug( "(MQTT connection %p) PUBACK in data stream.", pMqttConnection ); - - /* Choose PUBACK deserializer. */ - deserialize = _IotMqtt_DeserializePuback; - - #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 - if( pMqttConnection->pSerializer != NULL ) - { - if( pMqttConnection->pSerializer->deserialize.puback != NULL ) - { - deserialize = pMqttConnection->pSerializer->deserialize.puback; - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */ - - /* Deserialize PUBACK and notify of result. */ - status = deserialize( pIncomingPacket ); - pOperation = _IotMqtt_FindOperation( pMqttConnection, - IOT_MQTT_PUBLISH_TO_SERVER, - &( pIncomingPacket->packetIdentifier ) ); - - if( pOperation != NULL ) - { - pOperation->u.operation.status = status; - _IotMqtt_Notify( pOperation ); - } - else - { - EMPTY_ELSE_MARKER; - } - - break; - - case MQTT_PACKET_TYPE_SUBACK: - IotLogDebug( "(MQTT connection %p) SUBACK in data stream.", pMqttConnection ); - - /* Choose SUBACK deserializer. */ - deserialize = _IotMqtt_DeserializeSuback; - - #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 - if( pMqttConnection->pSerializer != NULL ) - { - if( pMqttConnection->pSerializer->deserialize.suback != NULL ) - { - deserialize = pMqttConnection->pSerializer->deserialize.suback; - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */ - - /* Deserialize SUBACK and notify of result. */ - pIncomingPacket->u.pMqttConnection = pMqttConnection; - status = deserialize( pIncomingPacket ); - pOperation = _IotMqtt_FindOperation( pMqttConnection, - IOT_MQTT_SUBSCRIBE, - &( pIncomingPacket->packetIdentifier ) ); - - if( pOperation != NULL ) - { - pOperation->u.operation.status = status; - _IotMqtt_Notify( pOperation ); - } - else - { - EMPTY_ELSE_MARKER; - } - - break; - - case MQTT_PACKET_TYPE_UNSUBACK: - IotLogDebug( "(MQTT connection %p) UNSUBACK in data stream.", pMqttConnection ); - - /* Choose UNSUBACK deserializer. */ - deserialize = _IotMqtt_DeserializeUnsuback; - - #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 - if( pMqttConnection->pSerializer != NULL ) - { - if( pMqttConnection->pSerializer->deserialize.unsuback != NULL ) - { - deserialize = pMqttConnection->pSerializer->deserialize.unsuback; - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */ - - /* Deserialize UNSUBACK and notify of result. */ - status = deserialize( pIncomingPacket ); - pOperation = _IotMqtt_FindOperation( pMqttConnection, - IOT_MQTT_UNSUBSCRIBE, - &( pIncomingPacket->packetIdentifier ) ); - - if( pOperation != NULL ) - { - pOperation->u.operation.status = status; - _IotMqtt_Notify( pOperation ); - } - else - { - EMPTY_ELSE_MARKER; - } - - break; - - default: - /* The only remaining valid type is PINGRESP. */ - IotMqtt_Assert( ( pIncomingPacket->type & 0xf0 ) == MQTT_PACKET_TYPE_PINGRESP ); - IotLogDebug( "(MQTT connection %p) PINGRESP in data stream.", pMqttConnection ); - - /* Choose PINGRESP deserializer. */ - deserialize = _IotMqtt_DeserializePingresp; - - #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 - if( pMqttConnection->pSerializer != NULL ) - { - if( pMqttConnection->pSerializer->deserialize.pingresp != NULL ) - { - deserialize = pMqttConnection->pSerializer->deserialize.pingresp; - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */ - - /* Deserialize PINGRESP. */ - status = deserialize( pIncomingPacket ); - - if( status == IOT_MQTT_SUCCESS ) - { - if( Atomic_CompareAndSwap_u32( &( pMqttConnection->pingreq.u.operation.periodic.ping.failure ), - 0, - 1 ) == 1 ) - { - IotLogDebug( "(MQTT connection %p) PINGRESP successfully parsed.", - pMqttConnection ); - } - else - { - IotLogWarn( "(MQTT connection %p) Unexpected PINGRESP received.", - pMqttConnection ); - } - } - else - { - EMPTY_ELSE_MARKER; - } - - break; - } - - if( status != IOT_MQTT_SUCCESS ) - { - IotLogError( "(MQTT connection %p) Packet parser status %s.", - pMqttConnection, - IotMqtt_strerror( status ) ); - } - else - { - EMPTY_ELSE_MARKER; - } - - return status; -} - -/*-----------------------------------------------------------*/ - -static void _sendPuback( _mqttConnection_t * pMqttConnection, - uint16_t packetIdentifier ) -{ - IotMqttError_t status = IOT_MQTT_STATUS_PENDING; - _mqttOperation_t * pPubackOperation = NULL; - - /* Default PUBACK serializer function. */ - IotMqttError_t ( * serializePuback )( uint16_t, - uint8_t **, - size_t * ) = _IotMqtt_SerializePuback; - - IotLogDebug( "(MQTT connection %p) Sending PUBACK for received PUBLISH %hu.", - pMqttConnection, - packetIdentifier ); - - /* Choose PUBACK serializer and free packet functions. */ - #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 - if( pMqttConnection->pSerializer != NULL ) - { - if( pMqttConnection->pSerializer->serialize.puback != NULL ) - { - serializePuback = pMqttConnection->pSerializer->serialize.puback; - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */ - - /* Create a PUBACK operation. */ - status = _IotMqtt_CreateOperation( pMqttConnection, - 0, - NULL, - &pPubackOperation ); - - if( status != IOT_MQTT_SUCCESS ) - { - IOT_GOTO_CLEANUP(); - } - - /* Set the operation type. */ - pPubackOperation->u.operation.type = IOT_MQTT_PUBACK; - - /* Generate a PUBACK packet from the packet identifier. */ - status = serializePuback( packetIdentifier, - &( pPubackOperation->u.operation.pMqttPacket ), - &( pPubackOperation->u.operation.packetSize ) ); - - if( status != IOT_MQTT_SUCCESS ) - { - IOT_GOTO_CLEANUP(); - } - - /* Add the PUBACK operation to the send queue for network transmission. */ - status = _IotMqtt_ScheduleOperation( pPubackOperation, - _IotMqtt_ProcessSend, - 0 ); - - if( status != IOT_MQTT_SUCCESS ) - { - IotLogError( "(MQTT connection %p) Failed to enqueue PUBACK for sending.", - pMqttConnection ); - - IOT_GOTO_CLEANUP(); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Clean up on error. */ - IOT_FUNCTION_CLEANUP_BEGIN(); - - if( status != IOT_MQTT_SUCCESS ) - { - if( pPubackOperation != NULL ) - { - _IotMqtt_DestroyOperation( pPubackOperation ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } -} - -/*-----------------------------------------------------------*/ - -static void _flushPacket( void * pNetworkConnection, - const _mqttConnection_t * pMqttConnection, - size_t length ) -{ - size_t bytesFlushed = 0; - uint8_t receivedByte = 0; - - for( bytesFlushed = 0; bytesFlushed < length; bytesFlushed++ ) - { - ( void ) _IotMqtt_GetNextByte( pNetworkConnection, - pMqttConnection->pNetworkInterface, - &receivedByte ); - } -} - -/*-----------------------------------------------------------*/ - -bool _IotMqtt_GetNextByte( void * pNetworkConnection, - const IotNetworkInterface_t * pNetworkInterface, - uint8_t * pIncomingByte ) -{ - bool status = false; - uint8_t incomingByte = 0; - size_t bytesReceived = 0; - - /* Attempt to read 1 byte. */ - bytesReceived = pNetworkInterface->receive( pNetworkConnection, - &incomingByte, - 1 ); - - /* Set the output parameter and return success if 1 byte was read. */ - if( bytesReceived == 1 ) - { - *pIncomingByte = incomingByte; - status = true; - } - else - { - /* Network receive must return 0 on failure. */ - IotMqtt_Assert( bytesReceived == 0 ); - } - - return status; -} - -/*-----------------------------------------------------------*/ - -void _IotMqtt_CloseNetworkConnection( IotMqttDisconnectReason_t disconnectReason, - _mqttConnection_t * pMqttConnection ) -{ - IotTaskPoolError_t taskPoolStatus = IOT_TASKPOOL_SUCCESS; - IotNetworkError_t closeStatus = IOT_NETWORK_SUCCESS; - IotMqttCallbackParam_t callbackParam = { .u.message = { 0 } }; - void * pNetworkConnection = NULL, * pDisconnectCallbackContext = NULL; - - /* Disconnect callback function. */ - void ( * disconnectCallback )( void *, - IotMqttCallbackParam_t * ) = NULL; - - /* Network close function. */ - IotNetworkError_t ( * closeConnection) ( void * ) = NULL; - - /* Default free packet function. */ - void ( * freePacket )( uint8_t * ) = _IotMqtt_FreePacket; - - /* Mark the MQTT connection as disconnected and the keep-alive as failed. */ - IotMutex_Lock( &( pMqttConnection->referencesMutex ) ); - pMqttConnection->disconnected = true; - - if( pMqttConnection->pingreq.u.operation.periodic.ping.keepAliveMs != 0 ) - { - /* Keep-alive must have a PINGREQ allocated. */ - IotMqtt_Assert( pMqttConnection->pingreq.u.operation.pMqttPacket != NULL ); - IotMqtt_Assert( pMqttConnection->pingreq.u.operation.packetSize != 0 ); - - /* PINGREQ provides a reference to the connection, so reference count must - * be nonzero. */ - IotMqtt_Assert( pMqttConnection->references > 0 ); - - /* Attempt to cancel the keep-alive job. */ - taskPoolStatus = IotTaskPool_TryCancel( IOT_SYSTEM_TASKPOOL, - pMqttConnection->pingreq.job, - NULL ); - - /* If the keep-alive job was not canceled, it must be already executing. - * Any other return value is invalid. */ - IotMqtt_Assert( ( taskPoolStatus == IOT_TASKPOOL_SUCCESS ) || - ( taskPoolStatus == IOT_TASKPOOL_CANCEL_FAILED ) ); - - /* Clean up keep-alive if its job was successfully canceled. Otherwise, - * the executing keep-alive job will clean up itself. */ - if( taskPoolStatus == IOT_TASKPOOL_SUCCESS ) - { - /* Choose a function to free the packet. */ - #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 - if( pMqttConnection->pSerializer != NULL ) - { - if( pMqttConnection->pSerializer->freePacket != NULL ) - { - freePacket = pMqttConnection->pSerializer->freePacket; - } - } - #endif - - freePacket( pMqttConnection->pingreq.u.operation.pMqttPacket ); - - /* Clear data about the keep-alive. */ - pMqttConnection->pingreq.u.operation.periodic.ping.keepAliveMs = 0; - pMqttConnection->pingreq.u.operation.pMqttPacket = NULL; - pMqttConnection->pingreq.u.operation.packetSize = 0; - - /* Keep-alive is cleaned up; decrement reference count. Since this - * function must be followed with a call to DISCONNECT, a check to - * destroy the connection is not done here. */ - pMqttConnection->references--; - - IotLogDebug( "(MQTT connection %p) Keep-alive job canceled and cleaned up.", - pMqttConnection ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Copy the function pointers and contexts, as the MQTT connection may be - * modified after the mutex is released. */ - disconnectCallback = pMqttConnection->disconnectCallback.function; - pDisconnectCallbackContext = pMqttConnection->disconnectCallback.pCallbackContext; - - closeConnection = pMqttConnection->pNetworkInterface->close; - pNetworkConnection = pMqttConnection->pNetworkConnection; - - IotMutex_Unlock( &( pMqttConnection->referencesMutex ) ); - - /* Close the network connection. */ - if( closeConnection != NULL ) - { - closeStatus = closeConnection( pNetworkConnection ); - - if( closeStatus == IOT_NETWORK_SUCCESS ) - { - IotLogInfo( "(MQTT connection %p) Network connection closed.", pMqttConnection ); - } - else - { - IotLogWarn( "(MQTT connection %p) Failed to close network connection, error %d.", - pMqttConnection, - closeStatus ); - } - } - else - { - IotLogWarn( "(MQTT connection %p) No network close function was set. Network connection" - " not closed.", pMqttConnection ); - } - - /* Invoke the disconnect callback. */ - if( disconnectCallback != NULL ) - { - /* Set the members of the callback parameter. */ - callbackParam.mqttConnection = pMqttConnection; - callbackParam.u.disconnectReason = disconnectReason; - - disconnectCallback( pDisconnectCallbackContext, - &callbackParam ); - } - else - { - EMPTY_ELSE_MARKER; - } -} - -/*-----------------------------------------------------------*/ - -void IotMqtt_ReceiveCallback( void * pNetworkConnection, - void * pReceiveContext ) -{ - IotMqttError_t status = IOT_MQTT_SUCCESS; - _mqttPacket_t incomingPacket = { .u.pMqttConnection = NULL }; - - /* Cast context to correct type. */ - _mqttConnection_t * pMqttConnection = ( _mqttConnection_t * ) pReceiveContext; - - /* Read an MQTT packet from the network. */ - status = _getIncomingPacket( pNetworkConnection, - pMqttConnection, - &incomingPacket ); - - if( status == IOT_MQTT_SUCCESS ) - { - /* Deserialize the received packet. */ - status = _deserializeIncomingPacket( pMqttConnection, - &incomingPacket ); - - /* Free any buffers allocated for the MQTT packet. */ - if( incomingPacket.pRemainingData != NULL ) - { - IotMqtt_FreeMessage( incomingPacket.pRemainingData ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Close the network connection on a bad response. */ - if( status == IOT_MQTT_BAD_RESPONSE ) - { - IotLogError( "(MQTT connection %p) Error processing incoming data. Closing connection.", - pMqttConnection ); - - _IotMqtt_CloseNetworkConnection( IOT_MQTT_BAD_PACKET_RECEIVED, - pMqttConnection ); - } - else - { - EMPTY_ELSE_MARKER; - } -} - -/*-----------------------------------------------------------*/ 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 deleted file mode 100644 index af343f637..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_operation.c +++ /dev/null @@ -1,1373 +0,0 @@ -/* - * Amazon FreeRTOS MQTT V2.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_mqtt_operation.c - * @brief Implements functions that process MQTT operations. - */ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* Standard includes. */ -#include - -/* Error handling include. */ -#include "private/iot_error.h" - -/* MQTT internal include. */ -#include "private/iot_mqtt_internal.h" - -/* Platform layer includes. */ -#include "platform/iot_clock.h" -#include "platform/iot_threads.h" - -/* Atomics include. */ -#include "iot_atomic.h" - -/*-----------------------------------------------------------*/ - -/** - * @brief First parameter to #_mqttOperation_match. - */ -typedef struct _operationMatchParam -{ - IotMqttOperationType_t type; /**< @brief The type of operation to look for. */ - const uint16_t * pPacketIdentifier; /**< @brief The packet identifier associated with the operation. - * Set to `NULL` to ignore packet identifier. */ -} _operationMatchParam_t; - -/*-----------------------------------------------------------*/ - -/** - * @brief Match an MQTT operation by type and packet identifier. - * - * @param[in] pOperationLink Pointer to the link member of an #_mqttOperation_t. - * @param[in] pMatch Pointer to an #_operationMatchParam_t. - * - * @return `true` if the operation matches the parameters in `pArgument`; `false` - * otherwise. - */ -static bool _mqttOperation_match( const IotLink_t * pOperationLink, - void * pMatch ); - -/** - * @brief Check if an operation with retry has exceeded its retry limit. - * - * If a PUBLISH operation is available for retry, this function also sets any - * necessary DUP flags. - * - * @param[in] pOperation The operation to check. - * - * @return `true` if the operation may be retried; `false` otherwise. - */ -static bool _checkRetryLimit( _mqttOperation_t * pOperation ); - -/** - * @brief Schedule the next send of an operation with retry. - * - * @param[in] pOperation The operation to schedule. - * - * @return `true` if the reschedule succeeded; `false` otherwise. - */ -static bool _scheduleNextRetry( _mqttOperation_t * pOperation ); - -/*-----------------------------------------------------------*/ - -static bool _mqttOperation_match( const IotLink_t * pOperationLink, - void * pMatch ) -{ - bool match = false; - - /* Because this function is called from a container function, the given link - * must never be NULL. */ - IotMqtt_Assert( pOperationLink != NULL ); - - _mqttOperation_t * pOperation = IotLink_Container( _mqttOperation_t, - pOperationLink, - link ); - _operationMatchParam_t * pParam = ( _operationMatchParam_t * ) pMatch; - - /* Check for matching operations. */ - if( pParam->type == pOperation->u.operation.type ) - { - /* Check for matching packet identifiers. */ - if( pParam->pPacketIdentifier == NULL ) - { - match = true; - } - else - { - match = ( *( pParam->pPacketIdentifier ) == pOperation->u.operation.packetIdentifier ); - } - } - else - { - EMPTY_ELSE_MARKER; - } - - return match; -} - -/*-----------------------------------------------------------*/ - -static bool _checkRetryLimit( _mqttOperation_t * pOperation ) -{ - _mqttConnection_t * pMqttConnection = pOperation->pMqttConnection; - bool status = true, setDup = false; - - /* Choose a set DUP function. */ - void ( * publishSetDup )( uint8_t *, - uint8_t *, - uint16_t * ) = _IotMqtt_PublishSetDup; - - #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 - if( pMqttConnection->pSerializer != NULL ) - { - if( pMqttConnection->pSerializer->serialize.publishSetDup != NULL ) - { - publishSetDup = pMqttConnection->pSerializer->serialize.publishSetDup; - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */ - - /* Only PUBLISH may be retried. */ - IotMqtt_Assert( pOperation->u.operation.type == IOT_MQTT_PUBLISH_TO_SERVER ); - - /* Check if the retry limit is exhausted. */ - if( pOperation->u.operation.periodic.retry.count > pOperation->u.operation.periodic.retry.limit ) - { - /* The retry count may be at most one more than the retry limit, which - * accounts for the final check for a PUBACK. */ - IotMqtt_Assert( pOperation->u.operation.periodic.retry.count == - pOperation->u.operation.periodic.retry.limit + 1 ); - - IotLogDebug( "(MQTT connection %p, PUBLISH operation %p) No response received after %lu retries.", - pMqttConnection, - pOperation, - pOperation->u.operation.periodic.retry.limit ); - - status = false; - } - else - { - if( pOperation->u.operation.periodic.retry.count == 1 ) - { - /* The DUP flag should always be set on the first retry. */ - setDup = true; - } - else if( pMqttConnection->awsIotMqttMode == true ) - { - /* In AWS IoT MQTT mode, the DUP flag (really a change to the packet - * identifier) must be reset on every retry. */ - setDup = true; - } - else - { - EMPTY_ELSE_MARKER; - } - - if( setDup == true ) - { - /* In AWS IoT MQTT mode, the references mutex must be locked to - * prevent the packet identifier from being read while it is being - * changed. */ - if( pMqttConnection->awsIotMqttMode == true ) - { - IotMutex_Lock( &( pMqttConnection->referencesMutex ) ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Always set the DUP flag on the first retry. */ - publishSetDup( pOperation->u.operation.pMqttPacket, - pOperation->u.operation.pPacketIdentifierHigh, - &( pOperation->u.operation.packetIdentifier ) ); - - if( pMqttConnection->awsIotMqttMode == true ) - { - IotMutex_Unlock( &( pMqttConnection->referencesMutex ) ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - } - - return status; -} - -/*-----------------------------------------------------------*/ - -static bool _scheduleNextRetry( _mqttOperation_t * pOperation ) -{ - bool firstRetry = false; - uint32_t scheduleDelay = 0; - IotMqttError_t status = IOT_MQTT_STATUS_PENDING; - _mqttConnection_t * pMqttConnection = pOperation->pMqttConnection; - - /* This function should never be called with retry count greater than - * retry limit. */ - IotMqtt_Assert( pOperation->u.operation.periodic.retry.count <= - pOperation->u.operation.periodic.retry.limit ); - - /* Increment the retry count. */ - ( pOperation->u.operation.periodic.retry.count )++; - - /* Check for a response shortly for the final retry. Otherwise, calculate the - * next retry period. */ - if( pOperation->u.operation.periodic.retry.count > - pOperation->u.operation.periodic.retry.limit ) - { - scheduleDelay = IOT_MQTT_RESPONSE_WAIT_MS; - - IotLogDebug( "(MQTT connection %p, PUBLISH operation %p) Final retry was sent. Will check " - "for response in %d ms.", - pMqttConnection, - pOperation, - IOT_MQTT_RESPONSE_WAIT_MS ); - } - else - { - scheduleDelay = pOperation->u.operation.periodic.retry.nextPeriodMs; - - /* Double the retry period, subject to a ceiling value. */ - pOperation->u.operation.periodic.retry.nextPeriodMs *= 2; - - if( pOperation->u.operation.periodic.retry.nextPeriodMs > IOT_MQTT_RETRY_MS_CEILING ) - { - pOperation->u.operation.periodic.retry.nextPeriodMs = IOT_MQTT_RETRY_MS_CEILING; - } - else - { - EMPTY_ELSE_MARKER; - } - - IotLogDebug( "(MQTT connection %p, PUBLISH operation %p) Scheduling retry %lu of %lu in %lu ms.", - pMqttConnection, - pOperation, - ( unsigned long ) pOperation->u.operation.periodic.retry.count, - ( unsigned long ) pOperation->u.operation.periodic.retry.limit, - ( unsigned long ) scheduleDelay ); - - /* Check if this is the first retry. */ - firstRetry = ( pOperation->u.operation.periodic.retry.count == 1 ); - - /* On the first retry, the PUBLISH will be moved from the pending processing - * list to the pending responses list. Lock the connection references mutex - * to manipulate the lists. */ - if( firstRetry == true ) - { - IotMutex_Lock( &( pMqttConnection->referencesMutex ) ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - - /* Reschedule the PUBLISH for another send. */ - status = _IotMqtt_ScheduleOperation( pOperation, - _IotMqtt_ProcessSend, - scheduleDelay ); - - /* Check for successful reschedule. */ - if( status == IOT_MQTT_SUCCESS ) - { - /* Move a successfully rescheduled PUBLISH from the pending processing - * list to the pending responses list on the first retry. */ - if( firstRetry == true ) - { - /* Operation must be linked. */ - IotMqtt_Assert( IotLink_IsLinked( &( pOperation->link ) ) == true ); - - /* Transfer to pending response list. */ - IotListDouble_Remove( &( pOperation->link ) ); - IotListDouble_InsertHead( &( pMqttConnection->pendingResponse ), - &( pOperation->link ) ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* The references mutex only needs to be unlocked on the first retry, since - * only the first retry manipulates the connection lists. */ - if( firstRetry == true ) - { - IotMutex_Unlock( &( pMqttConnection->referencesMutex ) ); - } - else - { - EMPTY_ELSE_MARKER; - } - - return( status == IOT_MQTT_SUCCESS ); -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t _IotMqtt_CreateOperation( _mqttConnection_t * pMqttConnection, - uint32_t flags, - const IotMqttCallbackInfo_t * pCallbackInfo, - _mqttOperation_t ** pNewOperation ) -{ - IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS ); - bool decrementOnError = false; - _mqttOperation_t * pOperation = NULL; - bool waitable = ( ( flags & IOT_MQTT_FLAG_WAITABLE ) == IOT_MQTT_FLAG_WAITABLE ); - - /* If the waitable flag is set, make sure that there's no callback. */ - if( waitable == true ) - { - if( pCallbackInfo != NULL ) - { - IotLogError( "Callback should not be set for a waitable operation." ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - IotLogDebug( "(MQTT connection %p) Creating new operation record.", - pMqttConnection ); - - /* Increment the reference count for the MQTT connection when creating a new - * operation. */ - if( _IotMqtt_IncrementConnectionReferences( pMqttConnection ) == false ) - { - IotLogError( "(MQTT connection %p) New operation record cannot be created" - " for a closed connection", - pMqttConnection ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NETWORK_ERROR ); - } - else - { - /* Reference count will need to be decremented on error. */ - decrementOnError = true; - } - - /* Allocate memory for a new operation. */ - pOperation = IotMqtt_MallocOperation( sizeof( _mqttOperation_t ) ); - - if( pOperation == NULL ) - { - IotLogError( "(MQTT connection %p) Failed to allocate memory for new " - "operation record.", - pMqttConnection ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NO_MEMORY ); - } - else - { - /* Clear the operation data. */ - ( void ) memset( pOperation, 0x00, sizeof( _mqttOperation_t ) ); - - /* Initialize some members of the new operation. */ - pOperation->pMqttConnection = pMqttConnection; - pOperation->u.operation.jobReference = 1; - pOperation->u.operation.flags = flags; - pOperation->u.operation.status = IOT_MQTT_STATUS_PENDING; - } - - /* Check if the waitable flag is set. If it is, create a semaphore to - * wait on. */ - if( waitable == true ) - { - /* Create a semaphore to wait on for a waitable operation. */ - if( IotSemaphore_Create( &( pOperation->u.operation.notify.waitSemaphore ), 0, 1 ) == false ) - { - IotLogError( "(MQTT connection %p) Failed to create semaphore for " - "waitable operation.", - pMqttConnection ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NO_MEMORY ); - } - else - { - /* A waitable operation is created with an additional reference for the - * Wait function. */ - ( pOperation->u.operation.jobReference )++; - } - } - else - { - /* If the waitable flag isn't set but a callback is, copy the callback - * information. */ - if( pCallbackInfo != NULL ) - { - pOperation->u.operation.notify.callback = *pCallbackInfo; - } - else - { - EMPTY_ELSE_MARKER; - } - } - - /* Add this operation to the MQTT connection's operation list. */ - IotMutex_Lock( &( pMqttConnection->referencesMutex ) ); - IotListDouble_InsertHead( &( pMqttConnection->pendingProcessing ), - &( pOperation->link ) ); - IotMutex_Unlock( &( pMqttConnection->referencesMutex ) ); - - /* Set the output parameter. */ - *pNewOperation = pOperation; - - /* Clean up operation and decrement reference count if this function failed. */ - IOT_FUNCTION_CLEANUP_BEGIN(); - - if( status != IOT_MQTT_SUCCESS ) - { - if( decrementOnError == true ) - { - _IotMqtt_DecrementConnectionReferences( pMqttConnection ); - } - else - { - EMPTY_ELSE_MARKER; - } - - if( pOperation != NULL ) - { - IotMqtt_FreeOperation( pOperation ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - IOT_FUNCTION_CLEANUP_END(); -} - -/*-----------------------------------------------------------*/ - -bool _IotMqtt_DecrementOperationReferences( _mqttOperation_t * pOperation, - bool cancelJob ) -{ - bool destroyOperation = false; - IotTaskPoolError_t taskPoolStatus = IOT_TASKPOOL_SUCCESS; - _mqttConnection_t * pMqttConnection = pOperation->pMqttConnection; - - /* Attempt to cancel the operation's job. */ - if( cancelJob == true ) - { - taskPoolStatus = IotTaskPool_TryCancel( IOT_SYSTEM_TASKPOOL, - pOperation->job, - NULL ); - - /* If the operation's job was not canceled, it must be already executing. - * Any other return value is invalid. */ - IotMqtt_Assert( ( taskPoolStatus == IOT_TASKPOOL_SUCCESS ) || - ( taskPoolStatus == IOT_TASKPOOL_CANCEL_FAILED ) ); - - if( taskPoolStatus == IOT_TASKPOOL_SUCCESS ) - { - IotLogDebug( "(MQTT connection %p, %s operation %p) Job canceled.", - pMqttConnection, - IotMqtt_OperationType( pOperation->u.operation.type ), - pOperation ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Decrement job reference count. */ - if( taskPoolStatus == IOT_TASKPOOL_SUCCESS ) - { - IotMutex_Lock( &( pMqttConnection->referencesMutex ) ); - pOperation->u.operation.jobReference--; - - IotLogDebug( "(MQTT connection %p, %s operation %p) Job reference changed" - " from %ld to %ld.", - pMqttConnection, - IotMqtt_OperationType( pOperation->u.operation.type ), - pOperation, - ( long ) ( pOperation->u.operation.jobReference + 1 ), - ( long ) ( pOperation->u.operation.jobReference ) ); - - /* The job reference count must be 0 or 1 after the decrement. */ - IotMqtt_Assert( ( pOperation->u.operation.jobReference == 0 ) || - ( pOperation->u.operation.jobReference == 1 ) ); - - /* This operation may be destroyed if its reference count is 0. */ - if( pOperation->u.operation.jobReference == 0 ) - { - destroyOperation = true; - } - else - { - EMPTY_ELSE_MARKER; - } - - IotMutex_Unlock( &( pMqttConnection->referencesMutex ) ); - } - else - { - EMPTY_ELSE_MARKER; - } - - return destroyOperation; -} - -/*-----------------------------------------------------------*/ - -void _IotMqtt_DestroyOperation( _mqttOperation_t * pOperation ) -{ - _mqttConnection_t * pMqttConnection = pOperation->pMqttConnection; - - /* Default free packet function. */ - void ( * freePacket )( uint8_t * ) = _IotMqtt_FreePacket; - - IotLogDebug( "(MQTT connection %p, %s operation %p) Destroying operation.", - pMqttConnection, - IotMqtt_OperationType( pOperation->u.operation.type ), - pOperation ); - - /* The job reference count must be between 0 and 2. */ - IotMqtt_Assert( ( pOperation->u.operation.jobReference >= 0 ) && - ( pOperation->u.operation.jobReference <= 2 ) ); - - /* Jobs to be destroyed should be removed from the MQTT connection's - * lists. */ - IotMutex_Lock( &( pMqttConnection->referencesMutex ) ); - - if( IotLink_IsLinked( &( pOperation->link ) ) == true ) - { - IotLogDebug( "(MQTT connection %p, %s operation %p) Removed operation from connection lists.", - pMqttConnection, - IotMqtt_OperationType( pOperation->u.operation.type ), - pOperation, - pMqttConnection ); - - IotListDouble_Remove( &( pOperation->link ) ); - } - else - { - IotLogDebug( "(MQTT connection %p, %s operation %p) Operation was not present in connection lists.", - pMqttConnection, - IotMqtt_OperationType( pOperation->u.operation.type ), - pOperation ); - } - - IotMutex_Unlock( &( pMqttConnection->referencesMutex ) ); - - /* Free any allocated MQTT packet. */ - if( pOperation->u.operation.pMqttPacket != NULL ) - { - #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 - if( pMqttConnection->pSerializer != NULL ) - { - if( pMqttConnection->pSerializer->freePacket != NULL ) - { - freePacket = pMqttConnection->pSerializer->freePacket; - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - #endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */ - - freePacket( pOperation->u.operation.pMqttPacket ); - - IotLogDebug( "(MQTT connection %p, %s operation %p) MQTT packet freed.", - pMqttConnection, - IotMqtt_OperationType( pOperation->u.operation.type ), - pOperation ); - } - else - { - IotLogDebug( "(MQTT connection %p, %s operation %p) Operation has no allocated MQTT packet.", - pMqttConnection, - IotMqtt_OperationType( pOperation->u.operation.type ), - pOperation ); - } - - /* Check if a wait semaphore was created for this operation. */ - if( ( pOperation->u.operation.flags & IOT_MQTT_FLAG_WAITABLE ) == IOT_MQTT_FLAG_WAITABLE ) - { - IotSemaphore_Destroy( &( pOperation->u.operation.notify.waitSemaphore ) ); - - IotLogDebug( "(MQTT connection %p, %s operation %p) Wait semaphore destroyed.", - pMqttConnection, - IotMqtt_OperationType( pOperation->u.operation.type ), - pOperation ); - } - else - { - EMPTY_ELSE_MARKER; - } - - IotLogDebug( "(MQTT connection %p, %s operation %p) Operation record destroyed.", - pMqttConnection, - IotMqtt_OperationType( pOperation->u.operation.type ), - pOperation ); - - /* Free the memory used to hold operation data. */ - IotMqtt_FreeOperation( pOperation ); - - /* Decrement the MQTT connection's reference count after destroying an - * operation. */ - _IotMqtt_DecrementConnectionReferences( pMqttConnection ); -} - -/*-----------------------------------------------------------*/ - -void _IotMqtt_ProcessKeepAlive( IotTaskPool_t pTaskPool, - IotTaskPoolJob_t pKeepAliveJob, - void * pContext ) -{ - bool status = true; - uint32_t swapStatus = 0; - IotTaskPoolError_t taskPoolStatus = IOT_TASKPOOL_SUCCESS; - size_t bytesSent = 0; - - /* Swap status is not checked when asserts are disabled. */ - ( void ) swapStatus; - - /* Retrieve the MQTT connection from the context. */ - _mqttConnection_t * pMqttConnection = ( _mqttConnection_t * ) pContext; - _mqttOperation_t * pPingreqOperation = &( pMqttConnection->pingreq ); - - /* Check parameters. */ - /* IotMqtt_Assert( pTaskPool == IOT_SYSTEM_TASKPOOL ); */ - IotMqtt_Assert( pKeepAliveJob == pPingreqOperation->job ); - - /* Check that keep-alive interval is valid. The MQTT spec states its maximum - * value is 65,535 seconds. */ - IotMqtt_Assert( pPingreqOperation->u.operation.periodic.ping.keepAliveMs <= 65535000 ); - - /* Only two values are valid for the next keep alive job delay. */ - IotMqtt_Assert( ( pPingreqOperation->u.operation.periodic.ping.nextPeriodMs == - pPingreqOperation->u.operation.periodic.ping.keepAliveMs ) || - ( pPingreqOperation->u.operation.periodic.ping.nextPeriodMs - == IOT_MQTT_RESPONSE_WAIT_MS ) ); - - IotLogDebug( "(MQTT connection %p) Keep-alive job started.", pMqttConnection ); - - /* Re-create the keep-alive job for rescheduling. This should never fail. */ - taskPoolStatus = IotTaskPool_CreateJob( _IotMqtt_ProcessKeepAlive, - pContext, - IotTaskPool_GetJobStorageFromHandle( pKeepAliveJob ), - &pKeepAliveJob ); - IotMqtt_Assert( taskPoolStatus == IOT_TASKPOOL_SUCCESS ); - - /* Determine whether to send a PINGREQ or check for PINGRESP. */ - if( pPingreqOperation->u.operation.periodic.ping.nextPeriodMs == - pPingreqOperation->u.operation.periodic.ping.keepAliveMs ) - { - IotLogDebug( "(MQTT connection %p) Sending PINGREQ.", pMqttConnection ); - - /* Because PINGREQ may be used to keep the MQTT connection alive, it is - * more important than other operations. Bypass the queue of jobs for - * operations by directly sending the PINGREQ in this job. */ - bytesSent = pMqttConnection->pNetworkInterface->send( pMqttConnection->pNetworkConnection, - pPingreqOperation->u.operation.pMqttPacket, - pPingreqOperation->u.operation.packetSize ); - - if( bytesSent != pPingreqOperation->u.operation.packetSize ) - { - IotLogError( "(MQTT connection %p) Failed to send PINGREQ.", pMqttConnection ); - status = false; - } - else - { - /* Assume the keep-alive will fail. The network receive callback will - * clear the failure flag upon receiving a PINGRESP. */ - swapStatus = Atomic_CompareAndSwap_u32( &( pPingreqOperation->u.operation.periodic.ping.failure ), - 1, - 0 ); - IotMqtt_Assert( swapStatus == 1 ); - - /* Schedule a check for PINGRESP. */ - pPingreqOperation->u.operation.periodic.ping.nextPeriodMs = IOT_MQTT_RESPONSE_WAIT_MS; - - IotLogDebug( "(MQTT connection %p) PINGREQ sent. Scheduling check for PINGRESP in %d ms.", - pMqttConnection, - IOT_MQTT_RESPONSE_WAIT_MS ); - } - } - else - { - IotLogDebug( "(MQTT connection %p) Checking for PINGRESP.", pMqttConnection ); - - if( Atomic_Add_u32( &( pPingreqOperation->u.operation.periodic.ping.failure ), 0 ) == 0 ) - { - IotLogDebug( "(MQTT connection %p) PINGRESP was received.", pMqttConnection ); - - /* PINGRESP was received. Schedule the next PINGREQ transmission. */ - pPingreqOperation->u.operation.periodic.ping.nextPeriodMs = - pPingreqOperation->u.operation.periodic.ping.keepAliveMs; - } - else - { - IotLogError( "(MQTT connection %p) Failed to receive PINGRESP within %d ms.", - pMqttConnection, - IOT_MQTT_RESPONSE_WAIT_MS ); - - /* The network receive callback did not clear the failure flag. */ - status = false; - } - } - - /* When a PINGREQ is successfully sent, reschedule this job to check for a - * response shortly. */ - if( status == true ) - { - taskPoolStatus = IotTaskPool_ScheduleDeferred( pTaskPool, - pKeepAliveJob, - pPingreqOperation->u.operation.periodic.ping.nextPeriodMs ); - - if( taskPoolStatus == IOT_TASKPOOL_SUCCESS ) - { - IotLogDebug( "(MQTT connection %p) Next keep-alive job in %lu ms.", - pMqttConnection, - ( unsigned long ) pPingreqOperation->u.operation.periodic.ping.nextPeriodMs ); - } - else - { - IotLogError( "(MQTT connection %p) Failed to reschedule keep-alive job, error %s.", - pMqttConnection, - IotTaskPool_strerror( taskPoolStatus ) ); - - status = false; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Close the connection on failures. */ - if( status == false ) - { - _IotMqtt_CloseNetworkConnection( IOT_MQTT_KEEP_ALIVE_TIMEOUT, - pMqttConnection ); - } - else - { - EMPTY_ELSE_MARKER; - } -} - -/*-----------------------------------------------------------*/ - -void _IotMqtt_ProcessIncomingPublish( IotTaskPool_t pTaskPool, - IotTaskPoolJob_t pPublishJob, - void * pContext ) -{ - _mqttOperation_t * pOperation = pContext; - IotMqttCallbackParam_t callbackParam = { .mqttConnection = NULL }; - - /* Check parameters. The task pool and job parameter is not used when asserts - * are disabled. */ - ( void ) pTaskPool; - ( void ) pPublishJob; - /* IotMqtt_Assert( pTaskPool == IOT_SYSTEM_TASKPOOL ); */ - IotMqtt_Assert( pOperation->incomingPublish == true ); - IotMqtt_Assert( pPublishJob == pOperation->job ); - - /* Remove the operation from the pending processing list. */ - IotMutex_Lock( &( pOperation->pMqttConnection->referencesMutex ) ); - - if( IotLink_IsLinked( &( pOperation->link ) ) == true ) - { - IotListDouble_Remove( &( pOperation->link ) ); - } - else - { - /* This operation may have already been removed by cleanup of pending - * operations (called from Disconnect). In that case, do nothing here. */ - EMPTY_ELSE_MARKER; - } - - IotMutex_Unlock( &( pOperation->pMqttConnection->referencesMutex ) ); - - /* Process the current PUBLISH. */ - callbackParam.u.message.info = pOperation->u.publish.publishInfo; - - _IotMqtt_InvokeSubscriptionCallback( pOperation->pMqttConnection, - &callbackParam ); - - /* Free buffers associated with the current PUBLISH message. */ - IotMqtt_Assert( pOperation->u.publish.pReceivedData != NULL ); - IotMqtt_FreeMessage( ( void * ) pOperation->u.publish.pReceivedData ); - - /* Free the incoming PUBLISH operation. */ - IotMqtt_FreeOperation( pOperation ); -} - -/*-----------------------------------------------------------*/ - -void _IotMqtt_ProcessSend( IotTaskPool_t pTaskPool, - IotTaskPoolJob_t pSendJob, - void * pContext ) -{ - size_t bytesSent = 0; - bool destroyOperation = false, waitable = false, networkPending = false; - _mqttOperation_t * pOperation = ( _mqttOperation_t * ) pContext; - _mqttConnection_t * pMqttConnection = pOperation->pMqttConnection; - - /* Check parameters. The task pool and job parameter is not used when asserts - * are disabled. */ - ( void ) pTaskPool; - ( void ) pSendJob; - /* IotMqtt_Assert( pTaskPool == IOT_SYSTEM_TASKPOOL ); */ - IotMqtt_Assert( pSendJob == pOperation->job ); - - /* The given operation must have an allocated packet and be waiting for a status. */ - IotMqtt_Assert( pOperation->u.operation.pMqttPacket != NULL ); - IotMqtt_Assert( pOperation->u.operation.packetSize != 0 ); - IotMqtt_Assert( pOperation->u.operation.status == IOT_MQTT_STATUS_PENDING ); - - /* Check if this operation is waitable. */ - waitable = ( pOperation->u.operation.flags & IOT_MQTT_FLAG_WAITABLE ) == IOT_MQTT_FLAG_WAITABLE; - - /* Check PUBLISH retry counts and limits. */ - if( pOperation->u.operation.periodic.retry.limit > 0 ) - { - if( _checkRetryLimit( pOperation ) == false ) - { - pOperation->u.operation.status = IOT_MQTT_RETRY_NO_RESPONSE; - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Send an operation that is waiting for a response. */ - if( pOperation->u.operation.status == IOT_MQTT_STATUS_PENDING ) - { - IotLogDebug( "(MQTT connection %p, %s operation %p) Sending MQTT packet.", - pMqttConnection, - IotMqtt_OperationType( pOperation->u.operation.type ), - pOperation ); - - /* Transmit the MQTT packet from the operation over the network. */ - bytesSent = pMqttConnection->pNetworkInterface->send( pMqttConnection->pNetworkConnection, - pOperation->u.operation.pMqttPacket, - pOperation->u.operation.packetSize ); - - /* Check transmission status. */ - if( bytesSent != pOperation->u.operation.packetSize ) - { - pOperation->u.operation.status = IOT_MQTT_NETWORK_ERROR; - } - else - { - /* DISCONNECT operations are considered successful upon successful - * transmission. In addition, non-waitable operations with no callback - * may also be considered successful. */ - if( pOperation->u.operation.type == IOT_MQTT_DISCONNECT ) - { - /* DISCONNECT operations are always waitable. */ - IotMqtt_Assert( waitable == true ); - - pOperation->u.operation.status = IOT_MQTT_SUCCESS; - } - else if( waitable == false ) - { - if( pOperation->u.operation.notify.callback.function == NULL ) - { - pOperation->u.operation.status = IOT_MQTT_SUCCESS; - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check if this operation requires further processing. */ - if( pOperation->u.operation.status == IOT_MQTT_STATUS_PENDING ) - { - /* Check if this operation should be scheduled for retransmission. */ - if( pOperation->u.operation.periodic.retry.limit > 0 ) - { - if( _scheduleNextRetry( pOperation ) == false ) - { - pOperation->u.operation.status = IOT_MQTT_SCHEDULING_ERROR; - } - else - { - /* A successfully scheduled PUBLISH retry is awaiting a response - * from the network. */ - networkPending = true; - } - } - else - { - /* Decrement reference count to signal completion of send job. Check - * if the operation should be destroyed. */ - if( waitable == true ) - { - destroyOperation = _IotMqtt_DecrementOperationReferences( pOperation, false ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* If the operation should not be destroyed, transfer it from the - * pending processing to the pending response list. */ - if( destroyOperation == false ) - { - IotMutex_Lock( &( pMqttConnection->referencesMutex ) ); - - /* Operation must be linked. */ - IotMqtt_Assert( IotLink_IsLinked( &( pOperation->link ) ) ); - - /* Transfer to pending response list. */ - IotListDouble_Remove( &( pOperation->link ) ); - IotListDouble_InsertHead( &( pMqttConnection->pendingResponse ), - &( pOperation->link ) ); - - IotMutex_Unlock( &( pMqttConnection->referencesMutex ) ); - - /* This operation is now awaiting a response from the network. */ - networkPending = true; - } - else - { - EMPTY_ELSE_MARKER; - } - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Destroy the operation or notify of completion if necessary. */ - if( destroyOperation == true ) - { - _IotMqtt_DestroyOperation( pOperation ); - } - else - { - /* Do not check the operation status if a network response is pending, - * since a network response could modify the status. */ - if( networkPending == false ) - { - /* Notify of operation completion if this job set a status. */ - if( pOperation->u.operation.status != IOT_MQTT_STATUS_PENDING ) - { - _IotMqtt_Notify( pOperation ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - } -} - -/*-----------------------------------------------------------*/ - -void _IotMqtt_ProcessCompletedOperation( IotTaskPool_t pTaskPool, - IotTaskPoolJob_t pOperationJob, - void * pContext ) -{ - _mqttOperation_t * pOperation = ( _mqttOperation_t * ) pContext; - IotMqttCallbackParam_t callbackParam = { 0 }; - - /* Check parameters. The task pool and job parameter is not used when asserts - * are disabled. */ - ( void ) pTaskPool; - ( void ) pOperationJob; - /* IotMqtt_Assert( pTaskPool == IOT_SYSTEM_TASKPOOL ); */ - IotMqtt_Assert( pOperationJob == pOperation->job ); - - /* The operation's callback function and status must be set. */ - IotMqtt_Assert( pOperation->u.operation.notify.callback.function != NULL ); - IotMqtt_Assert( pOperation->u.operation.status != IOT_MQTT_STATUS_PENDING ); - - callbackParam.mqttConnection = pOperation->pMqttConnection; - callbackParam.u.operation.type = pOperation->u.operation.type; - callbackParam.u.operation.reference = pOperation; - callbackParam.u.operation.result = pOperation->u.operation.status; - - /* Invoke the user callback function. */ - pOperation->u.operation.notify.callback.function( pOperation->u.operation.notify.callback.pCallbackContext, - &callbackParam ); - - /* Attempt to destroy the operation once the user callback returns. */ - if( _IotMqtt_DecrementOperationReferences( pOperation, false ) == true ) - { - _IotMqtt_DestroyOperation( pOperation ); - } - else - { - EMPTY_ELSE_MARKER; - } -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t _IotMqtt_ScheduleOperation( _mqttOperation_t * pOperation, - IotTaskPoolRoutine_t jobRoutine, - uint32_t delay ) -{ - IotMqttError_t status = IOT_MQTT_SUCCESS; - IotTaskPoolError_t taskPoolStatus = IOT_TASKPOOL_SUCCESS; - - /* Check that job routine is valid. */ - IotMqtt_Assert( ( jobRoutine == _IotMqtt_ProcessSend ) || - ( jobRoutine == _IotMqtt_ProcessCompletedOperation ) || - ( jobRoutine == _IotMqtt_ProcessIncomingPublish ) ); - - /* Creating a new job should never fail when parameters are valid. */ - taskPoolStatus = IotTaskPool_CreateJob( jobRoutine, - pOperation, - &( pOperation->jobStorage ), - &( pOperation->job ) ); - IotMqtt_Assert( taskPoolStatus == IOT_TASKPOOL_SUCCESS ); - - /* Schedule the new job with a delay. */ - taskPoolStatus = IotTaskPool_ScheduleDeferred( IOT_SYSTEM_TASKPOOL, - pOperation->job, - delay ); - - if( taskPoolStatus != IOT_TASKPOOL_SUCCESS ) - { - /* Scheduling a newly-created job should never be invalid or illegal. */ - IotMqtt_Assert( taskPoolStatus != IOT_TASKPOOL_BAD_PARAMETER ); - IotMqtt_Assert( taskPoolStatus != IOT_TASKPOOL_ILLEGAL_OPERATION ); - - IotLogWarn( "(MQTT connection %p, %s operation %p) Failed to schedule operation job, error %s.", - pOperation->pMqttConnection, - IotMqtt_OperationType( pOperation->u.operation.type ), - pOperation, - IotTaskPool_strerror( taskPoolStatus ) ); - - status = IOT_MQTT_SCHEDULING_ERROR; - } - else - { - EMPTY_ELSE_MARKER; - } - - return status; -} - -/*-----------------------------------------------------------*/ - -_mqttOperation_t * _IotMqtt_FindOperation( _mqttConnection_t * pMqttConnection, - IotMqttOperationType_t type, - const uint16_t * pPacketIdentifier ) -{ - bool waitable = false; - IotTaskPoolError_t taskPoolStatus = IOT_TASKPOOL_SUCCESS; - _mqttOperation_t * pResult = NULL; - IotLink_t * pResultLink = NULL; - _operationMatchParam_t param = { 0 }; - - param.type = type; - param.pPacketIdentifier = pPacketIdentifier; - - if( pPacketIdentifier != NULL ) - { - IotLogDebug( "(MQTT connection %p) Searching for operation %s pending response " - "with packet identifier %hu.", - pMqttConnection, - IotMqtt_OperationType( type ), - *pPacketIdentifier ); - } - else - { - IotLogDebug( "(MQTT connection %p) Searching for operation %s pending response.", - pMqttConnection, - IotMqtt_OperationType( type ) ); - } - - /* Find and remove the first matching element in the list. */ - IotMutex_Lock( &( pMqttConnection->referencesMutex ) ); - pResultLink = IotListDouble_FindFirstMatch( &( pMqttConnection->pendingResponse ), - NULL, - _mqttOperation_match, - ¶m ); - - /* Check if a match was found. */ - if( pResultLink != NULL ) - { - /* Get operation pointer and check if it is waitable. */ - pResult = IotLink_Container( _mqttOperation_t, pResultLink, link ); - waitable = ( pResult->u.operation.flags & IOT_MQTT_FLAG_WAITABLE ) == IOT_MQTT_FLAG_WAITABLE; - - /* Check if the matched operation is a PUBLISH with retry. If it is, cancel - * the retry job. */ - if( pResult->u.operation.periodic.retry.limit > 0 ) - { - taskPoolStatus = IotTaskPool_TryCancel( IOT_SYSTEM_TASKPOOL, - pResult->job, - NULL ); - - /* If the retry job could not be canceled, then it is currently - * executing. Ignore the operation. */ - if( taskPoolStatus != IOT_TASKPOOL_SUCCESS ) - { - pResult = NULL; - } - else - { - /* Check job reference counts. A waitable operation should have a - * count of 2; a non-waitable operation should have a count of 1. */ - IotMqtt_Assert( pResult->u.operation.jobReference == ( 1 + ( waitable == true ) ) ); - } - } - else - { - /* An operation with no retry in the pending responses list should - * always have a job reference of 1. */ - IotMqtt_Assert( pResult->u.operation.jobReference == 1 ); - - /* Increment job references of a waitable operation to prevent Wait from - * destroying this operation if it times out. */ - if( waitable == true ) - { - ( pResult->u.operation.jobReference )++; - - IotLogDebug( "(MQTT connection %p, %s operation %p) Job reference changed from %ld to %ld.", - pMqttConnection, - IotMqtt_OperationType( type ), - pResult, - ( long int ) ( pResult->u.operation.jobReference - 1 ), - ( long int ) ( pResult->u.operation.jobReference ) ); - } - } - } - else - { - EMPTY_ELSE_MARKER; - } - - if( pResult != NULL ) - { - IotLogDebug( "(MQTT connection %p) Found operation %s.", - pMqttConnection, - IotMqtt_OperationType( type ) ); - - /* Remove the matched operation from the list. */ - IotListDouble_Remove( &( pResult->link ) ); - } - else - { - IotLogDebug( "(MQTT connection %p) Operation %s not found.", - pMqttConnection, - IotMqtt_OperationType( type ) ); - } - - IotMutex_Unlock( &( pMqttConnection->referencesMutex ) ); - - return pResult; -} - -/*-----------------------------------------------------------*/ - -void _IotMqtt_Notify( _mqttOperation_t * pOperation ) -{ - IotMqttError_t status = IOT_MQTT_SCHEDULING_ERROR; - _mqttConnection_t * pMqttConnection = pOperation->pMqttConnection; - - /* Check if operation is waitable. */ - bool waitable = ( pOperation->u.operation.flags & IOT_MQTT_FLAG_WAITABLE ) == IOT_MQTT_FLAG_WAITABLE; - - /* Remove any lingering subscriptions if a SUBSCRIBE failed. Rejected - * subscriptions are removed by the deserializer, so not removed here. */ - if( pOperation->u.operation.type == IOT_MQTT_SUBSCRIBE ) - { - switch( pOperation->u.operation.status ) - { - case IOT_MQTT_SUCCESS: - break; - - case IOT_MQTT_SERVER_REFUSED: - break; - - default: - _IotMqtt_RemoveSubscriptionByPacket( pOperation->pMqttConnection, - pOperation->u.operation.packetIdentifier, - -1 ); - break; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Schedule callback invocation for non-waitable operation. */ - if( waitable == false ) - { - /* Non-waitable operation should have job reference of 1. */ - IotMqtt_Assert( pOperation->u.operation.jobReference == 1 ); - - /* Schedule an invocation of the callback. */ - if( pOperation->u.operation.notify.callback.function != NULL ) - { - IotMutex_Lock( &( pMqttConnection->referencesMutex ) ); - - status = _IotMqtt_ScheduleOperation( pOperation, - _IotMqtt_ProcessCompletedOperation, - 0 ); - - if( status == IOT_MQTT_SUCCESS ) - { - IotLogDebug( "(MQTT connection %p, %s operation %p) Callback scheduled.", - pOperation->pMqttConnection, - IotMqtt_OperationType( pOperation->u.operation.type ), - pOperation ); - - /* Place the scheduled operation back in the list of operations pending - * processing. */ - if( IotLink_IsLinked( &( pOperation->link ) ) == true ) - { - IotListDouble_Remove( &( pOperation->link ) ); - } - else - { - EMPTY_ELSE_MARKER; - } - - IotListDouble_InsertHead( &( pMqttConnection->pendingProcessing ), - &( pOperation->link ) ); - } - else - { - IotLogWarn( "(MQTT connection %p, %s operation %p) Failed to schedule callback.", - pOperation->pMqttConnection, - IotMqtt_OperationType( pOperation->u.operation.type ), - pOperation ); - } - - IotMutex_Unlock( &( pMqttConnection->referencesMutex ) ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Operations that weren't scheduled may be destroyed. */ - if( status == IOT_MQTT_SCHEDULING_ERROR ) - { - /* Decrement reference count of operations not scheduled. */ - if( _IotMqtt_DecrementOperationReferences( pOperation, false ) == true ) - { - _IotMqtt_DestroyOperation( pOperation ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Post to a waitable operation's semaphore. */ - if( waitable == true ) - { - IotLogDebug( "(MQTT connection %p, %s operation %p) Waitable operation " - "notified of completion.", - pOperation->pMqttConnection, - IotMqtt_OperationType( pOperation->u.operation.type ), - pOperation ); - - IotSemaphore_Post( &( pOperation->u.operation.notify.waitSemaphore ) ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - IotMqtt_Assert( status == IOT_MQTT_SUCCESS ); - } -} - -/*-----------------------------------------------------------*/ 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 deleted file mode 100644 index d3447eefd..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_serialize.c +++ /dev/null @@ -1,1939 +0,0 @@ -/* - * Amazon FreeRTOS MQTT V2.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_mqtt_serialize.c - * @brief Implements functions that generate and decode MQTT network packets. - */ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* Standard includes. */ -#include - -/* Error handling include. */ -#include "private/iot_error.h" - -/* MQTT internal includes. */ -#include "private/iot_mqtt_internal.h" - -/* Platform layer includes. */ -#include "platform/iot_threads.h" - -/* Atomic operations. */ -#include "iot_atomic.h" - -/*-----------------------------------------------------------*/ - -/* - * Macros for reading the high and low byte of a 2-byte unsigned int. - */ -#define UINT16_HIGH_BYTE( x ) ( ( uint8_t ) ( x >> 8 ) ) /**< @brief Get high byte. */ -#define UINT16_LOW_BYTE( x ) ( ( uint8_t ) ( x & 0x00ff ) ) /**< @brief Get low byte. */ - -/** - * @brief Macro for decoding a 2-byte unsigned int from a sequence of bytes. - * - * @param[in] ptr A uint8_t* that points to the high byte. - */ -#define UINT16_DECODE( ptr ) \ - ( uint16_t ) ( ( ( ( uint16_t ) ( *( ptr ) ) ) << 8 ) | \ - ( ( uint16_t ) ( *( ptr + 1 ) ) ) ) - -/** - * @brief Macro for setting a bit in a 1-byte unsigned int. - * - * @param[in] x The unsigned int to set. - * @param[in] position Which bit to set. - */ -#define UINT8_SET_BIT( x, position ) ( x = ( uint8_t ) ( x | ( 0x01 << position ) ) ) - -/** - * @brief Macro for checking if a bit is set in a 1-byte unsigned int. - * - * @param[in] x The unsigned int to check. - * @param[in] position Which bit to check. - */ -#define UINT8_CHECK_BIT( x, position ) ( ( x & ( 0x01 << position ) ) == ( 0x01 << position ) ) - -/* - * Positions of each flag in the "Connect Flag" field of an MQTT CONNECT - * packet. - */ -#define MQTT_CONNECT_FLAG_CLEAN ( 1 ) /**< @brief Clean session. */ -#define MQTT_CONNECT_FLAG_WILL ( 2 ) /**< @brief Will present. */ -#define MQTT_CONNECT_FLAG_WILL_QOS1 ( 3 ) /**< @brief Will QoS1. */ -#define MQTT_CONNECT_FLAG_WILL_QOS2 ( 4 ) /**< @brief Will QoS2. */ -#define MQTT_CONNECT_FLAG_WILL_RETAIN ( 5 ) /**< @brief Will retain. */ -#define MQTT_CONNECT_FLAG_PASSWORD ( 6 ) /**< @brief Password present. */ -#define MQTT_CONNECT_FLAG_USERNAME ( 7 ) /**< @brief Username present. */ - -/* - * Positions of each flag in the first byte of an MQTT PUBLISH packet's - * fixed header. - */ -#define MQTT_PUBLISH_FLAG_RETAIN ( 0 ) /**< @brief Message retain flag. */ -#define MQTT_PUBLISH_FLAG_QOS1 ( 1 ) /**< @brief Publish QoS 1. */ -#define MQTT_PUBLISH_FLAG_QOS2 ( 2 ) /**< @brief Publish QoS 2. */ -#define MQTT_PUBLISH_FLAG_DUP ( 3 ) /**< @brief Duplicate message. */ - -/** - * @brief The constant specifying MQTT version 3.1.1. Placed in the CONNECT packet. - */ -#define MQTT_VERSION_3_1_1 ( ( uint8_t ) 4U ) - -/** - * @brief Per the MQTT 3.1.1 spec, the largest "Remaining Length" of an MQTT - * packet is this value. - */ -#define MQTT_MAX_REMAINING_LENGTH ( 268435455UL ) - -/** - * @brief The maximum possible size of a CONNECT packet. - * - * All strings in a CONNECT packet are constrained to 2-byte lengths, giving a - * maximum length smaller than the max "Remaining Length" constant above. - */ -#define MQTT_PACKET_CONNECT_MAX_SIZE ( 327700UL ) - -/* - * Constants relating to CONNACK packets, defined by MQTT 3.1.1 spec. - */ -#define MQTT_PACKET_CONNACK_REMAINING_LENGTH ( ( uint8_t ) 2 ) /**< @brief A CONNACK packet always has a "Remaining length" of 2. */ -#define MQTT_PACKET_CONNACK_SESSION_PRESENT_MASK ( ( uint8_t ) 0x01 ) /**< @brief The "Session Present" bit is always the lowest bit. */ - -/* - * Constants relating to PUBLISH and PUBACK packets, defined by MQTT - * 3.1.1 spec. - */ -#define MQTT_PACKET_PUBACK_SIZE ( 4 ) /**< @brief A PUBACK packet is always 4 bytes in size. */ -#define MQTT_PACKET_PUBACK_REMAINING_LENGTH ( ( uint8_t ) 2 ) /**< @brief A PUBACK packet always has a "Remaining length" of 2. */ - -/* - * Constants relating to SUBACK and UNSUBACK packets, defined by MQTT - * 3.1.1 spec. - */ -#define MQTT_PACKET_SUBACK_MINIMUM_SIZE ( 5 ) /**< @brief The size of the smallest valid SUBACK packet. */ -#define MQTT_PACKET_UNSUBACK_REMAINING_LENGTH ( ( uint8_t ) 2 ) /**< @brief An UNSUBACK packet always has a "Remaining length" of 2. */ - -/* - * Constants relating to PINGREQ and PINGRESP packets, defined by MQTT 3.1.1 spec. - */ -#define MQTT_PACKET_PINGREQ_SIZE ( 2 ) /**< @brief A PINGREQ packet is always 2 bytes in size. */ -#define MQTT_PACKET_PINGRESP_REMAINING_LENGTH ( 0 ) /**< @brief A PINGRESP packet always has a "Remaining length" of 0. */ - -/* - * Constants relating to DISCONNECT packets, defined by MQTT 3.1.1 spec. - */ -#define MQTT_PACKET_DISCONNECT_SIZE ( 2 ) /**< @brief A DISCONNECT packet is always 2 bytes in size. */ - -/* Username for metrics with AWS IoT. */ -#if AWS_IOT_MQTT_ENABLE_METRICS == 1 || DOXYGEN == 1 - #ifndef AWS_IOT_METRICS_USERNAME - -/** - * @brief Specify C SDK and version. - */ - #define AWS_IOT_METRICS_USERNAME "?SDK=C&Version=4.0.0" - -/** - * @brief The length of #AWS_IOT_METRICS_USERNAME. - */ - #define AWS_IOT_METRICS_USERNAME_LENGTH ( ( uint16_t ) sizeof( AWS_IOT_METRICS_USERNAME ) - 1 ) - #endif /* ifndef AWS_IOT_METRICS_USERNAME */ -#endif /* if AWS_IOT_MQTT_ENABLE_METRICS == 1 || DOXYGEN == 1 */ - -/*-----------------------------------------------------------*/ - -/** - * @brief Generate and return a 2-byte packet identifier. - * - * This packet identifier will be nonzero. - * - * @return The packet identifier. - */ -static uint16_t _nextPacketIdentifier( void ); - -/** - * @brief Calculate the number of bytes required to encode an MQTT - * "Remaining length" field. - * - * @param[in] length The value of the "Remaining length" to encode. - * - * @return The size of the encoding of length. This is always `1`, `2`, `3`, or `4`. - */ -static size_t _remainingLengthEncodedSize( size_t length ); - -/** - * @brief Encode the "Remaining length" field per MQTT spec. - * - * @param[out] pDestination Where to write the encoded "Remaining length". - * @param[in] length The "Remaining length" to encode. - * - * @return Pointer to the end of the encoded "Remaining length", which is 1-4 - * bytes greater than `pDestination`. - * - * @warning This function does not check the size of `pDestination`! Ensure that - * `pDestination` is large enough to hold the encoded "Remaining length" using - * the function #_remainingLengthEncodedSize to avoid buffer overflows. - */ -static uint8_t * _encodeRemainingLength( uint8_t * pDestination, - size_t length ); - -/** - * @brief Encode a C string as a UTF-8 string, per MQTT 3.1.1 spec. - * - * @param[out] pDestination Where to write the encoded string. - * @param[in] source The string to encode. - * @param[in] sourceLength The length of source. - * - * @return Pointer to the end of the encoded string, which is `sourceLength+2` - * bytes greater than `pDestination`. - * - * @warning This function does not check the size of `pDestination`! Ensure that - * `pDestination` is large enough to hold `sourceLength+2` bytes to avoid a buffer - * overflow. - */ -static uint8_t * _encodeString( uint8_t * pDestination, - const char * source, - uint16_t sourceLength ); - -/** - * @brief Calculate the size and "Remaining length" of a CONNECT packet generated - * from the given parameters. - * - * @param[in] pConnectInfo User-provided CONNECT information struct. - * @param[out] pRemainingLength Output for calculated "Remaining length" field. - * @param[out] pPacketSize Output for calculated total packet size. - * - * @return `true` if the packet is within the length allowed by MQTT 3.1.1 spec; `false` - * otherwise. If this function returns `false`, the output parameters should be ignored. - */ -static bool _connectPacketSize( const IotMqttConnectInfo_t * pConnectInfo, - size_t * pRemainingLength, - size_t * pPacketSize ); - -/** - * @brief Calculate the size and "Remaining length" of a PUBLISH packet generated - * from the given parameters. - * - * @param[in] pPublishInfo User-provided PUBLISH information struct. - * @param[out] pRemainingLength Output for calculated "Remaining length" field. - * @param[out] pPacketSize Output for calculated total packet size. - * - * @return `true` if the packet is within the length allowed by MQTT 3.1.1 spec; `false` - * otherwise. If this function returns `false`, the output parameters should be ignored. - */ -static bool _publishPacketSize( const IotMqttPublishInfo_t * pPublishInfo, - size_t * pRemainingLength, - size_t * pPacketSize ); - -/** - * @brief Calculate the size and "Remaining length" of a SUBSCRIBE or UNSUBSCRIBE - * packet generated from the given parameters. - * - * @param[in] type Either IOT_MQTT_SUBSCRIBE or IOT_MQTT_UNSUBSCRIBE. - * @param[in] pSubscriptionList User-provided array of subscriptions. - * @param[in] subscriptionCount Size of `pSubscriptionList`. - * @param[out] pRemainingLength Output for calculated "Remaining length" field. - * @param[out] pPacketSize Output for calculated total packet size. - * - * @return `true` if the packet is within the length allowed by MQTT 3.1.1 spec; `false` - * otherwise. If this function returns `false`, the output parameters should be ignored. - */ -static bool _subscriptionPacketSize( IotMqttOperationType_t type, - const IotMqttSubscription_t * pSubscriptionList, - size_t subscriptionCount, - size_t * pRemainingLength, - size_t * pPacketSize ); - -/*-----------------------------------------------------------*/ - -#if LIBRARY_LOG_LEVEL > IOT_LOG_NONE - -/** - * @brief If logging is enabled, define a log configuration that only prints the log - * string. This is used when printing out details of deserialized MQTT packets. - */ - static const IotLogConfig_t _logHideAll = - { - .hideLibraryName = true, - .hideLogLevel = true, - .hideTimestring = true - }; -#endif - -/*-----------------------------------------------------------*/ - -static uint16_t _nextPacketIdentifier( void ) -{ - /* MQTT specifies 2 bytes for the packet identifier; however, operating on - * 32-bit integers is generally faster. */ - static uint32_t nextPacketIdentifier = 1; - - /* The next packet identifier will be greater by 2. This prevents packet - * identifiers from ever being 0, which is not allowed by MQTT 3.1.1. Packet - * identifiers will follow the sequence 1,3,5...65535,1,3,5... */ - return ( uint16_t ) Atomic_Add_u32( &nextPacketIdentifier, 2 ); -} - -/*-----------------------------------------------------------*/ - -static size_t _remainingLengthEncodedSize( size_t length ) -{ - size_t encodedSize = 0; - - /* length should have already been checked before calling this function. */ - IotMqtt_Assert( length <= MQTT_MAX_REMAINING_LENGTH ); - - /* Determine how many bytes are needed to encode length. - * The values below are taken from the MQTT 3.1.1 spec. */ - - /* 1 byte is needed to encode lengths between 0 and 127. */ - if( length < 128 ) - { - encodedSize = 1; - } - /* 2 bytes are needed to encode lengths between 128 and 16,383. */ - else if( length < 16384 ) - { - encodedSize = 2; - } - /* 3 bytes are needed to encode lengths between 16,384 and 2,097,151. */ - else if( length < 2097152 ) - { - encodedSize = 3; - } - /* 4 bytes are needed to encode lengths between 2,097,152 and 268,435,455. */ - else - { - encodedSize = 4; - } - - return encodedSize; -} - -/*-----------------------------------------------------------*/ - -static uint8_t * _encodeRemainingLength( uint8_t * pDestination, - size_t length ) -{ - uint8_t lengthByte = 0, * pLengthEnd = pDestination; - - /* This algorithm is copied from the MQTT v3.1.1 spec. */ - do - { - lengthByte = length % 128; - length = length / 128; - - /* Set the high bit of this byte, indicating that there's more data. */ - if( length > 0 ) - { - UINT8_SET_BIT( lengthByte, 7 ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Output a single encoded byte. */ - *pLengthEnd = lengthByte; - pLengthEnd++; - } while( length > 0 ); - - return pLengthEnd; -} - -/*-----------------------------------------------------------*/ - -static uint8_t * _encodeString( uint8_t * pDestination, - const char * source, - uint16_t sourceLength ) -{ - /* The first byte of a UTF-8 string is the high byte of the string length. */ - *pDestination = UINT16_HIGH_BYTE( sourceLength ); - pDestination++; - - /* The second byte of a UTF-8 string is the low byte of the string length. */ - *pDestination = UINT16_LOW_BYTE( sourceLength ); - pDestination++; - - /* Copy the string into pDestination. */ - ( void ) memcpy( pDestination, source, sourceLength ); - - /* Return the pointer to the end of the encoded string. */ - pDestination += sourceLength; - - return pDestination; -} - -/*-----------------------------------------------------------*/ - -static bool _connectPacketSize( const IotMqttConnectInfo_t * pConnectInfo, - size_t * pRemainingLength, - size_t * pPacketSize ) -{ - bool status = true; - size_t connectPacketSize = 0, remainingLength = 0; - - /* The CONNECT packet will always include a 10-byte variable header. */ - connectPacketSize += 10U; - - /* Add the length of the client identifier if provided. */ - if( pConnectInfo->clientIdentifierLength > 0 ) - { - connectPacketSize += pConnectInfo->clientIdentifierLength + sizeof( uint16_t ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Add the lengths of the will message and topic name if provided. */ - if( pConnectInfo->pWillInfo != NULL ) - { - connectPacketSize += pConnectInfo->pWillInfo->topicNameLength + sizeof( uint16_t ) + - pConnectInfo->pWillInfo->payloadLength + sizeof( uint16_t ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Depending on the status of metrics, add the length of the metrics username - * or the user-provided username. */ - if( pConnectInfo->awsIotMqttMode == true ) - { - #if AWS_IOT_MQTT_ENABLE_METRICS == 1 - connectPacketSize += AWS_IOT_METRICS_USERNAME_LENGTH + sizeof( uint16_t ); - #endif - } - else - { - /* Add the lengths of the username and password if provided and not - * connecting to an AWS IoT MQTT server. */ - if( pConnectInfo->pUserName != NULL ) - { - connectPacketSize += pConnectInfo->userNameLength + sizeof( uint16_t ); - } - else - { - EMPTY_ELSE_MARKER; - } - - if( pConnectInfo->pPassword != NULL ) - { - connectPacketSize += pConnectInfo->passwordLength + sizeof( uint16_t ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - - /* At this point, the "Remaining Length" field of the MQTT CONNECT packet has - * been calculated. */ - remainingLength = connectPacketSize; - - /* Calculate the full size of the MQTT CONNECT packet by adding the size of - * the "Remaining Length" field plus 1 byte for the "Packet Type" field. */ - connectPacketSize += 1 + _remainingLengthEncodedSize( connectPacketSize ); - - /* Check that the CONNECT packet is within the bounds of the MQTT spec. */ - if( connectPacketSize > MQTT_PACKET_CONNECT_MAX_SIZE ) - { - status = false; - } - else - { - *pRemainingLength = remainingLength; - *pPacketSize = connectPacketSize; - } - - return status; -} - -/*-----------------------------------------------------------*/ - -static bool _publishPacketSize( const IotMqttPublishInfo_t * pPublishInfo, - size_t * pRemainingLength, - size_t * pPacketSize ) -{ - bool status = true; - size_t publishPacketSize = 0, payloadLimit = 0; - - /* The variable header of a PUBLISH packet always contains the topic name. */ - publishPacketSize += pPublishInfo->topicNameLength + sizeof( uint16_t ); - - /* The variable header of a QoS 1 or 2 PUBLISH packet contains a 2-byte - * packet identifier. */ - if( pPublishInfo->qos > IOT_MQTT_QOS_0 ) - { - publishPacketSize += sizeof( uint16_t ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Calculate the maximum allowed size of the payload for the given parameters. - * This calculation excludes the "Remaining length" encoding, whose size is not - * yet known. */ - payloadLimit = MQTT_MAX_REMAINING_LENGTH - publishPacketSize - 1; - - /* Ensure that the given payload fits within the calculated limit. */ - if( pPublishInfo->payloadLength > payloadLimit ) - { - status = false; - } - else - { - /* Add the length of the PUBLISH payload. At this point, the "Remaining length" - * has been calculated. */ - publishPacketSize += pPublishInfo->payloadLength; - - /* Now that the "Remaining length" is known, recalculate the payload limit - * based on the size of its encoding. */ - payloadLimit -= _remainingLengthEncodedSize( publishPacketSize ); - - /* Check that the given payload fits within the size allowed by MQTT spec. */ - if( pPublishInfo->payloadLength > payloadLimit ) - { - status = false; - } - else - { - /* Set the "Remaining length" output parameter and calculate the full - * size of the PUBLISH packet. */ - *pRemainingLength = publishPacketSize; - - publishPacketSize += 1 + _remainingLengthEncodedSize( publishPacketSize ); - *pPacketSize = publishPacketSize; - } - } - - return status; -} - -/*-----------------------------------------------------------*/ - -static bool _subscriptionPacketSize( IotMqttOperationType_t type, - const IotMqttSubscription_t * pSubscriptionList, - size_t subscriptionCount, - size_t * pRemainingLength, - size_t * pPacketSize ) -{ - bool status = true; - size_t i = 0, subscriptionPacketSize = 0; - - /* Only SUBSCRIBE and UNSUBSCRIBE operations should call this function. */ - IotMqtt_Assert( ( type == IOT_MQTT_SUBSCRIBE ) || ( type == IOT_MQTT_UNSUBSCRIBE ) ); - - /* The variable header of a subscription packet consists of a 2-byte packet - * identifier. */ - subscriptionPacketSize += sizeof( uint16_t ); - - /* Sum the lengths of all subscription topic filters; add 1 byte for each - * subscription's QoS if type is IOT_MQTT_SUBSCRIBE. */ - for( i = 0; i < subscriptionCount; i++ ) - { - /* Add the length of the topic filter. */ - subscriptionPacketSize += pSubscriptionList[ i ].topicFilterLength + sizeof( uint16_t ); - - /* Only SUBSCRIBE packets include the QoS. */ - if( type == IOT_MQTT_SUBSCRIBE ) - { - subscriptionPacketSize += 1; - } - else - { - EMPTY_ELSE_MARKER; - } - } - - /* At this point, the "Remaining length" has been calculated. Return error - * if the "Remaining length" exceeds what is allowed by MQTT 3.1.1. Otherwise, - * set the output parameter.*/ - if( subscriptionPacketSize > MQTT_MAX_REMAINING_LENGTH ) - { - status = false; - } - else - { - *pRemainingLength = subscriptionPacketSize; - - /* Calculate the full size of the subscription packet by adding the size of the - * "Remaining length" field plus 1 byte for the "Packet type" field. Set the - * pPacketSize output parameter. */ - subscriptionPacketSize += 1 + _remainingLengthEncodedSize( subscriptionPacketSize ); - *pPacketSize = subscriptionPacketSize; - } - - return status; -} - -/*-----------------------------------------------------------*/ - -uint8_t _IotMqtt_GetPacketType( void * pNetworkConnection, - const IotNetworkInterface_t * pNetworkInterface ) -{ - uint8_t packetType = 0xff; - - /* The MQTT packet type is in the first byte of the packet. */ - ( void ) _IotMqtt_GetNextByte( pNetworkConnection, - pNetworkInterface, - &packetType ); - - return packetType; -} - -/*-----------------------------------------------------------*/ - -size_t _IotMqtt_GetRemainingLength( void * pNetworkConnection, - const IotNetworkInterface_t * pNetworkInterface ) -{ - uint8_t encodedByte = 0; - size_t remainingLength = 0, multiplier = 1, bytesDecoded = 0, expectedSize = 0; - - /* This algorithm is copied from the MQTT v3.1.1 spec. */ - do - { - if( multiplier > 2097152 ) /* 128 ^ 3 */ - { - remainingLength = MQTT_REMAINING_LENGTH_INVALID; - break; - } - else - { - if( _IotMqtt_GetNextByte( pNetworkConnection, - pNetworkInterface, - &encodedByte ) == true ) - { - remainingLength += ( encodedByte & 0x7F ) * multiplier; - multiplier *= 128; - bytesDecoded++; - } - else - { - remainingLength = MQTT_REMAINING_LENGTH_INVALID; - break; - } - } - } while( ( encodedByte & 0x80 ) != 0 ); - - /* Check that the decoded remaining length conforms to the MQTT specification. */ - if( remainingLength != MQTT_REMAINING_LENGTH_INVALID ) - { - expectedSize = _remainingLengthEncodedSize( remainingLength ); - - if( bytesDecoded != expectedSize ) - { - remainingLength = MQTT_REMAINING_LENGTH_INVALID; - } - else - { - /* Valid remaining length should be at most 4 bytes. */ - IotMqtt_Assert( bytesDecoded <= 4 ); - } - } - else - { - EMPTY_ELSE_MARKER; - } - - return remainingLength; -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t _IotMqtt_SerializeConnect( const IotMqttConnectInfo_t * pConnectInfo, - uint8_t ** pConnectPacket, - size_t * pPacketSize ) -{ - IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS ); - uint8_t connectFlags = 0; - size_t remainingLength = 0, connectPacketSize = 0; - uint8_t * pBuffer = NULL; - - /* Calculate the "Remaining length" field and total packet size. If it exceeds - * what is allowed in the MQTT standard, return an error. */ - if( _connectPacketSize( pConnectInfo, &remainingLength, &connectPacketSize ) == false ) - { - IotLogError( "Connect packet length exceeds %lu, which is the maximum" - " size allowed by MQTT 3.1.1.", - MQTT_PACKET_CONNECT_MAX_SIZE ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Total size of the connect packet should be larger than the "Remaining length" - * field. */ - IotMqtt_Assert( connectPacketSize > remainingLength ); - - /* Allocate memory to hold the CONNECT packet. */ - pBuffer = IotMqtt_MallocMessage( connectPacketSize ); - - /* Check that sufficient memory was allocated. */ - if( pBuffer == NULL ) - { - IotLogError( "Failed to allocate memory for CONNECT packet." ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NO_MEMORY ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Set the output parameters. The remainder of this function always succeeds. */ - *pConnectPacket = pBuffer; - *pPacketSize = connectPacketSize; - - /* The first byte in the CONNECT packet is the control packet type. */ - *pBuffer = MQTT_PACKET_TYPE_CONNECT; - pBuffer++; - - /* The remaining length of the CONNECT packet is encoded starting from the - * second byte. The remaining length does not include the length of the fixed - * header or the encoding of the remaining length. */ - pBuffer = _encodeRemainingLength( pBuffer, remainingLength ); - - /* The string "MQTT" is placed at the beginning of the CONNECT packet's variable - * header. This string is 4 bytes long. */ - pBuffer = _encodeString( pBuffer, "MQTT", 4 ); - - /* The MQTT protocol version is the second byte of the variable header. */ - *pBuffer = MQTT_VERSION_3_1_1; - pBuffer++; - - /* Set the CONNECT flags based on the given parameters. */ - if( pConnectInfo->cleanSession == true ) - { - UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_CLEAN ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Username and password depend on MQTT mode. */ - if( pConnectInfo->awsIotMqttMode == true ) - { - /* Set the username flag for AWS IoT metrics. The AWS IoT MQTT server - * never uses a password. */ - #if AWS_IOT_MQTT_ENABLE_METRICS == 1 - UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_USERNAME ); - #endif - } - else - { - /* Set the flags for username and password if provided. */ - if( pConnectInfo->pUserName != NULL ) - { - UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_USERNAME ); - } - else - { - EMPTY_ELSE_MARKER; - } - - if( pConnectInfo->pPassword != NULL ) - { - UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_PASSWORD ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - - /* Set will flag if an LWT is provided. */ - if( pConnectInfo->pWillInfo != NULL ) - { - UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_WILL ); - - /* Flags only need to be changed for will QoS 1 and 2. */ - switch( pConnectInfo->pWillInfo->qos ) - { - case IOT_MQTT_QOS_1: - UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_WILL_QOS1 ); - break; - - case IOT_MQTT_QOS_2: - UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_WILL_QOS2 ); - break; - - default: - break; - } - - if( pConnectInfo->pWillInfo->retain == true ) - { - UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_WILL_RETAIN ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - *pBuffer = connectFlags; - pBuffer++; - - /* Write the 2 bytes of the keep alive interval into the CONNECT packet. */ - *pBuffer = UINT16_HIGH_BYTE( pConnectInfo->keepAliveSeconds ); - *( pBuffer + 1 ) = UINT16_LOW_BYTE( pConnectInfo->keepAliveSeconds ); - pBuffer += 2; - - /* Write the client identifier into the CONNECT packet. */ - pBuffer = _encodeString( pBuffer, - pConnectInfo->pClientIdentifier, - pConnectInfo->clientIdentifierLength ); - - /* Write the will topic name and message into the CONNECT packet if provided. */ - if( pConnectInfo->pWillInfo != NULL ) - { - pBuffer = _encodeString( pBuffer, - pConnectInfo->pWillInfo->pTopicName, - pConnectInfo->pWillInfo->topicNameLength ); - - pBuffer = _encodeString( pBuffer, - pConnectInfo->pWillInfo->pPayload, - ( uint16_t ) pConnectInfo->pWillInfo->payloadLength ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* If metrics are enabled, write the metrics username into the CONNECT packet. - * Otherwise, write the username and password only when not connecting to an - * AWS IoT MQTT server. */ - if( pConnectInfo->awsIotMqttMode == true ) - { - #if AWS_IOT_MQTT_ENABLE_METRICS == 1 - IotLogInfo( "Anonymous metrics (SDK language, SDK version) will be provided to AWS IoT. " - "Recompile with AWS_IOT_MQTT_ENABLE_METRICS set to 0 to disable." ); - - pBuffer = _encodeString( pBuffer, - AWS_IOT_METRICS_USERNAME, - AWS_IOT_METRICS_USERNAME_LENGTH ); - #endif - } - else - { - if( pConnectInfo->pUserName != NULL ) - { - pBuffer = _encodeString( pBuffer, - pConnectInfo->pUserName, - pConnectInfo->userNameLength ); - } - else - { - EMPTY_ELSE_MARKER; - } - - if( pConnectInfo->pPassword != NULL ) - { - pBuffer = _encodeString( pBuffer, - pConnectInfo->pPassword, - pConnectInfo->passwordLength ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - - /* Ensure that the difference between the end and beginning of the buffer - * is equal to connectPacketSize, i.e. pBuffer did not overflow. */ - IotMqtt_Assert( ( size_t ) ( pBuffer - *pConnectPacket ) == connectPacketSize ); - - /* Print out the serialized CONNECT packet for debugging purposes. */ - IotLog_PrintBuffer( "MQTT CONNECT packet:", *pConnectPacket, connectPacketSize ); - - IOT_FUNCTION_EXIT_NO_CLEANUP(); -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t _IotMqtt_DeserializeConnack( _mqttPacket_t * pConnack ) -{ - IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS ); - const uint8_t * pRemainingData = pConnack->pRemainingData; - - /* If logging is enabled, declare the CONNACK response code strings. The - * fourth byte of CONNACK indexes into this array for the corresponding response. */ - #if LIBRARY_LOG_LEVEL > IOT_LOG_NONE - static const char * pConnackResponses[ 6 ] = - { - "Connection accepted.", /* 0 */ - "Connection refused: unacceptable protocol version.", /* 1 */ - "Connection refused: identifier rejected.", /* 2 */ - "Connection refused: server unavailable", /* 3 */ - "Connection refused: bad user name or password.", /* 4 */ - "Connection refused: not authorized." /* 5 */ - }; - #endif - - /* Check that the control packet type is 0x20. */ - if( pConnack->type != MQTT_PACKET_TYPE_CONNACK ) - { - IotLog( IOT_LOG_ERROR, - &_logHideAll, - "Bad control packet type 0x%02x.", - pConnack->type ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* According to MQTT 3.1.1, the second byte of CONNACK must specify a - * "Remaining length" of 2. */ - if( pConnack->remainingLength != MQTT_PACKET_CONNACK_REMAINING_LENGTH ) - { - IotLog( IOT_LOG_ERROR, - &_logHideAll, - "CONNACK does not have remaining length of %d.", - MQTT_PACKET_CONNACK_REMAINING_LENGTH ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check the reserved bits in CONNACK. The high 7 bits of the second byte - * in CONNACK must be 0. */ - if( ( pRemainingData[ 0 ] | 0x01 ) != 0x01 ) - { - IotLog( IOT_LOG_ERROR, - &_logHideAll, - "Reserved bits in CONNACK incorrect." ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Determine if the "Session Present" bit it set. This is the lowest bit of - * the second byte in CONNACK. */ - if( ( pRemainingData[ 0 ] & MQTT_PACKET_CONNACK_SESSION_PRESENT_MASK ) - == MQTT_PACKET_CONNACK_SESSION_PRESENT_MASK ) - { - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "CONNACK session present bit set." ); - - /* MQTT 3.1.1 specifies that the fourth byte in CONNACK must be 0 if the - * "Session Present" bit is set. */ - if( pRemainingData[ 1 ] != 0 ) - { - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "CONNACK session present bit not set." ); - } - - /* In MQTT 3.1.1, only values 0 through 5 are valid CONNACK response codes. */ - if( pRemainingData[ 1 ] > 5 ) - { - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "CONNACK response %hhu is not valid.", - pRemainingData[ 1 ] ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Print the appropriate message for the CONNACK response code if logs are - * enabled. */ - #if LIBRARY_LOG_LEVEL > IOT_LOG_NONE - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "%s", - pConnackResponses[ pRemainingData[ 1 ] ] ); - #endif - - /* A nonzero CONNACK response code means the connection was refused. */ - if( pRemainingData[ 1 ] > 0 ) - { - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_SERVER_REFUSED ); - } - else - { - EMPTY_ELSE_MARKER; - } - - IOT_FUNCTION_EXIT_NO_CLEANUP(); -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t _IotMqtt_SerializePublish( const IotMqttPublishInfo_t * pPublishInfo, - uint8_t ** pPublishPacket, - size_t * pPacketSize, - uint16_t * pPacketIdentifier, - uint8_t ** pPacketIdentifierHigh ) -{ - IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS ); - uint8_t publishFlags = 0; - uint16_t packetIdentifier = 0; - size_t remainingLength = 0, publishPacketSize = 0; - uint8_t * pBuffer = NULL; - - /* Calculate the "Remaining length" field and total packet size. If it exceeds - * what is allowed in the MQTT standard, return an error. */ - if( _publishPacketSize( pPublishInfo, &remainingLength, &publishPacketSize ) == false ) - { - IotLogError( "Publish packet remaining length exceeds %lu, which is the " - "maximum size allowed by MQTT 3.1.1.", - MQTT_MAX_REMAINING_LENGTH ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Total size of the publish packet should be larger than the "Remaining length" - * field. */ - IotMqtt_Assert( publishPacketSize > remainingLength ); - - /* Allocate memory to hold the PUBLISH packet. */ - pBuffer = IotMqtt_MallocMessage( publishPacketSize ); - - /* Check that sufficient memory was allocated. */ - if( pBuffer == NULL ) - { - IotLogError( "Failed to allocate memory for PUBLISH packet." ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NO_MEMORY ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Set the output parameters. The remainder of this function always succeeds. */ - *pPublishPacket = pBuffer; - *pPacketSize = publishPacketSize; - - /* The first byte of a PUBLISH packet contains the packet type and flags. */ - publishFlags = MQTT_PACKET_TYPE_PUBLISH; - - if( pPublishInfo->qos == IOT_MQTT_QOS_1 ) - { - UINT8_SET_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS1 ); - } - else if( pPublishInfo->qos == IOT_MQTT_QOS_2 ) - { - UINT8_SET_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS2 ); - } - else - { - EMPTY_ELSE_MARKER; - } - - if( pPublishInfo->retain == true ) - { - UINT8_SET_BIT( publishFlags, MQTT_PUBLISH_FLAG_RETAIN ); - } - else - { - EMPTY_ELSE_MARKER; - } - - *pBuffer = publishFlags; - pBuffer++; - - /* The "Remaining length" is encoded from the second byte. */ - pBuffer = _encodeRemainingLength( pBuffer, remainingLength ); - - /* The topic name is placed after the "Remaining length". */ - pBuffer = _encodeString( pBuffer, - pPublishInfo->pTopicName, - pPublishInfo->topicNameLength ); - - /* A packet identifier is required for QoS 1 and 2 messages. */ - if( pPublishInfo->qos > IOT_MQTT_QOS_0 ) - { - /* Get the next packet identifier. It should always be nonzero. */ - packetIdentifier = _nextPacketIdentifier(); - IotMqtt_Assert( packetIdentifier != 0 ); - - /* Set the packet identifier output parameters. */ - *pPacketIdentifier = packetIdentifier; - - if( pPacketIdentifierHigh != NULL ) - { - *pPacketIdentifierHigh = pBuffer; - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Place the packet identifier into the PUBLISH packet. */ - *pBuffer = UINT16_HIGH_BYTE( packetIdentifier ); - *( pBuffer + 1 ) = UINT16_LOW_BYTE( packetIdentifier ); - pBuffer += 2; - } - else - { - EMPTY_ELSE_MARKER; - } - - /* The payload is placed after the packet identifier. */ - if( pPublishInfo->payloadLength > 0 ) - { - ( void ) memcpy( pBuffer, pPublishInfo->pPayload, pPublishInfo->payloadLength ); - pBuffer += pPublishInfo->payloadLength; - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Ensure that the difference between the end and beginning of the buffer - * is equal to publishPacketSize, i.e. pBuffer did not overflow. */ - IotMqtt_Assert( ( size_t ) ( pBuffer - *pPublishPacket ) == publishPacketSize ); - - /* Print out the serialized PUBLISH packet for debugging purposes. */ - IotLog_PrintBuffer( "MQTT PUBLISH packet:", *pPublishPacket, publishPacketSize ); - - IOT_FUNCTION_EXIT_NO_CLEANUP(); -} - -/*-----------------------------------------------------------*/ - -void _IotMqtt_PublishSetDup( uint8_t * pPublishPacket, - uint8_t * pPacketIdentifierHigh, - uint16_t * pNewPacketIdentifier ) -{ - uint16_t newPacketIdentifier = 0; - - /* For an AWS IoT MQTT server, change the packet identifier. */ - if( pPacketIdentifierHigh != NULL ) - { - /* Output parameter for new packet identifier must be provided. */ - IotMqtt_Assert( pNewPacketIdentifier != NULL ); - - /* Generate a new packet identifier. */ - newPacketIdentifier = _nextPacketIdentifier(); - - IotLogDebug( "Changing PUBLISH packet identifier %hu to %hu.", - UINT16_DECODE( pPacketIdentifierHigh ), - newPacketIdentifier ); - - /* Replace the packet identifier. */ - *pPacketIdentifierHigh = UINT16_HIGH_BYTE( newPacketIdentifier ); - *( pPacketIdentifierHigh + 1 ) = UINT16_LOW_BYTE( newPacketIdentifier ); - *pNewPacketIdentifier = newPacketIdentifier; - } - else - { - /* For a compliant MQTT 3.1.1 server, set the DUP flag. */ - UINT8_SET_BIT( *pPublishPacket, MQTT_PUBLISH_FLAG_DUP ); - - IotLogDebug( "PUBLISH DUP flag set." ); - } -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t _IotMqtt_DeserializePublish( _mqttPacket_t * pPublish ) -{ - IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS ); - IotMqttPublishInfo_t * pOutput = &( pPublish->u.pIncomingPublish->u.publish.publishInfo ); - uint8_t publishFlags = 0; - const uint8_t * pVariableHeader = pPublish->pRemainingData, * pPacketIdentifierHigh = NULL; - - /* The flags are the lower 4 bits of the first byte in PUBLISH. */ - publishFlags = pPublish->type; - - /* Parse the Retain bit. */ - pOutput->retain = UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_RETAIN ); - - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "Retain bit is %d.", pOutput->retain ); - - /* Check for QoS 2. */ - if( UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS2 ) == true ) - { - /* PUBLISH packet is invalid if both QoS 1 and QoS 2 bits are set. */ - if( UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS1 ) == true ) - { - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "Bad QoS: 3." ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE ); - } - else - { - EMPTY_ELSE_MARKER; - } - - pOutput->qos = IOT_MQTT_QOS_2; - } - /* Check for QoS 1. */ - else if( UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS1 ) == true ) - { - pOutput->qos = IOT_MQTT_QOS_1; - } - /* If the PUBLISH isn't QoS 1 or 2, then it's QoS 0. */ - else - { - pOutput->qos = IOT_MQTT_QOS_0; - } - - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "QoS is %d.", pOutput->qos ); - - /* Parse the DUP bit. */ - if( UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_DUP ) == true ) - { - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "DUP is 1." ); - } - else - { - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "DUP is 0." ); - } - - /* Sanity checks for "Remaining length". */ - if( pOutput->qos == IOT_MQTT_QOS_0 ) - { - /* A QoS 0 PUBLISH must have a remaining length of at least 3 to accommodate - * topic name length (2 bytes) and topic name (at least 1 byte). */ - if( pPublish->remainingLength < 3 ) - { - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "QoS 0 PUBLISH cannot have a remaining length less than 3." ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - /* A QoS 1 or 2 PUBLISH must have a remaining length of at least 5 to - * accommodate a packet identifier as well as the topic name length and - * topic name. */ - if( pPublish->remainingLength < 5 ) - { - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "QoS 1 or 2 PUBLISH cannot have a remaining length less than 5." ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - - /* Extract the topic name starting from the first byte of the variable header. - * The topic name string starts at byte 3 in the variable header. */ - pOutput->topicNameLength = UINT16_DECODE( pVariableHeader ); - - /* Sanity checks for topic name length and "Remaining length". */ - if( pOutput->qos == IOT_MQTT_QOS_0 ) - { - /* Check that the "Remaining length" is at least as large as the variable - * header. */ - if( pPublish->remainingLength < pOutput->topicNameLength + sizeof( uint16_t ) ) - { - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "Remaining length cannot be less than variable header length." ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - /* Check that the "Remaining length" is at least as large as the variable - * header. */ - if( pPublish->remainingLength < pOutput->topicNameLength + 2 * sizeof( uint16_t ) ) - { - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "Remaining length cannot be less than variable header length." ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - - /* Parse the topic. */ - pOutput->pTopicName = ( const char * ) ( pVariableHeader + sizeof( uint16_t ) ); - - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "Topic name length %hu: %.*s", - pOutput->topicNameLength, - pOutput->topicNameLength, - pOutput->pTopicName ); - - /* Extract the packet identifier for QoS 1 or 2 PUBLISH packets. Packet - * identifier starts immediately after the topic name. */ - pPacketIdentifierHigh = ( const uint8_t * ) ( pOutput->pTopicName + pOutput->topicNameLength ); - - if( pOutput->qos > IOT_MQTT_QOS_0 ) - { - pPublish->packetIdentifier = UINT16_DECODE( pPacketIdentifierHigh ); - - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "Packet identifier %hu.", pPublish->packetIdentifier ); - - /* Packet identifier cannot be 0. */ - if( pPublish->packetIdentifier == 0 ) - { - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Calculate the length of the payload. QoS 1 or 2 PUBLISH packets contain - * a packet identifer, but QoS 0 PUBLISH packets do not. */ - if( pOutput->qos == IOT_MQTT_QOS_0 ) - { - pOutput->payloadLength = ( pPublish->remainingLength - pOutput->topicNameLength - sizeof( uint16_t ) ); - pOutput->pPayload = pPacketIdentifierHigh; - } - else - { - pOutput->payloadLength = ( pPublish->remainingLength - pOutput->topicNameLength - 2 * sizeof( uint16_t ) ); - pOutput->pPayload = pPacketIdentifierHigh + sizeof( uint16_t ); - } - - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "Payload length %hu.", pOutput->payloadLength ); - - IOT_FUNCTION_EXIT_NO_CLEANUP(); -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t _IotMqtt_SerializePuback( uint16_t packetIdentifier, - uint8_t ** pPubackPacket, - size_t * pPacketSize ) -{ - IotMqttError_t status = IOT_MQTT_SUCCESS; - - /* Allocate memory for PUBACK. */ - uint8_t * pBuffer = IotMqtt_MallocMessage( MQTT_PACKET_PUBACK_SIZE ); - - if( pBuffer == NULL ) - { - IotLogError( "Failed to allocate memory for PUBACK packet" ); - - status = IOT_MQTT_NO_MEMORY; - } - else - { - /* Set the output parameters. The remainder of this function always succeeds. */ - *pPubackPacket = pBuffer; - *pPacketSize = MQTT_PACKET_PUBACK_SIZE; - - /* Set the 4 bytes in PUBACK. */ - pBuffer[ 0 ] = MQTT_PACKET_TYPE_PUBACK; - pBuffer[ 1 ] = MQTT_PACKET_PUBACK_REMAINING_LENGTH; - pBuffer[ 2 ] = UINT16_HIGH_BYTE( packetIdentifier ); - pBuffer[ 3 ] = UINT16_LOW_BYTE( packetIdentifier ); - - /* Print out the serialized PUBACK packet for debugging purposes. */ - IotLog_PrintBuffer( "MQTT PUBACK packet:", *pPubackPacket, MQTT_PACKET_PUBACK_SIZE ); - } - - return status; -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t _IotMqtt_DeserializePuback( _mqttPacket_t * pPuback ) -{ - IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS ); - - /* Check the "Remaining length" of the received PUBACK. */ - if( pPuback->remainingLength != MQTT_PACKET_PUBACK_REMAINING_LENGTH ) - { - IotLog( IOT_LOG_ERROR, - &_logHideAll, - "PUBACK does not have remaining length of %d.", - MQTT_PACKET_PUBACK_REMAINING_LENGTH ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Extract the packet identifier (third and fourth bytes) from PUBACK. */ - pPuback->packetIdentifier = UINT16_DECODE( pPuback->pRemainingData ); - - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "Packet identifier %hu.", pPuback->packetIdentifier ); - - /* Packet identifier cannot be 0. */ - if( pPuback->packetIdentifier == 0 ) - { - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check that the control packet type is 0x40 (this must be done after the - * packet identifier is parsed). */ - if( pPuback->type != MQTT_PACKET_TYPE_PUBACK ) - { - IotLog( IOT_LOG_ERROR, - &_logHideAll, - "Bad control packet type 0x%02x.", - pPuback->type ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE ); - } - else - { - EMPTY_ELSE_MARKER; - } - - IOT_FUNCTION_EXIT_NO_CLEANUP(); -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t _IotMqtt_SerializeSubscribe( const IotMqttSubscription_t * pSubscriptionList, - size_t subscriptionCount, - uint8_t ** pSubscribePacket, - size_t * pPacketSize, - uint16_t * pPacketIdentifier ) -{ - IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS ); - size_t i = 0, subscribePacketSize = 0, remainingLength = 0; - uint16_t packetIdentifier = 0; - uint8_t * pBuffer = NULL; - - /* Calculate the "Remaining length" field and total packet size. If it exceeds - * what is allowed in the MQTT standard, return an error. */ - if( _subscriptionPacketSize( IOT_MQTT_SUBSCRIBE, - pSubscriptionList, - subscriptionCount, - &remainingLength, - &subscribePacketSize ) == false ) - { - IotLogError( "Subscribe packet remaining length exceeds %lu, which is the " - "maximum size allowed by MQTT 3.1.1.", - MQTT_MAX_REMAINING_LENGTH ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Total size of the subscribe packet should be larger than the "Remaining length" - * field. */ - IotMqtt_Assert( subscribePacketSize > remainingLength ); - - /* Allocate memory to hold the SUBSCRIBE packet. */ - pBuffer = IotMqtt_MallocMessage( subscribePacketSize ); - - /* Check that sufficient memory was allocated. */ - if( pBuffer == NULL ) - { - IotLogError( "Failed to allocate memory for SUBSCRIBE packet." ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NO_MEMORY ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Set the output parameters. The remainder of this function always succeeds. */ - *pSubscribePacket = pBuffer; - *pPacketSize = subscribePacketSize; - - /* The first byte in SUBSCRIBE is the packet type. */ - *pBuffer = MQTT_PACKET_TYPE_SUBSCRIBE; - pBuffer++; - - /* Encode the "Remaining length" starting from the second byte. */ - pBuffer = _encodeRemainingLength( pBuffer, remainingLength ); - - /* Get the next packet identifier. It should always be nonzero. */ - packetIdentifier = _nextPacketIdentifier(); - *pPacketIdentifier = packetIdentifier; - IotMqtt_Assert( packetIdentifier != 0 ); - - /* Place the packet identifier into the SUBSCRIBE packet. */ - *pBuffer = UINT16_HIGH_BYTE( packetIdentifier ); - *( pBuffer + 1 ) = UINT16_LOW_BYTE( packetIdentifier ); - pBuffer += 2; - - /* Serialize each subscription topic filter and QoS. */ - for( i = 0; i < subscriptionCount; i++ ) - { - pBuffer = _encodeString( pBuffer, - pSubscriptionList[ i ].pTopicFilter, - pSubscriptionList[ i ].topicFilterLength ); - - /* Place the QoS in the SUBSCRIBE packet. */ - *pBuffer = ( uint8_t ) ( pSubscriptionList[ i ].qos ); - pBuffer++; - } - - /* Ensure that the difference between the end and beginning of the buffer - * is equal to subscribePacketSize, i.e. pBuffer did not overflow. */ - IotMqtt_Assert( ( size_t ) ( pBuffer - *pSubscribePacket ) == subscribePacketSize ); - - /* Print out the serialized SUBSCRIBE packet for debugging purposes. */ - IotLog_PrintBuffer( "MQTT SUBSCRIBE packet:", *pSubscribePacket, subscribePacketSize ); - - IOT_FUNCTION_EXIT_NO_CLEANUP(); -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t _IotMqtt_DeserializeSuback( _mqttPacket_t * pSuback ) -{ - IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS ); - size_t i = 0, remainingLength = pSuback->remainingLength; - uint8_t subscriptionStatus = 0; - const uint8_t * pVariableHeader = pSuback->pRemainingData; - - /* A SUBACK must have a remaining length of at least 3 to accommodate the - * packet identifer and at least 1 return code. */ - if( remainingLength < 3 ) - { - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "SUBACK cannot have a remaining length less than 3." ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Extract the packet identifier (first 2 bytes of variable header) from SUBACK. */ - pSuback->packetIdentifier = UINT16_DECODE( pVariableHeader ); - - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "Packet identifier %hu.", pSuback->packetIdentifier ); - - /* Check that the control packet type is 0x90 (this must be done after the - * packet identifier is parsed). */ - if( pSuback->type != MQTT_PACKET_TYPE_SUBACK ) - { - IotLog( IOT_LOG_ERROR, - &_logHideAll, - "Bad control packet type 0x%02x.", - pSuback->type ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Iterate through each status byte in the SUBACK packet. */ - for( i = 0; i < remainingLength - sizeof( uint16_t ); i++ ) - { - /* Read a single status byte in SUBACK. */ - subscriptionStatus = *( pVariableHeader + sizeof( uint16_t ) + i ); - - /* MQTT 3.1.1 defines the following values as status codes. */ - switch( subscriptionStatus ) - { - case 0x00: - case 0x01: - case 0x02: - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "Topic filter %lu accepted, max QoS %hhu.", - ( unsigned long ) i, subscriptionStatus ); - break; - - case 0x80: - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "Topic filter %lu refused.", ( unsigned long ) i ); - - /* Remove a rejected subscription from the subscription manager. */ - _IotMqtt_RemoveSubscriptionByPacket( pSuback->u.pMqttConnection, - pSuback->packetIdentifier, - ( int32_t ) i ); - - status = IOT_MQTT_SERVER_REFUSED; - - break; - - default: - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "Bad SUBSCRIBE status %hhu.", subscriptionStatus ); - - status = IOT_MQTT_BAD_RESPONSE; - - break; - } - - /* Stop parsing the subscription statuses if a bad response was received. */ - if( status == IOT_MQTT_BAD_RESPONSE ) - { - break; - } - else - { - EMPTY_ELSE_MARKER; - } - } - - IOT_FUNCTION_EXIT_NO_CLEANUP(); -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t _IotMqtt_SerializeUnsubscribe( const IotMqttSubscription_t * pSubscriptionList, - size_t subscriptionCount, - uint8_t ** pUnsubscribePacket, - size_t * pPacketSize, - uint16_t * pPacketIdentifier ) -{ - IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS ); - size_t i = 0, unsubscribePacketSize = 0, remainingLength = 0; - uint16_t packetIdentifier = 0; - uint8_t * pBuffer = NULL; - - /* Calculate the "Remaining length" field and total packet size. If it exceeds - * what is allowed in the MQTT standard, return an error. */ - if( _subscriptionPacketSize( IOT_MQTT_UNSUBSCRIBE, - pSubscriptionList, - subscriptionCount, - &remainingLength, - &unsubscribePacketSize ) == false ) - { - IotLogError( "Unsubscribe packet remaining length exceeds %lu, which is the " - "maximum size allowed by MQTT 3.1.1.", - MQTT_MAX_REMAINING_LENGTH ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_PARAMETER ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Total size of the unsubscribe packet should be larger than the "Remaining length" - * field. */ - IotMqtt_Assert( unsubscribePacketSize > remainingLength ); - - /* Allocate memory to hold the UNSUBSCRIBE packet. */ - pBuffer = IotMqtt_MallocMessage( unsubscribePacketSize ); - - /* Check that sufficient memory was allocated. */ - if( pBuffer == NULL ) - { - IotLogError( "Failed to allocate memory for UNSUBSCRIBE packet." ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_NO_MEMORY ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Set the output parameters. The remainder of this function always succeeds. */ - *pUnsubscribePacket = pBuffer; - *pPacketSize = unsubscribePacketSize; - - /* The first byte in UNSUBSCRIBE is the packet type. */ - *pBuffer = MQTT_PACKET_TYPE_UNSUBSCRIBE; - pBuffer++; - - /* Encode the "Remaining length" starting from the second byte. */ - pBuffer = _encodeRemainingLength( pBuffer, remainingLength ); - - /* Get the next packet identifier. It should always be nonzero. */ - packetIdentifier = _nextPacketIdentifier(); - *pPacketIdentifier = packetIdentifier; - IotMqtt_Assert( packetIdentifier != 0 ); - - /* Place the packet identifier into the UNSUBSCRIBE packet. */ - *pBuffer = UINT16_HIGH_BYTE( packetIdentifier ); - *( pBuffer + 1 ) = UINT16_LOW_BYTE( packetIdentifier ); - pBuffer += 2; - - /* Serialize each subscription topic filter. */ - for( i = 0; i < subscriptionCount; i++ ) - { - pBuffer = _encodeString( pBuffer, - pSubscriptionList[ i ].pTopicFilter, - pSubscriptionList[ i ].topicFilterLength ); - } - - /* Ensure that the difference between the end and beginning of the buffer - * is equal to unsubscribePacketSize, i.e. pBuffer did not overflow. */ - IotMqtt_Assert( ( size_t ) ( pBuffer - *pUnsubscribePacket ) == unsubscribePacketSize ); - - /* Print out the serialized UNSUBSCRIBE packet for debugging purposes. */ - IotLog_PrintBuffer( "MQTT UNSUBSCRIBE packet:", *pUnsubscribePacket, unsubscribePacketSize ); - - IOT_FUNCTION_EXIT_NO_CLEANUP(); -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t _IotMqtt_DeserializeUnsuback( _mqttPacket_t * pUnsuback ) -{ - IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS ); - - /* Check the "Remaining length" (second byte) of the received UNSUBACK. */ - if( pUnsuback->remainingLength != MQTT_PACKET_UNSUBACK_REMAINING_LENGTH ) - { - IotLog( IOT_LOG_ERROR, - &_logHideAll, - "UNSUBACK does not have remaining length of %d.", - MQTT_PACKET_UNSUBACK_REMAINING_LENGTH ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Extract the packet identifier (third and fourth bytes) from UNSUBACK. */ - pUnsuback->packetIdentifier = UINT16_DECODE( pUnsuback->pRemainingData ); - - /* Packet identifier cannot be 0. */ - if( pUnsuback->packetIdentifier == 0 ) - { - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE ); - } - else - { - EMPTY_ELSE_MARKER; - } - - IotLog( IOT_LOG_DEBUG, - &_logHideAll, - "Packet identifier %hu.", pUnsuback->packetIdentifier ); - - /* Check that the control packet type is 0xb0 (this must be done after the - * packet identifier is parsed). */ - if( pUnsuback->type != MQTT_PACKET_TYPE_UNSUBACK ) - { - IotLog( IOT_LOG_ERROR, - &_logHideAll, - "Bad control packet type 0x%02x.", - pUnsuback->type ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE ); - } - else - { - EMPTY_ELSE_MARKER; - } - - IOT_FUNCTION_EXIT_NO_CLEANUP(); -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t _IotMqtt_SerializePingreq( uint8_t ** pPingreqPacket, - size_t * pPacketSize ) -{ - /* PINGREQ packets are always the same. */ - static const uint8_t pPingreq[ MQTT_PACKET_PINGREQ_SIZE ] = - { - MQTT_PACKET_TYPE_PINGREQ, - 0x00 - }; - - /* Set the output parameters. */ - *pPingreqPacket = ( uint8_t * ) pPingreq; - *pPacketSize = MQTT_PACKET_PINGREQ_SIZE; - - /* Print out the PINGREQ packet for debugging purposes. */ - IotLog_PrintBuffer( "MQTT PINGREQ packet:", pPingreq, MQTT_PACKET_PINGREQ_SIZE ); - - return IOT_MQTT_SUCCESS; -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t _IotMqtt_DeserializePingresp( _mqttPacket_t * pPingresp ) -{ - IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_SUCCESS ); - - /* Check that the control packet type is 0xd0. */ - if( pPingresp->type != MQTT_PACKET_TYPE_PINGRESP ) - { - IotLog( IOT_LOG_ERROR, - &_logHideAll, - "Bad control packet type 0x%02x.", - pPingresp->type ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check the "Remaining length" (second byte) of the received PINGRESP. */ - if( pPingresp->remainingLength != MQTT_PACKET_PINGRESP_REMAINING_LENGTH ) - { - IotLog( IOT_LOG_ERROR, - &_logHideAll, - "PINGRESP does not have remaining length of %d.", - MQTT_PACKET_PINGRESP_REMAINING_LENGTH ); - - IOT_SET_AND_GOTO_CLEANUP( IOT_MQTT_BAD_RESPONSE ); - } - else - { - EMPTY_ELSE_MARKER; - } - - IOT_FUNCTION_EXIT_NO_CLEANUP(); -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t _IotMqtt_SerializeDisconnect( uint8_t ** pDisconnectPacket, - size_t * pPacketSize ) -{ - /* DISCONNECT packets are always the same. */ - static const uint8_t pDisconnect[ MQTT_PACKET_DISCONNECT_SIZE ] = - { - MQTT_PACKET_TYPE_DISCONNECT, - 0x00 - }; - - /* Set the output parameters. */ - *pDisconnectPacket = ( uint8_t * ) pDisconnect; - *pPacketSize = MQTT_PACKET_DISCONNECT_SIZE; - - /* Print out the DISCONNECT packet for debugging purposes. */ - IotLog_PrintBuffer( "MQTT DISCONNECT packet:", pDisconnect, MQTT_PACKET_DISCONNECT_SIZE ); - - return IOT_MQTT_SUCCESS; -} - -/*-----------------------------------------------------------*/ - -void _IotMqtt_FreePacket( uint8_t * pPacket ) -{ - uint8_t packetType = *pPacket; - - /* Don't call free on DISCONNECT and PINGREQ; those are allocated from static - * memory. */ - if( packetType != MQTT_PACKET_TYPE_DISCONNECT ) - { - if( packetType != MQTT_PACKET_TYPE_PINGREQ ) - { - IotMqtt_FreeMessage( pPacket ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } -} - -/*-----------------------------------------------------------*/ 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 deleted file mode 100644 index 000fcbadc..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_static_memory.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Amazon FreeRTOS MQTT V2.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_mqtt_static_memory.c - * @brief Implementation of MQTT static memory functions. - */ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* This file should only be compiled if dynamic memory allocation is forbidden. */ -#if IOT_STATIC_MEMORY_ONLY == 1 - -/* Standard includes. */ -#include -#include -#include - -/* Static memory include. */ -#include "private/iot_static_memory.h" - -/* MQTT internal include. */ -#include "private/iot_mqtt_internal.h" - -/*-----------------------------------------------------------*/ - -/** - * @cond DOXYGEN_IGNORE - * Doxygen should ignore this section. - * - * Provide default values for undefined configuration constants. - */ -#ifndef IOT_MQTT_CONNECTIONS - #define IOT_MQTT_CONNECTIONS ( 1 ) -#endif -#ifndef IOT_MQTT_MAX_IN_PROGRESS_OPERATIONS - #define IOT_MQTT_MAX_IN_PROGRESS_OPERATIONS ( 10 ) -#endif -#ifndef IOT_MQTT_SUBSCRIPTIONS - #define IOT_MQTT_SUBSCRIPTIONS ( 8 ) -#endif -/** @endcond */ - -/* Validate static memory configuration settings. */ -#if IOT_MQTT_CONNECTIONS <= 0 - #error "IOT_MQTT_CONNECTIONS cannot be 0 or negative." -#endif -#if IOT_MQTT_MAX_IN_PROGRESS_OPERATIONS <= 0 - #error "IOT_MQTT_MAX_IN_PROGRESS_OPERATIONS cannot be 0 or negative." -#endif -#if IOT_MQTT_SUBSCRIPTIONS <= 0 - #error "IOT_MQTT_SUBSCRIPTIONS cannot be 0 or negative." -#endif - -/** - * @brief The size of a static memory MQTT subscription. - * - * Since the pTopic member of #_mqttSubscription_t is variable-length, the constant - * #AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH is used for the length of - * #_mqttSubscription_t.pTopicFilter. - */ -#define MQTT_SUBSCRIPTION_SIZE ( sizeof( _mqttSubscription_t ) + AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH ) - -/*-----------------------------------------------------------*/ - -/* - * Static memory buffers and flags, allocated and zeroed at compile-time. - */ -static bool _pInUseMqttConnections[ IOT_MQTT_CONNECTIONS ] = { 0 }; /**< @brief MQTT connection in-use flags. */ -static _mqttConnection_t _pMqttConnections[ IOT_MQTT_CONNECTIONS ] = { { 0 } }; /**< @brief MQTT connections. */ - -static bool _pInUseMqttOperations[ IOT_MQTT_MAX_IN_PROGRESS_OPERATIONS ] = { 0 }; /**< @brief MQTT operation in-use flags. */ -static _mqttOperation_t _pMqttOperations[ IOT_MQTT_MAX_IN_PROGRESS_OPERATIONS ] = { { .link = { 0 } } }; /**< @brief MQTT operations. */ - -static bool _pInUseMqttSubscriptions[ IOT_MQTT_SUBSCRIPTIONS ] = { 0 }; /**< @brief MQTT subscription in-use flags. */ -static char _pMqttSubscriptions[ IOT_MQTT_SUBSCRIPTIONS ][ MQTT_SUBSCRIPTION_SIZE ] = { { 0 } }; /**< @brief MQTT subscriptions. */ - -/*-----------------------------------------------------------*/ - -void * IotMqtt_MallocConnection( size_t size ) -{ - int32_t freeIndex = -1; - void * pNewConnection = NULL; - - /* Check size argument. */ - if( size == sizeof( _mqttConnection_t ) ) - { - /* Find a free MQTT connection. */ - freeIndex = IotStaticMemory_FindFree( _pInUseMqttConnections, - IOT_MQTT_CONNECTIONS ); - - if( freeIndex != -1 ) - { - pNewConnection = &( _pMqttConnections[ freeIndex ] ); - } - } - - return pNewConnection; -} - -/*-----------------------------------------------------------*/ - -void IotMqtt_FreeConnection( void * ptr ) -{ - /* Return the in-use MQTT connection. */ - IotStaticMemory_ReturnInUse( ptr, - _pMqttConnections, - _pInUseMqttConnections, - IOT_MQTT_CONNECTIONS, - sizeof( _mqttConnection_t ) ); -} - -/*-----------------------------------------------------------*/ - -void * IotMqtt_MallocOperation( size_t size ) -{ - int32_t freeIndex = -1; - void * pNewOperation = NULL; - - /* Check size argument. */ - if( size == sizeof( _mqttOperation_t ) ) - { - /* Find a free MQTT operation. */ - freeIndex = IotStaticMemory_FindFree( _pInUseMqttOperations, - IOT_MQTT_MAX_IN_PROGRESS_OPERATIONS ); - - if( freeIndex != -1 ) - { - pNewOperation = &( _pMqttOperations[ freeIndex ] ); - } - } - - return pNewOperation; -} - -/*-----------------------------------------------------------*/ - -void IotMqtt_FreeOperation( void * ptr ) -{ - /* Return the in-use MQTT operation. */ - IotStaticMemory_ReturnInUse( ptr, - _pMqttOperations, - _pInUseMqttOperations, - IOT_MQTT_MAX_IN_PROGRESS_OPERATIONS, - sizeof( _mqttOperation_t ) ); -} - -/*-----------------------------------------------------------*/ - -void * IotMqtt_MallocSubscription( size_t size ) -{ - int32_t freeIndex = -1; - void * pNewSubscription = NULL; - - if( size <= MQTT_SUBSCRIPTION_SIZE ) - { - /* Get the index of a free MQTT subscription. */ - freeIndex = IotStaticMemory_FindFree( _pInUseMqttSubscriptions, - IOT_MQTT_SUBSCRIPTIONS ); - - if( freeIndex != -1 ) - { - pNewSubscription = &( _pMqttSubscriptions[ freeIndex ][ 0 ] ); - } - } - - return pNewSubscription; -} - -/*-----------------------------------------------------------*/ - -void IotMqtt_FreeSubscription( void * ptr ) -{ - /* Return the in-use MQTT subscription. */ - IotStaticMemory_ReturnInUse( ptr, - _pMqttSubscriptions, - _pInUseMqttSubscriptions, - IOT_MQTT_SUBSCRIPTIONS, - MQTT_SUBSCRIPTION_SIZE ); -} - -/*-----------------------------------------------------------*/ - -#endif 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 deleted file mode 100644 index f4546b558..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_subscription.c +++ /dev/null @@ -1,645 +0,0 @@ -/* - * Amazon FreeRTOS MQTT V2.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_mqtt_subscription.c - * @brief Implements functions that manage subscriptions for an MQTT connection. - */ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* Standard includes. */ -#include -#include - -/* Error handling include. */ -#include "private/iot_error.h" - -/* MQTT internal include. */ -#include "private/iot_mqtt_internal.h" - -/* Platform layer includes. */ -#include "platform/iot_threads.h" - -/*-----------------------------------------------------------*/ - -/** - * @brief First parameter to #_topicMatch. - */ -typedef struct _topicMatchParams -{ - const char * pTopicName; /**< @brief The topic name to parse. */ - uint16_t topicNameLength; /**< @brief Length of #_topicMatchParams_t.pTopicName. */ - bool exactMatchOnly; /**< @brief Whether to allow wildcards or require exact matches. */ -} _topicMatchParams_t; - -/** - * @brief First parameter to #_packetMatch. - */ -typedef struct _packetMatchParams -{ - uint16_t packetIdentifier; /**< Packet identifier to match. */ - int32_t order; /**< Order to match. Set to `-1` to ignore. */ -} _packetMatchParams_t; - -/*-----------------------------------------------------------*/ - -/** - * @brief Matches a topic name (from a publish) with a topic filter (from a - * subscription). - * - * @param[in] pSubscriptionLink Pointer to the link member of an #_mqttSubscription_t. - * @param[in] pMatch Pointer to a #_topicMatchParams_t. - * - * @return `true` if the arguments match the subscription topic filter; `false` - * otherwise. - */ -static bool _topicMatch( const IotLink_t * pSubscriptionLink, - void * pMatch ); - -/** - * @brief Matches a packet identifier and order. - * - * @param[in] pSubscriptionLink Pointer to the link member of an #_mqttSubscription_t. - * @param[in] pMatch Pointer to a #_packetMatchParams_t. - * - * @return `true` if the arguments match the subscription's packet info; `false` - * otherwise. - */ -static bool _packetMatch( const IotLink_t * pSubscriptionLink, - void * pMatch ); - -/*-----------------------------------------------------------*/ - -static bool _topicMatch( const IotLink_t * pSubscriptionLink, - void * pMatch ) -{ - IOT_FUNCTION_ENTRY( bool, false ); - uint16_t nameIndex = 0, filterIndex = 0; - - /* Because this function is called from a container function, the given link - * must never be NULL. */ - IotMqtt_Assert( pSubscriptionLink != NULL ); - - _mqttSubscription_t * pSubscription = IotLink_Container( _mqttSubscription_t, - pSubscriptionLink, - link ); - _topicMatchParams_t * pParam = ( _topicMatchParams_t * ) pMatch; - - /* Extract the relevant strings and lengths from parameters. */ - const char * pTopicName = pParam->pTopicName; - const char * pTopicFilter = pSubscription->pTopicFilter; - const uint16_t topicNameLength = pParam->topicNameLength; - const uint16_t topicFilterLength = pSubscription->topicFilterLength; - - /* Check for an exact match. */ - if( topicNameLength == topicFilterLength ) - { - status = ( strncmp( pTopicName, pTopicFilter, topicNameLength ) == 0 ); - - IOT_GOTO_CLEANUP(); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* If the topic lengths are different but an exact match is required, return - * false. */ - if( pParam->exactMatchOnly == true ) - { - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - - while( ( nameIndex < topicNameLength ) && ( filterIndex < topicFilterLength ) ) - { - /* Check if the character in the topic name matches the corresponding - * character in the topic filter string. */ - if( pTopicName[ nameIndex ] == pTopicFilter[ filterIndex ] ) - { - /* Handle special corner cases as documented by the MQTT protocol spec. */ - - /* Filter "sport/#" also matches "sport" since # includes the parent level. */ - if( nameIndex == topicNameLength - 1 ) - { - if( filterIndex == topicFilterLength - 3 ) - { - if( pTopicFilter[ filterIndex + 1 ] == '/' ) - { - if( pTopicFilter[ filterIndex + 2 ] == '#' ) - { - IOT_SET_AND_GOTO_CLEANUP( true ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Filter "sport/+" also matches the "sport/" but not "sport". */ - if( nameIndex == topicNameLength - 1 ) - { - if( filterIndex == topicFilterLength - 2 ) - { - if( pTopicFilter[ filterIndex + 1 ] == '+' ) - { - IOT_SET_AND_GOTO_CLEANUP( true ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - /* Check for wildcards. */ - if( pTopicFilter[ filterIndex ] == '+' ) - { - /* Move topic name index to the end of the current level. - * This is identified by '/'. */ - while( nameIndex < topicNameLength && pTopicName[ nameIndex ] != '/' ) - { - nameIndex++; - } - - /* Increment filter index to skip '/'. */ - filterIndex++; - continue; - } - else if( pTopicFilter[ filterIndex ] == '#' ) - { - /* Subsequent characters don't need to be checked if the for the - * multi-level wildcard. */ - IOT_SET_AND_GOTO_CLEANUP( true ); - } - else - { - /* Any character mismatch other than '+' or '#' means the topic - * name does not match the topic filter. */ - IOT_SET_AND_GOTO_CLEANUP( false ); - } - } - - /* Increment indexes. */ - nameIndex++; - filterIndex++; - } - - /* If the end of both strings has been reached, they match. */ - if( ( nameIndex == topicNameLength ) && ( filterIndex == topicFilterLength ) ) - { - IOT_SET_AND_GOTO_CLEANUP( true ); - } - else - { - EMPTY_ELSE_MARKER; - } - - IOT_FUNCTION_EXIT_NO_CLEANUP(); -} - -/*-----------------------------------------------------------*/ - -static bool _packetMatch( const IotLink_t * pSubscriptionLink, - void * pMatch ) -{ - bool match = false; - - /* Because this function is called from a container function, the given link - * must never be NULL. */ - IotMqtt_Assert( pSubscriptionLink != NULL ); - - _mqttSubscription_t * pSubscription = IotLink_Container( _mqttSubscription_t, - pSubscriptionLink, - link ); - _packetMatchParams_t * pParam = ( _packetMatchParams_t * ) pMatch; - - /* Compare packet identifiers. */ - if( pParam->packetIdentifier == pSubscription->packetInfo.identifier ) - { - /* Compare orders if order is not -1. */ - if( pParam->order == -1 ) - { - match = true; - } - else - { - match = ( ( size_t ) pParam->order ) == pSubscription->packetInfo.order; - } - } - - /* If this subscription should be removed, check the reference count. */ - if( match == true ) - { - /* Reference count must not be negative. */ - IotMqtt_Assert( pSubscription->references >= 0 ); - - /* If the reference count is positive, this subscription cannot be - * removed yet because there are subscription callbacks using it. */ - if( pSubscription->references > 0 ) - { - match = false; - - /* Set the unsubscribed flag. The last active subscription callback - * will remove and clean up this subscription. */ - pSubscription->unsubscribed = true; - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - return match; -} - -/*-----------------------------------------------------------*/ - -IotMqttError_t _IotMqtt_AddSubscriptions( _mqttConnection_t * pMqttConnection, - uint16_t subscribePacketIdentifier, - const IotMqttSubscription_t * pSubscriptionList, - size_t subscriptionCount ) -{ - IotMqttError_t status = IOT_MQTT_SUCCESS; - size_t i = 0; - _mqttSubscription_t * pNewSubscription = NULL; - IotLink_t * pSubscriptionLink = NULL; - _topicMatchParams_t topicMatchParams = { .exactMatchOnly = true }; - - IotMutex_Lock( &( pMqttConnection->subscriptionMutex ) ); - - for( i = 0; i < subscriptionCount; i++ ) - { - /* Check if this topic filter is already registered. */ - topicMatchParams.pTopicName = pSubscriptionList[ i ].pTopicFilter; - topicMatchParams.topicNameLength = pSubscriptionList[ i ].topicFilterLength; - pSubscriptionLink = IotListDouble_FindFirstMatch( &( pMqttConnection->subscriptionList ), - NULL, - _topicMatch, - &topicMatchParams ); - - if( pSubscriptionLink != NULL ) - { - pNewSubscription = IotLink_Container( _mqttSubscription_t, pSubscriptionLink, link ); - - /* The lengths of exactly matching topic filters must match. */ - IotMqtt_Assert( pNewSubscription->topicFilterLength == pSubscriptionList[ i ].topicFilterLength ); - - /* Replace the callback and packet info with the new parameters. */ - pNewSubscription->callback = pSubscriptionList[ i ].callback; - pNewSubscription->packetInfo.identifier = subscribePacketIdentifier; - pNewSubscription->packetInfo.order = i; - } - else - { - /* Allocate memory for a new subscription. */ - pNewSubscription = IotMqtt_MallocSubscription( sizeof( _mqttSubscription_t ) + - pSubscriptionList[ i ].topicFilterLength ); - - if( pNewSubscription == NULL ) - { - status = IOT_MQTT_NO_MEMORY; - break; - } - else - { - /* Clear the new subscription. */ - ( void ) memset( pNewSubscription, - 0x00, - sizeof( _mqttSubscription_t ) + pSubscriptionList[ i ].topicFilterLength ); - - /* Set the members of the new subscription and add it to the list. */ - pNewSubscription->packetInfo.identifier = subscribePacketIdentifier; - pNewSubscription->packetInfo.order = i; - pNewSubscription->callback = pSubscriptionList[ i ].callback; - pNewSubscription->topicFilterLength = pSubscriptionList[ i ].topicFilterLength; - ( void ) memcpy( pNewSubscription->pTopicFilter, - pSubscriptionList[ i ].pTopicFilter, - ( size_t ) ( pSubscriptionList[ i ].topicFilterLength ) ); - - IotListDouble_InsertHead( &( pMqttConnection->subscriptionList ), - &( pNewSubscription->link ) ); - } - } - } - - IotMutex_Unlock( &( pMqttConnection->subscriptionMutex ) ); - - /* If memory allocation failed, remove all previously added subscriptions. */ - if( status != IOT_MQTT_SUCCESS ) - { - _IotMqtt_RemoveSubscriptionByTopicFilter( pMqttConnection, - pSubscriptionList, - i ); - } - else - { - EMPTY_ELSE_MARKER; - } - - return status; -} - -/*-----------------------------------------------------------*/ - -void _IotMqtt_InvokeSubscriptionCallback( _mqttConnection_t * pMqttConnection, - IotMqttCallbackParam_t * pCallbackParam ) -{ - _mqttSubscription_t * pSubscription = NULL; - IotLink_t * pCurrentLink = NULL, * pNextLink = NULL; - void * pCallbackContext = NULL; - - void ( * callbackFunction )( void *, - IotMqttCallbackParam_t * ) = NULL; - _topicMatchParams_t topicMatchParams = { 0 }; - - topicMatchParams.pTopicName = pCallbackParam->u.message.info.pTopicName; - topicMatchParams.topicNameLength = pCallbackParam->u.message.info.topicNameLength; - topicMatchParams.exactMatchOnly = false; - - /* Prevent any other thread from modifying the subscription list while this - * function is searching. */ - IotMutex_Lock( &( pMqttConnection->subscriptionMutex ) ); - - /* Search the subscription list for all matching subscriptions starting at - * the list head. */ - while( true ) - { - pCurrentLink = IotListDouble_FindFirstMatch( &( pMqttConnection->subscriptionList ), - pCurrentLink, - _topicMatch, - &topicMatchParams ); - - /* No subscription found. Exit loop. */ - if( pCurrentLink == NULL ) - { - break; - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Subscription found. Calculate pointer to subscription object. */ - pSubscription = IotLink_Container( _mqttSubscription_t, pCurrentLink, link ); - - /* Subscription validation should not have allowed a NULL callback function. */ - IotMqtt_Assert( pSubscription->callback.function != NULL ); - - /* Increment the subscription's reference count. */ - ( pSubscription->references )++; - - /* Copy the necessary members of the subscription before releasing the - * subscription list mutex. */ - pCallbackContext = pSubscription->callback.pCallbackContext; - callbackFunction = pSubscription->callback.function; - - /* Unlock the subscription list mutex. */ - IotMutex_Unlock( &( pMqttConnection->subscriptionMutex ) ); - - /* Set the members of the callback parameter. */ - pCallbackParam->mqttConnection = pMqttConnection; - pCallbackParam->u.message.pTopicFilter = pSubscription->pTopicFilter; - pCallbackParam->u.message.topicFilterLength = pSubscription->topicFilterLength; - - /* Invoke the subscription callback. */ - callbackFunction( pCallbackContext, pCallbackParam ); - - /* Lock the subscription list mutex to decrement the reference count. */ - IotMutex_Lock( &( pMqttConnection->subscriptionMutex ) ); - - /* Decrement the reference count. It must still be positive. */ - ( pSubscription->references )--; - IotMqtt_Assert( pSubscription->references >= 0 ); - - /* Save the pointer to the next link in case this subscription is freed. */ - pNextLink = pCurrentLink->pNext; - - /* Remove this subscription if it has no references and the unsubscribed - * flag is set. */ - if( pSubscription->unsubscribed == true ) - { - /* An unsubscribed subscription should have been removed from the list. */ - IotMqtt_Assert( IotLink_IsLinked( &( pSubscription->link ) ) == false ); - - /* Free subscriptions with no references. */ - if( pSubscription->references == 0 ) - { - IotMqtt_FreeSubscription( pSubscription ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Move current link pointer. */ - pCurrentLink = pNextLink; - } - - IotMutex_Unlock( &( pMqttConnection->subscriptionMutex ) ); - - _IotMqtt_DecrementConnectionReferences( pMqttConnection ); -} - -/*-----------------------------------------------------------*/ - -void _IotMqtt_RemoveSubscriptionByPacket( _mqttConnection_t * pMqttConnection, - uint16_t packetIdentifier, - int32_t order ) -{ - _packetMatchParams_t packetMatchParams = { 0 }; - - packetMatchParams.packetIdentifier = packetIdentifier; - packetMatchParams.order = order; - - IotMutex_Lock( &( pMqttConnection->subscriptionMutex ) ); - IotListDouble_RemoveAllMatches( &( pMqttConnection->subscriptionList ), - _packetMatch, - ( void * ) ( &packetMatchParams ), - IotMqtt_FreeSubscription, - offsetof( _mqttSubscription_t, link ) ); - IotMutex_Unlock( &( pMqttConnection->subscriptionMutex ) ); -} - -/*-----------------------------------------------------------*/ - -void _IotMqtt_RemoveSubscriptionByTopicFilter( _mqttConnection_t * pMqttConnection, - const IotMqttSubscription_t * pSubscriptionList, - size_t subscriptionCount ) -{ - size_t i = 0; - _mqttSubscription_t * pSubscription = NULL; - IotLink_t * pSubscriptionLink = NULL; - _topicMatchParams_t topicMatchParams = { 0 }; - - /* Prevent any other thread from modifying the subscription list while this - * function is running. */ - IotMutex_Lock( &( pMqttConnection->subscriptionMutex ) ); - - /* Find and remove each topic filter from the list. */ - for( i = 0; i < subscriptionCount; i++ ) - { - topicMatchParams.pTopicName = pSubscriptionList[ i ].pTopicFilter; - topicMatchParams.topicNameLength = pSubscriptionList[ i ].topicFilterLength; - topicMatchParams.exactMatchOnly = true; - - pSubscriptionLink = IotListDouble_FindFirstMatch( &( pMqttConnection->subscriptionList ), - NULL, - _topicMatch, - &topicMatchParams ); - - if( pSubscriptionLink != NULL ) - { - pSubscription = IotLink_Container( _mqttSubscription_t, pSubscriptionLink, link ); - - /* Reference count must not be negative. */ - IotMqtt_Assert( pSubscription->references >= 0 ); - - /* Remove subscription from list. */ - IotListDouble_Remove( pSubscriptionLink ); - - /* Check the reference count. This subscription cannot be removed if - * there are subscription callbacks using it. */ - if( pSubscription->references > 0 ) - { - /* Set the unsubscribed flag. The last active subscription callback - * will remove and clean up this subscription. */ - pSubscription->unsubscribed = true; - } - else - { - /* Free a subscription with no references. */ - IotMqtt_FreeSubscription( pSubscription ); - } - } - else - { - EMPTY_ELSE_MARKER; - } - } - - IotMutex_Unlock( &( pMqttConnection->subscriptionMutex ) ); -} - -/*-----------------------------------------------------------*/ - -bool IotMqtt_IsSubscribed( IotMqttConnection_t mqttConnection, - const char * pTopicFilter, - uint16_t topicFilterLength, - IotMqttSubscription_t * const pCurrentSubscription ) -{ - bool status = false; - _mqttSubscription_t * pSubscription = NULL; - IotLink_t * pSubscriptionLink = NULL; - _topicMatchParams_t topicMatchParams = { 0 }; - - topicMatchParams.pTopicName = pTopicFilter; - topicMatchParams.topicNameLength = topicFilterLength; - topicMatchParams.exactMatchOnly = true; - - /* Prevent any other thread from modifying the subscription list while this - * function is running. */ - IotMutex_Lock( &( mqttConnection->subscriptionMutex ) ); - - /* Search for a matching subscription. */ - pSubscriptionLink = IotListDouble_FindFirstMatch( &( mqttConnection->subscriptionList ), - NULL, - _topicMatch, - &topicMatchParams ); - - /* Check if a matching subscription was found. */ - if( pSubscriptionLink != NULL ) - { - pSubscription = IotLink_Container( _mqttSubscription_t, pSubscriptionLink, link ); - - /* Copy the matching subscription to the output parameter. */ - if( pCurrentSubscription != NULL ) - { - pCurrentSubscription->pTopicFilter = pTopicFilter; - pCurrentSubscription->topicFilterLength = topicFilterLength; - pCurrentSubscription->qos = IOT_MQTT_QOS_0; - pCurrentSubscription->callback = pSubscription->callback; - } - else - { - EMPTY_ELSE_MARKER; - } - - status = true; - } - else - { - EMPTY_ELSE_MARKER; - } - - IotMutex_Unlock( &( mqttConnection->subscriptionMutex ) ); - - return status; -} - -/*-----------------------------------------------------------*/ - -/* Provide access to internal functions and variables if testing. */ -#if IOT_BUILD_TESTS == 1 - #include "iot_test_access_mqtt_subscription.c" -#endif 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 deleted file mode 100644 index 8556959d8..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_mqtt_validate.c +++ /dev/null @@ -1,593 +0,0 @@ -/* - * Amazon FreeRTOS MQTT V2.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_mqtt_validate.c - * @brief Implements functions that validate the structs of the MQTT library. - */ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* Error handling include. */ -#include "private/iot_error.h" - -/* MQTT internal include. */ -#include "private/iot_mqtt_internal.h" - -/*-----------------------------------------------------------*/ - -bool _IotMqtt_ValidateConnect( const IotMqttConnectInfo_t * pConnectInfo ) -{ - IOT_FUNCTION_ENTRY( bool, true ); - - /* Check for NULL. */ - if( pConnectInfo == NULL ) - { - IotLogError( "MQTT connection information cannot be NULL." ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check that a client identifier was set. */ - if( pConnectInfo->pClientIdentifier == NULL ) - { - IotLogError( "Client identifier must be set." ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check for a zero-length client identifier. Zero-length client identifiers - * are not allowed with clean sessions. */ - if( pConnectInfo->clientIdentifierLength == 0 ) - { - IotLogWarn( "A zero-length client identifier was provided." ); - - if( pConnectInfo->cleanSession == true ) - { - IotLogError( "A zero-length client identifier cannot be used with a clean session." ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check that the number of persistent session subscriptions is valid. */ - if( pConnectInfo->cleanSession == false ) - { - if( pConnectInfo->pPreviousSubscriptions != NULL ) - { - if( pConnectInfo->previousSubscriptionCount == 0 ) - { - IotLogError( "Previous subscription count cannot be 0." ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* In MQTT 3.1.1, servers are not obligated to accept client identifiers longer - * than 23 characters. */ - if( pConnectInfo->clientIdentifierLength > 23 ) - { - IotLogWarn( "A client identifier length of %hu is longer than 23, which is " - "the longest client identifier a server must accept.", - pConnectInfo->clientIdentifierLength ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check for compatibility with the AWS IoT MQTT service limits. */ - if( pConnectInfo->awsIotMqttMode == true ) - { - /* Check that client identifier is within the service limit. */ - if( pConnectInfo->clientIdentifierLength > AWS_IOT_MQTT_SERVER_MAX_CLIENTID ) - { - IotLogError( "AWS IoT does not support client identifiers longer than %d bytes.", - AWS_IOT_MQTT_SERVER_MAX_CLIENTID ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check for compliance with AWS IoT keep-alive limits. */ - if( pConnectInfo->keepAliveSeconds == 0 ) - { - IotLogWarn( "AWS IoT does not support disabling keep-alive. Default keep-alive " - "of %d seconds will be used.", - AWS_IOT_MQTT_SERVER_MAX_KEEPALIVE ); - } - else if( pConnectInfo->keepAliveSeconds < AWS_IOT_MQTT_SERVER_MIN_KEEPALIVE ) - { - IotLogWarn( "AWS IoT does not support keep-alive intervals less than %d seconds. " - "An interval of %d seconds will be used.", - AWS_IOT_MQTT_SERVER_MIN_KEEPALIVE, - AWS_IOT_MQTT_SERVER_MIN_KEEPALIVE ); - } - else if( pConnectInfo->keepAliveSeconds > AWS_IOT_MQTT_SERVER_MAX_KEEPALIVE ) - { - IotLogWarn( "AWS IoT does not support keep-alive intervals greater than %d seconds. " - "An interval of %d seconds will be used.", - AWS_IOT_MQTT_SERVER_MAX_KEEPALIVE, - AWS_IOT_MQTT_SERVER_MAX_KEEPALIVE ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - IOT_FUNCTION_EXIT_NO_CLEANUP(); -} - -/*-----------------------------------------------------------*/ - -bool _IotMqtt_ValidatePublish( bool awsIotMqttMode, - const IotMqttPublishInfo_t * pPublishInfo ) -{ - IOT_FUNCTION_ENTRY( bool, true ); - - /* Check for NULL. */ - if( pPublishInfo == NULL ) - { - IotLogError( "Publish information cannot be NULL." ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check topic name for NULL or zero-length. */ - if( pPublishInfo->pTopicName == NULL ) - { - IotLogError( "Publish topic name must be set." ); - } - else - { - EMPTY_ELSE_MARKER; - } - - if( pPublishInfo->topicNameLength == 0 ) - { - IotLogError( "Publish topic name length cannot be 0." ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Only allow NULL payloads with zero length. */ - if( pPublishInfo->pPayload == NULL ) - { - if( pPublishInfo->payloadLength != 0 ) - { - IotLogError( "Nonzero payload length cannot have a NULL payload." ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check for a valid QoS. */ - if( pPublishInfo->qos != IOT_MQTT_QOS_0 ) - { - if( pPublishInfo->qos != IOT_MQTT_QOS_1 ) - { - IotLogError( "Publish QoS must be either 0 or 1." ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check the retry parameters. */ - if( pPublishInfo->retryLimit > 0 ) - { - if( pPublishInfo->retryMs == 0 ) - { - IotLogError( "Publish retry time must be positive." ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check for compatibility with AWS IoT MQTT server. */ - if( awsIotMqttMode == true ) - { - /* Check for retained message. */ - if( pPublishInfo->retain == true ) - { - IotLogError( "AWS IoT does not support retained publish messages." ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check topic name length. */ - if( pPublishInfo->topicNameLength > AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH ) - { - IotLogError( "AWS IoT does not support topic names longer than %d bytes.", - AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - IOT_FUNCTION_EXIT_NO_CLEANUP(); -} - -/*-----------------------------------------------------------*/ - -bool _IotMqtt_ValidateOperation( IotMqttOperation_t operation ) -{ - IOT_FUNCTION_ENTRY( bool, true ); - - /* Check for NULL. */ - if( operation == NULL ) - { - IotLogError( "Operation reference cannot be NULL." ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check that reference is waitable. */ - if( ( operation->u.operation.flags & IOT_MQTT_FLAG_WAITABLE ) != IOT_MQTT_FLAG_WAITABLE ) - { - IotLogError( "Operation is not waitable." ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - - IOT_FUNCTION_EXIT_NO_CLEANUP(); -} - -/*-----------------------------------------------------------*/ - -bool _IotMqtt_ValidateSubscriptionList( IotMqttOperationType_t operation, - bool awsIotMqttMode, - const IotMqttSubscription_t * pListStart, - size_t listSize ) -{ - IOT_FUNCTION_ENTRY( bool, true ); - size_t i = 0; - uint16_t j = 0; - const IotMqttSubscription_t * pListElement = NULL; - - /* Operation must be either subscribe or unsubscribe. */ - IotMqtt_Assert( ( operation == IOT_MQTT_SUBSCRIBE ) || - ( operation == IOT_MQTT_UNSUBSCRIBE ) ); - - /* Check for empty list. */ - if( pListStart == NULL ) - { - IotLogError( "Subscription list pointer cannot be NULL." ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - - if( listSize == 0 ) - { - IotLogError( "Empty subscription list." ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* AWS IoT supports at most 8 topic filters in a single SUBSCRIBE packet. */ - if( awsIotMqttMode == true ) - { - if( listSize > AWS_IOT_MQTT_SERVER_MAX_TOPIC_FILTERS_PER_SUBSCRIBE ) - { - IotLogError( "AWS IoT does not support more than %d topic filters per " - "subscription request.", - AWS_IOT_MQTT_SERVER_MAX_TOPIC_FILTERS_PER_SUBSCRIBE ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - for( i = 0; i < listSize; i++ ) - { - pListElement = &( pListStart[ i ] ); - - /* Check for a valid QoS and callback function when subscribing. */ - if( operation == IOT_MQTT_SUBSCRIBE ) - { - if( pListElement->qos != IOT_MQTT_QOS_0 ) - { - if( pListElement->qos != IOT_MQTT_QOS_1 ) - { - IotLogError( "Subscription QoS must be either 0 or 1." ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - if( pListElement->callback.function == NULL ) - { - IotLogError( "Callback function must be set." ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check subscription topic filter. */ - if( pListElement->pTopicFilter == NULL ) - { - IotLogError( "Subscription topic filter cannot be NULL." ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - - if( pListElement->topicFilterLength == 0 ) - { - IotLogError( "Subscription topic filter length cannot be 0." ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check for compatibility with AWS IoT MQTT server. */ - if( awsIotMqttMode == true ) - { - /* Check topic filter length. */ - if( pListElement->topicFilterLength > AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH ) - { - IotLogError( "AWS IoT does not support topic filters longer than %d bytes.", - AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Check that the wildcards '+' and '#' are being used correctly. */ - for( j = 0; j < pListElement->topicFilterLength; j++ ) - { - switch( pListElement->pTopicFilter[ j ] ) - { - /* Check that the single level wildcard '+' is used correctly. */ - case '+': - - /* Unless '+' is the first character in the filter, it must be preceded by '/'. */ - if( j > 0 ) - { - if( pListElement->pTopicFilter[ j - 1 ] != '/' ) - { - IotLogError( "Invalid topic filter %.*s -- '+' must be preceded by '/'.", - pListElement->topicFilterLength, - pListElement->pTopicFilter ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Unless '+' is the last character in the filter, it must be succeeded by '/'. */ - if( j < pListElement->topicFilterLength - 1 ) - { - if( pListElement->pTopicFilter[ j + 1 ] != '/' ) - { - IotLogError( "Invalid topic filter %.*s -- '+' must be succeeded by '/'.", - pListElement->topicFilterLength, - pListElement->pTopicFilter ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - break; - - /* Check that the multi-level wildcard '#' is used correctly. */ - case '#': - - /* '#' must be the last character in the filter. */ - if( j != pListElement->topicFilterLength - 1 ) - { - IotLogError( "Invalid topic filter %.*s -- '#' must be the last character.", - pListElement->topicFilterLength, - pListElement->pTopicFilter ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - - /* Unless '#' is standalone, it must be preceded by '/'. */ - if( pListElement->topicFilterLength > 1 ) - { - if( pListElement->pTopicFilter[ j - 1 ] != '/' ) - { - IotLogError( "Invalid topic filter %.*s -- '#' must be preceded by '/'.", - pListElement->topicFilterLength, - pListElement->pTopicFilter ); - - IOT_SET_AND_GOTO_CLEANUP( false ); - } - else - { - EMPTY_ELSE_MARKER; - } - } - else - { - EMPTY_ELSE_MARKER; - } - - break; - - default: - break; - } - } - } - - IOT_FUNCTION_EXIT_NO_CLEANUP(); -} - -/*-----------------------------------------------------------*/ 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 deleted file mode 100644 index 5ac1b9489..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/private/iot_mqtt_internal.h +++ /dev/null @@ -1,928 +0,0 @@ -/* - * Amazon FreeRTOS MQTT V2.0.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - -/** - * @file iot_mqtt_internal.h - * @brief Internal header of MQTT library. This header should not be included in - * typical application code. - */ - -#ifndef IOT_MQTT_INTERNAL_H_ -#define IOT_MQTT_INTERNAL_H_ - -/* The config header is always included first. */ -#include "iot_config.h" - -/* Linear containers (lists and queues) include. */ -#include "iot_linear_containers.h" - -/* MQTT include. */ -#include "iot_mqtt.h" - -/* Task pool include. */ -#include "iot_taskpool.h" - -/** - * @def IotMqtt_Assert( expression ) - * @brief Assertion macro for the MQTT library. - * - * Set @ref IOT_MQTT_ENABLE_ASSERTS to `1` to enable assertions in the MQTT - * library. - * - * @param[in] expression Expression to be evaluated. - */ -#if IOT_MQTT_ENABLE_ASSERTS == 1 - #ifndef IotMqtt_Assert - #include - #define IotMqtt_Assert( expression ) assert( expression ) - #endif -#else - #define IotMqtt_Assert( expression ) -#endif - -/* Configure logs for MQTT functions. */ -#ifdef IOT_LOG_LEVEL_MQTT - #define LIBRARY_LOG_LEVEL IOT_LOG_LEVEL_MQTT -#else - #ifdef IOT_LOG_LEVEL_GLOBAL - #define LIBRARY_LOG_LEVEL IOT_LOG_LEVEL_GLOBAL - #else - #define LIBRARY_LOG_LEVEL IOT_LOG_NONE - #endif -#endif - -#define LIBRARY_LOG_NAME ( "MQTT" ) -#include "iot_logging_setup.h" - -/* - * Provide default values for undefined memory allocation functions based on - * the usage of dynamic memory allocation. - */ -#if IOT_STATIC_MEMORY_ONLY == 1 - #include "private/iot_static_memory.h" - -/** - * @brief Allocate an #_mqttConnection_t. This function should have the same - * signature as [malloc] - * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html). - */ - void * IotMqtt_MallocConnection( size_t size ); - -/** - * @brief Free an #_mqttConnection_t. This function should have the same - * signature as [free] - * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html). - */ - void IotMqtt_FreeConnection( void * ptr ); - -/** - * @brief Allocate memory for an MQTT packet. This function should have the - * same signature as [malloc] - * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html). - */ - #define IotMqtt_MallocMessage Iot_MallocMessageBuffer - -/** - * @brief Free an MQTT packet. This function should have the same signature - * as [free] - * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html). - */ - #define IotMqtt_FreeMessage Iot_FreeMessageBuffer - -/** - * @brief Allocate an #_mqttOperation_t. This function should have the same - * signature as [malloc] - * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html). - */ - void * IotMqtt_MallocOperation( size_t size ); - -/** - * @brief Free an #_mqttOperation_t. This function should have the same - * signature as [free] - * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html). - */ - void IotMqtt_FreeOperation( void * ptr ); - -/** - * @brief Allocate an #_mqttSubscription_t. This function should have the - * same signature as [malloc] - * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html). - */ - void * IotMqtt_MallocSubscription( size_t size ); - -/** - * @brief Free an #_mqttSubscription_t. This function should have the same - * signature as [free] - * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html). - */ - void IotMqtt_FreeSubscription( void * ptr ); -#else /* if IOT_STATIC_MEMORY_ONLY == 1 */ - #include - - #ifndef IotMqtt_MallocConnection - #define IotMqtt_MallocConnection malloc - #endif - - #ifndef IotMqtt_FreeConnection - #define IotMqtt_FreeConnection free - #endif - - #ifndef IotMqtt_MallocMessage - #define IotMqtt_MallocMessage malloc - #endif - - #ifndef IotMqtt_FreeMessage - #define IotMqtt_FreeMessage free - #endif - - #ifndef IotMqtt_MallocOperation - #define IotMqtt_MallocOperation malloc - #endif - - #ifndef IotMqtt_FreeOperation - #define IotMqtt_FreeOperation free - #endif - - #ifndef IotMqtt_MallocSubscription - #define IotMqtt_MallocSubscription malloc - #endif - - #ifndef IotMqtt_FreeSubscription - #define IotMqtt_FreeSubscription free - #endif -#endif /* if IOT_STATIC_MEMORY_ONLY == 1 */ - -/** - * @cond DOXYGEN_IGNORE - * Doxygen should ignore this section. - * - * Provide default values for undefined configuration constants. - */ -#ifndef AWS_IOT_MQTT_ENABLE_METRICS - #define AWS_IOT_MQTT_ENABLE_METRICS ( 1 ) -#endif -#ifndef IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES - #define IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES ( 0 ) -#endif -#ifndef IOT_MQTT_RESPONSE_WAIT_MS - #define IOT_MQTT_RESPONSE_WAIT_MS ( 1000 ) -#endif -#ifndef IOT_MQTT_RETRY_MS_CEILING - #define IOT_MQTT_RETRY_MS_CEILING ( 60000 ) -#endif -/** @endcond */ - -/** - * @brief Marks the empty statement of an `else` branch. - * - * Does nothing, but allows test coverage to detect branches not taken. By default, - * this is defined to nothing. When running code coverage testing, this is defined - * to an assembly NOP. - */ -#ifndef EMPTY_ELSE_MARKER - #define EMPTY_ELSE_MARKER -#endif - -/* - * Constants related to limits defined in AWS Service Limits. - * - * For details, see - * https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html - * - * Used to validate parameters if when connecting to an AWS IoT MQTT server. - */ -#define AWS_IOT_MQTT_SERVER_MIN_KEEPALIVE ( 30 ) /**< @brief Minumum keep-alive interval accepted by AWS IoT. */ -#define AWS_IOT_MQTT_SERVER_MAX_KEEPALIVE ( 1200 ) /**< @brief Maximum keep-alive interval accepted by AWS IoT. */ -#define AWS_IOT_MQTT_SERVER_MAX_CLIENTID ( 128 ) /**< @brief Maximum length of client identifier accepted by AWS IoT. */ -#define AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH ( 256 ) /**< @brief Maximum length of topic names or filters accepted by AWS IoT. */ -#define AWS_IOT_MQTT_SERVER_MAX_TOPIC_FILTERS_PER_SUBSCRIBE ( 8 ) /**< @brief Maximum number of topic filters in a single SUBSCRIBE packet. */ - -/* - * MQTT control packet type and flags. Always the first byte of an MQTT - * packet. - * - * For details, see - * http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/csprd02/mqtt-v3.1.1-csprd02.html#_Toc385349757 - */ -#define MQTT_PACKET_TYPE_CONNECT ( ( uint8_t ) 0x10U ) /**< @brief CONNECT (client-to-server). */ -#define MQTT_PACKET_TYPE_CONNACK ( ( uint8_t ) 0x20U ) /**< @brief CONNACK (server-to-client). */ -#define MQTT_PACKET_TYPE_PUBLISH ( ( uint8_t ) 0x30U ) /**< @brief PUBLISH (bi-directional). */ -#define MQTT_PACKET_TYPE_PUBACK ( ( uint8_t ) 0x40U ) /**< @brief PUBACK (server-to-client). */ -#define MQTT_PACKET_TYPE_SUBSCRIBE ( ( uint8_t ) 0x82U ) /**< @brief SUBSCRIBE (client-to-server). */ -#define MQTT_PACKET_TYPE_SUBACK ( ( uint8_t ) 0x90U ) /**< @brief SUBACK (server-to-client). */ -#define MQTT_PACKET_TYPE_UNSUBSCRIBE ( ( uint8_t ) 0xa2U ) /**< @brief UNSUBSCRIBE (client-to-server). */ -#define MQTT_PACKET_TYPE_UNSUBACK ( ( uint8_t ) 0xb0U ) /**< @brief UNSUBACK (server-to-client). */ -#define MQTT_PACKET_TYPE_PINGREQ ( ( uint8_t ) 0xc0U ) /**< @brief PINGREQ (client-to-server). */ -#define MQTT_PACKET_TYPE_PINGRESP ( ( uint8_t ) 0xd0U ) /**< @brief PINGRESP (server-to-client). */ -#define MQTT_PACKET_TYPE_DISCONNECT ( ( uint8_t ) 0xe0U ) /**< @brief DISCONNECT (client-to-server). */ - -/** - * @brief A value that represents an invalid remaining length. - * - * This value is greater than what is allowed by the MQTT specification. - */ -#define MQTT_REMAINING_LENGTH_INVALID ( ( size_t ) 268435456 ) - -/*---------------------- MQTT internal data structures ----------------------*/ - -/** - * @cond DOXYGEN_IGNORE - * Doxygen should ignore this section. - * - * Forward declaration of MQTT connection type. - */ -struct _mqttConnection; -/** @endcond */ - -/** - * @brief Internal structure representing a single MQTT operation, such as - * CONNECT, SUBSCRIBE, PUBLISH, etc. - * - * Queues of these structures keeps track of all in-progress MQTT operations. - */ -typedef struct _mqttOperation -{ - /* Pointers to neighboring queue elements. */ - IotLink_t link; /**< @brief List link member. */ - - bool incomingPublish; /**< @brief Set to true if this operation an incoming PUBLISH. */ - struct _mqttConnection * pMqttConnection; /**< @brief MQTT connection associated with this operation. */ - - IotTaskPoolJobStorage_t jobStorage; /**< @brief Task pool job storage associated with this operation. */ - IotTaskPoolJob_t job; /**< @brief Task pool job associated with this operation. */ - - union - { - /* If incomingPublish is false, this struct is valid. */ - struct - { - /* Basic operation information. */ - int32_t jobReference; /**< @brief Tracks if a job is using this operation. Must always be 0, 1, or 2. */ - IotMqttOperationType_t type; /**< @brief What operation this structure represents. */ - uint32_t flags; /**< @brief Flags passed to the function that created this operation. */ - uint16_t packetIdentifier; /**< @brief The packet identifier used with this operation. */ - - /* Serialized packet and size. */ - uint8_t * pMqttPacket; /**< @brief The MQTT packet to send over the network. */ - uint8_t * pPacketIdentifierHigh; /**< @brief The location of the high byte of the packet identifier in the MQTT packet. */ - size_t packetSize; /**< @brief Size of `pMqttPacket`. */ - - /* How to notify of an operation's completion. */ - union - { - IotSemaphore_t waitSemaphore; /**< @brief Semaphore to be used with @ref mqtt_function_wait. */ - IotMqttCallbackInfo_t callback; /**< @brief User-provided callback function and parameter. */ - } notify; /**< @brief How to notify of this operation's completion. */ - IotMqttError_t status; /**< @brief Result of this operation. This is reported once a response is received. */ - - union - { - struct - { - uint32_t count; /**< @brief Current number of retries. */ - uint32_t limit; /**< @brief Maximum number of retries allowed. */ - uint32_t nextPeriodMs; /**< @brief Next retry period. */ - } retry; /**< @brief Additional information for PUBLISH retry. */ - - struct - { - uint32_t failure; /**< @brief Flag tracking keep-alive status. */ - uint32_t keepAliveMs; /**< @brief Keep-alive interval in milliseconds. Its max value (per spec) is 65,535,000. */ - uint32_t nextPeriodMs; /**< @brief Relative delay for next keep-alive job. */ - } ping; /**< @brief Additional information for keep-alive pings. */ - } periodic; /**< @brief Additional information for periodic operations. */ - } operation; - - /* If incomingPublish is true, this struct is valid. */ - struct - { - IotMqttPublishInfo_t publishInfo; /**< @brief Deserialized PUBLISH. */ - const void * pReceivedData; /**< @brief Any buffer associated with this PUBLISH that should be freed. */ - } publish; - } u; /**< @brief Valid member depends on _mqttOperation_t.incomingPublish. */ -} _mqttOperation_t; - -/** - * @brief Represents an MQTT connection. - */ -typedef struct _mqttConnection -{ - bool awsIotMqttMode; /**< @brief Specifies if this connection is to an AWS IoT MQTT server. */ - bool ownNetworkConnection; /**< @brief Whether this MQTT connection owns its network connection. */ - void * pNetworkConnection; /**< @brief References the transport-layer network connection. */ - const IotNetworkInterface_t * pNetworkInterface; /**< @brief Network interface provided to @ref mqtt_function_connect. */ - IotMqttCallbackInfo_t disconnectCallback; /**< @brief A function to invoke when this connection is disconnected. */ - - #if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 - const IotMqttSerializer_t * pSerializer; /**< @brief MQTT packet serializer overrides. */ - #endif - - bool disconnected; /**< @brief Tracks if this connection has been disconnected. */ - IotMutex_t referencesMutex; /**< @brief Recursive mutex. Grants access to connection state and operation lists. */ - int32_t references; /**< @brief Counts callbacks and operations using this connection. */ - IotListDouble_t pendingProcessing; /**< @brief List of operations waiting to be processed by a task pool routine. */ - IotListDouble_t pendingResponse; /**< @brief List of processed operations awaiting a server response. */ - - IotListDouble_t subscriptionList; /**< @brief Holds subscriptions associated with this connection. */ - IotMutex_t subscriptionMutex; /**< @brief Grants exclusive access to the subscription list. */ - - _mqttOperation_t pingreq; /**< @brief Operation used for MQTT keep-alive. */ -} _mqttConnection_t; - -/** - * @brief Represents a subscription stored in an MQTT connection. - */ -typedef struct _mqttSubscription -{ - IotLink_t link; /**< @brief List link member. */ - - int32_t references; /**< @brief How many subscription callbacks are using this subscription. */ - - /** - * @brief Tracks whether @ref mqtt_function_unsubscribe has been called for - * this subscription. - * - * If there are active subscription callbacks, @ref mqtt_function_unsubscribe - * cannot remove this subscription. Instead, it will set this flag, which - * schedules the removal of this subscription once all subscription callbacks - * terminate. - */ - bool unsubscribed; - - struct - { - uint16_t identifier; /**< @brief Packet identifier. */ - size_t order; /**< @brief Order in the packet's list of subscriptions. */ - } packetInfo; /**< @brief Information about the SUBSCRIBE packet that registered this subscription. */ - - IotMqttCallbackInfo_t callback; /**< @brief Callback information for this subscription. */ - - uint16_t topicFilterLength; /**< @brief Length of #_mqttSubscription_t.pTopicFilter. */ - char pTopicFilter[]; /**< @brief The subscription topic filter. */ -} _mqttSubscription_t; - -/** - * @brief Represents an MQTT packet received from the network. - * - * This struct is used to hold parameters for the deserializers so that all - * deserializers have the same function signature. - */ -typedef struct _mqttPacket -{ - union - { - /** - * @brief (Input) MQTT connection associated with this packet. Only used - * when deserializing SUBACKs. - */ - _mqttConnection_t * pMqttConnection; - - /** - * @brief (Output) Operation representing an incoming PUBLISH. Only used - * when deserializing PUBLISHes. - */ - _mqttOperation_t * pIncomingPublish; - } u; /**< @brief Valid member depends on packet being decoded. */ - - uint8_t * pRemainingData; /**< @brief (Input) The remaining data in MQTT packet. */ - size_t remainingLength; /**< @brief (Input) Length of the remaining data in the MQTT packet. */ - uint16_t packetIdentifier; /**< @brief (Output) MQTT packet identifier. */ - uint8_t type; /**< @brief (Input) A value identifying the packet type. */ -} _mqttPacket_t; - -/*-------------------- MQTT struct validation functions ---------------------*/ - -/** - * @brief Check that an #IotMqttConnectInfo_t is valid. - * - * @param[in] pConnectInfo The #IotMqttConnectInfo_t to validate. - * - * @return `true` if `pConnectInfo` is valid; `false` otherwise. - */ -bool _IotMqtt_ValidateConnect( const IotMqttConnectInfo_t * pConnectInfo ); - -/** - * @brief Check that an #IotMqttPublishInfo_t is valid. - * - * @param[in] awsIotMqttMode Specifies if this PUBLISH packet is being sent to - * an AWS IoT MQTT server. - * @param[in] pPublishInfo The #IotMqttPublishInfo_t to validate. - * - * @return `true` if `pPublishInfo` is valid; `false` otherwise. - */ -bool _IotMqtt_ValidatePublish( bool awsIotMqttMode, - const IotMqttPublishInfo_t * pPublishInfo ); - -/** - * @brief Check that an #IotMqttOperation_t is valid and waitable. - * - * @param[in] operation The #IotMqttOperation_t to validate. - * - * @return `true` if `operation` is valid; `false` otherwise. - */ -bool _IotMqtt_ValidateOperation( IotMqttOperation_t operation ); - -/** - * @brief Check that a list of #IotMqttSubscription_t is valid. - * - * @param[in] operation Either #IOT_MQTT_SUBSCRIBE or #IOT_MQTT_UNSUBSCRIBE. - * Some parameters are not validated for #IOT_MQTT_UNSUBSCRIBE. - * @param[in] awsIotMqttMode Specifies if this SUBSCRIBE packet is being sent to - * an AWS IoT MQTT server. - * @param[in] pListStart First element of the list to validate. - * @param[in] listSize Number of elements in the subscription list. - * - * @return `true` if every element in the list is valid; `false` otherwise. - */ -bool _IotMqtt_ValidateSubscriptionList( IotMqttOperationType_t operation, - bool awsIotMqttMode, - const IotMqttSubscription_t * pListStart, - size_t listSize ); - -/*-------------------- MQTT packet serializer functions ---------------------*/ - -/** - * @brief Get the MQTT packet type from a stream of bytes off the network. - * - * @param[in] pNetworkConnection Reference to the network connection. - * @param[in] pNetworkInterface Function pointers used to interact with the - * network. - * - * @return One of the server-to-client MQTT packet types. - * - * @note This function is only used for incoming packets, and may not work - * correctly for outgoing packets. - */ -uint8_t _IotMqtt_GetPacketType( void * pNetworkConnection, - const IotNetworkInterface_t * pNetworkInterface ); - -/** - * @brief Get the remaining length from a stream of bytes off the network. - * - * @param[in] pNetworkConnection Reference to the network connection. - * @param[in] pNetworkInterface Function pointers used to interact with the - * network. - * - * @return The remaining length; #MQTT_REMAINING_LENGTH_INVALID on error. - */ -size_t _IotMqtt_GetRemainingLength( void * pNetworkConnection, - const IotNetworkInterface_t * pNetworkInterface ); - -/** - * @brief Generate a CONNECT packet from the given parameters. - * - * @param[in] pConnectInfo User-provided CONNECT information. - * @param[out] pConnectPacket Where the CONNECT packet is written. - * @param[out] pPacketSize Size of the packet written to `pConnectPacket`. - * - * @return #IOT_MQTT_SUCCESS or #IOT_MQTT_NO_MEMORY. - */ -IotMqttError_t _IotMqtt_SerializeConnect( const IotMqttConnectInfo_t * pConnectInfo, - uint8_t ** pConnectPacket, - size_t * pPacketSize ); - -/** - * @brief Deserialize a CONNACK packet. - * - * Converts the packet from a stream of bytes to an #IotMqttError_t. Also - * prints out debug log messages about the packet. - * - * @param[in,out] pConnack Pointer to an MQTT packet struct representing a CONNACK. - * - * @return #IOT_MQTT_SUCCESS if CONNACK specifies that CONNECT was accepted; - * #IOT_MQTT_SERVER_REFUSED if CONNACK specifies that CONNECT was rejected; - * #IOT_MQTT_BAD_RESPONSE if the CONNACK packet doesn't follow MQTT spec. - */ -IotMqttError_t _IotMqtt_DeserializeConnack( _mqttPacket_t * pConnack ); - -/** - * @brief Generate a PUBLISH packet from the given parameters. - * - * @param[in] pPublishInfo User-provided PUBLISH information. - * @param[out] pPublishPacket Where the PUBLISH packet is written. - * @param[out] pPacketSize Size of the packet written to `pPublishPacket`. - * @param[out] pPacketIdentifier The packet identifier generated for this PUBLISH. - * @param[out] pPacketIdentifierHigh Where the high byte of the packet identifier - * is written. - * - * @return #IOT_MQTT_SUCCESS or #IOT_MQTT_NO_MEMORY. - */ -IotMqttError_t _IotMqtt_SerializePublish( const IotMqttPublishInfo_t * pPublishInfo, - uint8_t ** pPublishPacket, - size_t * pPacketSize, - uint16_t * pPacketIdentifier, - uint8_t ** pPacketIdentifierHigh ); - -/** - * @brief Set the DUP bit in a QoS 1 PUBLISH packet. - * - * @param[in] pPublishPacket Pointer to the PUBLISH packet to modify. - * @param[in] pPacketIdentifierHigh The high byte of any packet identifier to modify. - * @param[out] pNewPacketIdentifier Since AWS IoT does not support the DUP flag, - * a new packet identifier is generated and should be written here. This parameter - * is only used when connected to an AWS IoT MQTT server. - * - * @note See #IotMqttPublishInfo_t for caveats with retransmission to the - * AWS IoT MQTT server. - */ -void _IotMqtt_PublishSetDup( uint8_t * pPublishPacket, - uint8_t * pPacketIdentifierHigh, - uint16_t * pNewPacketIdentifier ); - -/** - * @brief Deserialize a PUBLISH packet received from the server. - * - * Converts the packet from a stream of bytes to an #IotMqttPublishInfo_t and - * extracts the packet identifier. Also prints out debug log messages about the - * packet. - * - * @param[in,out] pPublish Pointer to an MQTT packet struct representing a PUBLISH. - * - * @return #IOT_MQTT_SUCCESS if PUBLISH is valid; #IOT_MQTT_BAD_RESPONSE - * if the PUBLISH packet doesn't follow MQTT spec. - */ -IotMqttError_t _IotMqtt_DeserializePublish( _mqttPacket_t * pPublish ); - -/** - * @brief Generate a PUBACK packet for the given packet identifier. - * - * @param[in] packetIdentifier The packet identifier to place in PUBACK. - * @param[out] pPubackPacket Where the PUBACK packet is written. - * @param[out] pPacketSize Size of the packet written to `pPubackPacket`. - * - * @return #IOT_MQTT_SUCCESS or #IOT_MQTT_NO_MEMORY. - */ -IotMqttError_t _IotMqtt_SerializePuback( uint16_t packetIdentifier, - uint8_t ** pPubackPacket, - size_t * pPacketSize ); - -/** - * @brief Deserialize a PUBACK packet. - * - * Converts the packet from a stream of bytes to an #IotMqttError_t and extracts - * the packet identifier. Also prints out debug log messages about the packet. - * - * @param[in,out] pPuback Pointer to an MQTT packet struct representing a PUBACK. - * - * @return #IOT_MQTT_SUCCESS if PUBACK is valid; #IOT_MQTT_BAD_RESPONSE - * if the PUBACK packet doesn't follow MQTT spec. - */ -IotMqttError_t _IotMqtt_DeserializePuback( _mqttPacket_t * pPuback ); - -/** - * @brief Generate a SUBSCRIBE packet from the given parameters. - * - * @param[in] pSubscriptionList User-provided array of subscriptions. - * @param[in] subscriptionCount Size of `pSubscriptionList`. - * @param[out] pSubscribePacket Where the SUBSCRIBE packet is written. - * @param[out] pPacketSize Size of the packet written to `pSubscribePacket`. - * @param[out] pPacketIdentifier The packet identifier generated for this SUBSCRIBE. - * - * @return #IOT_MQTT_SUCCESS or #IOT_MQTT_NO_MEMORY. - */ -IotMqttError_t _IotMqtt_SerializeSubscribe( const IotMqttSubscription_t * pSubscriptionList, - size_t subscriptionCount, - uint8_t ** pSubscribePacket, - size_t * pPacketSize, - uint16_t * pPacketIdentifier ); - -/** - * @brief Deserialize a SUBACK packet. - * - * Converts the packet from a stream of bytes to an #IotMqttError_t and extracts - * the packet identifier. Also prints out debug log messages about the packet. - * - * @param[in,out] pSuback Pointer to an MQTT packet struct representing a SUBACK. - * - * @return #IOT_MQTT_SUCCESS if SUBACK is valid; #IOT_MQTT_BAD_RESPONSE - * if the SUBACK packet doesn't follow MQTT spec. - */ -IotMqttError_t _IotMqtt_DeserializeSuback( _mqttPacket_t * pSuback ); - -/** - * @brief Generate an UNSUBSCRIBE packet from the given parameters. - * - * @param[in] pSubscriptionList User-provided array of subscriptions to remove. - * @param[in] subscriptionCount Size of `pSubscriptionList`. - * @param[out] pUnsubscribePacket Where the UNSUBSCRIBE packet is written. - * @param[out] pPacketSize Size of the packet written to `pUnsubscribePacket`. - * @param[out] pPacketIdentifier The packet identifier generated for this UNSUBSCRIBE. - * - * @return #IOT_MQTT_SUCCESS or #IOT_MQTT_NO_MEMORY. - */ -IotMqttError_t _IotMqtt_SerializeUnsubscribe( const IotMqttSubscription_t * pSubscriptionList, - size_t subscriptionCount, - uint8_t ** pUnsubscribePacket, - size_t * pPacketSize, - uint16_t * pPacketIdentifier ); - -/** - * @brief Deserialize a UNSUBACK packet. - * - * Converts the packet from a stream of bytes to an #IotMqttError_t and extracts - * the packet identifier. Also prints out debug log messages about the packet. - * - * @param[in,out] pUnsuback Pointer to an MQTT packet struct representing an UNSUBACK. - * - * @return #IOT_MQTT_SUCCESS if UNSUBACK is valid; #IOT_MQTT_BAD_RESPONSE - * if the UNSUBACK packet doesn't follow MQTT spec. - */ -IotMqttError_t _IotMqtt_DeserializeUnsuback( _mqttPacket_t * pUnsuback ); - -/** - * @brief Generate a PINGREQ packet. - * - * @param[out] pPingreqPacket Where the PINGREQ packet is written. - * @param[out] pPacketSize Size of the packet written to `pPingreqPacket`. - * - * @return Always returns #IOT_MQTT_SUCCESS. - */ -IotMqttError_t _IotMqtt_SerializePingreq( uint8_t ** pPingreqPacket, - size_t * pPacketSize ); - -/** - * @brief Deserialize a PINGRESP packet. - * - * Converts the packet from a stream of bytes to an #IotMqttError_t. Also - * prints out debug log messages about the packet. - * - * @param[in,out] pPingresp Pointer to an MQTT packet struct representing a PINGRESP. - * - * @return #IOT_MQTT_SUCCESS if PINGRESP is valid; #IOT_MQTT_BAD_RESPONSE - * if the PINGRESP packet doesn't follow MQTT spec. - */ -IotMqttError_t _IotMqtt_DeserializePingresp( _mqttPacket_t * pPingresp ); - -/** - * @brief Generate a DISCONNECT packet. - * - * @param[out] pDisconnectPacket Where the DISCONNECT packet is written. - * @param[out] pPacketSize Size of the packet written to `pDisconnectPacket`. - * - * @return Always returns #IOT_MQTT_SUCCESS. - */ -IotMqttError_t _IotMqtt_SerializeDisconnect( uint8_t ** pDisconnectPacket, - size_t * pPacketSize ); - -/** - * @brief Free a packet generated by the serializer. - * - * @param[in] pPacket The packet to free. - */ -void _IotMqtt_FreePacket( uint8_t * pPacket ); - -/*-------------------- MQTT operation record functions ----------------------*/ - -/** - * @brief Create a record for a new in-progress MQTT operation. - * - * @param[in] pMqttConnection The MQTT connection to associate with the operation. - * @param[in] flags Flags variable passed to a user-facing MQTT function. - * @param[in] pCallbackInfo User-provided callback function and parameter. - * @param[out] pNewOperation Set to point to the new operation on success. - * - * @return #IOT_MQTT_SUCCESS, #IOT_MQTT_BAD_PARAMETER, or #IOT_MQTT_NO_MEMORY. - */ -IotMqttError_t _IotMqtt_CreateOperation( _mqttConnection_t * pMqttConnection, - uint32_t flags, - const IotMqttCallbackInfo_t * pCallbackInfo, - _mqttOperation_t ** pNewOperation ); - -/** - * @brief Decrement the job reference count of an MQTT operation and optionally - * cancel its job. - * - * Checks if the operation may be destroyed afterwards. - * - * @param[in] pOperation The MQTT operation with the job to cancel. - * @param[in] cancelJob Whether to attempt cancellation of the operation's job. - * - * @return `true` if the the operation may be safely destroyed; `false` otherwise. - */ -bool _IotMqtt_DecrementOperationReferences( _mqttOperation_t * pOperation, - bool cancelJob ); - -/** - * @brief Free resources used to record an MQTT operation. This is called when - * the operation completes. - * - * @param[in] pOperation The operation which completed. - */ -void _IotMqtt_DestroyOperation( _mqttOperation_t * pOperation ); - -/** - * @brief Task pool routine for processing an MQTT connection's keep-alive. - * - * @param[in] pTaskPool Pointer to the system task pool. - * @param[in] pKeepAliveJob Pointer the an MQTT connection's keep-alive job. - * @param[in] pContext Pointer to an MQTT connection, passed as an opaque context. - */ -void _IotMqtt_ProcessKeepAlive( IotTaskPool_t pTaskPool, - IotTaskPoolJob_t pKeepAliveJob, - void * pContext ); - -/** - * @brief Task pool routine for processing an incoming PUBLISH message. - * - * @param[in] pTaskPool Pointer to the system task pool. - * @param[in] pPublishJob Pointer to the incoming PUBLISH operation's job. - * @param[in] pContext Pointer to the incoming PUBLISH operation, passed as an - * opaque context. - */ -void _IotMqtt_ProcessIncomingPublish( IotTaskPool_t pTaskPool, - IotTaskPoolJob_t pPublishJob, - void * pContext ); - -/** - * @brief Task pool routine for processing an MQTT operation to send. - * - * @param[in] pTaskPool Pointer to the system task pool. - * @param[in] pSendJob Pointer to an operation's job. - * @param[in] pContext Pointer to the operation to send, passed as an opaque - * context. - */ -void _IotMqtt_ProcessSend( IotTaskPool_t pTaskPool, - IotTaskPoolJob_t pSendJob, - void * pContext ); - -/** - * @brief Task pool routine for processing a completed MQTT operation. - * - * @param[in] pTaskPool Pointer to the system task pool. - * @param[in] pOperationJob Pointer to the completed operation's job. - * @param[in] pContext Pointer to the completed operation, passed as an opaque - * context. - */ -void _IotMqtt_ProcessCompletedOperation( IotTaskPool_t pTaskPool, - IotTaskPoolJob_t pOperationJob, - void * pContext ); - -/** - * @brief Schedule an operation for immediate processing. - * - * @param[in] pOperation The operation to schedule. - * @param[in] jobRoutine The routine to run for the job. Must be either - * #_IotMqtt_ProcessSend, #_IotMqtt_ProcessCompletedOperation, or - * #_IotMqtt_ProcessIncomingPublish. - * @param[in] delay A delay before the operation job should be executed. Pass - * `0` to execute ASAP. - * - * @return #IOT_MQTT_SUCCESS or #IOT_MQTT_SCHEDULING_ERROR. - */ -IotMqttError_t _IotMqtt_ScheduleOperation( _mqttOperation_t * pOperation, - IotTaskPoolRoutine_t jobRoutine, - uint32_t delay ); - -/** - * @brief Search a list of MQTT operations pending responses using an operation - * name and packet identifier. Removes a matching operation from the list if found. - * - * @param[in] pMqttConnection The connection associated with the operation. - * @param[in] type The operation type to look for. - * @param[in] pPacketIdentifier A packet identifier to match. Pass `NULL` to ignore. - * - * @return Pointer to any matching operation; `NULL` if no match was found. - */ -_mqttOperation_t * _IotMqtt_FindOperation( _mqttConnection_t * pMqttConnection, - IotMqttOperationType_t type, - const uint16_t * pPacketIdentifier ); - -/** - * @brief Notify of a completed MQTT operation. - * - * @param[in] pOperation The MQTT operation which completed. - * - * Depending on the parameters passed to a user-facing MQTT function, the - * notification will cause @ref mqtt_function_wait to return or invoke a - * user-provided callback. - */ -void _IotMqtt_Notify( _mqttOperation_t * pOperation ); - -/*----------------- MQTT subscription management functions ------------------*/ - -/** - * @brief Add an array of subscriptions to the subscription manager. - * - * @param[in] pMqttConnection The MQTT connection associated with the subscriptions. - * @param[in] subscribePacketIdentifier Packet identifier for the subscriptions' - * SUBSCRIBE packet. - * @param[in] pSubscriptionList The first element in the array. - * @param[in] subscriptionCount Number of elements in `pSubscriptionList`. - * - * @return #IOT_MQTT_SUCCESS or #IOT_MQTT_NO_MEMORY. - */ -IotMqttError_t _IotMqtt_AddSubscriptions( _mqttConnection_t * pMqttConnection, - uint16_t subscribePacketIdentifier, - const IotMqttSubscription_t * pSubscriptionList, - size_t subscriptionCount ); - -/** - * @brief Process a received PUBLISH from the server, invoking any subscription - * callbacks that have a matching topic filter. - * - * @param[in] pMqttConnection The MQTT connection associated with the received - * PUBLISH. - * @param[in] pCallbackParam The parameter to pass to a PUBLISH callback. - */ -void _IotMqtt_InvokeSubscriptionCallback( _mqttConnection_t * pMqttConnection, - IotMqttCallbackParam_t * pCallbackParam ); - -/** - * @brief Remove a single subscription from the subscription manager by - * packetIdentifier and order. - * - * @param[in] pMqttConnection The MQTT connection associated with the subscriptions. - * @param[in] packetIdentifier The packet identifier associated with the subscription's - * SUBSCRIBE packet. - * @param[in] order The order of the subscription in the SUBSCRIBE packet. - * Pass `-1` to ignore order and remove all subscriptions for `packetIdentifier`. - */ -void _IotMqtt_RemoveSubscriptionByPacket( _mqttConnection_t * pMqttConnection, - uint16_t packetIdentifier, - int32_t order ); - -/** - * @brief Remove an array of subscriptions from the subscription manager by - * topic filter. - * - * @param[in] pMqttConnection The MQTT connection associated with the subscriptions. - * @param[in] pSubscriptionList The first element in the array. - * @param[in] subscriptionCount Number of elements in `pSubscriptionList`. - */ -void _IotMqtt_RemoveSubscriptionByTopicFilter( _mqttConnection_t * pMqttConnection, - const IotMqttSubscription_t * pSubscriptionList, - size_t subscriptionCount ); - -/*------------------ MQTT connection management functions -------------------*/ - -/** - * @brief Attempt to increment the reference count of an MQTT connection. - * - * @param[in] pMqttConnection The referenced MQTT connection. - * - * @return `true` if the reference count was incremented; `false` otherwise. The - * reference count will not be incremented for a disconnected connection. - */ -bool _IotMqtt_IncrementConnectionReferences( _mqttConnection_t * pMqttConnection ); - -/** - * @brief Decrement the reference count of an MQTT connection. - * - * Also destroys an unreferenced MQTT connection. - * - * @param[in] pMqttConnection The referenced MQTT connection. - */ -void _IotMqtt_DecrementConnectionReferences( _mqttConnection_t * pMqttConnection ); - -/** - * @brief Read the next available byte on a network connection. - * - * @param[in] pNetworkConnection Reference to the network connection. - * @param[in] pNetworkInterface Function pointers used to interact with the - * network. - * @param[out] pIncomingByte The byte read from the network. - * - * @return `true` if a byte was successfully received from the network; `false` - * otherwise. - */ -bool _IotMqtt_GetNextByte( void * pNetworkConnection, - const IotNetworkInterface_t * pNetworkInterface, - uint8_t * pIncomingByte ); - -/** - * @brief Closes the network connection associated with an MQTT connection. - * - * A network disconnect function must be set in the network interface for the - * network connection to be closed. - * - * @param[in] disconnectReason A reason to pass to the connection's disconnect - * callback. - * @param[in] pMqttConnection The MQTT connection with the network connection - * to close. - */ -void _IotMqtt_CloseNetworkConnection( IotMqttDisconnectReason_t disconnectReason, - _mqttConnection_t * pMqttConnection ); - -#endif /* ifndef IOT_MQTT_INTERNAL_H_ */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/directories.txt b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/directories.txt deleted file mode 100644 index b22d7e6f0..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/directories.txt +++ /dev/null @@ -1,8 +0,0 @@ -Base directory for the FreeRTOS IoT Libraries. - -+ abstractions -Contains FreeRTOS specific implementations of abstractions used within the IoT -libraries. - -+ c_sdk -Contains the implementations of the IoT libraries - more will be rolled out soon. -- 2.39.2