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

Committer:
terencez
Date:
Wed Apr 19 11:30:02 2017 +0000
Revision:
0:1fa43ab66921
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
terencez 0:1fa43ab66921 1 /*******************************************************************************
terencez 0:1fa43ab66921 2 *
terencez 0:1fa43ab66921 3 * Copyright (c) 2013, 2014 Intel Corporation and others.
terencez 0:1fa43ab66921 4 * All rights reserved. This program and the accompanying materials
terencez 0:1fa43ab66921 5 * are made available under the terms of the Eclipse Public License v1.0
terencez 0:1fa43ab66921 6 * and Eclipse Distribution License v1.0 which accompany this distribution.
terencez 0:1fa43ab66921 7 *
terencez 0:1fa43ab66921 8 * The Eclipse Public License is available at
terencez 0:1fa43ab66921 9 * http://www.eclipse.org/legal/epl-v10.html
terencez 0:1fa43ab66921 10 * The Eclipse Distribution License is available at
terencez 0:1fa43ab66921 11 * http://www.eclipse.org/org/documents/edl-v10.php.
terencez 0:1fa43ab66921 12 *
terencez 0:1fa43ab66921 13 * Contributors:
terencez 0:1fa43ab66921 14 * David Navarro, Intel Corporation - initial API and implementation
terencez 0:1fa43ab66921 15 * Fabien Fleutot - Please refer to git log
terencez 0:1fa43ab66921 16 * Bosch Software Innovations GmbH - Please refer to git log
terencez 0:1fa43ab66921 17 *
terencez 0:1fa43ab66921 18 *******************************************************************************/
terencez 0:1fa43ab66921 19
terencez 0:1fa43ab66921 20 #include "internals.h"
terencez 0:1fa43ab66921 21 #include <stdlib.h>
terencez 0:1fa43ab66921 22 #include <string.h>
terencez 0:1fa43ab66921 23 #include <stdio.h>
terencez 0:1fa43ab66921 24 #include <inttypes.h>
terencez 0:1fa43ab66921 25 #include <float.h>
terencez 0:1fa43ab66921 26
terencez 0:1fa43ab66921 27 #ifndef LWM2M_BIG_ENDIAN
terencez 0:1fa43ab66921 28 #ifndef LWM2M_LITTLE_ENDIAN
terencez 0:1fa43ab66921 29 #error Please define LWM2M_BIG_ENDIAN or LWM2M_LITTLE_ENDIAN
terencez 0:1fa43ab66921 30 #endif
terencez 0:1fa43ab66921 31 #endif
terencez 0:1fa43ab66921 32
terencez 0:1fa43ab66921 33 #define _PRV_TLV_TYPE_MASK 0xC0
terencez 0:1fa43ab66921 34 #define _PRV_TLV_HEADER_MAX_LENGTH 6
terencez 0:1fa43ab66921 35
terencez 0:1fa43ab66921 36 #define _PRV_TLV_TYPE_UNKNOWN (uint8_t)0xFF
terencez 0:1fa43ab66921 37 #define _PRV_TLV_TYPE_OBJECT (uint8_t)0x10
terencez 0:1fa43ab66921 38 #define _PRV_TLV_TYPE_OBJECT_INSTANCE (uint8_t)0x00
terencez 0:1fa43ab66921 39 #define _PRV_TLV_TYPE_RESOURCE (uint8_t)0xC0
terencez 0:1fa43ab66921 40 #define _PRV_TLV_TYPE_MULTIPLE_RESOURCE (uint8_t)0x80
terencez 0:1fa43ab66921 41 #define _PRV_TLV_TYPE_RESOURCE_INSTANCE (uint8_t)0x40
terencez 0:1fa43ab66921 42
terencez 0:1fa43ab66921 43
terencez 0:1fa43ab66921 44 static uint8_t prv_getHeaderType(lwm2m_data_type_t type)
terencez 0:1fa43ab66921 45 {
terencez 0:1fa43ab66921 46 switch (type)
terencez 0:1fa43ab66921 47 {
terencez 0:1fa43ab66921 48 case LWM2M_TYPE_OBJECT:
terencez 0:1fa43ab66921 49 return _PRV_TLV_TYPE_OBJECT;
terencez 0:1fa43ab66921 50
terencez 0:1fa43ab66921 51 case LWM2M_TYPE_OBJECT_INSTANCE:
terencez 0:1fa43ab66921 52 return _PRV_TLV_TYPE_OBJECT_INSTANCE;
terencez 0:1fa43ab66921 53
terencez 0:1fa43ab66921 54 case LWM2M_TYPE_MULTIPLE_RESOURCE:
terencez 0:1fa43ab66921 55 return _PRV_TLV_TYPE_MULTIPLE_RESOURCE;
terencez 0:1fa43ab66921 56
terencez 0:1fa43ab66921 57
terencez 0:1fa43ab66921 58 case LWM2M_TYPE_STRING:
terencez 0:1fa43ab66921 59 case LWM2M_TYPE_INTEGER:
terencez 0:1fa43ab66921 60 case LWM2M_TYPE_FLOAT:
terencez 0:1fa43ab66921 61 case LWM2M_TYPE_BOOLEAN:
terencez 0:1fa43ab66921 62 case LWM2M_TYPE_OPAQUE:
terencez 0:1fa43ab66921 63 case LWM2M_TYPE_OBJECT_LINK:
terencez 0:1fa43ab66921 64 return _PRV_TLV_TYPE_RESOURCE;
terencez 0:1fa43ab66921 65
terencez 0:1fa43ab66921 66 case LWM2M_TYPE_UNDEFINED:
terencez 0:1fa43ab66921 67 default:
terencez 0:1fa43ab66921 68 return _PRV_TLV_TYPE_UNKNOWN;
terencez 0:1fa43ab66921 69 }
terencez 0:1fa43ab66921 70 }
terencez 0:1fa43ab66921 71
terencez 0:1fa43ab66921 72 static lwm2m_data_type_t prv_getDataType(uint8_t type)
terencez 0:1fa43ab66921 73 {
terencez 0:1fa43ab66921 74 switch (type)
terencez 0:1fa43ab66921 75 {
terencez 0:1fa43ab66921 76 case _PRV_TLV_TYPE_OBJECT:
terencez 0:1fa43ab66921 77 return LWM2M_TYPE_OBJECT;
terencez 0:1fa43ab66921 78
terencez 0:1fa43ab66921 79 case _PRV_TLV_TYPE_OBJECT_INSTANCE:
terencez 0:1fa43ab66921 80 return LWM2M_TYPE_OBJECT_INSTANCE;
terencez 0:1fa43ab66921 81
terencez 0:1fa43ab66921 82 case _PRV_TLV_TYPE_MULTIPLE_RESOURCE:
terencez 0:1fa43ab66921 83 return LWM2M_TYPE_MULTIPLE_RESOURCE;
terencez 0:1fa43ab66921 84
terencez 0:1fa43ab66921 85 case _PRV_TLV_TYPE_RESOURCE:
terencez 0:1fa43ab66921 86 case _PRV_TLV_TYPE_RESOURCE_INSTANCE:
terencez 0:1fa43ab66921 87 return LWM2M_TYPE_OPAQUE;
terencez 0:1fa43ab66921 88
terencez 0:1fa43ab66921 89 default:
terencez 0:1fa43ab66921 90 return LWM2M_TYPE_UNDEFINED;
terencez 0:1fa43ab66921 91 }
terencez 0:1fa43ab66921 92 }
terencez 0:1fa43ab66921 93
terencez 0:1fa43ab66921 94 static int prv_getHeaderLength(uint16_t id,
terencez 0:1fa43ab66921 95 size_t dataLen)
terencez 0:1fa43ab66921 96 {
terencez 0:1fa43ab66921 97 int length;
terencez 0:1fa43ab66921 98
terencez 0:1fa43ab66921 99 length = 2;
terencez 0:1fa43ab66921 100
terencez 0:1fa43ab66921 101 if (id > 0xFF)
terencez 0:1fa43ab66921 102 {
terencez 0:1fa43ab66921 103 length += 1;
terencez 0:1fa43ab66921 104 }
terencez 0:1fa43ab66921 105
terencez 0:1fa43ab66921 106 if (dataLen > 0xFFFF)
terencez 0:1fa43ab66921 107 {
terencez 0:1fa43ab66921 108 length += 3;
terencez 0:1fa43ab66921 109 }
terencez 0:1fa43ab66921 110 else if (dataLen > 0xFF)
terencez 0:1fa43ab66921 111 {
terencez 0:1fa43ab66921 112 length += 2;
terencez 0:1fa43ab66921 113 }
terencez 0:1fa43ab66921 114 else if (dataLen > 7)
terencez 0:1fa43ab66921 115 {
terencez 0:1fa43ab66921 116 length += 1;
terencez 0:1fa43ab66921 117 }
terencez 0:1fa43ab66921 118
terencez 0:1fa43ab66921 119 return length;
terencez 0:1fa43ab66921 120 }
terencez 0:1fa43ab66921 121
terencez 0:1fa43ab66921 122 static int prv_createHeader(uint8_t * header,
terencez 0:1fa43ab66921 123 bool isInstance,
terencez 0:1fa43ab66921 124 lwm2m_data_type_t type,
terencez 0:1fa43ab66921 125 uint16_t id,
terencez 0:1fa43ab66921 126 size_t data_len)
terencez 0:1fa43ab66921 127 {
terencez 0:1fa43ab66921 128 int header_len;
terencez 0:1fa43ab66921 129 int offset;
terencez 0:1fa43ab66921 130 uint8_t hdrType;
terencez 0:1fa43ab66921 131
terencez 0:1fa43ab66921 132 header_len = prv_getHeaderLength(id, data_len);
terencez 0:1fa43ab66921 133 if (isInstance == true)
terencez 0:1fa43ab66921 134 {
terencez 0:1fa43ab66921 135 hdrType = _PRV_TLV_TYPE_RESOURCE_INSTANCE;
terencez 0:1fa43ab66921 136 }
terencez 0:1fa43ab66921 137 else
terencez 0:1fa43ab66921 138 {
terencez 0:1fa43ab66921 139 hdrType = prv_getHeaderType(type);
terencez 0:1fa43ab66921 140 }
terencez 0:1fa43ab66921 141
terencez 0:1fa43ab66921 142 header[0] = 0;
terencez 0:1fa43ab66921 143 header[0] |= hdrType&_PRV_TLV_TYPE_MASK;
terencez 0:1fa43ab66921 144
terencez 0:1fa43ab66921 145 if (id > 0xFF)
terencez 0:1fa43ab66921 146 {
terencez 0:1fa43ab66921 147 header[0] |= 0x20;
terencez 0:1fa43ab66921 148 header[1] = (id >> 8) & 0XFF;
terencez 0:1fa43ab66921 149 header[2] = id & 0XFF;
terencez 0:1fa43ab66921 150 offset = 3;
terencez 0:1fa43ab66921 151 }
terencez 0:1fa43ab66921 152 else
terencez 0:1fa43ab66921 153 {
terencez 0:1fa43ab66921 154 header[1] = id;
terencez 0:1fa43ab66921 155 offset = 2;
terencez 0:1fa43ab66921 156 }
terencez 0:1fa43ab66921 157 if (data_len <= 7)
terencez 0:1fa43ab66921 158 {
terencez 0:1fa43ab66921 159 header[0] += data_len;
terencez 0:1fa43ab66921 160 }
terencez 0:1fa43ab66921 161 else if (data_len <= 0xFF)
terencez 0:1fa43ab66921 162 {
terencez 0:1fa43ab66921 163 header[0] |= 0x08;
terencez 0:1fa43ab66921 164 header[offset] = data_len;
terencez 0:1fa43ab66921 165 }
terencez 0:1fa43ab66921 166 else if (data_len <= 0xFFFF)
terencez 0:1fa43ab66921 167 {
terencez 0:1fa43ab66921 168 header[0] |= 0x10;
terencez 0:1fa43ab66921 169 header[offset] = (data_len >> 8) & 0XFF;
terencez 0:1fa43ab66921 170 header[offset + 1] = data_len & 0XFF;
terencez 0:1fa43ab66921 171 }
terencez 0:1fa43ab66921 172 else if (data_len <= 0xFFFFFF)
terencez 0:1fa43ab66921 173 {
terencez 0:1fa43ab66921 174 header[0] |= 0x18;
terencez 0:1fa43ab66921 175 header[offset] = (data_len >> 16) & 0XFF;
terencez 0:1fa43ab66921 176 header[offset + 1] = (data_len >> 8) & 0XFF;
terencez 0:1fa43ab66921 177 header[offset + 2] = data_len & 0XFF;
terencez 0:1fa43ab66921 178 }
terencez 0:1fa43ab66921 179
terencez 0:1fa43ab66921 180 return header_len;
terencez 0:1fa43ab66921 181 }
terencez 0:1fa43ab66921 182
terencez 0:1fa43ab66921 183 int lwm2m_decode_TLV(const uint8_t * buffer,
terencez 0:1fa43ab66921 184 size_t buffer_len,
terencez 0:1fa43ab66921 185 lwm2m_data_type_t * oType,
terencez 0:1fa43ab66921 186 uint16_t * oID,
terencez 0:1fa43ab66921 187 size_t * oDataIndex,
terencez 0:1fa43ab66921 188 size_t * oDataLen)
terencez 0:1fa43ab66921 189 {
terencez 0:1fa43ab66921 190
terencez 0:1fa43ab66921 191 LOG_ARG("buffer_len: %d", buffer_len);
terencez 0:1fa43ab66921 192 ;
terencez 0:1fa43ab66921 193 if (buffer_len < 2) return 0;
terencez 0:1fa43ab66921 194
terencez 0:1fa43ab66921 195 *oDataIndex = 2;
terencez 0:1fa43ab66921 196
terencez 0:1fa43ab66921 197 *oType = prv_getDataType(buffer[0]&_PRV_TLV_TYPE_MASK);
terencez 0:1fa43ab66921 198
terencez 0:1fa43ab66921 199 if ((buffer[0]&0x20) == 0x20)
terencez 0:1fa43ab66921 200 {
terencez 0:1fa43ab66921 201 // id is 16 bits long
terencez 0:1fa43ab66921 202 if (buffer_len < 3) return 0;
terencez 0:1fa43ab66921 203 *oDataIndex += 1;
terencez 0:1fa43ab66921 204 *oID = (buffer[1]<<8) + buffer[2];
terencez 0:1fa43ab66921 205 }
terencez 0:1fa43ab66921 206 else
terencez 0:1fa43ab66921 207 {
terencez 0:1fa43ab66921 208 // id is 8 bits long
terencez 0:1fa43ab66921 209 *oID = buffer[1];
terencez 0:1fa43ab66921 210 }
terencez 0:1fa43ab66921 211
terencez 0:1fa43ab66921 212 switch (buffer[0]&0x18)
terencez 0:1fa43ab66921 213 {
terencez 0:1fa43ab66921 214 case 0x00:
terencez 0:1fa43ab66921 215 // no length field
terencez 0:1fa43ab66921 216 *oDataLen = buffer[0]&0x07;
terencez 0:1fa43ab66921 217 break;
terencez 0:1fa43ab66921 218 case 0x08:
terencez 0:1fa43ab66921 219 // length field is 8 bits long
terencez 0:1fa43ab66921 220 if (buffer_len < *oDataIndex + 1) return 0;
terencez 0:1fa43ab66921 221 *oDataLen = buffer[*oDataIndex];
terencez 0:1fa43ab66921 222 *oDataIndex += 1;
terencez 0:1fa43ab66921 223 break;
terencez 0:1fa43ab66921 224 case 0x10:
terencez 0:1fa43ab66921 225 // length field is 16 bits long
terencez 0:1fa43ab66921 226 if (buffer_len < *oDataIndex + 2) return 0;
terencez 0:1fa43ab66921 227 *oDataLen = (buffer[*oDataIndex]<<8) + buffer[*oDataIndex+1];
terencez 0:1fa43ab66921 228 *oDataIndex += 2;
terencez 0:1fa43ab66921 229 break;
terencez 0:1fa43ab66921 230 case 0x18:
terencez 0:1fa43ab66921 231 // length field is 24 bits long
terencez 0:1fa43ab66921 232 if (buffer_len < *oDataIndex + 3) return 0;
terencez 0:1fa43ab66921 233 *oDataLen = (buffer[*oDataIndex]<<16) + (buffer[*oDataIndex+1]<<8) + buffer[*oDataIndex+2];
terencez 0:1fa43ab66921 234 *oDataIndex += 3;
terencez 0:1fa43ab66921 235 break;
terencez 0:1fa43ab66921 236 default:
terencez 0:1fa43ab66921 237 // can't happen
terencez 0:1fa43ab66921 238 return 0;
terencez 0:1fa43ab66921 239 }
terencez 0:1fa43ab66921 240
terencez 0:1fa43ab66921 241 if (*oDataIndex + *oDataLen > buffer_len) return 0;
terencez 0:1fa43ab66921 242
terencez 0:1fa43ab66921 243 return *oDataIndex + *oDataLen;
terencez 0:1fa43ab66921 244 }
terencez 0:1fa43ab66921 245
terencez 0:1fa43ab66921 246
terencez 0:1fa43ab66921 247 int tlv_parse(uint8_t * buffer,
terencez 0:1fa43ab66921 248 size_t bufferLen,
terencez 0:1fa43ab66921 249 lwm2m_data_t ** dataP)
terencez 0:1fa43ab66921 250 {
terencez 0:1fa43ab66921 251 lwm2m_data_type_t type;
terencez 0:1fa43ab66921 252 uint16_t id;
terencez 0:1fa43ab66921 253 size_t dataIndex;
terencez 0:1fa43ab66921 254 size_t dataLen;
terencez 0:1fa43ab66921 255 int index = 0;
terencez 0:1fa43ab66921 256 int result;
terencez 0:1fa43ab66921 257 int size = 0;
terencez 0:1fa43ab66921 258
terencez 0:1fa43ab66921 259 LOG_ARG("bufferLen: %d", bufferLen);
terencez 0:1fa43ab66921 260
terencez 0:1fa43ab66921 261 *dataP = NULL;
terencez 0:1fa43ab66921 262
terencez 0:1fa43ab66921 263 while (0 != (result = lwm2m_decode_TLV((uint8_t*)buffer + index, bufferLen - index, &type, &id, &dataIndex, &dataLen)))
terencez 0:1fa43ab66921 264 {
terencez 0:1fa43ab66921 265 lwm2m_data_t * newTlvP;
terencez 0:1fa43ab66921 266
terencez 0:1fa43ab66921 267 newTlvP = lwm2m_data_new(size + 1);
terencez 0:1fa43ab66921 268 if (size >= 1)
terencez 0:1fa43ab66921 269 {
terencez 0:1fa43ab66921 270 if (newTlvP == NULL)
terencez 0:1fa43ab66921 271 {
terencez 0:1fa43ab66921 272 lwm2m_data_free(size, *dataP);
terencez 0:1fa43ab66921 273 return 0;
terencez 0:1fa43ab66921 274 }
terencez 0:1fa43ab66921 275 else
terencez 0:1fa43ab66921 276 {
terencez 0:1fa43ab66921 277 memcpy(newTlvP, *dataP, size * sizeof(lwm2m_data_t));
terencez 0:1fa43ab66921 278 lwm2m_free(*dataP);
terencez 0:1fa43ab66921 279 }
terencez 0:1fa43ab66921 280 }
terencez 0:1fa43ab66921 281 *dataP = newTlvP;
terencez 0:1fa43ab66921 282
terencez 0:1fa43ab66921 283 (*dataP)[size].type = type;
terencez 0:1fa43ab66921 284 (*dataP)[size].id = id;
terencez 0:1fa43ab66921 285 if (type == LWM2M_TYPE_OBJECT_INSTANCE || type == LWM2M_TYPE_MULTIPLE_RESOURCE)
terencez 0:1fa43ab66921 286 {
terencez 0:1fa43ab66921 287 (*dataP)[size].value.asChildren.count = tlv_parse(buffer + index + dataIndex,
terencez 0:1fa43ab66921 288 dataLen,
terencez 0:1fa43ab66921 289 &((*dataP)[size].value.asChildren.array));
terencez 0:1fa43ab66921 290 if ((*dataP)[size].value.asChildren.count == 0)
terencez 0:1fa43ab66921 291 {
terencez 0:1fa43ab66921 292 lwm2m_data_free(size + 1, *dataP);
terencez 0:1fa43ab66921 293 return 0;
terencez 0:1fa43ab66921 294 }
terencez 0:1fa43ab66921 295 }
terencez 0:1fa43ab66921 296 else
terencez 0:1fa43ab66921 297 {
terencez 0:1fa43ab66921 298 lwm2m_data_encode_opaque(buffer + index + dataIndex, dataLen, (*dataP) + size);
terencez 0:1fa43ab66921 299 }
terencez 0:1fa43ab66921 300 size++;
terencez 0:1fa43ab66921 301 index += result;
terencez 0:1fa43ab66921 302 }
terencez 0:1fa43ab66921 303
terencez 0:1fa43ab66921 304 return size;
terencez 0:1fa43ab66921 305 }
terencez 0:1fa43ab66921 306
terencez 0:1fa43ab66921 307
terencez 0:1fa43ab66921 308 static int prv_getLength(int size,
terencez 0:1fa43ab66921 309 lwm2m_data_t * dataP)
terencez 0:1fa43ab66921 310 {
terencez 0:1fa43ab66921 311 int length;
terencez 0:1fa43ab66921 312 int i;
terencez 0:1fa43ab66921 313
terencez 0:1fa43ab66921 314 length = 0;
terencez 0:1fa43ab66921 315
terencez 0:1fa43ab66921 316 for (i = 0 ; i < size && length != -1 ; i++)
terencez 0:1fa43ab66921 317 {
terencez 0:1fa43ab66921 318 switch (dataP[i].type)
terencez 0:1fa43ab66921 319 {
terencez 0:1fa43ab66921 320 case LWM2M_TYPE_OBJECT_INSTANCE:
terencez 0:1fa43ab66921 321 case LWM2M_TYPE_MULTIPLE_RESOURCE:
terencez 0:1fa43ab66921 322 {
terencez 0:1fa43ab66921 323 int subLength;
terencez 0:1fa43ab66921 324
terencez 0:1fa43ab66921 325 subLength = prv_getLength(dataP[i].value.asChildren.count, dataP[i].value.asChildren.array);
terencez 0:1fa43ab66921 326 if (subLength == -1)
terencez 0:1fa43ab66921 327 {
terencez 0:1fa43ab66921 328 length = -1;
terencez 0:1fa43ab66921 329 }
terencez 0:1fa43ab66921 330 else
terencez 0:1fa43ab66921 331 {
terencez 0:1fa43ab66921 332 length += prv_getHeaderLength(dataP[i].id, subLength) + subLength;
terencez 0:1fa43ab66921 333 }
terencez 0:1fa43ab66921 334 }
terencez 0:1fa43ab66921 335 break;
terencez 0:1fa43ab66921 336
terencez 0:1fa43ab66921 337 case LWM2M_TYPE_STRING:
terencez 0:1fa43ab66921 338 case LWM2M_TYPE_OPAQUE:
terencez 0:1fa43ab66921 339 length += prv_getHeaderLength(dataP[i].id, dataP[i].value.asBuffer.length) + dataP[i].value.asBuffer.length;
terencez 0:1fa43ab66921 340 break;
terencez 0:1fa43ab66921 341
terencez 0:1fa43ab66921 342 case LWM2M_TYPE_INTEGER:
terencez 0:1fa43ab66921 343 {
terencez 0:1fa43ab66921 344 size_t data_len;
terencez 0:1fa43ab66921 345 uint8_t unused_buffer[_PRV_64BIT_BUFFER_SIZE];
terencez 0:1fa43ab66921 346
terencez 0:1fa43ab66921 347 data_len = utils_encodeInt(dataP[i].value.asInteger, unused_buffer);
terencez 0:1fa43ab66921 348 length += prv_getHeaderLength(dataP[i].id, data_len) + data_len;
terencez 0:1fa43ab66921 349 }
terencez 0:1fa43ab66921 350 break;
terencez 0:1fa43ab66921 351
terencez 0:1fa43ab66921 352 case LWM2M_TYPE_FLOAT:
terencez 0:1fa43ab66921 353 {
terencez 0:1fa43ab66921 354 size_t data_len;
terencez 0:1fa43ab66921 355
terencez 0:1fa43ab66921 356 if ((dataP[i].value.asFloat < 0.0 - (double)FLT_MAX)
terencez 0:1fa43ab66921 357 || (dataP[i].value.asFloat >(double)FLT_MAX))
terencez 0:1fa43ab66921 358 {
terencez 0:1fa43ab66921 359 data_len = 8;
terencez 0:1fa43ab66921 360 }
terencez 0:1fa43ab66921 361 else
terencez 0:1fa43ab66921 362 {
terencez 0:1fa43ab66921 363 data_len = 4;
terencez 0:1fa43ab66921 364 }
terencez 0:1fa43ab66921 365
terencez 0:1fa43ab66921 366 length += prv_getHeaderLength(dataP[i].id, data_len) + data_len;
terencez 0:1fa43ab66921 367 }
terencez 0:1fa43ab66921 368 break;
terencez 0:1fa43ab66921 369
terencez 0:1fa43ab66921 370 case LWM2M_TYPE_BOOLEAN:
terencez 0:1fa43ab66921 371 // Booleans are always encoded on one byte
terencez 0:1fa43ab66921 372 length += prv_getHeaderLength(dataP[i].id, 1) + 1;
terencez 0:1fa43ab66921 373 break;
terencez 0:1fa43ab66921 374
terencez 0:1fa43ab66921 375 case LWM2M_TYPE_OBJECT_LINK:
terencez 0:1fa43ab66921 376 // Object Link are always encoded on four bytes
terencez 0:1fa43ab66921 377 length += prv_getHeaderLength(dataP[i].id, 4) + 4;
terencez 0:1fa43ab66921 378 break;
terencez 0:1fa43ab66921 379
terencez 0:1fa43ab66921 380 default:
terencez 0:1fa43ab66921 381 length = -1;
terencez 0:1fa43ab66921 382 break;
terencez 0:1fa43ab66921 383 }
terencez 0:1fa43ab66921 384 }
terencez 0:1fa43ab66921 385
terencez 0:1fa43ab66921 386 return length;
terencez 0:1fa43ab66921 387 }
terencez 0:1fa43ab66921 388
terencez 0:1fa43ab66921 389
terencez 0:1fa43ab66921 390 int tlv_serialize(bool isResourceInstance,
terencez 0:1fa43ab66921 391 int size,
terencez 0:1fa43ab66921 392 lwm2m_data_t * dataP,
terencez 0:1fa43ab66921 393 uint8_t ** bufferP)
terencez 0:1fa43ab66921 394 {
terencez 0:1fa43ab66921 395 int length;
terencez 0:1fa43ab66921 396 int index;
terencez 0:1fa43ab66921 397 int i;
terencez 0:1fa43ab66921 398
terencez 0:1fa43ab66921 399 LOG_ARG("isResourceInstance: %s, size: %d", isResourceInstance?"true":"false", size);
terencez 0:1fa43ab66921 400
terencez 0:1fa43ab66921 401 *bufferP = NULL;
terencez 0:1fa43ab66921 402 length = prv_getLength(size, dataP);
terencez 0:1fa43ab66921 403 if (length <= 0) return length;
terencez 0:1fa43ab66921 404
terencez 0:1fa43ab66921 405 *bufferP = (uint8_t *)lwm2m_malloc(length);
terencez 0:1fa43ab66921 406 if (*bufferP == NULL) return 0;
terencez 0:1fa43ab66921 407
terencez 0:1fa43ab66921 408 index = 0;
terencez 0:1fa43ab66921 409 for (i = 0 ; i < size && length != 0 ; i++)
terencez 0:1fa43ab66921 410 {
terencez 0:1fa43ab66921 411 int headerLen;
terencez 0:1fa43ab66921 412 bool isInstance;
terencez 0:1fa43ab66921 413
terencez 0:1fa43ab66921 414 isInstance = isResourceInstance;
terencez 0:1fa43ab66921 415 switch (dataP[i].type)
terencez 0:1fa43ab66921 416 {
terencez 0:1fa43ab66921 417 case LWM2M_TYPE_MULTIPLE_RESOURCE:
terencez 0:1fa43ab66921 418 isInstance = true;
terencez 0:1fa43ab66921 419 // fall through
terencez 0:1fa43ab66921 420 case LWM2M_TYPE_OBJECT_INSTANCE:
terencez 0:1fa43ab66921 421 {
terencez 0:1fa43ab66921 422 uint8_t * tmpBuffer;
terencez 0:1fa43ab66921 423 int res;
terencez 0:1fa43ab66921 424
terencez 0:1fa43ab66921 425 res = tlv_serialize(isInstance, dataP[i].value.asChildren.count, dataP[i].value.asChildren.array, &tmpBuffer);
terencez 0:1fa43ab66921 426 if (res < 0)
terencez 0:1fa43ab66921 427 {
terencez 0:1fa43ab66921 428 length = -1;
terencez 0:1fa43ab66921 429 }
terencez 0:1fa43ab66921 430 else
terencez 0:1fa43ab66921 431 {
terencez 0:1fa43ab66921 432 size_t tmpLength;
terencez 0:1fa43ab66921 433
terencez 0:1fa43ab66921 434 tmpLength = (size_t)res;
terencez 0:1fa43ab66921 435 headerLen = prv_createHeader(*bufferP + index, false, dataP[i].type, dataP[i].id, tmpLength);
terencez 0:1fa43ab66921 436 index += headerLen;
terencez 0:1fa43ab66921 437 if (tmpLength > 0)
terencez 0:1fa43ab66921 438 {
terencez 0:1fa43ab66921 439 memcpy(*bufferP + index, tmpBuffer, tmpLength);
terencez 0:1fa43ab66921 440 index += tmpLength;
terencez 0:1fa43ab66921 441 lwm2m_free(tmpBuffer);
terencez 0:1fa43ab66921 442 }
terencez 0:1fa43ab66921 443 }
terencez 0:1fa43ab66921 444 }
terencez 0:1fa43ab66921 445 break;
terencez 0:1fa43ab66921 446
terencez 0:1fa43ab66921 447 case LWM2M_TYPE_OBJECT_LINK:
terencez 0:1fa43ab66921 448 {
terencez 0:1fa43ab66921 449 int k;
terencez 0:1fa43ab66921 450 uint8_t buf[4];
terencez 0:1fa43ab66921 451 uint32_t v = dataP[i].value.asObjLink.objectId;
terencez 0:1fa43ab66921 452 v <<= 16;
terencez 0:1fa43ab66921 453 v |= dataP[i].value.asObjLink.objectInstanceId;
terencez 0:1fa43ab66921 454 for (k = 3; k >= 0; --k) {
terencez 0:1fa43ab66921 455 buf[k] = (uint8_t)(v & 0xFF);
terencez 0:1fa43ab66921 456 v >>= 8;
terencez 0:1fa43ab66921 457 }
terencez 0:1fa43ab66921 458 // keep encoding as buffer
terencez 0:1fa43ab66921 459 headerLen = prv_createHeader(*bufferP + index, isInstance, dataP[i].type, dataP[i].id, 4);
terencez 0:1fa43ab66921 460 index += headerLen;
terencez 0:1fa43ab66921 461 memcpy(*bufferP + index, buf, 4);
terencez 0:1fa43ab66921 462 index += 4;
terencez 0:1fa43ab66921 463 }
terencez 0:1fa43ab66921 464 break;
terencez 0:1fa43ab66921 465
terencez 0:1fa43ab66921 466 case LWM2M_TYPE_STRING:
terencez 0:1fa43ab66921 467 case LWM2M_TYPE_OPAQUE:
terencez 0:1fa43ab66921 468 headerLen = prv_createHeader(*bufferP + index, isInstance, dataP[i].type, dataP[i].id, dataP[i].value.asBuffer.length);
terencez 0:1fa43ab66921 469 index += headerLen;
terencez 0:1fa43ab66921 470 memcpy(*bufferP + index, dataP[i].value.asBuffer.buffer, dataP[i].value.asBuffer.length);
terencez 0:1fa43ab66921 471 index += dataP[i].value.asBuffer.length;
terencez 0:1fa43ab66921 472 break;
terencez 0:1fa43ab66921 473
terencez 0:1fa43ab66921 474 case LWM2M_TYPE_INTEGER:
terencez 0:1fa43ab66921 475 {
terencez 0:1fa43ab66921 476 size_t data_len;
terencez 0:1fa43ab66921 477 uint8_t data_buffer[_PRV_64BIT_BUFFER_SIZE];
terencez 0:1fa43ab66921 478
terencez 0:1fa43ab66921 479 data_len = utils_encodeInt(dataP[i].value.asInteger, data_buffer);
terencez 0:1fa43ab66921 480 headerLen = prv_createHeader(*bufferP + index, isInstance, dataP[i].type, dataP[i].id, data_len);
terencez 0:1fa43ab66921 481 index += headerLen;
terencez 0:1fa43ab66921 482 memcpy(*bufferP + index, data_buffer, data_len);
terencez 0:1fa43ab66921 483 index += data_len;
terencez 0:1fa43ab66921 484 }
terencez 0:1fa43ab66921 485 break;
terencez 0:1fa43ab66921 486
terencez 0:1fa43ab66921 487 case LWM2M_TYPE_FLOAT:
terencez 0:1fa43ab66921 488 {
terencez 0:1fa43ab66921 489 size_t data_len;
terencez 0:1fa43ab66921 490 uint8_t data_buffer[_PRV_64BIT_BUFFER_SIZE];
terencez 0:1fa43ab66921 491
terencez 0:1fa43ab66921 492 data_len = utils_encodeFloat(dataP[i].value.asFloat, data_buffer);
terencez 0:1fa43ab66921 493 headerLen = prv_createHeader(*bufferP + index, isInstance, dataP[i].type, dataP[i].id, data_len);
terencez 0:1fa43ab66921 494 index += headerLen;
terencez 0:1fa43ab66921 495 memcpy(*bufferP + index, data_buffer, data_len);
terencez 0:1fa43ab66921 496 index += data_len;
terencez 0:1fa43ab66921 497 }
terencez 0:1fa43ab66921 498 break;
terencez 0:1fa43ab66921 499
terencez 0:1fa43ab66921 500 case LWM2M_TYPE_BOOLEAN:
terencez 0:1fa43ab66921 501 headerLen = prv_createHeader(*bufferP + index, isInstance, dataP[i].type, dataP[i].id, 1);
terencez 0:1fa43ab66921 502 index += headerLen;
terencez 0:1fa43ab66921 503 (*bufferP)[index] = dataP[i].value.asBoolean ? 1 : 0;
terencez 0:1fa43ab66921 504 index += 1;
terencez 0:1fa43ab66921 505 break;
terencez 0:1fa43ab66921 506
terencez 0:1fa43ab66921 507 default:
terencez 0:1fa43ab66921 508 length = -1;
terencez 0:1fa43ab66921 509 break;
terencez 0:1fa43ab66921 510 }
terencez 0:1fa43ab66921 511 }
terencez 0:1fa43ab66921 512
terencez 0:1fa43ab66921 513 if (length < 0)
terencez 0:1fa43ab66921 514 {
terencez 0:1fa43ab66921 515 lwm2m_free(*bufferP);
terencez 0:1fa43ab66921 516 *bufferP = NULL;
terencez 0:1fa43ab66921 517 }
terencez 0:1fa43ab66921 518
terencez 0:1fa43ab66921 519 LOG_ARG("returning %u", length);
terencez 0:1fa43ab66921 520
terencez 0:1fa43ab66921 521 return length;
terencez 0:1fa43ab66921 522 }
terencez 0:1fa43ab66921 523