]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS-Labs/Source/FreeRTOS-IoT-Libraries/c_sdk/aws/common/src/aws_iot_parser.c
Add the Labs projects provided in the V10.2.1_191129 zip file.
[freertos] / FreeRTOS-Labs / Source / FreeRTOS-IoT-Libraries / c_sdk / aws / common / src / aws_iot_parser.c
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 (file)
index 0000000..0ebed63
--- /dev/null
@@ -0,0 +1,181 @@
+/*\r
+ * AWS IoT Common V1.0.0\r
+ * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
+ * this software and associated documentation files (the "Software"), to deal in\r
+ * the Software without restriction, including without limitation the rights to\r
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
+ * the Software, and to permit persons to whom the Software is furnished to do so,\r
+ * subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ */\r
+\r
+/**\r
+ * @file aws_iot_parser.c\r
+ * @brief Parses topics for Thing Name and status.\r
+ */\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/* Standard includes. */\r
+#include <string.h>\r
+\r
+/* AWS IoT include. */\r
+#include "aws_iot.h"\r
+\r
+/* Error handling include. */\r
+#include "iot_error.h"\r
+\r
+/* AWS Parser include. */\r
+#include "aws_iot_doc_parser.h"\r
+\r
+/**\r
+ * @brief Minimum allowed topic length for an AWS IoT status topic.\r
+ *\r
+ * Topics must contain at least:\r
+ * - The common prefix\r
+ * - The suffix "/accepted" or "/rejected"\r
+ * - 1 character for the Thing Name\r
+ * - 2 characters for the operation name and the enclosing slashes\r
+ */\r
+#define MINIMUM_TOPIC_NAME_LENGTH                   \\r
+    ( uint16_t ) ( AWS_IOT_TOPIC_PREFIX_LENGTH +    \\r
+                   AWS_IOT_ACCEPTED_SUFFIX_LENGTH + \\r
+                   1 + 2 )\r
+\r
+/**\r
+ * @brief The longest client token accepted by AWS IoT service, per AWS IoT\r
+ * service limits.\r
+ */\r
+#define MAX_CLIENT_TOKEN_LENGTH    ( 64 )\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+bool AwsIot_GetClientToken( const char * pJsonDocument,\r
+                            size_t jsonDocumentLength,\r
+                            const char ** pClientToken,\r
+                            size_t * pClientTokenLength )\r
+{\r
+    /* Extract the client token from the JSON document. */\r
+    bool status = AwsIotDocParser_FindValue( pJsonDocument,\r
+                                             jsonDocumentLength,\r
+                                             AWS_IOT_CLIENT_TOKEN_KEY,\r
+                                             AWS_IOT_CLIENT_TOKEN_KEY_LENGTH,\r
+                                             pClientToken,\r
+                                             pClientTokenLength );\r
+\r
+    if( status == true )\r
+    {\r
+        /* Check that the length of the client token is valid. */\r
+        if( ( *pClientTokenLength < 2 ) ||\r
+            ( *pClientTokenLength > MAX_CLIENT_TOKEN_LENGTH ) )\r
+        {\r
+            status = false;\r
+        }\r
+    }\r
+\r
+    return status;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+bool AwsIot_ParseThingName( const char * pTopicName,\r
+                            uint16_t topicNameLength,\r
+                            const char ** pThingName,\r
+                            size_t * pThingNameLength )\r
+{\r
+    IOT_FUNCTION_ENTRY( bool, true );\r
+    const char * pThingNameStart = NULL;\r
+    size_t thingNameLength = 0;\r
+\r
+    /* Check that the topic name is at least as long as the minimum allowed. */\r
+    if( topicNameLength < MINIMUM_TOPIC_NAME_LENGTH )\r
+    {\r
+        IOT_SET_AND_GOTO_CLEANUP( false );\r
+    }\r
+\r
+    /* Check that the given topic starts with the common prefix. */\r
+    if( strncmp( AWS_IOT_TOPIC_PREFIX,\r
+                 pTopicName,\r
+                 AWS_IOT_TOPIC_PREFIX_LENGTH ) != 0 )\r
+    {\r
+        IOT_SET_AND_GOTO_CLEANUP( false );\r
+    }\r
+\r
+    /* The Thing Name starts immediately after the topic prefix. */\r
+    pThingNameStart = pTopicName + AWS_IOT_TOPIC_PREFIX_LENGTH;\r
+\r
+    /* Calculate the length of the Thing Name, which is terminated with a '/'. */\r
+    while( ( thingNameLength + AWS_IOT_TOPIC_PREFIX_LENGTH < ( size_t ) topicNameLength ) &&\r
+           ( pThingNameStart[ thingNameLength ] != '/' ) )\r
+    {\r
+        thingNameLength++;\r
+    }\r
+\r
+    /* The end of the topic name was reached without finding a '/'. The topic\r
+     * name is invalid. */\r
+    if( thingNameLength + AWS_IOT_TOPIC_PREFIX_LENGTH >= ( size_t ) topicNameLength )\r
+    {\r
+        IOT_SET_AND_GOTO_CLEANUP( false );\r
+    }\r
+\r
+    /* Set the output parameters. */\r
+    *pThingName = pThingNameStart;\r
+    *pThingNameLength = thingNameLength;\r
+\r
+    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+AwsIotStatus_t AwsIot_ParseStatus( const char * pTopicName,\r
+                                   uint16_t topicNameLength )\r
+{\r
+    IOT_FUNCTION_ENTRY( AwsIotStatus_t, AWS_IOT_UNKNOWN );\r
+    const char * pSuffixStart = NULL;\r
+\r
+    /* Both 'accepted' and  'rejected' topics are of the same length\r
+     * The below is a defensive check at run time to ensure that.\r
+     */\r
+    Iot_DefaultAssert( AWS_IOT_ACCEPTED_SUFFIX_LENGTH == AWS_IOT_REJECTED_SUFFIX_LENGTH );\r
+\r
+    /* Check that the status topic name is at least as long as the\r
+     * "accepted" suffix. This length check will be good for rejected also\r
+     * as both are of 8 characters in length. */\r
+    if( topicNameLength > AWS_IOT_ACCEPTED_SUFFIX_LENGTH )\r
+    {\r
+        /* Calculate where the "accepted" suffix should start. */\r
+        pSuffixStart = pTopicName + topicNameLength - AWS_IOT_ACCEPTED_SUFFIX_LENGTH;\r
+\r
+        /* Check if the end of the status topic name is "/accepted". */\r
+        if( strncmp( pSuffixStart,\r
+                     AWS_IOT_ACCEPTED_SUFFIX,\r
+                     AWS_IOT_ACCEPTED_SUFFIX_LENGTH ) == 0 )\r
+        {\r
+            IOT_SET_AND_GOTO_CLEANUP( AWS_IOT_ACCEPTED );\r
+        }\r
+\r
+        /* Check if the end of the status topic name is "/rejected". */\r
+        if( strncmp( pSuffixStart,\r
+                     AWS_IOT_REJECTED_SUFFIX,\r
+                     AWS_IOT_REJECTED_SUFFIX_LENGTH ) == 0 )\r
+        {\r
+            IOT_SET_AND_GOTO_CLEANUP( AWS_IOT_REJECTED );\r
+        }\r
+    }\r
+\r
+    IOT_FUNCTION_EXIT_NO_CLEANUP();\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r