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