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