summaryrefslogtreecommitdiff
path: root/FreeRTOS-Labs/Source/FreeRTOS-IoT-Libraries/c_sdk/aws/common/src/aws_iot_parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'FreeRTOS-Labs/Source/FreeRTOS-IoT-Libraries/c_sdk/aws/common/src/aws_iot_parser.c')
-rw-r--r--FreeRTOS-Labs/Source/FreeRTOS-IoT-Libraries/c_sdk/aws/common/src/aws_iot_parser.c181
1 files changed, 181 insertions, 0 deletions
diff --git a/FreeRTOS-Labs/Source/FreeRTOS-IoT-Libraries/c_sdk/aws/common/src/aws_iot_parser.c b/FreeRTOS-Labs/Source/FreeRTOS-IoT-Libraries/c_sdk/aws/common/src/aws_iot_parser.c
new file mode 100644
index 000000000..0ebed63e4
--- /dev/null
+++ b/FreeRTOS-Labs/Source/FreeRTOS-IoT-Libraries/c_sdk/aws/common/src/aws_iot_parser.c
@@ -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();
+}
+
+/*-----------------------------------------------------------*/