Pierre-Marie Ancèle
/
AWS-test
test
aws-iot/src/aws_iot_shadow_json.cpp@0:cd5404401c2f, 2017-04-12 (annotated)
- Committer:
- peyo
- Date:
- Wed Apr 12 14:07:09 2017 +0200
- Revision:
- 0:cd5404401c2f
first commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
peyo |
0:cd5404401c2f | 1 | /* |
peyo |
0:cd5404401c2f | 2 | * Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. |
peyo |
0:cd5404401c2f | 3 | * |
peyo |
0:cd5404401c2f | 4 | * Licensed under the Apache License, Version 2.0 (the "License"). |
peyo |
0:cd5404401c2f | 5 | * You may not use this file except in compliance with the License. |
peyo |
0:cd5404401c2f | 6 | * A copy of the License is located at |
peyo |
0:cd5404401c2f | 7 | * |
peyo |
0:cd5404401c2f | 8 | * http://aws.amazon.com/apache2.0 |
peyo |
0:cd5404401c2f | 9 | * |
peyo |
0:cd5404401c2f | 10 | * or in the "license" file accompanying this file. This file is distributed |
peyo |
0:cd5404401c2f | 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either |
peyo |
0:cd5404401c2f | 12 | * express or implied. See the License for the specific language governing |
peyo |
0:cd5404401c2f | 13 | * permissions and limitations under the License. |
peyo |
0:cd5404401c2f | 14 | */ |
peyo |
0:cd5404401c2f | 15 | |
peyo |
0:cd5404401c2f | 16 | /** |
peyo |
0:cd5404401c2f | 17 | * @file aws_iot_shadow_json.c |
peyo |
0:cd5404401c2f | 18 | * @brief Shadow client JSON parsing API definitions |
peyo |
0:cd5404401c2f | 19 | */ |
peyo |
0:cd5404401c2f | 20 | |
peyo |
0:cd5404401c2f | 21 | #ifdef __cplusplus |
peyo |
0:cd5404401c2f | 22 | extern "C" { |
peyo |
0:cd5404401c2f | 23 | #include <cinttypes> |
peyo |
0:cd5404401c2f | 24 | #else |
peyo |
0:cd5404401c2f | 25 | |
peyo |
0:cd5404401c2f | 26 | #include <inttypes.h> |
peyo |
0:cd5404401c2f | 27 | |
peyo |
0:cd5404401c2f | 28 | #endif |
peyo |
0:cd5404401c2f | 29 | |
peyo |
0:cd5404401c2f | 30 | #include "aws_iot_shadow_json.h" |
peyo |
0:cd5404401c2f | 31 | |
peyo |
0:cd5404401c2f | 32 | #include <string.h> |
peyo |
0:cd5404401c2f | 33 | #include <stdbool.h> |
peyo |
0:cd5404401c2f | 34 | |
peyo |
0:cd5404401c2f | 35 | #include "aws_iot_json_utils.h" |
peyo |
0:cd5404401c2f | 36 | #include "aws_iot_log.h" |
peyo |
0:cd5404401c2f | 37 | #include "aws_iot_shadow_key.h" |
peyo |
0:cd5404401c2f | 38 | #include "aws_iot_config.h" |
peyo |
0:cd5404401c2f | 39 | |
peyo |
0:cd5404401c2f | 40 | extern char mqttClientID[MAX_SIZE_OF_UNIQUE_CLIENT_ID_BYTES]; |
peyo |
0:cd5404401c2f | 41 | |
peyo |
0:cd5404401c2f | 42 | static uint32_t clientTokenNum = 0; |
peyo |
0:cd5404401c2f | 43 | |
peyo |
0:cd5404401c2f | 44 | //helper functions |
peyo |
0:cd5404401c2f | 45 | static IoT_Error_t convertDataToString(char *pStringBuffer, size_t maxSizoStringBuffer, JsonPrimitiveType type, |
peyo |
0:cd5404401c2f | 46 | void *pData); |
peyo |
0:cd5404401c2f | 47 | |
peyo |
0:cd5404401c2f | 48 | void resetClientTokenSequenceNum(void) { |
peyo |
0:cd5404401c2f | 49 | clientTokenNum = 0; |
peyo |
0:cd5404401c2f | 50 | } |
peyo |
0:cd5404401c2f | 51 | |
peyo |
0:cd5404401c2f | 52 | static void emptyJsonWithClientToken(char *pJsonDocument) { |
peyo |
0:cd5404401c2f | 53 | sprintf(pJsonDocument, "{\"clientToken\":\""); |
peyo |
0:cd5404401c2f | 54 | FillWithClientToken(pJsonDocument + strlen(pJsonDocument)); |
peyo |
0:cd5404401c2f | 55 | sprintf(pJsonDocument + strlen(pJsonDocument), "\"}"); |
peyo |
0:cd5404401c2f | 56 | } |
peyo |
0:cd5404401c2f | 57 | |
peyo |
0:cd5404401c2f | 58 | void aws_iot_shadow_internal_get_request_json(char *pJsonDocument) { |
peyo |
0:cd5404401c2f | 59 | emptyJsonWithClientToken(pJsonDocument); |
peyo |
0:cd5404401c2f | 60 | } |
peyo |
0:cd5404401c2f | 61 | |
peyo |
0:cd5404401c2f | 62 | void aws_iot_shadow_internal_delete_request_json(char *pJsonDocument) { |
peyo |
0:cd5404401c2f | 63 | emptyJsonWithClientToken(pJsonDocument); |
peyo |
0:cd5404401c2f | 64 | } |
peyo |
0:cd5404401c2f | 65 | |
peyo |
0:cd5404401c2f | 66 | static inline IoT_Error_t checkReturnValueOfSnPrintf(int32_t snPrintfReturn, size_t maxSizeOfJsonDocument) { |
peyo |
0:cd5404401c2f | 67 | if(snPrintfReturn < 0) { |
peyo |
0:cd5404401c2f | 68 | return SHADOW_JSON_ERROR; |
peyo |
0:cd5404401c2f | 69 | } else if((size_t) snPrintfReturn >= maxSizeOfJsonDocument) { |
peyo |
0:cd5404401c2f | 70 | return SHADOW_JSON_BUFFER_TRUNCATED; |
peyo |
0:cd5404401c2f | 71 | } |
peyo |
0:cd5404401c2f | 72 | return SUCCESS; |
peyo |
0:cd5404401c2f | 73 | } |
peyo |
0:cd5404401c2f | 74 | |
peyo |
0:cd5404401c2f | 75 | IoT_Error_t aws_iot_shadow_init_json_document(char *pJsonDocument, size_t maxSizeOfJsonDocument) { |
peyo |
0:cd5404401c2f | 76 | |
peyo |
0:cd5404401c2f | 77 | IoT_Error_t ret_val = SUCCESS; |
peyo |
0:cd5404401c2f | 78 | int32_t snPrintfReturn = 0; |
peyo |
0:cd5404401c2f | 79 | |
peyo |
0:cd5404401c2f | 80 | if(pJsonDocument == NULL) { |
peyo |
0:cd5404401c2f | 81 | return NULL_VALUE_ERROR; |
peyo |
0:cd5404401c2f | 82 | } |
peyo |
0:cd5404401c2f | 83 | snPrintfReturn = snprintf(pJsonDocument, maxSizeOfJsonDocument, "{\"state\":{"); |
peyo |
0:cd5404401c2f | 84 | |
peyo |
0:cd5404401c2f | 85 | ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, maxSizeOfJsonDocument); |
peyo |
0:cd5404401c2f | 86 | |
peyo |
0:cd5404401c2f | 87 | return ret_val; |
peyo |
0:cd5404401c2f | 88 | |
peyo |
0:cd5404401c2f | 89 | } |
peyo |
0:cd5404401c2f | 90 | |
peyo |
0:cd5404401c2f | 91 | IoT_Error_t aws_iot_shadow_add_desired(char *pJsonDocument, size_t maxSizeOfJsonDocument, uint8_t count, ...) { |
peyo |
0:cd5404401c2f | 92 | IoT_Error_t ret_val = SUCCESS; |
peyo |
0:cd5404401c2f | 93 | size_t tempSize = 0; |
peyo |
0:cd5404401c2f | 94 | int8_t i; |
peyo |
0:cd5404401c2f | 95 | size_t remSizeOfJsonBuffer = maxSizeOfJsonDocument; |
peyo |
0:cd5404401c2f | 96 | int32_t snPrintfReturn = 0; |
peyo |
0:cd5404401c2f | 97 | va_list pArgs; |
peyo |
0:cd5404401c2f | 98 | jsonStruct_t *pTemporary = NULL; |
peyo |
0:cd5404401c2f | 99 | va_start(pArgs, count); |
peyo |
0:cd5404401c2f | 100 | |
peyo |
0:cd5404401c2f | 101 | if(pJsonDocument == NULL) { |
peyo |
0:cd5404401c2f | 102 | return NULL_VALUE_ERROR; |
peyo |
0:cd5404401c2f | 103 | } |
peyo |
0:cd5404401c2f | 104 | |
peyo |
0:cd5404401c2f | 105 | tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument); |
peyo |
0:cd5404401c2f | 106 | if(tempSize <= 1) { |
peyo |
0:cd5404401c2f | 107 | return SHADOW_JSON_ERROR; |
peyo |
0:cd5404401c2f | 108 | } |
peyo |
0:cd5404401c2f | 109 | remSizeOfJsonBuffer = tempSize; |
peyo |
0:cd5404401c2f | 110 | |
peyo |
0:cd5404401c2f | 111 | snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer, "\"desired\":{"); |
peyo |
0:cd5404401c2f | 112 | ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer); |
peyo |
0:cd5404401c2f | 113 | |
peyo |
0:cd5404401c2f | 114 | if(ret_val != SUCCESS) { |
peyo |
0:cd5404401c2f | 115 | return ret_val; |
peyo |
0:cd5404401c2f | 116 | } |
peyo |
0:cd5404401c2f | 117 | |
peyo |
0:cd5404401c2f | 118 | for(i = 0; i < count; i++) { |
peyo |
0:cd5404401c2f | 119 | tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument); |
peyo |
0:cd5404401c2f | 120 | if(tempSize <= 1) { |
peyo |
0:cd5404401c2f | 121 | return SHADOW_JSON_ERROR; |
peyo |
0:cd5404401c2f | 122 | } |
peyo |
0:cd5404401c2f | 123 | remSizeOfJsonBuffer = tempSize; |
peyo |
0:cd5404401c2f | 124 | pTemporary = va_arg (pArgs, jsonStruct_t *); |
peyo |
0:cd5404401c2f | 125 | if(pTemporary != NULL) { |
peyo |
0:cd5404401c2f | 126 | snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer, "\"%s\":", |
peyo |
0:cd5404401c2f | 127 | pTemporary->pKey); |
peyo |
0:cd5404401c2f | 128 | ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer); |
peyo |
0:cd5404401c2f | 129 | if(ret_val != SUCCESS) { |
peyo |
0:cd5404401c2f | 130 | return ret_val; |
peyo |
0:cd5404401c2f | 131 | } |
peyo |
0:cd5404401c2f | 132 | if(pTemporary->pKey != NULL && pTemporary->pData != NULL) { |
peyo |
0:cd5404401c2f | 133 | ret_val = convertDataToString(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer, |
peyo |
0:cd5404401c2f | 134 | pTemporary->type, pTemporary->pData); |
peyo |
0:cd5404401c2f | 135 | } else { |
peyo |
0:cd5404401c2f | 136 | return NULL_VALUE_ERROR; |
peyo |
0:cd5404401c2f | 137 | } |
peyo |
0:cd5404401c2f | 138 | if(ret_val != SUCCESS) { |
peyo |
0:cd5404401c2f | 139 | return ret_val; |
peyo |
0:cd5404401c2f | 140 | } |
peyo |
0:cd5404401c2f | 141 | } else { |
peyo |
0:cd5404401c2f | 142 | return NULL_VALUE_ERROR; |
peyo |
0:cd5404401c2f | 143 | } |
peyo |
0:cd5404401c2f | 144 | } |
peyo |
0:cd5404401c2f | 145 | |
peyo |
0:cd5404401c2f | 146 | va_end(pArgs); |
peyo |
0:cd5404401c2f | 147 | snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument) - 1, remSizeOfJsonBuffer, "},"); |
peyo |
0:cd5404401c2f | 148 | ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer); |
peyo |
0:cd5404401c2f | 149 | return ret_val; |
peyo |
0:cd5404401c2f | 150 | } |
peyo |
0:cd5404401c2f | 151 | |
peyo |
0:cd5404401c2f | 152 | IoT_Error_t aws_iot_shadow_add_reported(char *pJsonDocument, size_t maxSizeOfJsonDocument, uint8_t count, ...) { |
peyo |
0:cd5404401c2f | 153 | IoT_Error_t ret_val = SUCCESS; |
peyo |
0:cd5404401c2f | 154 | |
peyo |
0:cd5404401c2f | 155 | int8_t i; |
peyo |
0:cd5404401c2f | 156 | size_t remSizeOfJsonBuffer = maxSizeOfJsonDocument; |
peyo |
0:cd5404401c2f | 157 | int32_t snPrintfReturn = 0; |
peyo |
0:cd5404401c2f | 158 | size_t tempSize = 0; |
peyo |
0:cd5404401c2f | 159 | jsonStruct_t *pTemporary; |
peyo |
0:cd5404401c2f | 160 | va_list pArgs; |
peyo |
0:cd5404401c2f | 161 | va_start(pArgs, count); |
peyo |
0:cd5404401c2f | 162 | |
peyo |
0:cd5404401c2f | 163 | if(pJsonDocument == NULL) { |
peyo |
0:cd5404401c2f | 164 | return NULL_VALUE_ERROR; |
peyo |
0:cd5404401c2f | 165 | } |
peyo |
0:cd5404401c2f | 166 | |
peyo |
0:cd5404401c2f | 167 | |
peyo |
0:cd5404401c2f | 168 | tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument); |
peyo |
0:cd5404401c2f | 169 | if(tempSize <= 1) { |
peyo |
0:cd5404401c2f | 170 | return SHADOW_JSON_ERROR; |
peyo |
0:cd5404401c2f | 171 | } |
peyo |
0:cd5404401c2f | 172 | remSizeOfJsonBuffer = tempSize; |
peyo |
0:cd5404401c2f | 173 | |
peyo |
0:cd5404401c2f | 174 | snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer, "\"reported\":{"); |
peyo |
0:cd5404401c2f | 175 | ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer); |
peyo |
0:cd5404401c2f | 176 | |
peyo |
0:cd5404401c2f | 177 | if(ret_val != SUCCESS) { |
peyo |
0:cd5404401c2f | 178 | return ret_val; |
peyo |
0:cd5404401c2f | 179 | } |
peyo |
0:cd5404401c2f | 180 | |
peyo |
0:cd5404401c2f | 181 | for(i = 0; i < count; i++) { |
peyo |
0:cd5404401c2f | 182 | tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument); |
peyo |
0:cd5404401c2f | 183 | if(tempSize <= 1) { |
peyo |
0:cd5404401c2f | 184 | return SHADOW_JSON_ERROR; |
peyo |
0:cd5404401c2f | 185 | } |
peyo |
0:cd5404401c2f | 186 | remSizeOfJsonBuffer = tempSize; |
peyo |
0:cd5404401c2f | 187 | |
peyo |
0:cd5404401c2f | 188 | pTemporary = va_arg (pArgs, jsonStruct_t *); |
peyo |
0:cd5404401c2f | 189 | if(pTemporary != NULL) { |
peyo |
0:cd5404401c2f | 190 | snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer, "\"%s\":", |
peyo |
0:cd5404401c2f | 191 | pTemporary->pKey); |
peyo |
0:cd5404401c2f | 192 | ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer); |
peyo |
0:cd5404401c2f | 193 | if(ret_val != SUCCESS) { |
peyo |
0:cd5404401c2f | 194 | return ret_val; |
peyo |
0:cd5404401c2f | 195 | } |
peyo |
0:cd5404401c2f | 196 | if(pTemporary->pKey != NULL && pTemporary->pData != NULL) { |
peyo |
0:cd5404401c2f | 197 | ret_val = convertDataToString(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer, |
peyo |
0:cd5404401c2f | 198 | pTemporary->type, pTemporary->pData); |
peyo |
0:cd5404401c2f | 199 | } else { |
peyo |
0:cd5404401c2f | 200 | return NULL_VALUE_ERROR; |
peyo |
0:cd5404401c2f | 201 | } |
peyo |
0:cd5404401c2f | 202 | if(ret_val != SUCCESS) { |
peyo |
0:cd5404401c2f | 203 | return ret_val; |
peyo |
0:cd5404401c2f | 204 | } |
peyo |
0:cd5404401c2f | 205 | } else { |
peyo |
0:cd5404401c2f | 206 | return NULL_VALUE_ERROR; |
peyo |
0:cd5404401c2f | 207 | } |
peyo |
0:cd5404401c2f | 208 | } |
peyo |
0:cd5404401c2f | 209 | |
peyo |
0:cd5404401c2f | 210 | va_end(pArgs); |
peyo |
0:cd5404401c2f | 211 | snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument) - 1, remSizeOfJsonBuffer, "},"); |
peyo |
0:cd5404401c2f | 212 | ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer); |
peyo |
0:cd5404401c2f | 213 | return ret_val; |
peyo |
0:cd5404401c2f | 214 | } |
peyo |
0:cd5404401c2f | 215 | |
peyo |
0:cd5404401c2f | 216 | |
peyo |
0:cd5404401c2f | 217 | int32_t FillWithClientTokenSize(char *pBufferToBeUpdatedWithClientToken, size_t maxSizeOfJsonDocument) { |
peyo |
0:cd5404401c2f | 218 | int32_t snPrintfReturn; |
peyo |
0:cd5404401c2f | 219 | snPrintfReturn = snprintf(pBufferToBeUpdatedWithClientToken, maxSizeOfJsonDocument, "%s-%d", mqttClientID, |
peyo |
0:cd5404401c2f | 220 | clientTokenNum++); |
peyo |
0:cd5404401c2f | 221 | |
peyo |
0:cd5404401c2f | 222 | return snPrintfReturn; |
peyo |
0:cd5404401c2f | 223 | } |
peyo |
0:cd5404401c2f | 224 | |
peyo |
0:cd5404401c2f | 225 | IoT_Error_t aws_iot_fill_with_client_token(char *pBufferToBeUpdatedWithClientToken, size_t maxSizeOfJsonDocument) { |
peyo |
0:cd5404401c2f | 226 | |
peyo |
0:cd5404401c2f | 227 | int32_t snPrintfRet = 0; |
peyo |
0:cd5404401c2f | 228 | snPrintfRet = FillWithClientTokenSize(pBufferToBeUpdatedWithClientToken, maxSizeOfJsonDocument); |
peyo |
0:cd5404401c2f | 229 | return checkReturnValueOfSnPrintf(snPrintfRet, maxSizeOfJsonDocument); |
peyo |
0:cd5404401c2f | 230 | |
peyo |
0:cd5404401c2f | 231 | } |
peyo |
0:cd5404401c2f | 232 | |
peyo |
0:cd5404401c2f | 233 | IoT_Error_t aws_iot_finalize_json_document(char *pJsonDocument, size_t maxSizeOfJsonDocument) { |
peyo |
0:cd5404401c2f | 234 | size_t remSizeOfJsonBuffer = maxSizeOfJsonDocument; |
peyo |
0:cd5404401c2f | 235 | int32_t snPrintfReturn = 0; |
peyo |
0:cd5404401c2f | 236 | size_t tempSize = 0; |
peyo |
0:cd5404401c2f | 237 | IoT_Error_t ret_val = SUCCESS; |
peyo |
0:cd5404401c2f | 238 | |
peyo |
0:cd5404401c2f | 239 | if(pJsonDocument == NULL) { |
peyo |
0:cd5404401c2f | 240 | return NULL_VALUE_ERROR; |
peyo |
0:cd5404401c2f | 241 | } |
peyo |
0:cd5404401c2f | 242 | |
peyo |
0:cd5404401c2f | 243 | tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument); |
peyo |
0:cd5404401c2f | 244 | if(tempSize <= 1) { |
peyo |
0:cd5404401c2f | 245 | return SHADOW_JSON_ERROR; |
peyo |
0:cd5404401c2f | 246 | } |
peyo |
0:cd5404401c2f | 247 | remSizeOfJsonBuffer = tempSize; |
peyo |
0:cd5404401c2f | 248 | |
peyo |
0:cd5404401c2f | 249 | // strlen(ShadowTxBuffer) - 1 is to ensure we remove the last ,(comma) that was added |
peyo |
0:cd5404401c2f | 250 | snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument) - 1, remSizeOfJsonBuffer, "}, \"%s\":\"", |
peyo |
0:cd5404401c2f | 251 | SHADOW_CLIENT_TOKEN_STRING); |
peyo |
0:cd5404401c2f | 252 | ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer); |
peyo |
0:cd5404401c2f | 253 | |
peyo |
0:cd5404401c2f | 254 | if(ret_val != SUCCESS) { |
peyo |
0:cd5404401c2f | 255 | return ret_val; |
peyo |
0:cd5404401c2f | 256 | } |
peyo |
0:cd5404401c2f | 257 | // refactor this XXX repeated code |
peyo |
0:cd5404401c2f | 258 | tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument); |
peyo |
0:cd5404401c2f | 259 | if(tempSize <= 1) { |
peyo |
0:cd5404401c2f | 260 | return SHADOW_JSON_ERROR; |
peyo |
0:cd5404401c2f | 261 | } |
peyo |
0:cd5404401c2f | 262 | remSizeOfJsonBuffer = tempSize; |
peyo |
0:cd5404401c2f | 263 | |
peyo |
0:cd5404401c2f | 264 | |
peyo |
0:cd5404401c2f | 265 | snPrintfReturn = FillWithClientTokenSize(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer); |
peyo |
0:cd5404401c2f | 266 | ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer); |
peyo |
0:cd5404401c2f | 267 | |
peyo |
0:cd5404401c2f | 268 | if(ret_val != SUCCESS) { |
peyo |
0:cd5404401c2f | 269 | return ret_val; |
peyo |
0:cd5404401c2f | 270 | } |
peyo |
0:cd5404401c2f | 271 | tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument); |
peyo |
0:cd5404401c2f | 272 | if(tempSize <= 1) { |
peyo |
0:cd5404401c2f | 273 | return SHADOW_JSON_ERROR; |
peyo |
0:cd5404401c2f | 274 | } |
peyo |
0:cd5404401c2f | 275 | remSizeOfJsonBuffer = tempSize; |
peyo |
0:cd5404401c2f | 276 | |
peyo |
0:cd5404401c2f | 277 | |
peyo |
0:cd5404401c2f | 278 | snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer, "\"}"); |
peyo |
0:cd5404401c2f | 279 | ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer); |
peyo |
0:cd5404401c2f | 280 | |
peyo |
0:cd5404401c2f | 281 | return ret_val; |
peyo |
0:cd5404401c2f | 282 | } |
peyo |
0:cd5404401c2f | 283 | |
peyo |
0:cd5404401c2f | 284 | void FillWithClientToken(char *pBufferToBeUpdatedWithClientToken) { |
peyo |
0:cd5404401c2f | 285 | sprintf(pBufferToBeUpdatedWithClientToken, "%s-%d", mqttClientID, clientTokenNum++); |
peyo |
0:cd5404401c2f | 286 | } |
peyo |
0:cd5404401c2f | 287 | |
peyo |
0:cd5404401c2f | 288 | static IoT_Error_t convertDataToString(char *pStringBuffer, size_t maxSizoStringBuffer, JsonPrimitiveType type, |
peyo |
0:cd5404401c2f | 289 | void *pData) { |
peyo |
0:cd5404401c2f | 290 | int32_t snPrintfReturn = 0; |
peyo |
0:cd5404401c2f | 291 | IoT_Error_t ret_val = SUCCESS; |
peyo |
0:cd5404401c2f | 292 | |
peyo |
0:cd5404401c2f | 293 | if(maxSizoStringBuffer == 0) { |
peyo |
0:cd5404401c2f | 294 | return SHADOW_JSON_ERROR; |
peyo |
0:cd5404401c2f | 295 | } |
peyo |
0:cd5404401c2f | 296 | |
peyo |
0:cd5404401c2f | 297 | if(type == SHADOW_JSON_INT32) { |
peyo |
0:cd5404401c2f | 298 | snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%" PRIi32",", *(int32_t *) (pData)); |
peyo |
0:cd5404401c2f | 299 | } else if(type == SHADOW_JSON_INT16) { |
peyo |
0:cd5404401c2f | 300 | snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%" PRIi16",", *(int16_t *) (pData)); |
peyo |
0:cd5404401c2f | 301 | } else if(type == SHADOW_JSON_INT8) { |
peyo |
0:cd5404401c2f | 302 | snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%" PRIi8",", *(int8_t *) (pData)); |
peyo |
0:cd5404401c2f | 303 | } else if(type == SHADOW_JSON_UINT32) { |
peyo |
0:cd5404401c2f | 304 | snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%" PRIu32",", *(uint32_t *) (pData)); |
peyo |
0:cd5404401c2f | 305 | } else if(type == SHADOW_JSON_UINT16) { |
peyo |
0:cd5404401c2f | 306 | snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%" PRIu16",", *(uint16_t *) (pData)); |
peyo |
0:cd5404401c2f | 307 | } else if(type == SHADOW_JSON_UINT8) { |
peyo |
0:cd5404401c2f | 308 | snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%" PRIu8",", *(uint8_t *) (pData)); |
peyo |
0:cd5404401c2f | 309 | } else if(type == SHADOW_JSON_DOUBLE) { |
peyo |
0:cd5404401c2f | 310 | snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%f,", *(double *) (pData)); |
peyo |
0:cd5404401c2f | 311 | } else if(type == SHADOW_JSON_FLOAT) { |
peyo |
0:cd5404401c2f | 312 | snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%f,", *(float *) (pData)); |
peyo |
0:cd5404401c2f | 313 | } else if(type == SHADOW_JSON_BOOL) { |
peyo |
0:cd5404401c2f | 314 | snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%s,", *(bool *) (pData) ? "true" : "false"); |
peyo |
0:cd5404401c2f | 315 | } else if(type == SHADOW_JSON_STRING) { |
peyo |
0:cd5404401c2f | 316 | snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "\"%s\",", (char *) (pData)); |
peyo |
0:cd5404401c2f | 317 | } |
peyo |
0:cd5404401c2f | 318 | |
peyo |
0:cd5404401c2f | 319 | ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, maxSizoStringBuffer); |
peyo |
0:cd5404401c2f | 320 | |
peyo |
0:cd5404401c2f | 321 | return ret_val; |
peyo |
0:cd5404401c2f | 322 | } |
peyo |
0:cd5404401c2f | 323 | |
peyo |
0:cd5404401c2f | 324 | static jsmn_parser shadowJsonParser; |
peyo |
0:cd5404401c2f | 325 | static jsmntok_t jsonTokenStruct[MAX_JSON_TOKEN_EXPECTED]; |
peyo |
0:cd5404401c2f | 326 | |
peyo |
0:cd5404401c2f | 327 | bool isJsonValidAndParse(const char *pJsonDocument, void *pJsonHandler, int32_t *pTokenCount) { |
peyo |
0:cd5404401c2f | 328 | int32_t tokenCount; |
peyo |
0:cd5404401c2f | 329 | |
peyo |
0:cd5404401c2f | 330 | jsmn_init(&shadowJsonParser); |
peyo |
0:cd5404401c2f | 331 | |
peyo |
0:cd5404401c2f | 332 | tokenCount = jsmn_parse(&shadowJsonParser, pJsonDocument, strlen(pJsonDocument), jsonTokenStruct, |
peyo |
0:cd5404401c2f | 333 | sizeof(jsonTokenStruct) / sizeof(jsonTokenStruct[0])); |
peyo |
0:cd5404401c2f | 334 | |
peyo |
0:cd5404401c2f | 335 | if(tokenCount < 0) { |
peyo |
0:cd5404401c2f | 336 | IOT_WARN("Failed to parse JSON: %d\n", tokenCount); |
peyo |
0:cd5404401c2f | 337 | return false; |
peyo |
0:cd5404401c2f | 338 | } |
peyo |
0:cd5404401c2f | 339 | |
peyo |
0:cd5404401c2f | 340 | /* Assume the top-level element is an object */ |
peyo |
0:cd5404401c2f | 341 | if(tokenCount < 1 || jsonTokenStruct[0].type != JSMN_OBJECT) { |
peyo |
0:cd5404401c2f | 342 | IOT_WARN("Top Level is not an object\n"); |
peyo |
0:cd5404401c2f | 343 | return false; |
peyo |
0:cd5404401c2f | 344 | } |
peyo |
0:cd5404401c2f | 345 | |
peyo |
0:cd5404401c2f | 346 | pJsonHandler = (void *) jsonTokenStruct; |
peyo |
0:cd5404401c2f | 347 | *pTokenCount = tokenCount; |
peyo |
0:cd5404401c2f | 348 | |
peyo |
0:cd5404401c2f | 349 | return true; |
peyo |
0:cd5404401c2f | 350 | } |
peyo |
0:cd5404401c2f | 351 | |
peyo |
0:cd5404401c2f | 352 | static IoT_Error_t UpdateValueIfNoObject(const char *pJsonString, jsonStruct_t *pDataStruct, jsmntok_t token) { |
peyo |
0:cd5404401c2f | 353 | IoT_Error_t ret_val = SUCCESS; |
peyo |
0:cd5404401c2f | 354 | if(pDataStruct->type == SHADOW_JSON_BOOL) { |
peyo |
0:cd5404401c2f | 355 | ret_val = parseBooleanValue((bool *) pDataStruct->pData, pJsonString, &token); |
peyo |
0:cd5404401c2f | 356 | } else if(pDataStruct->type == SHADOW_JSON_INT32) { |
peyo |
0:cd5404401c2f | 357 | ret_val = parseInteger32Value((int32_t *) pDataStruct->pData, pJsonString, &token); |
peyo |
0:cd5404401c2f | 358 | } else if(pDataStruct->type == SHADOW_JSON_INT16) { |
peyo |
0:cd5404401c2f | 359 | ret_val = parseInteger16Value((int16_t *) pDataStruct->pData, pJsonString, &token); |
peyo |
0:cd5404401c2f | 360 | } else if(pDataStruct->type == SHADOW_JSON_INT8) { |
peyo |
0:cd5404401c2f | 361 | ret_val = parseInteger8Value((int8_t *) pDataStruct->pData, pJsonString, &token); |
peyo |
0:cd5404401c2f | 362 | } else if(pDataStruct->type == SHADOW_JSON_UINT32) { |
peyo |
0:cd5404401c2f | 363 | ret_val = parseUnsignedInteger32Value((uint32_t *) pDataStruct->pData, pJsonString, &token); |
peyo |
0:cd5404401c2f | 364 | } else if(pDataStruct->type == SHADOW_JSON_UINT16) { |
peyo |
0:cd5404401c2f | 365 | ret_val = parseUnsignedInteger16Value((uint16_t *) pDataStruct->pData, pJsonString, &token); |
peyo |
0:cd5404401c2f | 366 | } else if(pDataStruct->type == SHADOW_JSON_UINT8) { |
peyo |
0:cd5404401c2f | 367 | ret_val = parseUnsignedInteger8Value((uint8_t *) pDataStruct->pData, pJsonString, &token); |
peyo |
0:cd5404401c2f | 368 | } else if(pDataStruct->type == SHADOW_JSON_FLOAT) { |
peyo |
0:cd5404401c2f | 369 | ret_val = parseFloatValue((float *) pDataStruct->pData, pJsonString, &token); |
peyo |
0:cd5404401c2f | 370 | } else if(pDataStruct->type == SHADOW_JSON_DOUBLE) { |
peyo |
0:cd5404401c2f | 371 | ret_val = parseDoubleValue((double *) pDataStruct->pData, pJsonString, &token); |
peyo |
0:cd5404401c2f | 372 | } |
peyo |
0:cd5404401c2f | 373 | |
peyo |
0:cd5404401c2f | 374 | return ret_val; |
peyo |
0:cd5404401c2f | 375 | } |
peyo |
0:cd5404401c2f | 376 | |
peyo |
0:cd5404401c2f | 377 | bool isJsonKeyMatchingAndUpdateValue(const char *pJsonDocument, void *pJsonHandler, int32_t tokenCount, |
peyo |
0:cd5404401c2f | 378 | jsonStruct_t *pDataStruct, uint32_t *pDataLength, int32_t *pDataPosition) { |
peyo |
0:cd5404401c2f | 379 | int32_t i; |
peyo |
0:cd5404401c2f | 380 | uint32_t dataLength; |
peyo |
0:cd5404401c2f | 381 | jsmntok_t *pJsonTokenStruct; |
peyo |
0:cd5404401c2f | 382 | jsmntok_t dataToken; |
peyo |
0:cd5404401c2f | 383 | |
peyo |
0:cd5404401c2f | 384 | pJsonTokenStruct = (jsmntok_t *) pJsonHandler; |
peyo |
0:cd5404401c2f | 385 | for(i = 1; i < tokenCount; i++) { |
peyo |
0:cd5404401c2f | 386 | if(jsoneq(pJsonDocument, &(jsonTokenStruct[i]), pDataStruct->pKey) == 0) { |
peyo |
0:cd5404401c2f | 387 | dataToken = jsonTokenStruct[i + 1]; |
peyo |
0:cd5404401c2f | 388 | dataLength = (uint32_t) (dataToken.end - dataToken.start); |
peyo |
0:cd5404401c2f | 389 | UpdateValueIfNoObject(pJsonDocument, pDataStruct, dataToken); |
peyo |
0:cd5404401c2f | 390 | *pDataPosition = dataToken.start; |
peyo |
0:cd5404401c2f | 391 | *pDataLength = dataLength; |
peyo |
0:cd5404401c2f | 392 | return true; |
peyo |
0:cd5404401c2f | 393 | } |
peyo |
0:cd5404401c2f | 394 | } |
peyo |
0:cd5404401c2f | 395 | return false; |
peyo |
0:cd5404401c2f | 396 | } |
peyo |
0:cd5404401c2f | 397 | |
peyo |
0:cd5404401c2f | 398 | bool isReceivedJsonValid(const char *pJsonDocument) { |
peyo |
0:cd5404401c2f | 399 | int32_t tokenCount; |
peyo |
0:cd5404401c2f | 400 | |
peyo |
0:cd5404401c2f | 401 | jsmn_init(&shadowJsonParser); |
peyo |
0:cd5404401c2f | 402 | |
peyo |
0:cd5404401c2f | 403 | tokenCount = jsmn_parse(&shadowJsonParser, pJsonDocument, strlen(pJsonDocument), jsonTokenStruct, |
peyo |
0:cd5404401c2f | 404 | sizeof(jsonTokenStruct) / sizeof(jsonTokenStruct[0])); |
peyo |
0:cd5404401c2f | 405 | |
peyo |
0:cd5404401c2f | 406 | if(tokenCount < 0) { |
peyo |
0:cd5404401c2f | 407 | IOT_WARN("Failed to parse JSON: %d\n", tokenCount); |
peyo |
0:cd5404401c2f | 408 | return false; |
peyo |
0:cd5404401c2f | 409 | } |
peyo |
0:cd5404401c2f | 410 | |
peyo |
0:cd5404401c2f | 411 | /* Assume the top-level element is an object */ |
peyo |
0:cd5404401c2f | 412 | if(tokenCount < 1 || jsonTokenStruct[0].type != JSMN_OBJECT) { |
peyo |
0:cd5404401c2f | 413 | return false; |
peyo |
0:cd5404401c2f | 414 | } |
peyo |
0:cd5404401c2f | 415 | |
peyo |
0:cd5404401c2f | 416 | return true; |
peyo |
0:cd5404401c2f | 417 | } |
peyo |
0:cd5404401c2f | 418 | |
peyo |
0:cd5404401c2f | 419 | bool extractClientToken(const char *pJsonDocument, char *pExtractedClientToken) { |
peyo |
0:cd5404401c2f | 420 | int32_t tokenCount, i; |
peyo |
0:cd5404401c2f | 421 | uint8_t length; |
peyo |
0:cd5404401c2f | 422 | jsmntok_t ClientJsonToken; |
peyo |
0:cd5404401c2f | 423 | jsmn_init(&shadowJsonParser); |
peyo |
0:cd5404401c2f | 424 | |
peyo |
0:cd5404401c2f | 425 | tokenCount = jsmn_parse(&shadowJsonParser, pJsonDocument, strlen(pJsonDocument), jsonTokenStruct, |
peyo |
0:cd5404401c2f | 426 | sizeof(jsonTokenStruct) / sizeof(jsonTokenStruct[0])); |
peyo |
0:cd5404401c2f | 427 | |
peyo |
0:cd5404401c2f | 428 | if(tokenCount < 0) { |
peyo |
0:cd5404401c2f | 429 | IOT_WARN("Failed to parse JSON: %d\n", tokenCount); |
peyo |
0:cd5404401c2f | 430 | return false; |
peyo |
0:cd5404401c2f | 431 | } |
peyo |
0:cd5404401c2f | 432 | |
peyo |
0:cd5404401c2f | 433 | /* Assume the top-level element is an object */ |
peyo |
0:cd5404401c2f | 434 | if(tokenCount < 1 || jsonTokenStruct[0].type != JSMN_OBJECT) { |
peyo |
0:cd5404401c2f | 435 | return false; |
peyo |
0:cd5404401c2f | 436 | } |
peyo |
0:cd5404401c2f | 437 | |
peyo |
0:cd5404401c2f | 438 | for(i = 1; i < tokenCount; i++) { |
peyo |
0:cd5404401c2f | 439 | if(jsoneq(pJsonDocument, &jsonTokenStruct[i], SHADOW_CLIENT_TOKEN_STRING) == 0) { |
peyo |
0:cd5404401c2f | 440 | ClientJsonToken = jsonTokenStruct[i + 1]; |
peyo |
0:cd5404401c2f | 441 | length = (uint8_t) (ClientJsonToken.end - ClientJsonToken.start); |
peyo |
0:cd5404401c2f | 442 | strncpy(pExtractedClientToken, pJsonDocument + ClientJsonToken.start, length); |
peyo |
0:cd5404401c2f | 443 | pExtractedClientToken[length] = '\0'; |
peyo |
0:cd5404401c2f | 444 | return true; |
peyo |
0:cd5404401c2f | 445 | } |
peyo |
0:cd5404401c2f | 446 | } |
peyo |
0:cd5404401c2f | 447 | |
peyo |
0:cd5404401c2f | 448 | return false; |
peyo |
0:cd5404401c2f | 449 | } |
peyo |
0:cd5404401c2f | 450 | |
peyo |
0:cd5404401c2f | 451 | bool extractVersionNumber(const char *pJsonDocument, void *pJsonHandler, int32_t tokenCount, uint32_t *pVersionNumber) { |
peyo |
0:cd5404401c2f | 452 | int32_t i; |
peyo |
0:cd5404401c2f | 453 | IoT_Error_t ret_val = SUCCESS; |
peyo |
0:cd5404401c2f | 454 | |
peyo |
0:cd5404401c2f | 455 | IOT_UNUSED(pJsonHandler); |
peyo |
0:cd5404401c2f | 456 | |
peyo |
0:cd5404401c2f | 457 | for(i = 1; i < tokenCount; i++) { |
peyo |
0:cd5404401c2f | 458 | if(jsoneq(pJsonDocument, &(jsonTokenStruct[i]), SHADOW_VERSION_STRING) == 0) { |
peyo |
0:cd5404401c2f | 459 | ret_val = parseUnsignedInteger32Value(pVersionNumber, pJsonDocument, &jsonTokenStruct[i + 1]); |
peyo |
0:cd5404401c2f | 460 | if(ret_val == SUCCESS) { |
peyo |
0:cd5404401c2f | 461 | return true; |
peyo |
0:cd5404401c2f | 462 | } |
peyo |
0:cd5404401c2f | 463 | } |
peyo |
0:cd5404401c2f | 464 | } |
peyo |
0:cd5404401c2f | 465 | return false; |
peyo |
0:cd5404401c2f | 466 | } |
peyo |
0:cd5404401c2f | 467 | |
peyo |
0:cd5404401c2f | 468 | #ifdef __cplusplus |
peyo |
0:cd5404401c2f | 469 | } |
peyo |
0:cd5404401c2f | 470 | #endif |
peyo |
0:cd5404401c2f | 471 |