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

Committer:
terencez
Date:
Wed Apr 19 11:28:00 2017 +0000
Revision:
0:3f48af28ebcd
Initial commit

Who changed what in which revision?

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