]> git.sur5r.net Git - freertos/blob - FreeRTOS-Labs/Source/FreeRTOS-IoT-Libraries/c_sdk/aws/shadow/src/aws_iot_shadow_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 / shadow / src / aws_iot_shadow_parser.c
1 /*\r
2  * AWS IoT Shadow V2.1.0\r
3  * Copyright (C) 2018 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6  * this software and associated documentation files (the "Software"), to deal in\r
7  * the Software without restriction, including without limitation the rights to\r
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9  * the Software, and to permit persons to whom the Software is furnished to do so,\r
10  * subject to the following conditions:\r
11  *\r
12  * The above copyright notice and this permission notice shall be included in all\r
13  * copies or substantial portions of the Software.\r
14  *\r
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
21  */\r
22 \r
23 /**\r
24  * @file aws_iot_shadow_parser.c\r
25  * @brief Implements JSON parsing functions of the Shadow library.\r
26  */\r
27 \r
28 /* The config header is always included first. */\r
29 #include "iot_config.h"\r
30 \r
31 /* Standard includes. */\r
32 #include <stdlib.h>\r
33 #include <string.h>\r
34 \r
35 /* Shadow internal include. */\r
36 #include "private/aws_iot_shadow_internal.h"\r
37 \r
38 /* Error handling include. */\r
39 #include "iot_error.h"\r
40 \r
41 /* AWS Parser include. */\r
42 #include "aws_iot_doc_parser.h"\r
43 \r
44 /*-----------------------------------------------------------*/\r
45 \r
46 /**\r
47  * @brief The JSON key for the error code in a Shadow error document.\r
48  */\r
49 #define ERROR_DOCUMENT_CODE_KEY              "code"\r
50 \r
51 /**\r
52  * @brief The length of #ERROR_DOCUMENT_CODE_KEY.\r
53  */\r
54 #define ERROR_DOCUMENT_CODE_KEY_LENGTH       ( sizeof( ERROR_DOCUMENT_CODE_KEY ) - 1 )\r
55 \r
56 /**\r
57  * @brief The JSON key for the error message in a Shadow error document.\r
58  */\r
59 #define ERROR_DOCUMENT_MESSAGE_KEY           "message"\r
60 \r
61 /**\r
62  * @brief The length of #ERROR_DOCUMENT_MESSAGE_KEY.\r
63  */\r
64 #define ERROR_DOCUMENT_MESSAGE_KEY_LENGTH    ( sizeof( ERROR_DOCUMENT_MESSAGE_KEY ) - 1 )\r
65 \r
66 /*-----------------------------------------------------------*/\r
67 \r
68 /**\r
69  * @brief Converts a `unsigned long` to an `AwsIotShadowError_t`.\r
70  *\r
71  * @param[in] code A value between 400 and 500 to convert.\r
72  *\r
73  * @return A corresponding #AwsIotShadowError_t; #AWS_IOT_SHADOW_BAD_RESPONSE\r
74  * if `code` is unknown.\r
75  */\r
76 static AwsIotShadowError_t _codeToShadowStatus( uint32_t code );\r
77 \r
78 /*-----------------------------------------------------------*/\r
79 \r
80 static AwsIotShadowError_t _codeToShadowStatus( uint32_t code )\r
81 {\r
82     AwsIotShadowError_t errorCode = AWS_IOT_SHADOW_STATUS_PENDING;\r
83 \r
84     /* Convert the Shadow response code to an AwsIotShadowError_t. */\r
85     switch( code )\r
86     {\r
87         case 400UL:\r
88             errorCode = AWS_IOT_SHADOW_BAD_REQUEST;\r
89             break;\r
90 \r
91         case 401UL:\r
92             errorCode = AWS_IOT_SHADOW_UNAUTHORIZED;\r
93             break;\r
94 \r
95         case 403UL:\r
96             errorCode = AWS_IOT_SHADOW_FORBIDDEN;\r
97             break;\r
98 \r
99         case 404UL:\r
100             errorCode = AWS_IOT_SHADOW_NOT_FOUND;\r
101             break;\r
102 \r
103         case 409UL:\r
104             errorCode = AWS_IOT_SHADOW_CONFLICT;\r
105             break;\r
106 \r
107         case 413UL:\r
108             errorCode = AWS_IOT_SHADOW_TOO_LARGE;\r
109             break;\r
110 \r
111         case 415UL:\r
112             errorCode = AWS_IOT_SHADOW_UNSUPPORTED;\r
113             break;\r
114 \r
115         case 429UL:\r
116             errorCode = AWS_IOT_SHADOW_TOO_MANY_REQUESTS;\r
117             break;\r
118 \r
119         case 500UL:\r
120             errorCode = AWS_IOT_SHADOW_SERVER_ERROR;\r
121             break;\r
122 \r
123         default:\r
124             errorCode = AWS_IOT_SHADOW_BAD_RESPONSE;\r
125             break;\r
126     }\r
127 \r
128     return errorCode;\r
129 }\r
130 \r
131 /*-----------------------------------------------------------*/\r
132 \r
133 AwsIotShadowError_t _AwsIotShadow_ParseErrorDocument( const char * pErrorDocument,\r
134                                                       size_t errorDocumentLength )\r
135 {\r
136     IOT_FUNCTION_ENTRY( AwsIotShadowError_t, AWS_IOT_SHADOW_STATUS_PENDING );\r
137     const char * pCode = NULL, * pMessage = NULL;\r
138     size_t codeLength = 0, messageLength = 0;\r
139     uint32_t code = 0;\r
140 \r
141     /* Parse the code from the error document. */\r
142     if( AwsIotDocParser_FindValue( pErrorDocument,\r
143                                    errorDocumentLength,\r
144                                    ERROR_DOCUMENT_CODE_KEY,\r
145                                    ERROR_DOCUMENT_CODE_KEY_LENGTH,\r
146                                    &pCode,\r
147                                    &codeLength ) == false )\r
148     {\r
149         /* Error parsing JSON document, or no "code" key was found. */\r
150         IotLogWarn( "Failed to parse code from error document.\n%.*s",\r
151                     errorDocumentLength,\r
152                     pErrorDocument );\r
153 \r
154         IOT_SET_AND_GOTO_CLEANUP( AWS_IOT_SHADOW_BAD_RESPONSE );\r
155     }\r
156 \r
157     /* Code must be in error document. */\r
158     AwsIotShadow_Assert( ( pCode > pErrorDocument ) &&\r
159                          ( pCode + codeLength < pErrorDocument + errorDocumentLength ) );\r
160 \r
161     /* Convert the code to an unsigned integer value. */\r
162     code = ( uint32_t ) strtoul( pCode, NULL, 10 );\r
163 \r
164     /* Parse the error message and print it. An error document must always contain\r
165      * a message. */\r
166     if( AwsIotDocParser_FindValue( pErrorDocument,\r
167                                    errorDocumentLength,\r
168                                    ERROR_DOCUMENT_MESSAGE_KEY,\r
169                                    ERROR_DOCUMENT_MESSAGE_KEY_LENGTH,\r
170                                    &pMessage,\r
171                                    &messageLength ) == true )\r
172     {\r
173         IotLogWarn( "Code %lu: %.*s.",\r
174                     code,\r
175                     messageLength,\r
176                     pMessage );\r
177     }\r
178     else\r
179     {\r
180         IotLogWarn( "Code %lu; failed to parse message from error document.\n%.*s",\r
181                     code,\r
182                     errorDocumentLength,\r
183                     pErrorDocument );\r
184 \r
185         /* An error document must contain a message; if it does not, then it is invalid. */\r
186         IOT_SET_AND_GOTO_CLEANUP( AWS_IOT_SHADOW_BAD_RESPONSE );\r
187     }\r
188 \r
189     /* Convert a successfully parsed JSON code to a Shadow status. */\r
190     status = _codeToShadowStatus( code );\r
191 \r
192     IOT_FUNCTION_EXIT_NO_CLEANUP();\r
193 }\r
194 \r
195 /*-----------------------------------------------------------*/\r