pick up wakaama files from https://github.com/eclipse/wakaama

Committer:
terencez
Date:
Wed Apr 19 11:27:34 2017 +0000
Revision:
0:c2dff8cbb91a
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
terencez 0:c2dff8cbb91a 1 /*******************************************************************************
terencez 0:c2dff8cbb91a 2 *
terencez 0:c2dff8cbb91a 3 * Copyright (c) 2015 Intel Corporation and others.
terencez 0:c2dff8cbb91a 4 * All rights reserved. This program and the accompanying materials
terencez 0:c2dff8cbb91a 5 * are made available under the terms of the Eclipse Public License v1.0
terencez 0:c2dff8cbb91a 6 * and Eclipse Distribution License v1.0 which accompany this distribution.
terencez 0:c2dff8cbb91a 7 *
terencez 0:c2dff8cbb91a 8 * The Eclipse Public License is available at
terencez 0:c2dff8cbb91a 9 * http://www.eclipse.org/legal/epl-v10.html
terencez 0:c2dff8cbb91a 10 * The Eclipse Distribution License is available at
terencez 0:c2dff8cbb91a 11 * http://www.eclipse.org/org/documents/edl-v10.php.
terencez 0:c2dff8cbb91a 12 *
terencez 0:c2dff8cbb91a 13 * Contributors:
terencez 0:c2dff8cbb91a 14 * David Navarro, Intel Corporation - initial API and implementation
terencez 0:c2dff8cbb91a 15 *
terencez 0:c2dff8cbb91a 16 *******************************************************************************/
terencez 0:c2dff8cbb91a 17
terencez 0:c2dff8cbb91a 18
terencez 0:c2dff8cbb91a 19 #include "internals.h"
terencez 0:c2dff8cbb91a 20 #include <stdlib.h>
terencez 0:c2dff8cbb91a 21 #include <string.h>
terencez 0:c2dff8cbb91a 22 #include <stdio.h>
terencez 0:c2dff8cbb91a 23 #include <inttypes.h>
terencez 0:c2dff8cbb91a 24
terencez 0:c2dff8cbb91a 25
terencez 0:c2dff8cbb91a 26 #ifdef LWM2M_SUPPORT_JSON
terencez 0:c2dff8cbb91a 27
terencez 0:c2dff8cbb91a 28 #define PRV_JSON_BUFFER_SIZE 1024
terencez 0:c2dff8cbb91a 29
terencez 0:c2dff8cbb91a 30 #define JSON_MIN_ARRAY_LEN 21 // e":[{"n":"N","v":X}]}
terencez 0:c2dff8cbb91a 31 #define JSON_MIN_BASE_LEN 7 // n":"N",
terencez 0:c2dff8cbb91a 32 #define JSON_ITEM_MAX_SIZE 36 // with ten characters for value
terencez 0:c2dff8cbb91a 33 #define JSON_MIN_BX_LEN 5 // bt":1
terencez 0:c2dff8cbb91a 34
terencez 0:c2dff8cbb91a 35 #define JSON_FALSE_STRING "false"
terencez 0:c2dff8cbb91a 36 #define JSON_TRUE_STRING "true"
terencez 0:c2dff8cbb91a 37
terencez 0:c2dff8cbb91a 38 #define JSON_RES_ITEM_URI "{\"n\":\""
terencez 0:c2dff8cbb91a 39 #define JSON_RES_ITEM_URI_SIZE 6
terencez 0:c2dff8cbb91a 40 #define JSON_ITEM_BOOL_TRUE "\",\"bv\":true},"
terencez 0:c2dff8cbb91a 41 #define JSON_ITEM_BOOL_TRUE_SIZE 13
terencez 0:c2dff8cbb91a 42 #define JSON_ITEM_BOOL_FALSE "\",\"bv\":false},"
terencez 0:c2dff8cbb91a 43 #define JSON_ITEM_BOOL_FALSE_SIZE 14
terencez 0:c2dff8cbb91a 44 #define JSON_ITEM_NUM "\",\"v\":"
terencez 0:c2dff8cbb91a 45 #define JSON_ITEM_NUM_SIZE 6
terencez 0:c2dff8cbb91a 46 #define JSON_ITEM_NUM_END "},"
terencez 0:c2dff8cbb91a 47 #define JSON_ITEM_NUM_END_SIZE 2
terencez 0:c2dff8cbb91a 48 #define JSON_ITEM_STRING_BEGIN "\",\"sv\":\""
terencez 0:c2dff8cbb91a 49 #define JSON_ITEM_STRING_BEGIN_SIZE 8
terencez 0:c2dff8cbb91a 50 #define JSON_ITEM_STRING_END "\"},"
terencez 0:c2dff8cbb91a 51 #define JSON_ITEM_STRING_END_SIZE 3
terencez 0:c2dff8cbb91a 52
terencez 0:c2dff8cbb91a 53 #define JSON_BN_HEADER_1 "{\"bn\":\""
terencez 0:c2dff8cbb91a 54 #define JSON_BN_HEADER_1_SIZE 7
terencez 0:c2dff8cbb91a 55 #define JSON_BN_HEADER_2 "\",\"e\":["
terencez 0:c2dff8cbb91a 56 #define JSON_BN_HEADER_2_SIZE 7
terencez 0:c2dff8cbb91a 57 #define JSON_HEADER "{\"e\":["
terencez 0:c2dff8cbb91a 58 #define JSON_HEADER_SIZE 6
terencez 0:c2dff8cbb91a 59 #define JSON_FOOTER "]}"
terencez 0:c2dff8cbb91a 60 #define JSON_FOOTER_SIZE 2
terencez 0:c2dff8cbb91a 61
terencez 0:c2dff8cbb91a 62
terencez 0:c2dff8cbb91a 63 #define _GO_TO_NEXT_CHAR(I,B,L) \
terencez 0:c2dff8cbb91a 64 { \
terencez 0:c2dff8cbb91a 65 I++; \
terencez 0:c2dff8cbb91a 66 I += prv_skipSpace(B+I, L-I); \
terencez 0:c2dff8cbb91a 67 if (I == L) goto error; \
terencez 0:c2dff8cbb91a 68 }
terencez 0:c2dff8cbb91a 69
terencez 0:c2dff8cbb91a 70 typedef enum
terencez 0:c2dff8cbb91a 71 {
terencez 0:c2dff8cbb91a 72 _STEP_START,
terencez 0:c2dff8cbb91a 73 _STEP_TOKEN,
terencez 0:c2dff8cbb91a 74 _STEP_ANY_SEPARATOR,
terencez 0:c2dff8cbb91a 75 _STEP_SEPARATOR,
terencez 0:c2dff8cbb91a 76 _STEP_QUOTED_VALUE,
terencez 0:c2dff8cbb91a 77 _STEP_VALUE,
terencez 0:c2dff8cbb91a 78 _STEP_DONE
terencez 0:c2dff8cbb91a 79 } _itemState;
terencez 0:c2dff8cbb91a 80
terencez 0:c2dff8cbb91a 81 typedef enum
terencez 0:c2dff8cbb91a 82 {
terencez 0:c2dff8cbb91a 83 _TYPE_UNSET,
terencez 0:c2dff8cbb91a 84 _TYPE_FALSE,
terencez 0:c2dff8cbb91a 85 _TYPE_TRUE,
terencez 0:c2dff8cbb91a 86 _TYPE_FLOAT,
terencez 0:c2dff8cbb91a 87 _TYPE_STRING
terencez 0:c2dff8cbb91a 88 } _type;
terencez 0:c2dff8cbb91a 89
terencez 0:c2dff8cbb91a 90 typedef struct
terencez 0:c2dff8cbb91a 91 {
terencez 0:c2dff8cbb91a 92 uint16_t ids[4];
terencez 0:c2dff8cbb91a 93 _type type;
terencez 0:c2dff8cbb91a 94 uint8_t * value;
terencez 0:c2dff8cbb91a 95 size_t valueLen;
terencez 0:c2dff8cbb91a 96 } _record_t;
terencez 0:c2dff8cbb91a 97
terencez 0:c2dff8cbb91a 98 static int prv_isReserved(char sign)
terencez 0:c2dff8cbb91a 99 {
terencez 0:c2dff8cbb91a 100 if (sign == '['
terencez 0:c2dff8cbb91a 101 || sign == '{'
terencez 0:c2dff8cbb91a 102 || sign == ']'
terencez 0:c2dff8cbb91a 103 || sign == '}'
terencez 0:c2dff8cbb91a 104 || sign == ':'
terencez 0:c2dff8cbb91a 105 || sign == ','
terencez 0:c2dff8cbb91a 106 || sign == '"')
terencez 0:c2dff8cbb91a 107 {
terencez 0:c2dff8cbb91a 108 return 1;
terencez 0:c2dff8cbb91a 109 }
terencez 0:c2dff8cbb91a 110
terencez 0:c2dff8cbb91a 111 return 0;
terencez 0:c2dff8cbb91a 112 }
terencez 0:c2dff8cbb91a 113
terencez 0:c2dff8cbb91a 114 static int prv_isWhiteSpace(uint8_t sign)
terencez 0:c2dff8cbb91a 115 {
terencez 0:c2dff8cbb91a 116 if (sign == 0x20
terencez 0:c2dff8cbb91a 117 || sign == 0x09
terencez 0:c2dff8cbb91a 118 || sign == 0x0A
terencez 0:c2dff8cbb91a 119 || sign == 0x0D)
terencez 0:c2dff8cbb91a 120 {
terencez 0:c2dff8cbb91a 121 return 1;
terencez 0:c2dff8cbb91a 122 }
terencez 0:c2dff8cbb91a 123
terencez 0:c2dff8cbb91a 124 return 0;
terencez 0:c2dff8cbb91a 125 }
terencez 0:c2dff8cbb91a 126
terencez 0:c2dff8cbb91a 127 static size_t prv_skipSpace(uint8_t * buffer,
terencez 0:c2dff8cbb91a 128 size_t bufferLen)
terencez 0:c2dff8cbb91a 129 {
terencez 0:c2dff8cbb91a 130 size_t i;
terencez 0:c2dff8cbb91a 131
terencez 0:c2dff8cbb91a 132 i = 0;
terencez 0:c2dff8cbb91a 133 while ((i < bufferLen)
terencez 0:c2dff8cbb91a 134 && prv_isWhiteSpace(buffer[i]))
terencez 0:c2dff8cbb91a 135 {
terencez 0:c2dff8cbb91a 136 i++;
terencez 0:c2dff8cbb91a 137 }
terencez 0:c2dff8cbb91a 138
terencez 0:c2dff8cbb91a 139 return i;
terencez 0:c2dff8cbb91a 140 }
terencez 0:c2dff8cbb91a 141
terencez 0:c2dff8cbb91a 142 static int prv_split(uint8_t * buffer,
terencez 0:c2dff8cbb91a 143 size_t bufferLen,
terencez 0:c2dff8cbb91a 144 int * tokenStartP,
terencez 0:c2dff8cbb91a 145 int * tokenLenP,
terencez 0:c2dff8cbb91a 146 int * valueStartP,
terencez 0:c2dff8cbb91a 147 int * valueLenP)
terencez 0:c2dff8cbb91a 148 {
terencez 0:c2dff8cbb91a 149 size_t index;
terencez 0:c2dff8cbb91a 150 _itemState step;
terencez 0:c2dff8cbb91a 151
terencez 0:c2dff8cbb91a 152 index = 0;
terencez 0:c2dff8cbb91a 153 step = _STEP_START;
terencez 0:c2dff8cbb91a 154
terencez 0:c2dff8cbb91a 155 index = prv_skipSpace(buffer + index, bufferLen - index);
terencez 0:c2dff8cbb91a 156 if (index == bufferLen) return -1;
terencez 0:c2dff8cbb91a 157
terencez 0:c2dff8cbb91a 158 while ((index < bufferLen)
terencez 0:c2dff8cbb91a 159 && (buffer[index] != ','))
terencez 0:c2dff8cbb91a 160 {
terencez 0:c2dff8cbb91a 161 switch (step)
terencez 0:c2dff8cbb91a 162 {
terencez 0:c2dff8cbb91a 163 case _STEP_START:
terencez 0:c2dff8cbb91a 164 if (buffer[index] != '"') return -1;
terencez 0:c2dff8cbb91a 165 *tokenStartP = index+1;
terencez 0:c2dff8cbb91a 166 step = _STEP_TOKEN;
terencez 0:c2dff8cbb91a 167 break;
terencez 0:c2dff8cbb91a 168
terencez 0:c2dff8cbb91a 169 case _STEP_TOKEN:
terencez 0:c2dff8cbb91a 170 if (buffer[index] == '"')
terencez 0:c2dff8cbb91a 171 {
terencez 0:c2dff8cbb91a 172 *tokenLenP = index - *tokenStartP;
terencez 0:c2dff8cbb91a 173 step = _STEP_ANY_SEPARATOR;
terencez 0:c2dff8cbb91a 174 }
terencez 0:c2dff8cbb91a 175 break;
terencez 0:c2dff8cbb91a 176
terencez 0:c2dff8cbb91a 177 case _STEP_ANY_SEPARATOR:
terencez 0:c2dff8cbb91a 178 if (buffer[index] != ':') return -1;
terencez 0:c2dff8cbb91a 179 step = _STEP_SEPARATOR;
terencez 0:c2dff8cbb91a 180 break;
terencez 0:c2dff8cbb91a 181
terencez 0:c2dff8cbb91a 182 case _STEP_SEPARATOR:
terencez 0:c2dff8cbb91a 183 if (buffer[index] == '"')
terencez 0:c2dff8cbb91a 184 {
terencez 0:c2dff8cbb91a 185 *valueStartP = index;
terencez 0:c2dff8cbb91a 186 step = _STEP_QUOTED_VALUE;
terencez 0:c2dff8cbb91a 187 } else if (!prv_isReserved(buffer[index]))
terencez 0:c2dff8cbb91a 188 {
terencez 0:c2dff8cbb91a 189 *valueStartP = index;
terencez 0:c2dff8cbb91a 190 step = _STEP_VALUE;
terencez 0:c2dff8cbb91a 191 } else
terencez 0:c2dff8cbb91a 192 {
terencez 0:c2dff8cbb91a 193 return -1;
terencez 0:c2dff8cbb91a 194 }
terencez 0:c2dff8cbb91a 195 break;
terencez 0:c2dff8cbb91a 196
terencez 0:c2dff8cbb91a 197 case _STEP_QUOTED_VALUE:
terencez 0:c2dff8cbb91a 198 if (buffer[index] == '"' && buffer[index-1] != '\\' )
terencez 0:c2dff8cbb91a 199 {
terencez 0:c2dff8cbb91a 200 *valueLenP = index - *valueStartP + 1;
terencez 0:c2dff8cbb91a 201 step = _STEP_DONE;
terencez 0:c2dff8cbb91a 202 }
terencez 0:c2dff8cbb91a 203 break;
terencez 0:c2dff8cbb91a 204
terencez 0:c2dff8cbb91a 205 case _STEP_VALUE:
terencez 0:c2dff8cbb91a 206 if (prv_isWhiteSpace(buffer[index]))
terencez 0:c2dff8cbb91a 207 {
terencez 0:c2dff8cbb91a 208 *valueLenP = index - *valueStartP;
terencez 0:c2dff8cbb91a 209 step = _STEP_DONE;
terencez 0:c2dff8cbb91a 210 }
terencez 0:c2dff8cbb91a 211 break;
terencez 0:c2dff8cbb91a 212
terencez 0:c2dff8cbb91a 213 case _STEP_DONE:
terencez 0:c2dff8cbb91a 214 default:
terencez 0:c2dff8cbb91a 215 return -1;
terencez 0:c2dff8cbb91a 216 }
terencez 0:c2dff8cbb91a 217
terencez 0:c2dff8cbb91a 218 index++;
terencez 0:c2dff8cbb91a 219 if (step == _STEP_START
terencez 0:c2dff8cbb91a 220 || step == _STEP_ANY_SEPARATOR
terencez 0:c2dff8cbb91a 221 || step == _STEP_SEPARATOR
terencez 0:c2dff8cbb91a 222 || step == _STEP_DONE)
terencez 0:c2dff8cbb91a 223 {
terencez 0:c2dff8cbb91a 224 index += prv_skipSpace(buffer + index, bufferLen - index);
terencez 0:c2dff8cbb91a 225 }
terencez 0:c2dff8cbb91a 226 }
terencez 0:c2dff8cbb91a 227
terencez 0:c2dff8cbb91a 228 if (step == _STEP_VALUE)
terencez 0:c2dff8cbb91a 229 {
terencez 0:c2dff8cbb91a 230 *valueLenP = index - *valueStartP;
terencez 0:c2dff8cbb91a 231 step = _STEP_DONE;
terencez 0:c2dff8cbb91a 232 }
terencez 0:c2dff8cbb91a 233
terencez 0:c2dff8cbb91a 234 if (step != _STEP_DONE) return -1;
terencez 0:c2dff8cbb91a 235
terencez 0:c2dff8cbb91a 236 return (int)index;
terencez 0:c2dff8cbb91a 237 }
terencez 0:c2dff8cbb91a 238
terencez 0:c2dff8cbb91a 239 static int prv_countItems(uint8_t * buffer,
terencez 0:c2dff8cbb91a 240 size_t bufferLen)
terencez 0:c2dff8cbb91a 241 {
terencez 0:c2dff8cbb91a 242 int count;
terencez 0:c2dff8cbb91a 243 size_t index;
terencez 0:c2dff8cbb91a 244 int in;
terencez 0:c2dff8cbb91a 245
terencez 0:c2dff8cbb91a 246 count = 0;
terencez 0:c2dff8cbb91a 247 index = 0;
terencez 0:c2dff8cbb91a 248 in = 0;
terencez 0:c2dff8cbb91a 249
terencez 0:c2dff8cbb91a 250 while (index < bufferLen)
terencez 0:c2dff8cbb91a 251 {
terencez 0:c2dff8cbb91a 252 if (in == 0)
terencez 0:c2dff8cbb91a 253 {
terencez 0:c2dff8cbb91a 254 if (buffer[index] != '{') return -1;
terencez 0:c2dff8cbb91a 255 in = 1;
terencez 0:c2dff8cbb91a 256 _GO_TO_NEXT_CHAR(index, buffer, bufferLen);
terencez 0:c2dff8cbb91a 257 }
terencez 0:c2dff8cbb91a 258 else
terencez 0:c2dff8cbb91a 259 {
terencez 0:c2dff8cbb91a 260 if (buffer[index] == '{') return -1;
terencez 0:c2dff8cbb91a 261 if (buffer[index] == '}')
terencez 0:c2dff8cbb91a 262 {
terencez 0:c2dff8cbb91a 263 in = 0;
terencez 0:c2dff8cbb91a 264 count++;
terencez 0:c2dff8cbb91a 265 _GO_TO_NEXT_CHAR(index, buffer, bufferLen);
terencez 0:c2dff8cbb91a 266 if (buffer[index] == ']')
terencez 0:c2dff8cbb91a 267 {
terencez 0:c2dff8cbb91a 268 break;
terencez 0:c2dff8cbb91a 269 }
terencez 0:c2dff8cbb91a 270 if (buffer[index] != ',') return -1;
terencez 0:c2dff8cbb91a 271 _GO_TO_NEXT_CHAR(index, buffer, bufferLen);
terencez 0:c2dff8cbb91a 272 }
terencez 0:c2dff8cbb91a 273 else
terencez 0:c2dff8cbb91a 274 {
terencez 0:c2dff8cbb91a 275 _GO_TO_NEXT_CHAR(index, buffer, bufferLen);
terencez 0:c2dff8cbb91a 276 }
terencez 0:c2dff8cbb91a 277 }
terencez 0:c2dff8cbb91a 278 }
terencez 0:c2dff8cbb91a 279 if (in == 1) return -1;
terencez 0:c2dff8cbb91a 280
terencez 0:c2dff8cbb91a 281 return count;
terencez 0:c2dff8cbb91a 282
terencez 0:c2dff8cbb91a 283 error:
terencez 0:c2dff8cbb91a 284 return -1;
terencez 0:c2dff8cbb91a 285 }
terencez 0:c2dff8cbb91a 286
terencez 0:c2dff8cbb91a 287 static int prv_parseItem(uint8_t * buffer,
terencez 0:c2dff8cbb91a 288 size_t bufferLen,
terencez 0:c2dff8cbb91a 289 _record_t * recordP)
terencez 0:c2dff8cbb91a 290 {
terencez 0:c2dff8cbb91a 291 size_t index;
terencez 0:c2dff8cbb91a 292
terencez 0:c2dff8cbb91a 293 memset(recordP->ids, 0xFF, 4*sizeof(uint16_t));
terencez 0:c2dff8cbb91a 294 recordP->type = _TYPE_UNSET;
terencez 0:c2dff8cbb91a 295 recordP->value = NULL;
terencez 0:c2dff8cbb91a 296 recordP->valueLen = 0;
terencez 0:c2dff8cbb91a 297
terencez 0:c2dff8cbb91a 298 index = 0;
terencez 0:c2dff8cbb91a 299 do
terencez 0:c2dff8cbb91a 300 {
terencez 0:c2dff8cbb91a 301 int tokenStart;
terencez 0:c2dff8cbb91a 302 int tokenLen;
terencez 0:c2dff8cbb91a 303 int valueStart;
terencez 0:c2dff8cbb91a 304 int valueLen;
terencez 0:c2dff8cbb91a 305 int next;
terencez 0:c2dff8cbb91a 306
terencez 0:c2dff8cbb91a 307 next = prv_split(buffer+index, bufferLen-index, &tokenStart, &tokenLen, &valueStart, &valueLen);
terencez 0:c2dff8cbb91a 308 if (next < 0) return -1;
terencez 0:c2dff8cbb91a 309
terencez 0:c2dff8cbb91a 310 switch (tokenLen)
terencez 0:c2dff8cbb91a 311 {
terencez 0:c2dff8cbb91a 312 case 1:
terencez 0:c2dff8cbb91a 313 {
terencez 0:c2dff8cbb91a 314 switch (buffer[index+tokenStart])
terencez 0:c2dff8cbb91a 315 {
terencez 0:c2dff8cbb91a 316 case 'n':
terencez 0:c2dff8cbb91a 317 {
terencez 0:c2dff8cbb91a 318 int i;
terencez 0:c2dff8cbb91a 319 int j;
terencez 0:c2dff8cbb91a 320
terencez 0:c2dff8cbb91a 321 if (recordP->ids[0] != LWM2M_MAX_ID) return -1;
terencez 0:c2dff8cbb91a 322
terencez 0:c2dff8cbb91a 323 // Check for " around URI
terencez 0:c2dff8cbb91a 324 if (valueLen < 3
terencez 0:c2dff8cbb91a 325 || buffer[index+valueStart] != '"'
terencez 0:c2dff8cbb91a 326 || buffer[index+valueStart+valueLen-1] != '"')
terencez 0:c2dff8cbb91a 327 {
terencez 0:c2dff8cbb91a 328 return -1;
terencez 0:c2dff8cbb91a 329 }
terencez 0:c2dff8cbb91a 330 // Ignore starting /
terencez 0:c2dff8cbb91a 331 if (buffer[index + valueStart + 1] == '/')
terencez 0:c2dff8cbb91a 332 {
terencez 0:c2dff8cbb91a 333 if (valueLen < 4)
terencez 0:c2dff8cbb91a 334 {
terencez 0:c2dff8cbb91a 335 return -1;
terencez 0:c2dff8cbb91a 336 }
terencez 0:c2dff8cbb91a 337 valueStart += 1;
terencez 0:c2dff8cbb91a 338 valueLen -= 1;
terencez 0:c2dff8cbb91a 339 }
terencez 0:c2dff8cbb91a 340 i = 0;
terencez 0:c2dff8cbb91a 341 j = 0;
terencez 0:c2dff8cbb91a 342 do {
terencez 0:c2dff8cbb91a 343 uint32_t readId;
terencez 0:c2dff8cbb91a 344
terencez 0:c2dff8cbb91a 345 readId = 0;
terencez 0:c2dff8cbb91a 346 i++;
terencez 0:c2dff8cbb91a 347 while (i < valueLen-1 && buffer[index+valueStart+i] != '/')
terencez 0:c2dff8cbb91a 348 {
terencez 0:c2dff8cbb91a 349 if (buffer[index+valueStart+i] < '0'
terencez 0:c2dff8cbb91a 350 || buffer[index+valueStart+i] > '9')
terencez 0:c2dff8cbb91a 351 {
terencez 0:c2dff8cbb91a 352 return -1;
terencez 0:c2dff8cbb91a 353 }
terencez 0:c2dff8cbb91a 354 readId *= 10;
terencez 0:c2dff8cbb91a 355 readId += buffer[index+valueStart+i] - '0';
terencez 0:c2dff8cbb91a 356 if (readId > LWM2M_MAX_ID) return -1;
terencez 0:c2dff8cbb91a 357 i++;
terencez 0:c2dff8cbb91a 358 }
terencez 0:c2dff8cbb91a 359 recordP->ids[j] = readId;
terencez 0:c2dff8cbb91a 360 j++;
terencez 0:c2dff8cbb91a 361 } while (i < valueLen-1 && j < 4 && buffer[index+valueStart+i] == '/');
terencez 0:c2dff8cbb91a 362 if (i < valueLen-1 ) return -1;
terencez 0:c2dff8cbb91a 363 }
terencez 0:c2dff8cbb91a 364 break;
terencez 0:c2dff8cbb91a 365
terencez 0:c2dff8cbb91a 366 case 'v':
terencez 0:c2dff8cbb91a 367 if (recordP->type != _TYPE_UNSET) return -1;
terencez 0:c2dff8cbb91a 368 recordP->type = _TYPE_FLOAT;
terencez 0:c2dff8cbb91a 369 recordP->value = buffer + index + valueStart;
terencez 0:c2dff8cbb91a 370 recordP->valueLen = valueLen;
terencez 0:c2dff8cbb91a 371 break;
terencez 0:c2dff8cbb91a 372
terencez 0:c2dff8cbb91a 373 case 't':
terencez 0:c2dff8cbb91a 374 // TODO: support time
terencez 0:c2dff8cbb91a 375 break;
terencez 0:c2dff8cbb91a 376
terencez 0:c2dff8cbb91a 377 default:
terencez 0:c2dff8cbb91a 378 return -1;
terencez 0:c2dff8cbb91a 379 }
terencez 0:c2dff8cbb91a 380 }
terencez 0:c2dff8cbb91a 381 break;
terencez 0:c2dff8cbb91a 382
terencez 0:c2dff8cbb91a 383 case 2:
terencez 0:c2dff8cbb91a 384 {
terencez 0:c2dff8cbb91a 385 // "bv", "ov", or "sv"
terencez 0:c2dff8cbb91a 386 if (buffer[index+tokenStart+1] != 'v') return -1;
terencez 0:c2dff8cbb91a 387 switch (buffer[index+tokenStart])
terencez 0:c2dff8cbb91a 388 {
terencez 0:c2dff8cbb91a 389 case 'b':
terencez 0:c2dff8cbb91a 390 if (recordP->type != _TYPE_UNSET) return -1;
terencez 0:c2dff8cbb91a 391 if (0 == lwm2m_strncmp(JSON_TRUE_STRING, (char *)buffer + index + valueStart, valueLen))
terencez 0:c2dff8cbb91a 392 {
terencez 0:c2dff8cbb91a 393 recordP->type = _TYPE_TRUE;
terencez 0:c2dff8cbb91a 394 }
terencez 0:c2dff8cbb91a 395 else if (0 == lwm2m_strncmp(JSON_FALSE_STRING, (char *)buffer + index + valueStart, valueLen))
terencez 0:c2dff8cbb91a 396 {
terencez 0:c2dff8cbb91a 397 recordP->type = _TYPE_FALSE;
terencez 0:c2dff8cbb91a 398 }
terencez 0:c2dff8cbb91a 399 else
terencez 0:c2dff8cbb91a 400 {
terencez 0:c2dff8cbb91a 401 return -1;
terencez 0:c2dff8cbb91a 402 }
terencez 0:c2dff8cbb91a 403 break;
terencez 0:c2dff8cbb91a 404
terencez 0:c2dff8cbb91a 405 case 'o':
terencez 0:c2dff8cbb91a 406 if (recordP->type != _TYPE_UNSET) return -1;
terencez 0:c2dff8cbb91a 407 // TODO: support object link
terencez 0:c2dff8cbb91a 408 break;
terencez 0:c2dff8cbb91a 409
terencez 0:c2dff8cbb91a 410 case 's':
terencez 0:c2dff8cbb91a 411 if (recordP->type != _TYPE_UNSET) return -1;
terencez 0:c2dff8cbb91a 412 // Check for " around value
terencez 0:c2dff8cbb91a 413 if (valueLen < 2
terencez 0:c2dff8cbb91a 414 || buffer[index+valueStart] != '"'
terencez 0:c2dff8cbb91a 415 || buffer[index+valueStart+valueLen-1] != '"')
terencez 0:c2dff8cbb91a 416 {
terencez 0:c2dff8cbb91a 417 return -1;
terencez 0:c2dff8cbb91a 418 }
terencez 0:c2dff8cbb91a 419 recordP->type = _TYPE_STRING;
terencez 0:c2dff8cbb91a 420 recordP->value = buffer + index + valueStart + 1;
terencez 0:c2dff8cbb91a 421 recordP->valueLen = valueLen - 2;
terencez 0:c2dff8cbb91a 422 break;
terencez 0:c2dff8cbb91a 423
terencez 0:c2dff8cbb91a 424 default:
terencez 0:c2dff8cbb91a 425 return -1;
terencez 0:c2dff8cbb91a 426 }
terencez 0:c2dff8cbb91a 427 }
terencez 0:c2dff8cbb91a 428 break;
terencez 0:c2dff8cbb91a 429
terencez 0:c2dff8cbb91a 430 default:
terencez 0:c2dff8cbb91a 431 return -1;
terencez 0:c2dff8cbb91a 432 }
terencez 0:c2dff8cbb91a 433
terencez 0:c2dff8cbb91a 434 index += next + 1;
terencez 0:c2dff8cbb91a 435 } while (index < bufferLen);
terencez 0:c2dff8cbb91a 436
terencez 0:c2dff8cbb91a 437 return 0;
terencez 0:c2dff8cbb91a 438 }
terencez 0:c2dff8cbb91a 439
terencez 0:c2dff8cbb91a 440 static bool prv_convertValue(_record_t * recordP,
terencez 0:c2dff8cbb91a 441 lwm2m_data_t * targetP)
terencez 0:c2dff8cbb91a 442 {
terencez 0:c2dff8cbb91a 443 switch (recordP->type)
terencez 0:c2dff8cbb91a 444 {
terencez 0:c2dff8cbb91a 445 case _TYPE_FALSE:
terencez 0:c2dff8cbb91a 446 lwm2m_data_encode_bool(false, targetP);
terencez 0:c2dff8cbb91a 447 break;
terencez 0:c2dff8cbb91a 448 case _TYPE_TRUE:
terencez 0:c2dff8cbb91a 449 lwm2m_data_encode_bool(true, targetP);
terencez 0:c2dff8cbb91a 450 break;
terencez 0:c2dff8cbb91a 451 case _TYPE_FLOAT:
terencez 0:c2dff8cbb91a 452 {
terencez 0:c2dff8cbb91a 453 size_t i;
terencez 0:c2dff8cbb91a 454
terencez 0:c2dff8cbb91a 455 i = 0;
terencez 0:c2dff8cbb91a 456 while (i < recordP->valueLen
terencez 0:c2dff8cbb91a 457 && recordP->value[i] != '.')
terencez 0:c2dff8cbb91a 458 {
terencez 0:c2dff8cbb91a 459 i++;
terencez 0:c2dff8cbb91a 460 }
terencez 0:c2dff8cbb91a 461 if (i == recordP->valueLen)
terencez 0:c2dff8cbb91a 462 {
terencez 0:c2dff8cbb91a 463 int64_t value;
terencez 0:c2dff8cbb91a 464
terencez 0:c2dff8cbb91a 465 if ( 1 != utils_plainTextToInt64(recordP->value,
terencez 0:c2dff8cbb91a 466 recordP->valueLen,
terencez 0:c2dff8cbb91a 467 &value))
terencez 0:c2dff8cbb91a 468 {
terencez 0:c2dff8cbb91a 469 return false;
terencez 0:c2dff8cbb91a 470 }
terencez 0:c2dff8cbb91a 471
terencez 0:c2dff8cbb91a 472 lwm2m_data_encode_int(value, targetP);
terencez 0:c2dff8cbb91a 473 }
terencez 0:c2dff8cbb91a 474 else
terencez 0:c2dff8cbb91a 475 {
terencez 0:c2dff8cbb91a 476 double value;
terencez 0:c2dff8cbb91a 477
terencez 0:c2dff8cbb91a 478 if ( 1 != utils_plainTextToFloat64(recordP->value,
terencez 0:c2dff8cbb91a 479 recordP->valueLen,
terencez 0:c2dff8cbb91a 480 &value))
terencez 0:c2dff8cbb91a 481 {
terencez 0:c2dff8cbb91a 482 return false;
terencez 0:c2dff8cbb91a 483 }
terencez 0:c2dff8cbb91a 484
terencez 0:c2dff8cbb91a 485 lwm2m_data_encode_float(value, targetP);
terencez 0:c2dff8cbb91a 486 }
terencez 0:c2dff8cbb91a 487 }
terencez 0:c2dff8cbb91a 488 break;
terencez 0:c2dff8cbb91a 489
terencez 0:c2dff8cbb91a 490 case _TYPE_STRING:
terencez 0:c2dff8cbb91a 491 lwm2m_data_encode_opaque(recordP->value, recordP->valueLen, targetP);
terencez 0:c2dff8cbb91a 492 targetP->type = LWM2M_TYPE_STRING;
terencez 0:c2dff8cbb91a 493 break;
terencez 0:c2dff8cbb91a 494
terencez 0:c2dff8cbb91a 495 case _TYPE_UNSET:
terencez 0:c2dff8cbb91a 496 default:
terencez 0:c2dff8cbb91a 497 return false;
terencez 0:c2dff8cbb91a 498 }
terencez 0:c2dff8cbb91a 499
terencez 0:c2dff8cbb91a 500 return true;
terencez 0:c2dff8cbb91a 501 }
terencez 0:c2dff8cbb91a 502
terencez 0:c2dff8cbb91a 503 static lwm2m_data_t * prv_findDataItem(lwm2m_data_t * listP,
terencez 0:c2dff8cbb91a 504 int count,
terencez 0:c2dff8cbb91a 505 uint16_t id)
terencez 0:c2dff8cbb91a 506 {
terencez 0:c2dff8cbb91a 507 int i;
terencez 0:c2dff8cbb91a 508
terencez 0:c2dff8cbb91a 509 i = 0;
terencez 0:c2dff8cbb91a 510 while (i < count)
terencez 0:c2dff8cbb91a 511 {
terencez 0:c2dff8cbb91a 512 if (listP[i].type != LWM2M_TYPE_UNDEFINED && listP[i].id == id)
terencez 0:c2dff8cbb91a 513 {
terencez 0:c2dff8cbb91a 514 return listP + i;
terencez 0:c2dff8cbb91a 515 }
terencez 0:c2dff8cbb91a 516 i++;
terencez 0:c2dff8cbb91a 517 }
terencez 0:c2dff8cbb91a 518
terencez 0:c2dff8cbb91a 519 return NULL;
terencez 0:c2dff8cbb91a 520 }
terencez 0:c2dff8cbb91a 521
terencez 0:c2dff8cbb91a 522 static uri_depth_t prv_decreaseLevel(uri_depth_t level)
terencez 0:c2dff8cbb91a 523 {
terencez 0:c2dff8cbb91a 524 switch(level)
terencez 0:c2dff8cbb91a 525 {
terencez 0:c2dff8cbb91a 526 case URI_DEPTH_OBJECT:
terencez 0:c2dff8cbb91a 527 return URI_DEPTH_OBJECT_INSTANCE;
terencez 0:c2dff8cbb91a 528 case URI_DEPTH_OBJECT_INSTANCE:
terencez 0:c2dff8cbb91a 529 return URI_DEPTH_RESOURCE;
terencez 0:c2dff8cbb91a 530 case URI_DEPTH_RESOURCE:
terencez 0:c2dff8cbb91a 531 return URI_DEPTH_RESOURCE_INSTANCE;
terencez 0:c2dff8cbb91a 532 case URI_DEPTH_RESOURCE_INSTANCE:
terencez 0:c2dff8cbb91a 533 return URI_DEPTH_RESOURCE_INSTANCE;
terencez 0:c2dff8cbb91a 534 default:
terencez 0:c2dff8cbb91a 535 return URI_DEPTH_RESOURCE;
terencez 0:c2dff8cbb91a 536 }
terencez 0:c2dff8cbb91a 537 }
terencez 0:c2dff8cbb91a 538
terencez 0:c2dff8cbb91a 539 static lwm2m_data_t * prv_extendData(lwm2m_data_t * parentP)
terencez 0:c2dff8cbb91a 540 {
terencez 0:c2dff8cbb91a 541 lwm2m_data_t * newP;
terencez 0:c2dff8cbb91a 542
terencez 0:c2dff8cbb91a 543 newP = lwm2m_data_new(parentP->value.asChildren.count + 1);
terencez 0:c2dff8cbb91a 544 if (newP == NULL) return NULL;
terencez 0:c2dff8cbb91a 545 if (parentP->value.asChildren.array != NULL)
terencez 0:c2dff8cbb91a 546 {
terencez 0:c2dff8cbb91a 547 memcpy(newP, parentP->value.asChildren.array, parentP->value.asChildren.count * sizeof(lwm2m_data_t));
terencez 0:c2dff8cbb91a 548 lwm2m_free(parentP->value.asChildren.array); // do not use lwm2m_data_free() to keep pointed values
terencez 0:c2dff8cbb91a 549 }
terencez 0:c2dff8cbb91a 550 parentP->value.asChildren.array = newP;
terencez 0:c2dff8cbb91a 551 parentP->value.asChildren.count += 1;
terencez 0:c2dff8cbb91a 552
terencez 0:c2dff8cbb91a 553 return newP + parentP->value.asChildren.count - 1;
terencez 0:c2dff8cbb91a 554 }
terencez 0:c2dff8cbb91a 555
terencez 0:c2dff8cbb91a 556 static int prv_convertRecord(lwm2m_uri_t * uriP,
terencez 0:c2dff8cbb91a 557 _record_t * recordArray,
terencez 0:c2dff8cbb91a 558 int count,
terencez 0:c2dff8cbb91a 559 lwm2m_data_t ** dataP)
terencez 0:c2dff8cbb91a 560 {
terencez 0:c2dff8cbb91a 561 int index;
terencez 0:c2dff8cbb91a 562 int freeIndex;
terencez 0:c2dff8cbb91a 563 lwm2m_data_t * rootP;
terencez 0:c2dff8cbb91a 564 int size;
terencez 0:c2dff8cbb91a 565 uri_depth_t rootLevel;
terencez 0:c2dff8cbb91a 566
terencez 0:c2dff8cbb91a 567 if (uriP == NULL)
terencez 0:c2dff8cbb91a 568 {
terencez 0:c2dff8cbb91a 569 size = count;
terencez 0:c2dff8cbb91a 570 *dataP = lwm2m_data_new(count);
terencez 0:c2dff8cbb91a 571 if (NULL == *dataP) return -1;
terencez 0:c2dff8cbb91a 572 rootLevel = URI_DEPTH_OBJECT;
terencez 0:c2dff8cbb91a 573 rootP = *dataP;
terencez 0:c2dff8cbb91a 574 }
terencez 0:c2dff8cbb91a 575 else
terencez 0:c2dff8cbb91a 576 {
terencez 0:c2dff8cbb91a 577 lwm2m_data_t * parentP;
terencez 0:c2dff8cbb91a 578 size = 1;
terencez 0:c2dff8cbb91a 579
terencez 0:c2dff8cbb91a 580 *dataP = lwm2m_data_new(1);
terencez 0:c2dff8cbb91a 581 if (NULL == *dataP) return -1;
terencez 0:c2dff8cbb91a 582 (*dataP)->type = LWM2M_TYPE_OBJECT;
terencez 0:c2dff8cbb91a 583 (*dataP)->id = uriP->objectId;
terencez 0:c2dff8cbb91a 584 rootLevel = URI_DEPTH_OBJECT_INSTANCE;
terencez 0:c2dff8cbb91a 585 parentP = *dataP;
terencez 0:c2dff8cbb91a 586 if (LWM2M_URI_IS_SET_INSTANCE(uriP))
terencez 0:c2dff8cbb91a 587 {
terencez 0:c2dff8cbb91a 588 parentP->value.asChildren.count = 1;
terencez 0:c2dff8cbb91a 589 parentP->value.asChildren.array = lwm2m_data_new(1);
terencez 0:c2dff8cbb91a 590 if (NULL == parentP->value.asChildren.array) goto error;
terencez 0:c2dff8cbb91a 591 parentP = parentP->value.asChildren.array;
terencez 0:c2dff8cbb91a 592 parentP->type = LWM2M_TYPE_OBJECT_INSTANCE;
terencez 0:c2dff8cbb91a 593 parentP->id = uriP->instanceId;
terencez 0:c2dff8cbb91a 594 rootLevel = URI_DEPTH_RESOURCE;
terencez 0:c2dff8cbb91a 595 if (LWM2M_URI_IS_SET_RESOURCE(uriP))
terencez 0:c2dff8cbb91a 596 {
terencez 0:c2dff8cbb91a 597 parentP->value.asChildren.count = 1;
terencez 0:c2dff8cbb91a 598 parentP->value.asChildren.array = lwm2m_data_new(1);
terencez 0:c2dff8cbb91a 599 if (NULL == parentP->value.asChildren.array) goto error;
terencez 0:c2dff8cbb91a 600 parentP = parentP->value.asChildren.array;
terencez 0:c2dff8cbb91a 601 parentP->type = LWM2M_TYPE_UNDEFINED;
terencez 0:c2dff8cbb91a 602 parentP->id = uriP->resourceId;
terencez 0:c2dff8cbb91a 603 rootLevel = URI_DEPTH_RESOURCE_INSTANCE;
terencez 0:c2dff8cbb91a 604 }
terencez 0:c2dff8cbb91a 605 }
terencez 0:c2dff8cbb91a 606 parentP->value.asChildren.count = count;
terencez 0:c2dff8cbb91a 607 parentP->value.asChildren.array = lwm2m_data_new(count);
terencez 0:c2dff8cbb91a 608 if (NULL == parentP->value.asChildren.array) goto error;
terencez 0:c2dff8cbb91a 609 rootP = parentP->value.asChildren.array;
terencez 0:c2dff8cbb91a 610 }
terencez 0:c2dff8cbb91a 611
terencez 0:c2dff8cbb91a 612 freeIndex = 0;
terencez 0:c2dff8cbb91a 613 for (index = 0 ; index < count ; index++)
terencez 0:c2dff8cbb91a 614 {
terencez 0:c2dff8cbb91a 615 lwm2m_data_t * targetP;
terencez 0:c2dff8cbb91a 616 int resSegmentIndex;
terencez 0:c2dff8cbb91a 617 int i;
terencez 0:c2dff8cbb91a 618
terencez 0:c2dff8cbb91a 619 // check URI depth
terencez 0:c2dff8cbb91a 620 // resSegmentIndex is set to the resource segment position
terencez 0:c2dff8cbb91a 621 switch(rootLevel)
terencez 0:c2dff8cbb91a 622 {
terencez 0:c2dff8cbb91a 623 case URI_DEPTH_OBJECT:
terencez 0:c2dff8cbb91a 624 resSegmentIndex = 2;
terencez 0:c2dff8cbb91a 625 break;
terencez 0:c2dff8cbb91a 626 case URI_DEPTH_OBJECT_INSTANCE:
terencez 0:c2dff8cbb91a 627 resSegmentIndex = 1;
terencez 0:c2dff8cbb91a 628 break;
terencez 0:c2dff8cbb91a 629 case URI_DEPTH_RESOURCE:
terencez 0:c2dff8cbb91a 630 resSegmentIndex = 0;
terencez 0:c2dff8cbb91a 631 break;
terencez 0:c2dff8cbb91a 632 case URI_DEPTH_RESOURCE_INSTANCE:
terencez 0:c2dff8cbb91a 633 resSegmentIndex = -1;
terencez 0:c2dff8cbb91a 634 break;
terencez 0:c2dff8cbb91a 635 default:
terencez 0:c2dff8cbb91a 636 goto error;
terencez 0:c2dff8cbb91a 637 }
terencez 0:c2dff8cbb91a 638 for (i = 0 ; i <= resSegmentIndex ; i++)
terencez 0:c2dff8cbb91a 639 {
terencez 0:c2dff8cbb91a 640 if (recordArray[index].ids[i] == LWM2M_MAX_ID) goto error;
terencez 0:c2dff8cbb91a 641 }
terencez 0:c2dff8cbb91a 642 if (resSegmentIndex < 2)
terencez 0:c2dff8cbb91a 643 {
terencez 0:c2dff8cbb91a 644 if (recordArray[index].ids[resSegmentIndex + 2] != LWM2M_MAX_ID) goto error;
terencez 0:c2dff8cbb91a 645 }
terencez 0:c2dff8cbb91a 646
terencez 0:c2dff8cbb91a 647 targetP = prv_findDataItem(rootP, count, recordArray[index].ids[0]);
terencez 0:c2dff8cbb91a 648 if (targetP == NULL)
terencez 0:c2dff8cbb91a 649 {
terencez 0:c2dff8cbb91a 650 targetP = rootP + freeIndex;
terencez 0:c2dff8cbb91a 651 freeIndex++;
terencez 0:c2dff8cbb91a 652 targetP->id = recordArray[index].ids[0];
terencez 0:c2dff8cbb91a 653 targetP->type = utils_depthToDatatype(rootLevel);
terencez 0:c2dff8cbb91a 654 }
terencez 0:c2dff8cbb91a 655 if (recordArray[index].ids[1] != LWM2M_MAX_ID)
terencez 0:c2dff8cbb91a 656 {
terencez 0:c2dff8cbb91a 657 lwm2m_data_t * parentP;
terencez 0:c2dff8cbb91a 658 uri_depth_t level;
terencez 0:c2dff8cbb91a 659
terencez 0:c2dff8cbb91a 660 parentP = targetP;
terencez 0:c2dff8cbb91a 661 level = prv_decreaseLevel(rootLevel);
terencez 0:c2dff8cbb91a 662 for (i = 1 ; i <= resSegmentIndex ; i++)
terencez 0:c2dff8cbb91a 663 {
terencez 0:c2dff8cbb91a 664 targetP = prv_findDataItem(parentP->value.asChildren.array, parentP->value.asChildren.count, recordArray[index].ids[i]);
terencez 0:c2dff8cbb91a 665 if (targetP == NULL)
terencez 0:c2dff8cbb91a 666 {
terencez 0:c2dff8cbb91a 667 targetP = prv_extendData(parentP);
terencez 0:c2dff8cbb91a 668 if (targetP == NULL) goto error;
terencez 0:c2dff8cbb91a 669 targetP->id = recordArray[index].ids[i];
terencez 0:c2dff8cbb91a 670 targetP->type = utils_depthToDatatype(level);
terencez 0:c2dff8cbb91a 671 }
terencez 0:c2dff8cbb91a 672 level = prv_decreaseLevel(level);
terencez 0:c2dff8cbb91a 673 parentP = targetP;
terencez 0:c2dff8cbb91a 674 }
terencez 0:c2dff8cbb91a 675 if (recordArray[index].ids[resSegmentIndex + 1] != LWM2M_MAX_ID)
terencez 0:c2dff8cbb91a 676 {
terencez 0:c2dff8cbb91a 677 targetP->type = LWM2M_TYPE_MULTIPLE_RESOURCE;
terencez 0:c2dff8cbb91a 678 targetP = prv_extendData(targetP);
terencez 0:c2dff8cbb91a 679 if (targetP == NULL) goto error;
terencez 0:c2dff8cbb91a 680 targetP->id = recordArray[index].ids[resSegmentIndex + 1];
terencez 0:c2dff8cbb91a 681 targetP->type = LWM2M_TYPE_UNDEFINED;
terencez 0:c2dff8cbb91a 682 }
terencez 0:c2dff8cbb91a 683 }
terencez 0:c2dff8cbb91a 684
terencez 0:c2dff8cbb91a 685 if (true != prv_convertValue(recordArray + index, targetP)) goto error;
terencez 0:c2dff8cbb91a 686 }
terencez 0:c2dff8cbb91a 687
terencez 0:c2dff8cbb91a 688 return size;
terencez 0:c2dff8cbb91a 689
terencez 0:c2dff8cbb91a 690 error:
terencez 0:c2dff8cbb91a 691 lwm2m_data_free(size, *dataP);
terencez 0:c2dff8cbb91a 692 *dataP = NULL;
terencez 0:c2dff8cbb91a 693
terencez 0:c2dff8cbb91a 694 return -1;
terencez 0:c2dff8cbb91a 695 }
terencez 0:c2dff8cbb91a 696
terencez 0:c2dff8cbb91a 697 static int prv_dataStrip(int size,
terencez 0:c2dff8cbb91a 698 lwm2m_data_t * dataP,
terencez 0:c2dff8cbb91a 699 lwm2m_data_t ** resultP)
terencez 0:c2dff8cbb91a 700 {
terencez 0:c2dff8cbb91a 701 int i;
terencez 0:c2dff8cbb91a 702 int j;
terencez 0:c2dff8cbb91a 703 int realSize;
terencez 0:c2dff8cbb91a 704
terencez 0:c2dff8cbb91a 705 realSize = 0;
terencez 0:c2dff8cbb91a 706 for (i = 0 ; i < size ; i++)
terencez 0:c2dff8cbb91a 707 {
terencez 0:c2dff8cbb91a 708 if (dataP[i].type != LWM2M_TYPE_UNDEFINED)
terencez 0:c2dff8cbb91a 709 {
terencez 0:c2dff8cbb91a 710 realSize++;
terencez 0:c2dff8cbb91a 711 }
terencez 0:c2dff8cbb91a 712 }
terencez 0:c2dff8cbb91a 713
terencez 0:c2dff8cbb91a 714 *resultP = lwm2m_data_new(realSize);
terencez 0:c2dff8cbb91a 715 if (*resultP == NULL) return -1;
terencez 0:c2dff8cbb91a 716
terencez 0:c2dff8cbb91a 717 j = 0;
terencez 0:c2dff8cbb91a 718 for (i = 0 ; i < size ; i++)
terencez 0:c2dff8cbb91a 719 {
terencez 0:c2dff8cbb91a 720 if (dataP[i].type != LWM2M_TYPE_UNDEFINED)
terencez 0:c2dff8cbb91a 721 {
terencez 0:c2dff8cbb91a 722 memcpy((*resultP) + j, dataP + i, sizeof(lwm2m_data_t));
terencez 0:c2dff8cbb91a 723
terencez 0:c2dff8cbb91a 724 if (dataP[i].type == LWM2M_TYPE_OBJECT
terencez 0:c2dff8cbb91a 725 || dataP[i].type == LWM2M_TYPE_OBJECT_INSTANCE
terencez 0:c2dff8cbb91a 726 || dataP[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE)
terencez 0:c2dff8cbb91a 727 {
terencez 0:c2dff8cbb91a 728 int childLen;
terencez 0:c2dff8cbb91a 729
terencez 0:c2dff8cbb91a 730 childLen = prv_dataStrip(dataP[i].value.asChildren.count, dataP[i].value.asChildren.array, &((*resultP)[j].value.asChildren.array));
terencez 0:c2dff8cbb91a 731 if (childLen <= 0)
terencez 0:c2dff8cbb91a 732 {
terencez 0:c2dff8cbb91a 733 // skip this one
terencez 0:c2dff8cbb91a 734 j--;
terencez 0:c2dff8cbb91a 735 }
terencez 0:c2dff8cbb91a 736 else
terencez 0:c2dff8cbb91a 737 {
terencez 0:c2dff8cbb91a 738 (*resultP)[j].value.asChildren.count = childLen;
terencez 0:c2dff8cbb91a 739 }
terencez 0:c2dff8cbb91a 740 }
terencez 0:c2dff8cbb91a 741 else
terencez 0:c2dff8cbb91a 742 {
terencez 0:c2dff8cbb91a 743 dataP[i].value.asBuffer.buffer = NULL;
terencez 0:c2dff8cbb91a 744 }
terencez 0:c2dff8cbb91a 745
terencez 0:c2dff8cbb91a 746 j++;
terencez 0:c2dff8cbb91a 747 }
terencez 0:c2dff8cbb91a 748 }
terencez 0:c2dff8cbb91a 749
terencez 0:c2dff8cbb91a 750 return realSize;
terencez 0:c2dff8cbb91a 751 }
terencez 0:c2dff8cbb91a 752
terencez 0:c2dff8cbb91a 753 int json_parse(lwm2m_uri_t * uriP,
terencez 0:c2dff8cbb91a 754 uint8_t * buffer,
terencez 0:c2dff8cbb91a 755 size_t bufferLen,
terencez 0:c2dff8cbb91a 756 lwm2m_data_t ** dataP)
terencez 0:c2dff8cbb91a 757 {
terencez 0:c2dff8cbb91a 758 size_t index;
terencez 0:c2dff8cbb91a 759 int count = 0;
terencez 0:c2dff8cbb91a 760 bool eFound = false;
terencez 0:c2dff8cbb91a 761 bool bnFound = false;
terencez 0:c2dff8cbb91a 762 bool btFound = false;
terencez 0:c2dff8cbb91a 763 int bnStart;
terencez 0:c2dff8cbb91a 764 int bnLen;
terencez 0:c2dff8cbb91a 765 _record_t * recordArray;
terencez 0:c2dff8cbb91a 766 lwm2m_data_t * parsedP;
terencez 0:c2dff8cbb91a 767
terencez 0:c2dff8cbb91a 768 LOG_ARG("bufferLen: %d, buffer: \"%s\"", bufferLen, (char *)buffer);
terencez 0:c2dff8cbb91a 769 LOG_URI(uriP);
terencez 0:c2dff8cbb91a 770 *dataP = NULL;
terencez 0:c2dff8cbb91a 771 recordArray = NULL;
terencez 0:c2dff8cbb91a 772 parsedP = NULL;
terencez 0:c2dff8cbb91a 773
terencez 0:c2dff8cbb91a 774 index = prv_skipSpace(buffer, bufferLen);
terencez 0:c2dff8cbb91a 775 if (index == bufferLen) return -1;
terencez 0:c2dff8cbb91a 776
terencez 0:c2dff8cbb91a 777 if (buffer[index] != '{') return -1;
terencez 0:c2dff8cbb91a 778 do
terencez 0:c2dff8cbb91a 779 {
terencez 0:c2dff8cbb91a 780 _GO_TO_NEXT_CHAR(index, buffer, bufferLen);
terencez 0:c2dff8cbb91a 781 if (buffer[index] != '"') goto error;
terencez 0:c2dff8cbb91a 782 if (index++ >= bufferLen) goto error;
terencez 0:c2dff8cbb91a 783 switch (buffer[index])
terencez 0:c2dff8cbb91a 784 {
terencez 0:c2dff8cbb91a 785 case 'e':
terencez 0:c2dff8cbb91a 786 {
terencez 0:c2dff8cbb91a 787 int recordIndex;
terencez 0:c2dff8cbb91a 788
terencez 0:c2dff8cbb91a 789 if (bufferLen-index < JSON_MIN_ARRAY_LEN) goto error;
terencez 0:c2dff8cbb91a 790 index++;
terencez 0:c2dff8cbb91a 791 if (buffer[index] != '"') goto error;
terencez 0:c2dff8cbb91a 792 if (eFound == true) goto error;
terencez 0:c2dff8cbb91a 793 eFound = true;
terencez 0:c2dff8cbb91a 794
terencez 0:c2dff8cbb91a 795 _GO_TO_NEXT_CHAR(index, buffer, bufferLen);
terencez 0:c2dff8cbb91a 796 if (buffer[index] != ':') goto error;
terencez 0:c2dff8cbb91a 797 _GO_TO_NEXT_CHAR(index, buffer, bufferLen);
terencez 0:c2dff8cbb91a 798 if (buffer[index] != '[') goto error;
terencez 0:c2dff8cbb91a 799 _GO_TO_NEXT_CHAR(index, buffer, bufferLen);
terencez 0:c2dff8cbb91a 800 count = prv_countItems(buffer + index, bufferLen - index);
terencez 0:c2dff8cbb91a 801 if (count <= 0) goto error;
terencez 0:c2dff8cbb91a 802 recordArray = (_record_t*)lwm2m_malloc(count * sizeof(_record_t));
terencez 0:c2dff8cbb91a 803 if (recordArray == NULL) goto error;
terencez 0:c2dff8cbb91a 804 // at this point we are sure buffer[index] is '{' and all { and } are matching
terencez 0:c2dff8cbb91a 805 recordIndex = 0;
terencez 0:c2dff8cbb91a 806 while (recordIndex < count)
terencez 0:c2dff8cbb91a 807 {
terencez 0:c2dff8cbb91a 808 int itemLen;
terencez 0:c2dff8cbb91a 809
terencez 0:c2dff8cbb91a 810 if (buffer[index] != '{') goto error;
terencez 0:c2dff8cbb91a 811 itemLen = 0;
terencez 0:c2dff8cbb91a 812 while (buffer[index + itemLen] != '}') itemLen++;
terencez 0:c2dff8cbb91a 813 if (0 != prv_parseItem(buffer + index + 1, itemLen - 1, recordArray + recordIndex))
terencez 0:c2dff8cbb91a 814 {
terencez 0:c2dff8cbb91a 815 goto error;
terencez 0:c2dff8cbb91a 816 }
terencez 0:c2dff8cbb91a 817 recordIndex++;
terencez 0:c2dff8cbb91a 818 index += itemLen;
terencez 0:c2dff8cbb91a 819 _GO_TO_NEXT_CHAR(index, buffer, bufferLen);
terencez 0:c2dff8cbb91a 820 switch (buffer[index])
terencez 0:c2dff8cbb91a 821 {
terencez 0:c2dff8cbb91a 822 case ',':
terencez 0:c2dff8cbb91a 823 _GO_TO_NEXT_CHAR(index, buffer, bufferLen);
terencez 0:c2dff8cbb91a 824 break;
terencez 0:c2dff8cbb91a 825 case ']':
terencez 0:c2dff8cbb91a 826 if (recordIndex == count) break;
terencez 0:c2dff8cbb91a 827 // else this is an error
terencez 0:c2dff8cbb91a 828 default:
terencez 0:c2dff8cbb91a 829 goto error;
terencez 0:c2dff8cbb91a 830 }
terencez 0:c2dff8cbb91a 831 }
terencez 0:c2dff8cbb91a 832 if (buffer[index] != ']') goto error;
terencez 0:c2dff8cbb91a 833 }
terencez 0:c2dff8cbb91a 834 break;
terencez 0:c2dff8cbb91a 835
terencez 0:c2dff8cbb91a 836 case 'b':
terencez 0:c2dff8cbb91a 837 if (bufferLen-index < JSON_MIN_BX_LEN) goto error;
terencez 0:c2dff8cbb91a 838 index++;
terencez 0:c2dff8cbb91a 839 switch (buffer[index])
terencez 0:c2dff8cbb91a 840 {
terencez 0:c2dff8cbb91a 841 case 't':
terencez 0:c2dff8cbb91a 842 index++;
terencez 0:c2dff8cbb91a 843 if (buffer[index] != '"') goto error;
terencez 0:c2dff8cbb91a 844 if (btFound == true) goto error;
terencez 0:c2dff8cbb91a 845 btFound = true;
terencez 0:c2dff8cbb91a 846
terencez 0:c2dff8cbb91a 847 // TODO: handle timed values
terencez 0:c2dff8cbb91a 848 // temp: skip this token
terencez 0:c2dff8cbb91a 849 while(index < bufferLen && buffer[index] != ',' && buffer[index] != '}') index++;
terencez 0:c2dff8cbb91a 850 if (index == bufferLen) goto error;
terencez 0:c2dff8cbb91a 851 index--;
terencez 0:c2dff8cbb91a 852 // end temp
terencez 0:c2dff8cbb91a 853 break;
terencez 0:c2dff8cbb91a 854 case 'n':
terencez 0:c2dff8cbb91a 855 {
terencez 0:c2dff8cbb91a 856 int next;
terencez 0:c2dff8cbb91a 857 int tokenStart;
terencez 0:c2dff8cbb91a 858 int tokenLen;
terencez 0:c2dff8cbb91a 859 int itemLen;
terencez 0:c2dff8cbb91a 860
terencez 0:c2dff8cbb91a 861 index++;
terencez 0:c2dff8cbb91a 862 if (buffer[index] != '"') goto error;
terencez 0:c2dff8cbb91a 863 if (bnFound == true) goto error;
terencez 0:c2dff8cbb91a 864 bnFound = true;
terencez 0:c2dff8cbb91a 865 index -= 3;
terencez 0:c2dff8cbb91a 866 itemLen = 0;
terencez 0:c2dff8cbb91a 867 while (buffer[index + itemLen] != '}'
terencez 0:c2dff8cbb91a 868 && buffer[index + itemLen] != ','
terencez 0:c2dff8cbb91a 869 && index + itemLen < bufferLen)
terencez 0:c2dff8cbb91a 870 {
terencez 0:c2dff8cbb91a 871 itemLen++;
terencez 0:c2dff8cbb91a 872 }
terencez 0:c2dff8cbb91a 873 if (index + itemLen == bufferLen) goto error;
terencez 0:c2dff8cbb91a 874 next = prv_split(buffer+index, itemLen, &tokenStart, &tokenLen, &bnStart, &bnLen);
terencez 0:c2dff8cbb91a 875 if (next < 0) goto error;
terencez 0:c2dff8cbb91a 876 bnStart += index;
terencez 0:c2dff8cbb91a 877 index += next - 1;
terencez 0:c2dff8cbb91a 878 }
terencez 0:c2dff8cbb91a 879 break;
terencez 0:c2dff8cbb91a 880 default:
terencez 0:c2dff8cbb91a 881 goto error;
terencez 0:c2dff8cbb91a 882 }
terencez 0:c2dff8cbb91a 883 break;
terencez 0:c2dff8cbb91a 884
terencez 0:c2dff8cbb91a 885 default:
terencez 0:c2dff8cbb91a 886 goto error;
terencez 0:c2dff8cbb91a 887 }
terencez 0:c2dff8cbb91a 888
terencez 0:c2dff8cbb91a 889 _GO_TO_NEXT_CHAR(index, buffer, bufferLen);
terencez 0:c2dff8cbb91a 890 } while (buffer[index] == ',');
terencez 0:c2dff8cbb91a 891
terencez 0:c2dff8cbb91a 892 if (buffer[index] != '}') goto error;
terencez 0:c2dff8cbb91a 893
terencez 0:c2dff8cbb91a 894 if (eFound == true)
terencez 0:c2dff8cbb91a 895 {
terencez 0:c2dff8cbb91a 896 lwm2m_uri_t baseURI;
terencez 0:c2dff8cbb91a 897 lwm2m_uri_t * baseUriP;
terencez 0:c2dff8cbb91a 898 lwm2m_data_t * resultP;
terencez 0:c2dff8cbb91a 899 int size;
terencez 0:c2dff8cbb91a 900
terencez 0:c2dff8cbb91a 901 memset(&baseURI, 0, sizeof(lwm2m_uri_t));
terencez 0:c2dff8cbb91a 902 if (bnFound == false)
terencez 0:c2dff8cbb91a 903 {
terencez 0:c2dff8cbb91a 904 baseUriP = uriP;
terencez 0:c2dff8cbb91a 905 }
terencez 0:c2dff8cbb91a 906 else
terencez 0:c2dff8cbb91a 907 {
terencez 0:c2dff8cbb91a 908 int res;
terencez 0:c2dff8cbb91a 909
terencez 0:c2dff8cbb91a 910 // we ignore the request URI and use the bn one.
terencez 0:c2dff8cbb91a 911
terencez 0:c2dff8cbb91a 912 // Check for " around URI
terencez 0:c2dff8cbb91a 913 if (bnLen < 3
terencez 0:c2dff8cbb91a 914 || buffer[bnStart] != '"'
terencez 0:c2dff8cbb91a 915 || buffer[bnStart+bnLen-1] != '"')
terencez 0:c2dff8cbb91a 916 {
terencez 0:c2dff8cbb91a 917 goto error;
terencez 0:c2dff8cbb91a 918 }
terencez 0:c2dff8cbb91a 919 bnStart += 1;
terencez 0:c2dff8cbb91a 920 bnLen -= 2;
terencez 0:c2dff8cbb91a 921
terencez 0:c2dff8cbb91a 922 if (bnLen == 1)
terencez 0:c2dff8cbb91a 923 {
terencez 0:c2dff8cbb91a 924 if (buffer[bnStart] != '/') goto error;
terencez 0:c2dff8cbb91a 925 baseUriP = NULL;
terencez 0:c2dff8cbb91a 926 }
terencez 0:c2dff8cbb91a 927 else
terencez 0:c2dff8cbb91a 928 {
terencez 0:c2dff8cbb91a 929 res = lwm2m_stringToUri((char *)buffer + bnStart, bnLen, &baseURI);
terencez 0:c2dff8cbb91a 930 if (res < 0 || res != bnLen) goto error;
terencez 0:c2dff8cbb91a 931 baseUriP = &baseURI;
terencez 0:c2dff8cbb91a 932 }
terencez 0:c2dff8cbb91a 933 }
terencez 0:c2dff8cbb91a 934
terencez 0:c2dff8cbb91a 935 count = prv_convertRecord(baseUriP, recordArray, count, &parsedP);
terencez 0:c2dff8cbb91a 936 lwm2m_free(recordArray);
terencez 0:c2dff8cbb91a 937 recordArray = NULL;
terencez 0:c2dff8cbb91a 938
terencez 0:c2dff8cbb91a 939 if (count > 0 && uriP != NULL)
terencez 0:c2dff8cbb91a 940 {
terencez 0:c2dff8cbb91a 941 if (parsedP->type != LWM2M_TYPE_OBJECT || parsedP->id != uriP->objectId) goto error;
terencez 0:c2dff8cbb91a 942 if (!LWM2M_URI_IS_SET_INSTANCE(uriP))
terencez 0:c2dff8cbb91a 943 {
terencez 0:c2dff8cbb91a 944 size = parsedP->value.asChildren.count;
terencez 0:c2dff8cbb91a 945 resultP = parsedP->value.asChildren.array;
terencez 0:c2dff8cbb91a 946 }
terencez 0:c2dff8cbb91a 947 else
terencez 0:c2dff8cbb91a 948 {
terencez 0:c2dff8cbb91a 949 int i;
terencez 0:c2dff8cbb91a 950
terencez 0:c2dff8cbb91a 951 resultP = NULL;
terencez 0:c2dff8cbb91a 952 // be permissive and allow full object JSON when requesting for a single instance
terencez 0:c2dff8cbb91a 953 for (i = 0 ; i < (int)parsedP->value.asChildren.count && resultP == NULL; i++)
terencez 0:c2dff8cbb91a 954 {
terencez 0:c2dff8cbb91a 955 lwm2m_data_t * targetP;
terencez 0:c2dff8cbb91a 956
terencez 0:c2dff8cbb91a 957 targetP = parsedP->value.asChildren.array + i;
terencez 0:c2dff8cbb91a 958 if (targetP->id == uriP->instanceId)
terencez 0:c2dff8cbb91a 959 {
terencez 0:c2dff8cbb91a 960 resultP = targetP->value.asChildren.array;
terencez 0:c2dff8cbb91a 961 size = targetP->value.asChildren.count;
terencez 0:c2dff8cbb91a 962 }
terencez 0:c2dff8cbb91a 963 }
terencez 0:c2dff8cbb91a 964 if (resultP == NULL) goto error;
terencez 0:c2dff8cbb91a 965 if (LWM2M_URI_IS_SET_RESOURCE(uriP))
terencez 0:c2dff8cbb91a 966 {
terencez 0:c2dff8cbb91a 967 lwm2m_data_t * resP;
terencez 0:c2dff8cbb91a 968
terencez 0:c2dff8cbb91a 969 resP = NULL;
terencez 0:c2dff8cbb91a 970 for (i = 0 ; i < size && resP == NULL; i++)
terencez 0:c2dff8cbb91a 971 {
terencez 0:c2dff8cbb91a 972 lwm2m_data_t * targetP;
terencez 0:c2dff8cbb91a 973
terencez 0:c2dff8cbb91a 974 targetP = resultP + i;
terencez 0:c2dff8cbb91a 975 if (targetP->id == uriP->resourceId)
terencez 0:c2dff8cbb91a 976 {
terencez 0:c2dff8cbb91a 977 if (targetP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
terencez 0:c2dff8cbb91a 978 {
terencez 0:c2dff8cbb91a 979 resP = targetP->value.asChildren.array;
terencez 0:c2dff8cbb91a 980 size = targetP->value.asChildren.count;
terencez 0:c2dff8cbb91a 981 }
terencez 0:c2dff8cbb91a 982 else
terencez 0:c2dff8cbb91a 983 {
terencez 0:c2dff8cbb91a 984 size = prv_dataStrip(1, targetP, &resP);
terencez 0:c2dff8cbb91a 985 if (size <= 0) goto error;
terencez 0:c2dff8cbb91a 986 lwm2m_data_free(count, parsedP);
terencez 0:c2dff8cbb91a 987 parsedP = NULL;
terencez 0:c2dff8cbb91a 988 }
terencez 0:c2dff8cbb91a 989 }
terencez 0:c2dff8cbb91a 990 }
terencez 0:c2dff8cbb91a 991 if (resP == NULL) goto error;
terencez 0:c2dff8cbb91a 992 resultP = resP;
terencez 0:c2dff8cbb91a 993 }
terencez 0:c2dff8cbb91a 994 }
terencez 0:c2dff8cbb91a 995 }
terencez 0:c2dff8cbb91a 996 else
terencez 0:c2dff8cbb91a 997 {
terencez 0:c2dff8cbb91a 998 resultP = parsedP;
terencez 0:c2dff8cbb91a 999 size = count;
terencez 0:c2dff8cbb91a 1000 }
terencez 0:c2dff8cbb91a 1001
terencez 0:c2dff8cbb91a 1002 if (parsedP != NULL)
terencez 0:c2dff8cbb91a 1003 {
terencez 0:c2dff8cbb91a 1004 lwm2m_data_t * tempP;
terencez 0:c2dff8cbb91a 1005
terencez 0:c2dff8cbb91a 1006 size = prv_dataStrip(size, resultP, &tempP);
terencez 0:c2dff8cbb91a 1007 if (size <= 0) goto error;
terencez 0:c2dff8cbb91a 1008 lwm2m_data_free(count, parsedP);
terencez 0:c2dff8cbb91a 1009 resultP = tempP;
terencez 0:c2dff8cbb91a 1010 }
terencez 0:c2dff8cbb91a 1011 count = size;
terencez 0:c2dff8cbb91a 1012 *dataP = resultP;
terencez 0:c2dff8cbb91a 1013 }
terencez 0:c2dff8cbb91a 1014
terencez 0:c2dff8cbb91a 1015 LOG_ARG("Parsing successful. count: %d", count);
terencez 0:c2dff8cbb91a 1016 return count;
terencez 0:c2dff8cbb91a 1017
terencez 0:c2dff8cbb91a 1018 error:
terencez 0:c2dff8cbb91a 1019 LOG("Parsing failed");
terencez 0:c2dff8cbb91a 1020 if (parsedP != NULL)
terencez 0:c2dff8cbb91a 1021 {
terencez 0:c2dff8cbb91a 1022 lwm2m_data_free(count, parsedP);
terencez 0:c2dff8cbb91a 1023 parsedP = NULL;
terencez 0:c2dff8cbb91a 1024 }
terencez 0:c2dff8cbb91a 1025 if (recordArray != NULL)
terencez 0:c2dff8cbb91a 1026 {
terencez 0:c2dff8cbb91a 1027 lwm2m_free(recordArray);
terencez 0:c2dff8cbb91a 1028 }
terencez 0:c2dff8cbb91a 1029 return -1;
terencez 0:c2dff8cbb91a 1030 }
terencez 0:c2dff8cbb91a 1031
terencez 0:c2dff8cbb91a 1032 static int prv_serializeValue(lwm2m_data_t * tlvP,
terencez 0:c2dff8cbb91a 1033 uint8_t * buffer,
terencez 0:c2dff8cbb91a 1034 size_t bufferLen)
terencez 0:c2dff8cbb91a 1035 {
terencez 0:c2dff8cbb91a 1036 int res;
terencez 0:c2dff8cbb91a 1037 int head;
terencez 0:c2dff8cbb91a 1038
terencez 0:c2dff8cbb91a 1039 switch (tlvP->type)
terencez 0:c2dff8cbb91a 1040 {
terencez 0:c2dff8cbb91a 1041 case LWM2M_TYPE_STRING:
terencez 0:c2dff8cbb91a 1042 if (bufferLen < JSON_ITEM_STRING_BEGIN_SIZE) return -1;
terencez 0:c2dff8cbb91a 1043 memcpy(buffer, JSON_ITEM_STRING_BEGIN, JSON_ITEM_STRING_BEGIN_SIZE);
terencez 0:c2dff8cbb91a 1044 head = JSON_ITEM_STRING_BEGIN_SIZE;
terencez 0:c2dff8cbb91a 1045
terencez 0:c2dff8cbb91a 1046 if (bufferLen - head < tlvP->value.asBuffer.length) return -1;
terencez 0:c2dff8cbb91a 1047 memcpy(buffer + head, tlvP->value.asBuffer.buffer, tlvP->value.asBuffer.length);
terencez 0:c2dff8cbb91a 1048 head += tlvP->value.asBuffer.length;
terencez 0:c2dff8cbb91a 1049
terencez 0:c2dff8cbb91a 1050 if (bufferLen - head < JSON_ITEM_STRING_END_SIZE) return -1;
terencez 0:c2dff8cbb91a 1051 memcpy(buffer + head, JSON_ITEM_STRING_END, JSON_ITEM_STRING_END_SIZE);
terencez 0:c2dff8cbb91a 1052 head += JSON_ITEM_STRING_END_SIZE;
terencez 0:c2dff8cbb91a 1053
terencez 0:c2dff8cbb91a 1054 break;
terencez 0:c2dff8cbb91a 1055
terencez 0:c2dff8cbb91a 1056 case LWM2M_TYPE_INTEGER:
terencez 0:c2dff8cbb91a 1057 {
terencez 0:c2dff8cbb91a 1058 int64_t value;
terencez 0:c2dff8cbb91a 1059
terencez 0:c2dff8cbb91a 1060 if (0 == lwm2m_data_decode_int(tlvP, &value)) return -1;
terencez 0:c2dff8cbb91a 1061
terencez 0:c2dff8cbb91a 1062 if (bufferLen < JSON_ITEM_NUM_SIZE) return -1;
terencez 0:c2dff8cbb91a 1063 memcpy(buffer, JSON_ITEM_NUM, JSON_ITEM_NUM_SIZE);
terencez 0:c2dff8cbb91a 1064 head = JSON_ITEM_NUM_SIZE;
terencez 0:c2dff8cbb91a 1065
terencez 0:c2dff8cbb91a 1066 res = utils_intToText(value, buffer + head, bufferLen - head);
terencez 0:c2dff8cbb91a 1067 if (res <= 0) return -1;
terencez 0:c2dff8cbb91a 1068 head += res;
terencez 0:c2dff8cbb91a 1069
terencez 0:c2dff8cbb91a 1070 if (bufferLen - head < JSON_ITEM_NUM_END_SIZE) return -1;
terencez 0:c2dff8cbb91a 1071 memcpy(buffer + head, JSON_ITEM_NUM_END, JSON_ITEM_NUM_END_SIZE);
terencez 0:c2dff8cbb91a 1072 head += JSON_ITEM_NUM_END_SIZE;
terencez 0:c2dff8cbb91a 1073 }
terencez 0:c2dff8cbb91a 1074 break;
terencez 0:c2dff8cbb91a 1075
terencez 0:c2dff8cbb91a 1076 case LWM2M_TYPE_FLOAT:
terencez 0:c2dff8cbb91a 1077 {
terencez 0:c2dff8cbb91a 1078 double value;
terencez 0:c2dff8cbb91a 1079
terencez 0:c2dff8cbb91a 1080 if (0 == lwm2m_data_decode_float(tlvP, &value)) return -1;
terencez 0:c2dff8cbb91a 1081
terencez 0:c2dff8cbb91a 1082 if (bufferLen < JSON_ITEM_NUM_SIZE) return -1;
terencez 0:c2dff8cbb91a 1083 memcpy(buffer, JSON_ITEM_NUM, JSON_ITEM_NUM_SIZE);
terencez 0:c2dff8cbb91a 1084 head = JSON_ITEM_NUM_SIZE;
terencez 0:c2dff8cbb91a 1085
terencez 0:c2dff8cbb91a 1086 res = utils_floatToText(value, buffer + head, bufferLen - head);
terencez 0:c2dff8cbb91a 1087 if (res <= 0) return -1;
terencez 0:c2dff8cbb91a 1088 head += res;
terencez 0:c2dff8cbb91a 1089
terencez 0:c2dff8cbb91a 1090 if (bufferLen - head < JSON_ITEM_NUM_END_SIZE) return -1;
terencez 0:c2dff8cbb91a 1091 memcpy(buffer + head, JSON_ITEM_NUM_END, JSON_ITEM_NUM_END_SIZE);
terencez 0:c2dff8cbb91a 1092 head += JSON_ITEM_NUM_END_SIZE;
terencez 0:c2dff8cbb91a 1093 }
terencez 0:c2dff8cbb91a 1094 break;
terencez 0:c2dff8cbb91a 1095
terencez 0:c2dff8cbb91a 1096 case LWM2M_TYPE_BOOLEAN:
terencez 0:c2dff8cbb91a 1097 {
terencez 0:c2dff8cbb91a 1098 bool value;
terencez 0:c2dff8cbb91a 1099
terencez 0:c2dff8cbb91a 1100 if (0 == lwm2m_data_decode_bool(tlvP, &value)) return -1;
terencez 0:c2dff8cbb91a 1101
terencez 0:c2dff8cbb91a 1102 if (value == true)
terencez 0:c2dff8cbb91a 1103 {
terencez 0:c2dff8cbb91a 1104 if (bufferLen < JSON_ITEM_BOOL_TRUE_SIZE) return -1;
terencez 0:c2dff8cbb91a 1105 memcpy(buffer, JSON_ITEM_BOOL_TRUE, JSON_ITEM_BOOL_TRUE_SIZE);
terencez 0:c2dff8cbb91a 1106 head = JSON_ITEM_BOOL_TRUE_SIZE;
terencez 0:c2dff8cbb91a 1107 }
terencez 0:c2dff8cbb91a 1108 else
terencez 0:c2dff8cbb91a 1109 {
terencez 0:c2dff8cbb91a 1110 if (bufferLen < JSON_ITEM_BOOL_FALSE_SIZE) return -1;
terencez 0:c2dff8cbb91a 1111 memcpy(buffer, JSON_ITEM_BOOL_FALSE, JSON_ITEM_BOOL_FALSE_SIZE);
terencez 0:c2dff8cbb91a 1112 head = JSON_ITEM_BOOL_FALSE_SIZE;
terencez 0:c2dff8cbb91a 1113 }
terencez 0:c2dff8cbb91a 1114 }
terencez 0:c2dff8cbb91a 1115 break;
terencez 0:c2dff8cbb91a 1116
terencez 0:c2dff8cbb91a 1117 case LWM2M_TYPE_OPAQUE:
terencez 0:c2dff8cbb91a 1118 if (bufferLen < JSON_ITEM_STRING_BEGIN_SIZE) return -1;
terencez 0:c2dff8cbb91a 1119 memcpy(buffer, JSON_ITEM_STRING_BEGIN, JSON_ITEM_STRING_BEGIN_SIZE);
terencez 0:c2dff8cbb91a 1120 head = JSON_ITEM_STRING_BEGIN_SIZE;
terencez 0:c2dff8cbb91a 1121
terencez 0:c2dff8cbb91a 1122 res = utils_base64Encode(tlvP->value.asBuffer.buffer, tlvP->value.asBuffer.length, buffer+head, bufferLen - head);
terencez 0:c2dff8cbb91a 1123 if (res == 0) return -1;
terencez 0:c2dff8cbb91a 1124 head += res;
terencez 0:c2dff8cbb91a 1125
terencez 0:c2dff8cbb91a 1126 if (bufferLen - head < JSON_ITEM_STRING_END_SIZE) return -1;
terencez 0:c2dff8cbb91a 1127 memcpy(buffer + head, JSON_ITEM_STRING_END, JSON_ITEM_STRING_END_SIZE);
terencez 0:c2dff8cbb91a 1128 head += JSON_ITEM_STRING_END_SIZE;
terencez 0:c2dff8cbb91a 1129 break;
terencez 0:c2dff8cbb91a 1130
terencez 0:c2dff8cbb91a 1131 case LWM2M_TYPE_OBJECT_LINK:
terencez 0:c2dff8cbb91a 1132 // TODO: implement
terencez 0:c2dff8cbb91a 1133 return -1;
terencez 0:c2dff8cbb91a 1134
terencez 0:c2dff8cbb91a 1135 default:
terencez 0:c2dff8cbb91a 1136 return -1;
terencez 0:c2dff8cbb91a 1137 }
terencez 0:c2dff8cbb91a 1138
terencez 0:c2dff8cbb91a 1139 return head;
terencez 0:c2dff8cbb91a 1140 }
terencez 0:c2dff8cbb91a 1141
terencez 0:c2dff8cbb91a 1142 int prv_serializeData(lwm2m_data_t * tlvP,
terencez 0:c2dff8cbb91a 1143 uint8_t * parentUriStr,
terencez 0:c2dff8cbb91a 1144 size_t parentUriLen,
terencez 0:c2dff8cbb91a 1145 uint8_t * buffer,
terencez 0:c2dff8cbb91a 1146 size_t bufferLen)
terencez 0:c2dff8cbb91a 1147 {
terencez 0:c2dff8cbb91a 1148 int head;
terencez 0:c2dff8cbb91a 1149 int res;
terencez 0:c2dff8cbb91a 1150
terencez 0:c2dff8cbb91a 1151 head = 0;
terencez 0:c2dff8cbb91a 1152
terencez 0:c2dff8cbb91a 1153 switch (tlvP->type)
terencez 0:c2dff8cbb91a 1154 {
terencez 0:c2dff8cbb91a 1155 case LWM2M_TYPE_OBJECT:
terencez 0:c2dff8cbb91a 1156 case LWM2M_TYPE_OBJECT_INSTANCE:
terencez 0:c2dff8cbb91a 1157 case LWM2M_TYPE_MULTIPLE_RESOURCE:
terencez 0:c2dff8cbb91a 1158 {
terencez 0:c2dff8cbb91a 1159 uint8_t uriStr[URI_MAX_STRING_LEN];
terencez 0:c2dff8cbb91a 1160 size_t uriLen;
terencez 0:c2dff8cbb91a 1161 size_t index;
terencez 0:c2dff8cbb91a 1162
terencez 0:c2dff8cbb91a 1163 if (parentUriLen > 0)
terencez 0:c2dff8cbb91a 1164 {
terencez 0:c2dff8cbb91a 1165 if (URI_MAX_STRING_LEN < parentUriLen) return -1;
terencez 0:c2dff8cbb91a 1166 memcpy(uriStr, parentUriStr, parentUriLen);
terencez 0:c2dff8cbb91a 1167 uriLen = parentUriLen;
terencez 0:c2dff8cbb91a 1168 }
terencez 0:c2dff8cbb91a 1169 else
terencez 0:c2dff8cbb91a 1170 {
terencez 0:c2dff8cbb91a 1171 uriLen = 0;
terencez 0:c2dff8cbb91a 1172 }
terencez 0:c2dff8cbb91a 1173 res = utils_intToText(tlvP->id, uriStr + uriLen, URI_MAX_STRING_LEN - uriLen);
terencez 0:c2dff8cbb91a 1174 if (res <= 0) return -1;
terencez 0:c2dff8cbb91a 1175 uriLen += res;
terencez 0:c2dff8cbb91a 1176 uriStr[uriLen] = '/';
terencez 0:c2dff8cbb91a 1177 uriLen++;
terencez 0:c2dff8cbb91a 1178
terencez 0:c2dff8cbb91a 1179 head = 0;
terencez 0:c2dff8cbb91a 1180 for (index = 0 ; index < tlvP->value.asChildren.count; index++)
terencez 0:c2dff8cbb91a 1181 {
terencez 0:c2dff8cbb91a 1182 res = prv_serializeData(tlvP->value.asChildren.array + index, uriStr, uriLen, buffer + head, bufferLen - head);
terencez 0:c2dff8cbb91a 1183 if (res < 0) return -1;
terencez 0:c2dff8cbb91a 1184 head += res;
terencez 0:c2dff8cbb91a 1185 }
terencez 0:c2dff8cbb91a 1186 }
terencez 0:c2dff8cbb91a 1187 break;
terencez 0:c2dff8cbb91a 1188
terencez 0:c2dff8cbb91a 1189 default:
terencez 0:c2dff8cbb91a 1190 if (bufferLen < JSON_RES_ITEM_URI_SIZE) return -1;
terencez 0:c2dff8cbb91a 1191 memcpy(buffer, JSON_RES_ITEM_URI, JSON_RES_ITEM_URI_SIZE);
terencez 0:c2dff8cbb91a 1192 head = JSON_RES_ITEM_URI_SIZE;
terencez 0:c2dff8cbb91a 1193
terencez 0:c2dff8cbb91a 1194 if (parentUriLen > 0)
terencez 0:c2dff8cbb91a 1195 {
terencez 0:c2dff8cbb91a 1196 if (bufferLen - head < parentUriLen) return -1;
terencez 0:c2dff8cbb91a 1197 memcpy(buffer + head, parentUriStr, parentUriLen);
terencez 0:c2dff8cbb91a 1198 head += parentUriLen;
terencez 0:c2dff8cbb91a 1199 }
terencez 0:c2dff8cbb91a 1200
terencez 0:c2dff8cbb91a 1201 res = utils_intToText(tlvP->id, buffer + head, bufferLen - head);
terencez 0:c2dff8cbb91a 1202 if (res <= 0) return -1;
terencez 0:c2dff8cbb91a 1203 head += res;
terencez 0:c2dff8cbb91a 1204
terencez 0:c2dff8cbb91a 1205 res = prv_serializeValue(tlvP, buffer + head, bufferLen - head);
terencez 0:c2dff8cbb91a 1206 if (res < 0) return -1;
terencez 0:c2dff8cbb91a 1207 head += res;
terencez 0:c2dff8cbb91a 1208 break;
terencez 0:c2dff8cbb91a 1209 }
terencez 0:c2dff8cbb91a 1210
terencez 0:c2dff8cbb91a 1211 return head;
terencez 0:c2dff8cbb91a 1212 }
terencez 0:c2dff8cbb91a 1213
terencez 0:c2dff8cbb91a 1214 static int prv_findAndCheckData(lwm2m_uri_t * uriP,
terencez 0:c2dff8cbb91a 1215 uri_depth_t level,
terencez 0:c2dff8cbb91a 1216 size_t size,
terencez 0:c2dff8cbb91a 1217 lwm2m_data_t * tlvP,
terencez 0:c2dff8cbb91a 1218 lwm2m_data_t ** targetP)
terencez 0:c2dff8cbb91a 1219 {
terencez 0:c2dff8cbb91a 1220 size_t index;
terencez 0:c2dff8cbb91a 1221 int result;
terencez 0:c2dff8cbb91a 1222
terencez 0:c2dff8cbb91a 1223 if (size == 0) return 0;
terencez 0:c2dff8cbb91a 1224
terencez 0:c2dff8cbb91a 1225 if (size > 1)
terencez 0:c2dff8cbb91a 1226 {
terencez 0:c2dff8cbb91a 1227 if (tlvP[0].type == LWM2M_TYPE_OBJECT || tlvP[0].type == LWM2M_TYPE_OBJECT_INSTANCE)
terencez 0:c2dff8cbb91a 1228 {
terencez 0:c2dff8cbb91a 1229 for (index = 0; index < size; index++)
terencez 0:c2dff8cbb91a 1230 {
terencez 0:c2dff8cbb91a 1231 if (tlvP[index].type != tlvP[0].type)
terencez 0:c2dff8cbb91a 1232 {
terencez 0:c2dff8cbb91a 1233 *targetP = NULL;
terencez 0:c2dff8cbb91a 1234 return -1;
terencez 0:c2dff8cbb91a 1235 }
terencez 0:c2dff8cbb91a 1236 }
terencez 0:c2dff8cbb91a 1237 }
terencez 0:c2dff8cbb91a 1238 else
terencez 0:c2dff8cbb91a 1239 {
terencez 0:c2dff8cbb91a 1240 for (index = 0; index < size; index++)
terencez 0:c2dff8cbb91a 1241 {
terencez 0:c2dff8cbb91a 1242 if (tlvP[index].type == LWM2M_TYPE_OBJECT || tlvP[index].type == LWM2M_TYPE_OBJECT_INSTANCE)
terencez 0:c2dff8cbb91a 1243 {
terencez 0:c2dff8cbb91a 1244 *targetP = NULL;
terencez 0:c2dff8cbb91a 1245 return -1;
terencez 0:c2dff8cbb91a 1246 }
terencez 0:c2dff8cbb91a 1247 }
terencez 0:c2dff8cbb91a 1248 }
terencez 0:c2dff8cbb91a 1249 }
terencez 0:c2dff8cbb91a 1250
terencez 0:c2dff8cbb91a 1251 *targetP = NULL;
terencez 0:c2dff8cbb91a 1252 result = -1;
terencez 0:c2dff8cbb91a 1253 switch (level)
terencez 0:c2dff8cbb91a 1254 {
terencez 0:c2dff8cbb91a 1255 case URI_DEPTH_OBJECT:
terencez 0:c2dff8cbb91a 1256 if (tlvP[0].type == LWM2M_TYPE_OBJECT)
terencez 0:c2dff8cbb91a 1257 {
terencez 0:c2dff8cbb91a 1258 *targetP = tlvP;
terencez 0:c2dff8cbb91a 1259 result = (int)size;
terencez 0:c2dff8cbb91a 1260 }
terencez 0:c2dff8cbb91a 1261 break;
terencez 0:c2dff8cbb91a 1262
terencez 0:c2dff8cbb91a 1263 case URI_DEPTH_OBJECT_INSTANCE:
terencez 0:c2dff8cbb91a 1264 switch (tlvP[0].type)
terencez 0:c2dff8cbb91a 1265 {
terencez 0:c2dff8cbb91a 1266 case LWM2M_TYPE_OBJECT:
terencez 0:c2dff8cbb91a 1267 for (index = 0; index < size; index++)
terencez 0:c2dff8cbb91a 1268 {
terencez 0:c2dff8cbb91a 1269 if (tlvP[index].id == uriP->objectId)
terencez 0:c2dff8cbb91a 1270 {
terencez 0:c2dff8cbb91a 1271 return prv_findAndCheckData(uriP, level, tlvP[index].value.asChildren.count, tlvP[index].value.asChildren.array, targetP);
terencez 0:c2dff8cbb91a 1272 }
terencez 0:c2dff8cbb91a 1273 }
terencez 0:c2dff8cbb91a 1274 break;
terencez 0:c2dff8cbb91a 1275 case LWM2M_TYPE_OBJECT_INSTANCE:
terencez 0:c2dff8cbb91a 1276 *targetP = tlvP;
terencez 0:c2dff8cbb91a 1277 result = (int)size;
terencez 0:c2dff8cbb91a 1278 break;
terencez 0:c2dff8cbb91a 1279 default:
terencez 0:c2dff8cbb91a 1280 break;
terencez 0:c2dff8cbb91a 1281 }
terencez 0:c2dff8cbb91a 1282 break;
terencez 0:c2dff8cbb91a 1283
terencez 0:c2dff8cbb91a 1284 case URI_DEPTH_RESOURCE:
terencez 0:c2dff8cbb91a 1285 switch (tlvP[0].type)
terencez 0:c2dff8cbb91a 1286 {
terencez 0:c2dff8cbb91a 1287 case LWM2M_TYPE_OBJECT:
terencez 0:c2dff8cbb91a 1288 for (index = 0; index < size; index++)
terencez 0:c2dff8cbb91a 1289 {
terencez 0:c2dff8cbb91a 1290 if (tlvP[index].id == uriP->objectId)
terencez 0:c2dff8cbb91a 1291 {
terencez 0:c2dff8cbb91a 1292 return prv_findAndCheckData(uriP, level, tlvP[index].value.asChildren.count, tlvP[index].value.asChildren.array, targetP);
terencez 0:c2dff8cbb91a 1293 }
terencez 0:c2dff8cbb91a 1294 }
terencez 0:c2dff8cbb91a 1295 break;
terencez 0:c2dff8cbb91a 1296 case LWM2M_TYPE_OBJECT_INSTANCE:
terencez 0:c2dff8cbb91a 1297 for (index = 0; index < size; index++)
terencez 0:c2dff8cbb91a 1298 {
terencez 0:c2dff8cbb91a 1299 if (tlvP[index].id == uriP->instanceId)
terencez 0:c2dff8cbb91a 1300 {
terencez 0:c2dff8cbb91a 1301 return prv_findAndCheckData(uriP, level, tlvP[index].value.asChildren.count, tlvP[index].value.asChildren.array, targetP);
terencez 0:c2dff8cbb91a 1302 }
terencez 0:c2dff8cbb91a 1303 }
terencez 0:c2dff8cbb91a 1304 break;
terencez 0:c2dff8cbb91a 1305 default:
terencez 0:c2dff8cbb91a 1306 *targetP = tlvP;
terencez 0:c2dff8cbb91a 1307 result = (int)size;
terencez 0:c2dff8cbb91a 1308 break;
terencez 0:c2dff8cbb91a 1309 }
terencez 0:c2dff8cbb91a 1310 break;
terencez 0:c2dff8cbb91a 1311
terencez 0:c2dff8cbb91a 1312 case URI_DEPTH_RESOURCE_INSTANCE:
terencez 0:c2dff8cbb91a 1313 switch (tlvP[0].type)
terencez 0:c2dff8cbb91a 1314 {
terencez 0:c2dff8cbb91a 1315 case LWM2M_TYPE_OBJECT:
terencez 0:c2dff8cbb91a 1316 for (index = 0; index < size; index++)
terencez 0:c2dff8cbb91a 1317 {
terencez 0:c2dff8cbb91a 1318 if (tlvP[index].id == uriP->objectId)
terencez 0:c2dff8cbb91a 1319 {
terencez 0:c2dff8cbb91a 1320 return prv_findAndCheckData(uriP, level, tlvP[index].value.asChildren.count, tlvP[index].value.asChildren.array, targetP);
terencez 0:c2dff8cbb91a 1321 }
terencez 0:c2dff8cbb91a 1322 }
terencez 0:c2dff8cbb91a 1323 break;
terencez 0:c2dff8cbb91a 1324 case LWM2M_TYPE_OBJECT_INSTANCE:
terencez 0:c2dff8cbb91a 1325 for (index = 0; index < size; index++)
terencez 0:c2dff8cbb91a 1326 {
terencez 0:c2dff8cbb91a 1327 if (tlvP[index].id == uriP->instanceId)
terencez 0:c2dff8cbb91a 1328 {
terencez 0:c2dff8cbb91a 1329 return prv_findAndCheckData(uriP, level, tlvP[index].value.asChildren.count, tlvP[index].value.asChildren.array, targetP);
terencez 0:c2dff8cbb91a 1330 }
terencez 0:c2dff8cbb91a 1331 }
terencez 0:c2dff8cbb91a 1332 break;
terencez 0:c2dff8cbb91a 1333 case LWM2M_TYPE_MULTIPLE_RESOURCE:
terencez 0:c2dff8cbb91a 1334 for (index = 0; index < size; index++)
terencez 0:c2dff8cbb91a 1335 {
terencez 0:c2dff8cbb91a 1336 if (tlvP[index].id == uriP->resourceId)
terencez 0:c2dff8cbb91a 1337 {
terencez 0:c2dff8cbb91a 1338 return prv_findAndCheckData(uriP, level, tlvP[index].value.asChildren.count, tlvP[index].value.asChildren.array, targetP);
terencez 0:c2dff8cbb91a 1339 }
terencez 0:c2dff8cbb91a 1340 }
terencez 0:c2dff8cbb91a 1341 break;
terencez 0:c2dff8cbb91a 1342 default:
terencez 0:c2dff8cbb91a 1343 *targetP = tlvP;
terencez 0:c2dff8cbb91a 1344 result = (int)size;
terencez 0:c2dff8cbb91a 1345 break;
terencez 0:c2dff8cbb91a 1346 }
terencez 0:c2dff8cbb91a 1347 break;
terencez 0:c2dff8cbb91a 1348
terencez 0:c2dff8cbb91a 1349 default:
terencez 0:c2dff8cbb91a 1350 break;
terencez 0:c2dff8cbb91a 1351 }
terencez 0:c2dff8cbb91a 1352
terencez 0:c2dff8cbb91a 1353 return result;
terencez 0:c2dff8cbb91a 1354 }
terencez 0:c2dff8cbb91a 1355
terencez 0:c2dff8cbb91a 1356 int json_serialize(lwm2m_uri_t * uriP,
terencez 0:c2dff8cbb91a 1357 int size,
terencez 0:c2dff8cbb91a 1358 lwm2m_data_t * tlvP,
terencez 0:c2dff8cbb91a 1359 uint8_t ** bufferP)
terencez 0:c2dff8cbb91a 1360 {
terencez 0:c2dff8cbb91a 1361 int index;
terencez 0:c2dff8cbb91a 1362 size_t head;
terencez 0:c2dff8cbb91a 1363 uint8_t bufferJSON[PRV_JSON_BUFFER_SIZE];
terencez 0:c2dff8cbb91a 1364 uint8_t baseUriStr[URI_MAX_STRING_LEN];
terencez 0:c2dff8cbb91a 1365 int baseUriLen;
terencez 0:c2dff8cbb91a 1366 uri_depth_t rootLevel;
terencez 0:c2dff8cbb91a 1367 int num;
terencez 0:c2dff8cbb91a 1368 lwm2m_data_t * targetP;
terencez 0:c2dff8cbb91a 1369
terencez 0:c2dff8cbb91a 1370 LOG_ARG("size: %d", size);
terencez 0:c2dff8cbb91a 1371 LOG_URI(uriP);
terencez 0:c2dff8cbb91a 1372 if (size != 0 && tlvP == NULL) return -1;
terencez 0:c2dff8cbb91a 1373
terencez 0:c2dff8cbb91a 1374 baseUriLen = uri_toString(uriP, baseUriStr, URI_MAX_STRING_LEN, &rootLevel);
terencez 0:c2dff8cbb91a 1375 if (baseUriLen < 0) return -1;
terencez 0:c2dff8cbb91a 1376
terencez 0:c2dff8cbb91a 1377 num = prv_findAndCheckData(uriP, rootLevel, size, tlvP, &targetP);
terencez 0:c2dff8cbb91a 1378 if (num < 0) return -1;
terencez 0:c2dff8cbb91a 1379
terencez 0:c2dff8cbb91a 1380 while (num == 1
terencez 0:c2dff8cbb91a 1381 && (targetP->type == LWM2M_TYPE_OBJECT
terencez 0:c2dff8cbb91a 1382 || targetP->type == LWM2M_TYPE_OBJECT_INSTANCE
terencez 0:c2dff8cbb91a 1383 || targetP->type == LWM2M_TYPE_MULTIPLE_RESOURCE))
terencez 0:c2dff8cbb91a 1384 {
terencez 0:c2dff8cbb91a 1385 int res;
terencez 0:c2dff8cbb91a 1386
terencez 0:c2dff8cbb91a 1387 res = utils_intToText(targetP->id, baseUriStr + baseUriLen, URI_MAX_STRING_LEN - baseUriLen);
terencez 0:c2dff8cbb91a 1388 if (res <= 0) return 0;
terencez 0:c2dff8cbb91a 1389 baseUriLen += res;
terencez 0:c2dff8cbb91a 1390 if (baseUriLen >= URI_MAX_STRING_LEN -1) return 0;
terencez 0:c2dff8cbb91a 1391 num = targetP->value.asChildren.count;
terencez 0:c2dff8cbb91a 1392 targetP = targetP->value.asChildren.array;
terencez 0:c2dff8cbb91a 1393 baseUriStr[baseUriLen] = '/';
terencez 0:c2dff8cbb91a 1394 baseUriLen++;
terencez 0:c2dff8cbb91a 1395 }
terencez 0:c2dff8cbb91a 1396
terencez 0:c2dff8cbb91a 1397 if (baseUriLen > 0)
terencez 0:c2dff8cbb91a 1398 {
terencez 0:c2dff8cbb91a 1399 memcpy(bufferJSON, JSON_BN_HEADER_1, JSON_BN_HEADER_1_SIZE);
terencez 0:c2dff8cbb91a 1400 head = JSON_BN_HEADER_1_SIZE;
terencez 0:c2dff8cbb91a 1401 memcpy(bufferJSON + head, baseUriStr, baseUriLen);
terencez 0:c2dff8cbb91a 1402 head += baseUriLen;
terencez 0:c2dff8cbb91a 1403 memcpy(bufferJSON + head, JSON_BN_HEADER_2, JSON_BN_HEADER_2_SIZE);
terencez 0:c2dff8cbb91a 1404 head += JSON_BN_HEADER_2_SIZE;
terencez 0:c2dff8cbb91a 1405 }
terencez 0:c2dff8cbb91a 1406 else
terencez 0:c2dff8cbb91a 1407 {
terencez 0:c2dff8cbb91a 1408 memcpy(bufferJSON, JSON_HEADER, JSON_HEADER_SIZE);
terencez 0:c2dff8cbb91a 1409 head = JSON_HEADER_SIZE;
terencez 0:c2dff8cbb91a 1410 }
terencez 0:c2dff8cbb91a 1411
terencez 0:c2dff8cbb91a 1412 for (index = 0 ; index < num && head < PRV_JSON_BUFFER_SIZE ; index++)
terencez 0:c2dff8cbb91a 1413 {
terencez 0:c2dff8cbb91a 1414 int res;
terencez 0:c2dff8cbb91a 1415
terencez 0:c2dff8cbb91a 1416 res = prv_serializeData(targetP + index, NULL, 0, bufferJSON + head, PRV_JSON_BUFFER_SIZE - head);
terencez 0:c2dff8cbb91a 1417 if (res < 0) return 0;
terencez 0:c2dff8cbb91a 1418 head += res;
terencez 0:c2dff8cbb91a 1419 }
terencez 0:c2dff8cbb91a 1420
terencez 0:c2dff8cbb91a 1421 if (head + JSON_FOOTER_SIZE - 1 > PRV_JSON_BUFFER_SIZE) return 0;
terencez 0:c2dff8cbb91a 1422
terencez 0:c2dff8cbb91a 1423 if (num > 0) head = head - 1;
terencez 0:c2dff8cbb91a 1424
terencez 0:c2dff8cbb91a 1425 memcpy(bufferJSON + head, JSON_FOOTER, JSON_FOOTER_SIZE);
terencez 0:c2dff8cbb91a 1426 head = head + JSON_FOOTER_SIZE;
terencez 0:c2dff8cbb91a 1427
terencez 0:c2dff8cbb91a 1428 *bufferP = (uint8_t *)lwm2m_malloc(head);
terencez 0:c2dff8cbb91a 1429 if (*bufferP == NULL) return 0;
terencez 0:c2dff8cbb91a 1430 memcpy(*bufferP, bufferJSON, head);
terencez 0:c2dff8cbb91a 1431
terencez 0:c2dff8cbb91a 1432 return head;
terencez 0:c2dff8cbb91a 1433 }
terencez 0:c2dff8cbb91a 1434
terencez 0:c2dff8cbb91a 1435 #endif
terencez 0:c2dff8cbb91a 1436