wolfssl-freertos/FreeRTOS-AWS/lib/include/private/aws_mqtt_buffer.h

232 lines
9.9 KiB
C
Executable File

/*
* Amazon FreeRTOS
* Copyright (C) 2017 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_buffer.h
* @brief MQTT Buffer management.
*
* Each MQTT buffer is represented as MQTTBufferHandle_t which is opaque
* to the user. Buffers are internally organized as circular doubly linked
* list and the metadata needed for that is stored in the beginning of the
* buffer along with the other metadata. This reduces the actual buffer
* space available to store the data. More specifically, the first
* sizeof( MQTTBufferMetadata_t ) bytes of each buffer are used to store
* the metadata. Macros provided in this file should be used to convert
* between raw buffer and MQTTBufferHandle_t and to access various fields.
*/
#ifndef _AWS_MQTT_BUFFER_H_
#define _AWS_MQTT_BUFFER_H_
/* Utils includes. */
#include "aws_doubly_linked_list.h"
/**
* @brief Opaque handle to represent an MQTT buffer.
*/
typedef void * MQTTBufferHandle_t;
/**
* @brief Structure containing the state of a transmitted buffer.
*
* Each buffer containing a transmitted MQTT message is put on a
* waiting ACK list and is removed when it is acknowledged by the
* broker or the operation times out. The packet identifier helps
* in matching the received ACK with the transmitted message while
* the recorded tick count and timeout ticks help in tracking timeout.
*/
typedef struct MQTTBufferState
{
uint64_t xRecordedTickCount; /**< The time-stamp when this packet was sent. */
uint32_t ulTimeoutTicks; /**< The time interval after which this packet should timeout i.e. stop waiting for ACK. */
uint16_t usPacketIdentifier; /**< Packet identifier sent with this packet. */
} MQTTBufferState_t;
/**
* @brief Metadata stored in each MQTT buffer.
*
* The first sizeof( MQTTBufferMetadata_t ) bytes of each buffer are
* used to store the metadata. This reduces the space available to store
* the actual data in the buffer. The metadata among other things include
* a link structure (of type Link_t) which helps in organizing the buffers
* as a doubly linked list, length of the buffer and the length of the
* data in the buffer.
*/
typedef struct MQTTBufferMetadata
{
MQTTBufferState_t xBufferState; /**< State of the buffer. @see MQTTBufferState_t. */
Link_t xLink; /**< Contains links to previous and next buffers in the list. */
uint32_t ulBufferLength; /**< The length of the buffer. */
uint32_t ulDataLength; /**< The length of the data in the buffer. */
} MQTTBufferMetadata_t;
/**
* @brief Given the buffer handle, extracts the link structure from the
* metadata portion of the buffer.
*
* @param[in] xBufferHandle The given buffer handle.
*/
#define mqttbufferGET_LINK( xBufferHandle ) ( ( ( MQTTBufferMetadata_t * ) ( xBufferHandle ) )->xLink )
/**
* @brief Given the pointer to a link structure, finds the buffer handle
* containing the link.
*
* @param[in] pxLink The pointer to the link struct.
*/
#define mqttbufferGET_BUFFER_HANDLE_FROM_LINK( pxLink ) ( ( MQTTBufferHandle_t ) listCONTAINER( pxLink, MQTTBufferMetadata_t, xLink ) )
/**
* @brief Given the buffer handle, finds the pointer to the starting of
* the buffer.
*
* @param[in] xBufferHandle The given buffer handle.
*/
#define mqttbufferGET_RAW_BUFFER_FROM_HANDLE( xBufferHandle ) ( ( uint8_t * ) ( xBufferHandle ) )
/**
* @brief Gets the buffer handle from the given uint8_t buffer.
*
* @param[in] pucBuffer The given uint8_t buffer.
*/
#define mqttbufferGET_HANDLE_FROM_RAW_BUFFER( pucBuffer ) ( ( MQTTBufferHandle_t ) ( pucBuffer ) )
/**
* @brief Given the buffer handle, extracts the total length of the buffer
* from the metadata portion of the buffer.
*
* @param[in] xBufferHandle The given buffer handle.
*/
#define mqttbufferGET_RAW_BUFFER_LENGTH( xBufferHandle ) ( ( ( MQTTBufferMetadata_t * ) ( xBufferHandle ) )->ulBufferLength )
/**
* @brief Given the buffer handle, finds the length of the space available
* to store the actual data.
*
* Effective Length = Total Buffer Length - Metadata Length.
*
* @param[in] xBufferHandle The given buffer handle.
*/
#define mqttbufferGET_EFFECTIVE_BUFFER_LENGTH( xBufferHandle ) ( ( ( ( MQTTBufferMetadata_t * ) ( xBufferHandle ) )->ulBufferLength ) - sizeof( MQTTBufferMetadata_t ) )
/**
* @brief Given the buffer handle, finds the pointer to the location of the
* actual data i.e. the location following the metadata.
*
* @param[in] xBufferHandle The given buffer handle.
*/
#define mqttbufferGET_DATA( xBufferHandle ) ( ( uint8_t * ) ( ( ( uint8_t * ) ( xBufferHandle ) ) + sizeof( MQTTBufferMetadata_t ) ) )
/**
* @brief Given the buffer handle, extracts the length of the data in the buffer
* from the metadata portion of the buffer.
*
* @param[in] xBufferHandle The given buffer handle.
*/
#define mqttbufferGET_DATA_LENGTH( xBufferHandle ) ( ( ( MQTTBufferMetadata_t * ) ( xBufferHandle ) )->ulDataLength )
/**
* @brief Given the buffer handle, extracts the packet identifier from the metadata
* portion of the buffer.
*
* @param[in] xBufferHandle The given buffer handle.
*/
#define mqttbufferGET_PACKET_IDENTIFIER( xBufferHandle ) ( ( ( MQTTBufferMetadata_t * ) ( xBufferHandle ) )->xBufferState.usPacketIdentifier )
/**
* @brief Given the buffer handle, extracts the recorded tick count from the
* metadata portion of the buffer.
*
* @param[in] xBufferHandle The given buffer handle.
*/
#define mqttbufferGET_PACKET_RECORDED_TICK_COUNT( xBufferHandle ) ( ( ( MQTTBufferMetadata_t * ) ( xBufferHandle ) )->xBufferState.xRecordedTickCount )
/**
* @brief Given the buffer handle, extracts the timeout ticks from the metadata
* portion of the buffer.
*
* @param[in] xBufferHandle The given buffer handle.
*/
#define mqttbufferGET_PACKET_TIMEOUT_TICKS( xBufferHandle ) ( ( ( MQTTBufferMetadata_t * ) ( xBufferHandle ) )->xBufferState.ulTimeoutTicks )
/**
* @brief Given a list head and a buffer handle, adds the buffer to the given
* list.
*
* @param[in] pxHead The head of the list to which the buffer is to be added.
* @param[in] xBufferHandle The given buffer handle.
*/
#define mqttbufferLIST_ADD( pxHead, xBufferHandle ) listADD( ( pxHead ), &( mqttbufferGET_LINK( xBufferHandle ) ) )
/**
* @brief Given a buffer handle, removes it from the list it is part of. If it is
* not a part of any list (i.e. next and previous nodes are NULL), nothing happens.
*
* @param[in] xBufferHandle The given buffer handle.
*/
#define mqttbufferLIST_REMOVE( xBufferHandle ) listREMOVE( &( mqttbufferGET_LINK( xBufferHandle ) ) )
/**
* @brief Given a pointer to a buffer and its length, initializes the metadata
* portion of the buffer.
*
* @param[in] pucBuffer The given buffer.
* @param[in] ulLength The length of the given buffer.
*/
#define mqttbufferINIT_BUFFER( pucBuffer, ulLength ) \
{ \
( ( MQTTBufferMetadata_t * ) ( pucBuffer ) )->xLink.pxPrev = NULL; \
( ( MQTTBufferMetadata_t * ) ( pucBuffer ) )->xLink.pxNext = NULL; \
( ( MQTTBufferMetadata_t * ) ( pucBuffer ) )->ulBufferLength = ( ulLength ); \
( ( MQTTBufferMetadata_t * ) ( pucBuffer ) )->ulDataLength = 0; \
}
/**
* @brief Removes the first node from the given list.
*
* It extracts the buffer handle corresponding to the removed node and assigns it to
* xBufferHandle. If the list is empty, it assigns NULL to the xBufferHandle.
*
* @param[in] pxHead The head of the list from which to remove the node.
* @param[out] xBufferHandle The output parameter to receive the buffer handle
* corresponding to the removed node.
*/
#define mqttbufferLIST_POP( pxHead, xBufferHandle ) \
{ \
Link_t * pxLink; \
listPOP( ( pxHead ), pxLink ); \
if( pxLink == NULL ) \
{ \
( xBufferHandle ) = NULL; \
} \
else \
{ \
( xBufferHandle ) = mqttbufferGET_BUFFER_HANDLE_FROM_LINK( pxLink ); \
} \
}
#endif /* _AWS_MQTT_BUFFER_H_ */