mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-30 15:08:42 -04:00
Add the Labs projects provided in the V10.2.1_191129 zip file.
This commit is contained in:
parent
46e5937529
commit
e5708b38e9
801 changed files with 356576 additions and 0 deletions
|
@ -0,0 +1,305 @@
|
|||
/*
|
||||
* AWS IoT Common 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file aws_iot.h
|
||||
* @brief Provides routines and constants that are common to AWS IoT libraries.
|
||||
* This header should not be included in typical application code.
|
||||
*/
|
||||
|
||||
#ifndef AWS_IOT_H_
|
||||
#define AWS_IOT_H_
|
||||
|
||||
/* The config header is always included first. */
|
||||
#include "iot_config.h"
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Platform types include. */
|
||||
#include "types/iot_platform_types.h"
|
||||
|
||||
/* MQTT types include. */
|
||||
#include "types/iot_mqtt_types.h"
|
||||
|
||||
/**
|
||||
* @brief The longest Thing Name accepted by AWS IoT, per the [AWS IoT
|
||||
* Service Limits](https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html#limits_iot).
|
||||
*/
|
||||
#define AWS_IOT_MAX_THING_NAME_LENGTH ( 128 )
|
||||
|
||||
/**
|
||||
* @brief The common prefix of all AWS IoT MQTT topics.
|
||||
*/
|
||||
#define AWS_IOT_TOPIC_PREFIX "$aws/things/"
|
||||
|
||||
/**
|
||||
* @brief The length of #AWS_IOT_TOPIC_PREFIX.
|
||||
*/
|
||||
#define AWS_IOT_TOPIC_PREFIX_LENGTH ( ( uint16_t ) ( sizeof( AWS_IOT_TOPIC_PREFIX ) - 1 ) )
|
||||
|
||||
/**
|
||||
* @brief The suffix for an AWS IoT operation "accepted" topic.
|
||||
*/
|
||||
#define AWS_IOT_ACCEPTED_SUFFIX "/accepted"
|
||||
|
||||
/**
|
||||
* @brief The length of #AWS_IOT_ACCEPTED_SUFFIX.
|
||||
*/
|
||||
#define AWS_IOT_ACCEPTED_SUFFIX_LENGTH ( ( uint16_t ) ( sizeof( AWS_IOT_ACCEPTED_SUFFIX ) - 1 ) )
|
||||
|
||||
/**
|
||||
* @brief The suffix for an AWS IoT operation "rejected" topic.
|
||||
*/
|
||||
#define AWS_IOT_REJECTED_SUFFIX "/rejected"
|
||||
|
||||
/**
|
||||
* @brief The length of #AWS_IOT_REJECTED_SUFFIX.
|
||||
*/
|
||||
#define AWS_IOT_REJECTED_SUFFIX_LENGTH ( ( uint16_t ) ( sizeof( AWS_IOT_REJECTED_SUFFIX ) - 1 ) )
|
||||
|
||||
/**
|
||||
* @brief The JSON key used to represent client tokens for AWS IoT.
|
||||
*/
|
||||
#define AWS_IOT_CLIENT_TOKEN_KEY "clientToken"
|
||||
|
||||
/**
|
||||
* @brief The length of #AWS_IOT_CLIENT_TOKEN_KEY.
|
||||
*/
|
||||
#define AWS_IOT_CLIENT_TOKEN_KEY_LENGTH ( sizeof( AWS_IOT_CLIENT_TOKEN_KEY ) - 1 )
|
||||
|
||||
/**
|
||||
* @brief The length of the longest client token allowed by AWS IoT.
|
||||
*/
|
||||
#define AWS_IOT_CLIENT_TOKEN_MAX_LENGTH ( 64 )
|
||||
|
||||
/**
|
||||
* @brief A flag to represent persistent subscriptions in a subscriptions
|
||||
* object.
|
||||
*
|
||||
* Its value is negative to distinguish it from valid subscription counts, which
|
||||
* are 0 or positive.
|
||||
*/
|
||||
#define AWS_IOT_PERSISTENT_SUBSCRIPTION ( -1 )
|
||||
|
||||
/**
|
||||
* @brief Function pointer representing an MQTT blocking operation.
|
||||
*
|
||||
* Currently, this is used to represent @ref mqtt_function_subscribesync or
|
||||
* @ref mqtt_function_unsubscribesync.
|
||||
*
|
||||
* @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 in milliseconds, this function returns #IOT_MQTT_TIMEOUT.
|
||||
*
|
||||
* @return One of the following:
|
||||
* - #IOT_MQTT_SUCCESS
|
||||
* - #IOT_MQTT_NOT_INITIALIZED
|
||||
* - #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
|
||||
*/
|
||||
typedef IotMqttError_t ( * AwsIotMqttFunction_t )( IotMqttConnection_t mqttConnection,
|
||||
const IotMqttSubscription_t * pSubscriptionList,
|
||||
size_t subscriptionCount,
|
||||
uint32_t flags,
|
||||
uint32_t timeoutMs );
|
||||
|
||||
/**
|
||||
* @brief Function pointer representing an MQTT library callback function.
|
||||
*
|
||||
* @param[in] pArgument Ignored.
|
||||
* @param[in] pMessage The received DELTA document (as an MQTT PUBLISH message).
|
||||
*/
|
||||
typedef void ( * AwsIotMqttCallbackFunction_t )( void * pArgument,
|
||||
IotMqttCallbackParam_t * pMessage );
|
||||
|
||||
/**
|
||||
* @brief Enumerations representing each of the statuses that may be parsed
|
||||
* from a topic.
|
||||
*/
|
||||
typedef enum AwsIotStatus
|
||||
{
|
||||
AWS_IOT_ACCEPTED = 0, /**< Operation accepted. */
|
||||
AWS_IOT_REJECTED = 1, /**< Operation rejected. */
|
||||
AWS_IOT_UNKNOWN = 2 /**< Unknown status (neither accepted nor rejected). */
|
||||
} AwsIotStatus_t;
|
||||
|
||||
/**
|
||||
* @brief Information required to generate a topic for AWS IoT.
|
||||
*/
|
||||
typedef struct AwsIotTopicInfo
|
||||
{
|
||||
const char * pThingName; /**< @brief The Thing Name associated with the operation. */
|
||||
size_t thingNameLength; /**< @brief The length of `pThingName`. */
|
||||
const char * pOperationName; /**< @brief The operation name to place in the topic. */
|
||||
uint16_t operationNameLength; /**< @brief The length of `pOperationName`. */
|
||||
uint16_t longestSuffixLength; /**< @brief The length of longest suffix that will be placed at the end of the topic. */
|
||||
void * ( *mallocString )( size_t size ); /**< @brief Function used to allocate a string, if needed. */
|
||||
} AwsIotTopicInfo_t;
|
||||
|
||||
/**
|
||||
* @brief Information needed to modify AWS IoT subscription topics.
|
||||
*
|
||||
* @warning The buffer passed as `pTopicFilterBase` must be large enough to
|
||||
* accommodate the "/accepted" and "/rejected" suffixes.
|
||||
*/
|
||||
typedef struct AwsIotSubscriptionInfo_t
|
||||
{
|
||||
IotMqttConnection_t mqttConnection; /**< @brief The MQTT connection to use. */
|
||||
AwsIotMqttCallbackFunction_t callbackFunction; /**< @brief Callback function for MQTT subscribe. */
|
||||
uint32_t timeout; /**< @brief Timeout for MQTT function. */
|
||||
|
||||
/* Topic filter. */
|
||||
char * pTopicFilterBase; /**< @brief Contains the base topic filter, without "/accepted" or "/rejected". */
|
||||
uint16_t topicFilterBaseLength; /**< @brief Length of the base topic filter. */
|
||||
} AwsIotSubscriptionInfo_t;
|
||||
|
||||
/**
|
||||
* @brief Thing Name and length, used to match subscriptions.
|
||||
*/
|
||||
typedef struct AwsIotThingName
|
||||
{
|
||||
const char * pThingName; /**< @brief Thing Name to compare. */
|
||||
size_t thingNameLength; /**< @brief Length of `pThingName`. */
|
||||
} AwsIotThingName_t;
|
||||
|
||||
/**
|
||||
* @brief Initializes the lists used by AWS IoT operations.
|
||||
*
|
||||
* @param[in] pPendingOperationsList The list that holds pending operations for
|
||||
* a library.
|
||||
* @param[in] pSubscriptionsList The list that holds subscriptions for a library.
|
||||
* @param[in] pPendingOperationsMutex The mutex that guards the pending operations
|
||||
* list.
|
||||
* @param[in] pSubscriptionsMutex The mutex that guards the subscriptions list.
|
||||
*
|
||||
* @return `true` if all initialization succeeded; `false` otherwise.
|
||||
*/
|
||||
bool AwsIot_InitLists( IotListDouble_t * pPendingOperationsList,
|
||||
IotListDouble_t * pSubscriptionsList,
|
||||
IotMutex_t * pPendingOperationsMutex,
|
||||
IotMutex_t * pSubscriptionsMutex );
|
||||
|
||||
/**
|
||||
* @brief Checks that a Thing Name is valid for AWS IoT.
|
||||
*
|
||||
* @param[in] pThingName Thing Name to validate.
|
||||
* @param[in] thingNameLength Length of `pThingName`.
|
||||
*
|
||||
* @return `true` if `pThingName` is valid; `false` otherwise.
|
||||
*/
|
||||
bool AwsIot_ValidateThingName( const char * pThingName,
|
||||
size_t thingNameLength );
|
||||
|
||||
/**
|
||||
* @brief Extracts the client token from a JSON document.
|
||||
*
|
||||
* The client token is used to differentiate AWS IoT operations. It is unique per
|
||||
* operation.
|
||||
*
|
||||
* @param[in] pJsonDocument The JSON document to parse.
|
||||
* @param[in] jsonDocumentLength The length of `pJsonDocument`.
|
||||
* @param[out] pClientToken Set to point to the client token in `pJsonDocument`.
|
||||
* @param[out] pClientTokenLength Set to the length of the client token.
|
||||
*
|
||||
* @return `true` if the client token was found; `false` otherwise. The output
|
||||
* parameters are only valid if this function returns `true`.
|
||||
*/
|
||||
bool AwsIot_GetClientToken( const char * pJsonDocument,
|
||||
size_t jsonDocumentLength,
|
||||
const char ** pClientToken,
|
||||
size_t * pClientTokenLength );
|
||||
|
||||
/**
|
||||
* @brief Parse the Thing Name from an MQTT topic.
|
||||
*
|
||||
* @param[in] pTopicName The topic to parse.
|
||||
* @param[in] topicNameLength The length of `pTopicName`.
|
||||
* @param[out] pThingName Set to point to the Thing Name.
|
||||
* @param[out] pThingNameLength Set to the length of the Thing Name.
|
||||
*
|
||||
* @return `true` if a Thing Name was successfully parsed; `false` otherwise. The output
|
||||
* parameters are only valid if this function returns `true`.
|
||||
*/
|
||||
bool AwsIot_ParseThingName( const char * pTopicName,
|
||||
uint16_t topicNameLength,
|
||||
const char ** pThingName,
|
||||
size_t * pThingNameLength );
|
||||
|
||||
/**
|
||||
* @brief Parse the operation status (accepted or rejected) from an MQTT topic.
|
||||
*
|
||||
* @param[in] pTopicName The topic to parse.
|
||||
* @param[in] topicNameLength The length of `pTopicName`.
|
||||
*
|
||||
* @return Any #AwsIotStatus_t.
|
||||
*/
|
||||
AwsIotStatus_t AwsIot_ParseStatus( const char * pTopicName,
|
||||
uint16_t topicNameLength );
|
||||
|
||||
/**
|
||||
* @brief Generate a topic to use for an AWS IoT operation.
|
||||
*
|
||||
* @param[in] pTopicInfo Information needed to generate an AWS IoT topic.
|
||||
* @param[in,out] pTopicBuffer Where to place the generated topic. An existing
|
||||
* buffer may be passed in. If `NULL`, this function will attempt to allocate a
|
||||
* new buffer.
|
||||
* @param[out] pOperationTopicLength Set to the length of the generated topic.
|
||||
*
|
||||
* @warning This function does not check the length of `pTopicBuffer`! Any provided
|
||||
* buffer must be long enough to accommodate the Thing Name, operation name, and
|
||||
* any other suffixes.
|
||||
*
|
||||
* @return `true` if the topic was successfully generated; `false` otherwise.
|
||||
* This function will always succeed when an input buffer is provided.
|
||||
*/
|
||||
bool AwsIot_GenerateOperationTopic( const AwsIotTopicInfo_t * pTopicInfo,
|
||||
char ** pTopicBuffer,
|
||||
uint16_t * pOperationTopicLength );
|
||||
|
||||
/**
|
||||
* @brief Add or remove subscriptions for AWS IoT operations.
|
||||
*
|
||||
* @param[in] mqttOperation Either @ref mqtt_function_subscribesync or
|
||||
* @ref mqtt_function_unsubscribesync.
|
||||
* @param[in] pSubscriptionInfo Information needed to process an MQTT
|
||||
* operation.
|
||||
*
|
||||
* @return See the return values of @ref mqtt_function_subscribesync or
|
||||
* @ref mqtt_function_unsubscribesync.
|
||||
*/
|
||||
IotMqttError_t AwsIot_ModifySubscriptions( AwsIotMqttFunction_t mqttOperation,
|
||||
const AwsIotSubscriptionInfo_t * pSubscriptionInfo );
|
||||
|
||||
#endif /* ifndef AWS_IOT_H_ */
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* AWS IoT 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file aws_iot_doc_parser.h
|
||||
* @brief Parser for AWS IoT Services Documents. This is a JSON parser
|
||||
* specifically designed to process and retrieve a value from a AWS IoT JSON
|
||||
* document, used in AWS IoT libraries such as Shadow and Jobs. Given a key and
|
||||
* a JSON document, AwsIotDocParser_FindValue() will find the first occurrence
|
||||
* of the key and return its respective value. The design goal of this parser
|
||||
* is to be light weight and to be of low memory footprint. However, it does
|
||||
* not check the correctness of the JSON documents. Hence, this parser is not
|
||||
* meant to be used for general purpose JSON parsing.
|
||||
*/
|
||||
|
||||
#ifndef AWS_IOT_DOC_PARSER_H_
|
||||
#define AWS_IOT_DOC_PARSER_H_
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/**
|
||||
* @brief Find a value for a key from a AWS IoT service JSON document.
|
||||
*
|
||||
* @warning The parsing will not check for the correctness of the JSON document.
|
||||
* It is designed to be light weight and to be of low memory footprint rather
|
||||
* than checking for the correctness of the JSON document. Hence this is not
|
||||
* meant to be used for a general purpose JSON parsing. This is recommended to
|
||||
* be used only with mutually authenticated AWS IoT services such as Shadow and
|
||||
* Jobs where the document will always be a well formatted JSON.
|
||||
*
|
||||
* @param[in] pAwsIotJsonDocument Pointer to AWS IoT Service JSON document.
|
||||
* @param[in] awsIotJsonDocumentLength Length of AWS IoT Service JSON document.
|
||||
* @param[in] pAwsIotJsonKey JSON key for finding the associated value.
|
||||
* @param[in] awsIotJsonKeyLength Length of the JSON key.
|
||||
* @param[out] pAwsIotJsonValue Pointer to the pointer of value found.
|
||||
* @param[out] pAwsIotJsonValueLength Pointer to the length of the value found.
|
||||
*
|
||||
* @returns `true` if a value is found, `false` if a value cannot be found. If
|
||||
* returns `false`, the values in out pointers will not be valid.
|
||||
*/
|
||||
bool AwsIotDocParser_FindValue( const char * pAwsIotJsonDocument,
|
||||
size_t awsIotJsonDocumentLength,
|
||||
const char * pAwsIotJsonKey,
|
||||
size_t awsIotJsonKeyLength,
|
||||
const char ** pAwsIotJsonValue,
|
||||
size_t * pAwsIotJsonValueLength );
|
||||
|
||||
#endif /* ifndef AWS_IOT_DOC_PARSER_H_ */
|
|
@ -0,0 +1,294 @@
|
|||
/*
|
||||
* AWS IoT 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file aws_iot_doc_parser.c
|
||||
* @brief Implements the functions in aws_iot_doc_parser.h
|
||||
*/
|
||||
|
||||
/* The config header is always included first. */
|
||||
#include "iot_config.h"
|
||||
|
||||
/* Standard includes. */
|
||||
#include <string.h>
|
||||
|
||||
/* JSON utilities include. */
|
||||
#include "aws_iot_doc_parser.h"
|
||||
|
||||
#define IS_QUOTE( str, idx ) \
|
||||
( ( str )[ ( idx ) ] == '"' && ( ( idx ) == 0 || ( str )[ ( idx ) - 1 ] != '\\' ) )
|
||||
#define IS_WHITESPACE( str, idx ) \
|
||||
( ( str )[ ( idx ) ] == ' ' || ( str )[ ( idx ) ] == '\n' || ( str )[ ( idx ) ] == '\r' || ( str )[ ( idx ) ] == '\t' )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
bool AwsIotDocParser_FindValue( const char * pAwsIotJsonDocument,
|
||||
size_t awsIotJsonDocumentLength,
|
||||
const char * pAwsIotJsonKey,
|
||||
size_t awsIotJsonKeyLength,
|
||||
const char ** pAwsIotJsonValue,
|
||||
size_t * pAwsIotJsonValueLength )
|
||||
{
|
||||
size_t i = 0;
|
||||
size_t jsonValueLength = 0;
|
||||
char openCharacter = '\0', closeCharacter = '\0';
|
||||
int nestingLevel = 0;
|
||||
bool isWithinQuotes = false;
|
||||
|
||||
/* Validate all the arguments.*/
|
||||
if( ( pAwsIotJsonDocument == NULL ) || ( pAwsIotJsonKey == NULL ) ||
|
||||
( awsIotJsonDocumentLength == 0 ) || ( awsIotJsonKeyLength == 0 ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Ensure the JSON document is long enough to contain the key/value pair. At
|
||||
* the very least, a JSON key/value pair must contain the key and the 6
|
||||
* characters {":""} */
|
||||
if( awsIotJsonDocumentLength < awsIotJsonKeyLength + 6 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Search the characters in the JSON document for the key. The end of the JSON
|
||||
* document does not have to be searched once too few characters remain to hold a
|
||||
* value. */
|
||||
while( i < awsIotJsonDocumentLength - awsIotJsonKeyLength - 3 )
|
||||
{
|
||||
/* If the first character in the key is found and there's an unescaped double
|
||||
* quote after the key length, do a string compare for the key. */
|
||||
if( ( IS_QUOTE( pAwsIotJsonDocument, i ) ) &&
|
||||
( IS_QUOTE( pAwsIotJsonDocument, i + 1 + awsIotJsonKeyLength ) ) &&
|
||||
( pAwsIotJsonDocument[ i + 1 ] == pAwsIotJsonKey[ 0 ] ) &&
|
||||
( strncmp( pAwsIotJsonDocument + i + 1,
|
||||
pAwsIotJsonKey,
|
||||
awsIotJsonKeyLength ) == 0 ) )
|
||||
{
|
||||
/* Key found; this is a potential match. */
|
||||
|
||||
/* Skip the characters in the JSON key and closing double quote. */
|
||||
/* While loop guarantees that i < awsIotJsonDocumentLength - 1 */
|
||||
i += awsIotJsonKeyLength + 2;
|
||||
|
||||
/* Skip all whitespace characters between the closing " and the : */
|
||||
while( IS_WHITESPACE( pAwsIotJsonDocument, i ) )
|
||||
{
|
||||
i++;
|
||||
|
||||
/* If the end of the document is reached, this isn't a match. */
|
||||
if( i >= awsIotJsonDocumentLength )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* The character immediately following a key (and any whitespace) must be a :
|
||||
* If it's another character, then this string is a JSON value; skip it. */
|
||||
if( pAwsIotJsonDocument[ i ] != ':' )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Skip the : */
|
||||
i++;
|
||||
}
|
||||
|
||||
/* If the end of the document is reached, this isn't a match. */
|
||||
if( i >= awsIotJsonDocumentLength )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Skip all whitespace characters between : and the first character in the value. */
|
||||
while( IS_WHITESPACE( pAwsIotJsonDocument, i ) )
|
||||
{
|
||||
i++;
|
||||
|
||||
/* If the end of the document is reached, this isn't a match. */
|
||||
if( i >= awsIotJsonDocumentLength )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Value found. Set the output parameter. */
|
||||
if( pAwsIotJsonValue != NULL )
|
||||
{
|
||||
*pAwsIotJsonValue = pAwsIotJsonDocument + i;
|
||||
}
|
||||
|
||||
/* Calculate the value's length. */
|
||||
switch( pAwsIotJsonDocument[ i ] )
|
||||
{
|
||||
/* Calculate length of a JSON string. */
|
||||
case '\"':
|
||||
/* Include the length of the opening and closing double quotes. */
|
||||
jsonValueLength = 2;
|
||||
|
||||
/* Skip the opening double quote. */
|
||||
i++;
|
||||
|
||||
/* If the end of the document is reached, this isn't a match. */
|
||||
if( i >= awsIotJsonDocumentLength )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Add the length of all characters in the JSON string. */
|
||||
while( pAwsIotJsonDocument[ i ] != '\"' )
|
||||
{
|
||||
/* Ignore escaped double quotes. */
|
||||
if( ( pAwsIotJsonDocument[ i ] == '\\' ) &&
|
||||
( i + 1 < awsIotJsonDocumentLength ) &&
|
||||
( pAwsIotJsonDocument[ i + 1 ] == '\"' ) )
|
||||
{
|
||||
/* Skip the characters \" */
|
||||
i += 2;
|
||||
jsonValueLength += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Add the length of a single character. */
|
||||
i++;
|
||||
jsonValueLength++;
|
||||
}
|
||||
|
||||
/* If the end of the document is reached, this isn't a match. */
|
||||
if( i >= awsIotJsonDocumentLength )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
/* Set the matching opening and closing characters of a JSON object or array.
|
||||
* The length calculation is performed below. */
|
||||
case '{':
|
||||
openCharacter = '{';
|
||||
closeCharacter = '}';
|
||||
break;
|
||||
|
||||
case '[':
|
||||
openCharacter = '[';
|
||||
closeCharacter = ']';
|
||||
break;
|
||||
|
||||
/* Calculate the length of a JSON primitive. */
|
||||
default:
|
||||
|
||||
/* Skip the characters in the JSON value. The JSON value ends with a , or } */
|
||||
while( pAwsIotJsonDocument[ i ] != ',' &&
|
||||
pAwsIotJsonDocument[ i ] != '}' )
|
||||
{
|
||||
/* Any whitespace before a , or } means the JSON document is invalid. */
|
||||
if( IS_WHITESPACE( pAwsIotJsonDocument, i ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
i++;
|
||||
jsonValueLength++;
|
||||
|
||||
/* If the end of the document is reached, this isn't a match. */
|
||||
if( i >= awsIotJsonDocumentLength )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Calculate the length of a JSON object or array. */
|
||||
if( ( openCharacter != '\0' ) && ( closeCharacter != '\0' ) )
|
||||
{
|
||||
/* Include the length of the opening and closing characters. */
|
||||
jsonValueLength = 2;
|
||||
|
||||
/* Skip the opening character. */
|
||||
i++;
|
||||
|
||||
/* If the end of the document is reached, this isn't a match. */
|
||||
if( i >= awsIotJsonDocumentLength )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Add the length of all characters in the JSON object or array. This
|
||||
* includes the length of nested objects. */
|
||||
while( pAwsIotJsonDocument[ i ] != closeCharacter ||
|
||||
( pAwsIotJsonDocument[ i ] == closeCharacter && ( nestingLevel != 0 || isWithinQuotes ) ) )
|
||||
{
|
||||
/* Check if its a quote so as to avoid considering the
|
||||
* nested levels for opening and closing characters within
|
||||
* quotes.
|
||||
*/
|
||||
if( IS_QUOTE( pAwsIotJsonDocument, i ) )
|
||||
{
|
||||
/*Toggle the flag*/
|
||||
isWithinQuotes = !isWithinQuotes;
|
||||
}
|
||||
|
||||
/* Calculate the nesting levels only if not in quotes. */
|
||||
if( !isWithinQuotes )
|
||||
{
|
||||
/* An opening character starts a nested object. */
|
||||
if( pAwsIotJsonDocument[ i ] == openCharacter )
|
||||
{
|
||||
nestingLevel++;
|
||||
}
|
||||
/* A closing character ends a nested object. */
|
||||
else if( pAwsIotJsonDocument[ i ] == closeCharacter )
|
||||
{
|
||||
nestingLevel--;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
jsonValueLength++;
|
||||
|
||||
/* If the end of the document is reached, this isn't a match. */
|
||||
if( i >= awsIotJsonDocumentLength )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* JSON value length calculated; set the output parameter. */
|
||||
if( pAwsIotJsonValueLength != NULL )
|
||||
{
|
||||
*pAwsIotJsonValueLength = jsonValueLength;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* AWS IoT Common 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file aws_iot_operation.c
|
||||
* @brief Functions for common AWS IoT operations.
|
||||
*/
|
||||
|
||||
/* The config header is always included first. */
|
||||
#include "iot_config.h"
|
||||
|
||||
/* Standard includes. */
|
||||
#include <string.h>
|
||||
|
||||
/* Platform threads include. */
|
||||
#include "platform/iot_threads.h"
|
||||
|
||||
/* AWS IoT include. */
|
||||
#include "aws_iot.h"
|
||||
|
||||
/* Error handling include. */
|
||||
#include "iot_error.h"
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
bool AwsIot_InitLists( IotListDouble_t * pPendingOperationsList,
|
||||
IotListDouble_t * pSubscriptionsList,
|
||||
IotMutex_t * pPendingOperationsMutex,
|
||||
IotMutex_t * pSubscriptionsMutex )
|
||||
{
|
||||
IOT_FUNCTION_ENTRY( bool, true );
|
||||
|
||||
/* Flags to track cleanup. */
|
||||
bool operationsMutexCreated = false;
|
||||
bool subscriptionsMutexCreated = false;
|
||||
|
||||
/* Create the mutex guarding the pending operations list. */
|
||||
operationsMutexCreated = IotMutex_Create( pPendingOperationsMutex, false );
|
||||
|
||||
if( operationsMutexCreated == false )
|
||||
{
|
||||
IOT_SET_AND_GOTO_CLEANUP( false );
|
||||
}
|
||||
|
||||
/* Create the mutex guarding the subscriptions list. */
|
||||
subscriptionsMutexCreated = IotMutex_Create( pSubscriptionsMutex, false );
|
||||
|
||||
if( subscriptionsMutexCreated == false )
|
||||
{
|
||||
IOT_SET_AND_GOTO_CLEANUP( false );
|
||||
}
|
||||
|
||||
/* Initialize lists. */
|
||||
IotListDouble_Create( pPendingOperationsList );
|
||||
IotListDouble_Create( pSubscriptionsList );
|
||||
|
||||
IOT_FUNCTION_CLEANUP_BEGIN();
|
||||
|
||||
/* Clean up on error. */
|
||||
if( status == false )
|
||||
{
|
||||
if( operationsMutexCreated == true )
|
||||
{
|
||||
IotMutex_Destroy( pPendingOperationsMutex );
|
||||
}
|
||||
}
|
||||
|
||||
IOT_FUNCTION_CLEANUP_END();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
bool AwsIot_GenerateOperationTopic( const AwsIotTopicInfo_t * pTopicInfo,
|
||||
char ** pTopicBuffer,
|
||||
uint16_t * pOperationTopicLength )
|
||||
{
|
||||
bool status = true;
|
||||
uint16_t bufferLength = 0;
|
||||
uint16_t operationTopicLength = 0;
|
||||
char * pBuffer = NULL;
|
||||
|
||||
/* Calculate the required topic buffer length. */
|
||||
bufferLength = ( uint16_t ) ( AWS_IOT_TOPIC_PREFIX_LENGTH +
|
||||
pTopicInfo->thingNameLength +
|
||||
pTopicInfo->operationNameLength +
|
||||
pTopicInfo->longestSuffixLength );
|
||||
|
||||
/* Allocate memory for the topic buffer if no topic buffer is given. */
|
||||
if( *pTopicBuffer == NULL )
|
||||
{
|
||||
pBuffer = pTopicInfo->mallocString( ( size_t ) bufferLength );
|
||||
|
||||
if( pBuffer == NULL )
|
||||
{
|
||||
status = false;
|
||||
}
|
||||
}
|
||||
/* Otherwise, use the given topic buffer. */
|
||||
else
|
||||
{
|
||||
pBuffer = *pTopicBuffer;
|
||||
}
|
||||
|
||||
if( status == true )
|
||||
{
|
||||
/* Copy the AWS IoT topic prefix into the topic buffer. */
|
||||
( void ) memcpy( pBuffer, AWS_IOT_TOPIC_PREFIX, AWS_IOT_TOPIC_PREFIX_LENGTH );
|
||||
operationTopicLength = ( uint16_t ) ( operationTopicLength + AWS_IOT_TOPIC_PREFIX_LENGTH );
|
||||
|
||||
/* Copy the Thing Name into the topic buffer. */
|
||||
( void ) memcpy( pBuffer + operationTopicLength,
|
||||
pTopicInfo->pThingName,
|
||||
pTopicInfo->thingNameLength );
|
||||
operationTopicLength = ( uint16_t ) ( operationTopicLength + pTopicInfo->thingNameLength );
|
||||
|
||||
/* Copy the Shadow operation string into the topic buffer. */
|
||||
( void ) memcpy( pBuffer + operationTopicLength,
|
||||
pTopicInfo->pOperationName,
|
||||
pTopicInfo->operationNameLength );
|
||||
operationTopicLength = ( uint16_t ) ( operationTopicLength + pTopicInfo->operationNameLength );
|
||||
|
||||
/* Set the output parameters. */
|
||||
if( *pTopicBuffer == NULL )
|
||||
{
|
||||
*pTopicBuffer = pBuffer;
|
||||
}
|
||||
|
||||
*pOperationTopicLength = operationTopicLength;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* AWS IoT Common 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file aws_iot_parser.c
|
||||
* @brief Parses topics for Thing Name and status.
|
||||
*/
|
||||
|
||||
/* The config header is always included first. */
|
||||
#include "iot_config.h"
|
||||
|
||||
/* Standard includes. */
|
||||
#include <string.h>
|
||||
|
||||
/* AWS IoT include. */
|
||||
#include "aws_iot.h"
|
||||
|
||||
/* Error handling include. */
|
||||
#include "iot_error.h"
|
||||
|
||||
/* AWS Parser include. */
|
||||
#include "aws_iot_doc_parser.h"
|
||||
|
||||
/**
|
||||
* @brief Minimum allowed topic length for an AWS IoT status topic.
|
||||
*
|
||||
* Topics must contain at least:
|
||||
* - The common prefix
|
||||
* - The suffix "/accepted" or "/rejected"
|
||||
* - 1 character for the Thing Name
|
||||
* - 2 characters for the operation name and the enclosing slashes
|
||||
*/
|
||||
#define MINIMUM_TOPIC_NAME_LENGTH \
|
||||
( uint16_t ) ( AWS_IOT_TOPIC_PREFIX_LENGTH + \
|
||||
AWS_IOT_ACCEPTED_SUFFIX_LENGTH + \
|
||||
1 + 2 )
|
||||
|
||||
/**
|
||||
* @brief The longest client token accepted by AWS IoT service, per AWS IoT
|
||||
* service limits.
|
||||
*/
|
||||
#define MAX_CLIENT_TOKEN_LENGTH ( 64 )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
bool AwsIot_GetClientToken( const char * pJsonDocument,
|
||||
size_t jsonDocumentLength,
|
||||
const char ** pClientToken,
|
||||
size_t * pClientTokenLength )
|
||||
{
|
||||
/* Extract the client token from the JSON document. */
|
||||
bool status = AwsIotDocParser_FindValue( pJsonDocument,
|
||||
jsonDocumentLength,
|
||||
AWS_IOT_CLIENT_TOKEN_KEY,
|
||||
AWS_IOT_CLIENT_TOKEN_KEY_LENGTH,
|
||||
pClientToken,
|
||||
pClientTokenLength );
|
||||
|
||||
if( status == true )
|
||||
{
|
||||
/* Check that the length of the client token is valid. */
|
||||
if( ( *pClientTokenLength < 2 ) ||
|
||||
( *pClientTokenLength > MAX_CLIENT_TOKEN_LENGTH ) )
|
||||
{
|
||||
status = false;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
bool AwsIot_ParseThingName( const char * pTopicName,
|
||||
uint16_t topicNameLength,
|
||||
const char ** pThingName,
|
||||
size_t * pThingNameLength )
|
||||
{
|
||||
IOT_FUNCTION_ENTRY( bool, true );
|
||||
const char * pThingNameStart = NULL;
|
||||
size_t thingNameLength = 0;
|
||||
|
||||
/* Check that the topic name is at least as long as the minimum allowed. */
|
||||
if( topicNameLength < MINIMUM_TOPIC_NAME_LENGTH )
|
||||
{
|
||||
IOT_SET_AND_GOTO_CLEANUP( false );
|
||||
}
|
||||
|
||||
/* Check that the given topic starts with the common prefix. */
|
||||
if( strncmp( AWS_IOT_TOPIC_PREFIX,
|
||||
pTopicName,
|
||||
AWS_IOT_TOPIC_PREFIX_LENGTH ) != 0 )
|
||||
{
|
||||
IOT_SET_AND_GOTO_CLEANUP( false );
|
||||
}
|
||||
|
||||
/* The Thing Name starts immediately after the topic prefix. */
|
||||
pThingNameStart = pTopicName + AWS_IOT_TOPIC_PREFIX_LENGTH;
|
||||
|
||||
/* Calculate the length of the Thing Name, which is terminated with a '/'. */
|
||||
while( ( thingNameLength + AWS_IOT_TOPIC_PREFIX_LENGTH < ( size_t ) topicNameLength ) &&
|
||||
( pThingNameStart[ thingNameLength ] != '/' ) )
|
||||
{
|
||||
thingNameLength++;
|
||||
}
|
||||
|
||||
/* The end of the topic name was reached without finding a '/'. The topic
|
||||
* name is invalid. */
|
||||
if( thingNameLength + AWS_IOT_TOPIC_PREFIX_LENGTH >= ( size_t ) topicNameLength )
|
||||
{
|
||||
IOT_SET_AND_GOTO_CLEANUP( false );
|
||||
}
|
||||
|
||||
/* Set the output parameters. */
|
||||
*pThingName = pThingNameStart;
|
||||
*pThingNameLength = thingNameLength;
|
||||
|
||||
IOT_FUNCTION_EXIT_NO_CLEANUP();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
AwsIotStatus_t AwsIot_ParseStatus( const char * pTopicName,
|
||||
uint16_t topicNameLength )
|
||||
{
|
||||
IOT_FUNCTION_ENTRY( AwsIotStatus_t, AWS_IOT_UNKNOWN );
|
||||
const char * pSuffixStart = NULL;
|
||||
|
||||
/* Both 'accepted' and 'rejected' topics are of the same length
|
||||
* The below is a defensive check at run time to ensure that.
|
||||
*/
|
||||
Iot_DefaultAssert( AWS_IOT_ACCEPTED_SUFFIX_LENGTH == AWS_IOT_REJECTED_SUFFIX_LENGTH );
|
||||
|
||||
/* Check that the status topic name is at least as long as the
|
||||
* "accepted" suffix. This length check will be good for rejected also
|
||||
* as both are of 8 characters in length. */
|
||||
if( topicNameLength > AWS_IOT_ACCEPTED_SUFFIX_LENGTH )
|
||||
{
|
||||
/* Calculate where the "accepted" suffix should start. */
|
||||
pSuffixStart = pTopicName + topicNameLength - AWS_IOT_ACCEPTED_SUFFIX_LENGTH;
|
||||
|
||||
/* Check if the end of the status topic name is "/accepted". */
|
||||
if( strncmp( pSuffixStart,
|
||||
AWS_IOT_ACCEPTED_SUFFIX,
|
||||
AWS_IOT_ACCEPTED_SUFFIX_LENGTH ) == 0 )
|
||||
{
|
||||
IOT_SET_AND_GOTO_CLEANUP( AWS_IOT_ACCEPTED );
|
||||
}
|
||||
|
||||
/* Check if the end of the status topic name is "/rejected". */
|
||||
if( strncmp( pSuffixStart,
|
||||
AWS_IOT_REJECTED_SUFFIX,
|
||||
AWS_IOT_REJECTED_SUFFIX_LENGTH ) == 0 )
|
||||
{
|
||||
IOT_SET_AND_GOTO_CLEANUP( AWS_IOT_REJECTED );
|
||||
}
|
||||
}
|
||||
|
||||
IOT_FUNCTION_EXIT_NO_CLEANUP();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* AWS IoT Common 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file aws_iot_subscription.c
|
||||
* @brief Functions for common AWS IoT subscriptions.
|
||||
*/
|
||||
|
||||
/* The config header is always included first. */
|
||||
#include "iot_config.h"
|
||||
|
||||
/* Standard includes. */
|
||||
#include <string.h>
|
||||
|
||||
/* AWS IoT include. */
|
||||
#include "aws_iot.h"
|
||||
|
||||
/* Error handling include. */
|
||||
#include "iot_error.h"
|
||||
|
||||
/* MQTT include. */
|
||||
#include "iot_mqtt.h"
|
||||
|
||||
/**
|
||||
* @brief Modify subscriptions, either by unsubscribing or subscribing.
|
||||
*
|
||||
* @param[in] mqttOperation Either @ref mqtt_function_subscribesync or @ref
|
||||
* mqtt_function_unsubscribesync.
|
||||
* @param[in] pSubscriptionInfo Information needed to process an MQTT
|
||||
* operation.
|
||||
* @param[in] pTopicFilter The topic filter to modify.
|
||||
* @param[in] topicFilterLength The length of `pTopicFilter`.
|
||||
*
|
||||
* @return See the return values of @ref mqtt_function_subscribesync or
|
||||
* @ref mqtt_function_unsubscribesync.
|
||||
*/
|
||||
static IotMqttError_t _modifySubscriptions( AwsIotMqttFunction_t mqttOperation,
|
||||
const AwsIotSubscriptionInfo_t * pSubscriptionInfo,
|
||||
const char * pTopicFilter,
|
||||
uint16_t topicFilterLength );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static IotMqttError_t _modifySubscriptions( AwsIotMqttFunction_t mqttOperation,
|
||||
const AwsIotSubscriptionInfo_t * pSubscriptionInfo,
|
||||
const char * pTopicFilter,
|
||||
uint16_t topicFilterLength )
|
||||
{
|
||||
IotMqttError_t status = IOT_MQTT_STATUS_PENDING;
|
||||
IotMqttSubscription_t subscription = IOT_MQTT_SUBSCRIPTION_INITIALIZER;
|
||||
|
||||
/* Per the AWS IoT documentation, topic subscriptions are QoS 1. */
|
||||
subscription.qos = IOT_MQTT_QOS_1;
|
||||
|
||||
/* Set the members of the subscription parameter. */
|
||||
subscription.pTopicFilter = pTopicFilter;
|
||||
subscription.topicFilterLength = topicFilterLength;
|
||||
subscription.callback.pCallbackContext = NULL;
|
||||
subscription.callback.function = pSubscriptionInfo->callbackFunction;
|
||||
|
||||
/* Call the MQTT operation function.
|
||||
* Subscription count is 1 in this case.
|
||||
* None of the flags are set in this call. Hence 0 is passed for flags.
|
||||
* Please refer to documentation for AwsIotMqttFunction_t for more details.
|
||||
*/
|
||||
status = mqttOperation( pSubscriptionInfo->mqttConnection,
|
||||
&subscription,
|
||||
1,
|
||||
0,
|
||||
pSubscriptionInfo->timeout );
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
IotMqttError_t AwsIot_ModifySubscriptions( AwsIotMqttFunction_t mqttOperation,
|
||||
const AwsIotSubscriptionInfo_t * pSubscriptionInfo )
|
||||
{
|
||||
IOT_FUNCTION_ENTRY( IotMqttError_t, IOT_MQTT_STATUS_PENDING );
|
||||
IotMqttError_t acceptedStatus = IOT_MQTT_STATUS_PENDING;
|
||||
uint16_t topicFilterLength = 0;
|
||||
|
||||
/* Place the topic "accepted" suffix at the end of the topic buffer. */
|
||||
( void ) memcpy( pSubscriptionInfo->pTopicFilterBase
|
||||
+ pSubscriptionInfo->topicFilterBaseLength,
|
||||
AWS_IOT_ACCEPTED_SUFFIX,
|
||||
AWS_IOT_ACCEPTED_SUFFIX_LENGTH );
|
||||
topicFilterLength = ( uint16_t ) ( pSubscriptionInfo->topicFilterBaseLength
|
||||
+ AWS_IOT_ACCEPTED_SUFFIX_LENGTH );
|
||||
|
||||
/* Modify the subscription to the "accepted" topic. */
|
||||
acceptedStatus = _modifySubscriptions( mqttOperation,
|
||||
pSubscriptionInfo,
|
||||
pSubscriptionInfo->pTopicFilterBase,
|
||||
topicFilterLength );
|
||||
|
||||
if( acceptedStatus != IOT_MQTT_SUCCESS )
|
||||
{
|
||||
IOT_SET_AND_GOTO_CLEANUP( acceptedStatus );
|
||||
}
|
||||
|
||||
/* Place the topic "rejected" suffix at the end of the topic buffer. */
|
||||
( void ) memcpy( pSubscriptionInfo->pTopicFilterBase
|
||||
+ pSubscriptionInfo->topicFilterBaseLength,
|
||||
AWS_IOT_REJECTED_SUFFIX,
|
||||
AWS_IOT_REJECTED_SUFFIX_LENGTH );
|
||||
topicFilterLength = ( uint16_t ) ( pSubscriptionInfo->topicFilterBaseLength
|
||||
+ AWS_IOT_REJECTED_SUFFIX_LENGTH );
|
||||
|
||||
/* Modify the subscription to the "rejected" topic. */
|
||||
status = _modifySubscriptions( mqttOperation,
|
||||
pSubscriptionInfo,
|
||||
pSubscriptionInfo->pTopicFilterBase,
|
||||
topicFilterLength );
|
||||
|
||||
IOT_FUNCTION_CLEANUP_BEGIN();
|
||||
|
||||
/* Clean up on error. */
|
||||
if( status != IOT_MQTT_SUCCESS )
|
||||
{
|
||||
/* Remove the subscription to the "accepted" topic if the subscription
|
||||
* to the "rejected" topic failed. */
|
||||
if( ( mqttOperation == IotMqtt_SubscribeSync ) &&
|
||||
( acceptedStatus == IOT_MQTT_SUCCESS ) )
|
||||
{
|
||||
/* Place the topic "accepted" suffix at the end of the topic buffer. */
|
||||
( void ) memcpy( pSubscriptionInfo->pTopicFilterBase
|
||||
+ pSubscriptionInfo->topicFilterBaseLength,
|
||||
AWS_IOT_ACCEPTED_SUFFIX,
|
||||
AWS_IOT_ACCEPTED_SUFFIX_LENGTH );
|
||||
topicFilterLength = ( uint16_t ) ( pSubscriptionInfo->topicFilterBaseLength
|
||||
+ AWS_IOT_ACCEPTED_SUFFIX_LENGTH );
|
||||
|
||||
( void ) _modifySubscriptions( IotMqtt_UnsubscribeSync,
|
||||
pSubscriptionInfo,
|
||||
pSubscriptionInfo->pTopicFilterBase,
|
||||
topicFilterLength );
|
||||
}
|
||||
}
|
||||
|
||||
IOT_FUNCTION_CLEANUP_END();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* AWS IoT Common 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file aws_iot_validate.c
|
||||
* @brief Validates Thing Names and other parameters to AWS IoT.
|
||||
*/
|
||||
|
||||
/* The config header is always included first. */
|
||||
#include "iot_config.h"
|
||||
|
||||
/* AWS IoT include. */
|
||||
#include "aws_iot.h"
|
||||
|
||||
/* Error handling include. */
|
||||
#include "iot_error.h"
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
bool AwsIot_ValidateThingName( const char * pThingName,
|
||||
size_t thingNameLength )
|
||||
{
|
||||
IOT_FUNCTION_ENTRY( bool, true );
|
||||
|
||||
if( pThingName == NULL )
|
||||
{
|
||||
IOT_SET_AND_GOTO_CLEANUP( false );
|
||||
}
|
||||
|
||||
if( thingNameLength == 0 )
|
||||
{
|
||||
IOT_SET_AND_GOTO_CLEANUP( false );
|
||||
}
|
||||
|
||||
if( thingNameLength > AWS_IOT_MAX_THING_NAME_LENGTH )
|
||||
{
|
||||
IOT_SET_AND_GOTO_CLEANUP( false );
|
||||
}
|
||||
|
||||
IOT_FUNCTION_EXIT_NO_CLEANUP();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
Loading…
Add table
Add a link
Reference in a new issue