Toyomasa Watarai / simple-mbed-cloud-client

Dependents:  

Committer:
MACRUM
Date:
Mon Jul 02 08:06:37 2018 +0000
Revision:
2:bf2124b482f9
Parent:
0:276e7a263c35
Update library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MACRUM 0:276e7a263c35 1 /*
MACRUM 0:276e7a263c35 2 * Copyright (c) 2015 ARM Limited. All rights reserved.
MACRUM 0:276e7a263c35 3 * SPDX-License-Identifier: Apache-2.0
MACRUM 0:276e7a263c35 4 * Licensed under the Apache License, Version 2.0 (the License); you may
MACRUM 0:276e7a263c35 5 * not use this file except in compliance with the License.
MACRUM 0:276e7a263c35 6 * You may obtain a copy of the License at
MACRUM 0:276e7a263c35 7 *
MACRUM 0:276e7a263c35 8 * http://www.apache.org/licenses/LICENSE-2.0
MACRUM 0:276e7a263c35 9 *
MACRUM 0:276e7a263c35 10 * Unless required by applicable law or agreed to in writing, software
MACRUM 0:276e7a263c35 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
MACRUM 0:276e7a263c35 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
MACRUM 0:276e7a263c35 13 * See the License for the specific language governing permissions and
MACRUM 0:276e7a263c35 14 * limitations under the License.
MACRUM 0:276e7a263c35 15 */
MACRUM 0:276e7a263c35 16 #include "include/m2mtlvserializer.h"
MACRUM 0:276e7a263c35 17 #include "mbed-client/m2mconstants.h"
MACRUM 0:276e7a263c35 18
MACRUM 0:276e7a263c35 19 #include <stdlib.h>
MACRUM 0:276e7a263c35 20 #include "common_functions.h"
MACRUM 0:276e7a263c35 21
MACRUM 0:276e7a263c35 22 #define TRACE_GROUP "mClt"
MACRUM 0:276e7a263c35 23
MACRUM 0:276e7a263c35 24 #define MAX_TLV_LENGTH_SIZE 3
MACRUM 0:276e7a263c35 25 #define MAX_TLV_ID_SIZE 2
MACRUM 0:276e7a263c35 26 #define TLV_TYPE_SIZE 1
MACRUM 0:276e7a263c35 27
MACRUM 0:276e7a263c35 28 uint8_t* M2MTLVSerializer::serialize(const M2MObjectInstanceList &object_instance_list, uint32_t &size)
MACRUM 0:276e7a263c35 29 {
MACRUM 0:276e7a263c35 30 return serialize_object_instances(object_instance_list, size);
MACRUM 0:276e7a263c35 31 }
MACRUM 0:276e7a263c35 32
MACRUM 0:276e7a263c35 33 uint8_t* M2MTLVSerializer::serialize(const M2MResourceList &resource_list, uint32_t &size)
MACRUM 0:276e7a263c35 34 {
MACRUM 0:276e7a263c35 35 bool valid = true;
MACRUM 0:276e7a263c35 36 return serialize_resources(resource_list, size,valid);
MACRUM 0:276e7a263c35 37 }
MACRUM 0:276e7a263c35 38
MACRUM 0:276e7a263c35 39 uint8_t* M2MTLVSerializer::serialize(const M2MResource *resource, uint32_t &size)
MACRUM 0:276e7a263c35 40 {
MACRUM 0:276e7a263c35 41 uint8_t* data = NULL;
MACRUM 0:276e7a263c35 42 serialize(resource, data, size);
MACRUM 0:276e7a263c35 43 return data;
MACRUM 0:276e7a263c35 44 }
MACRUM 0:276e7a263c35 45
MACRUM 0:276e7a263c35 46 uint8_t* M2MTLVSerializer::serialize_object_instances(const M2MObjectInstanceList &object_instance_list, uint32_t &size)
MACRUM 0:276e7a263c35 47 {
MACRUM 0:276e7a263c35 48 uint8_t *data = NULL;
MACRUM 0:276e7a263c35 49
MACRUM 0:276e7a263c35 50 if(!object_instance_list.empty()) {
MACRUM 0:276e7a263c35 51 M2MObjectInstanceList::const_iterator it;
MACRUM 0:276e7a263c35 52 it = object_instance_list.begin();
MACRUM 0:276e7a263c35 53 for (; it!=object_instance_list.end(); it++) {
MACRUM 0:276e7a263c35 54 uint16_t id = (*it)->instance_id();
MACRUM 0:276e7a263c35 55 serialize(id, *it, data, size);
MACRUM 0:276e7a263c35 56 }
MACRUM 0:276e7a263c35 57 }
MACRUM 0:276e7a263c35 58 return data;
MACRUM 0:276e7a263c35 59 }
MACRUM 0:276e7a263c35 60
MACRUM 0:276e7a263c35 61 uint8_t* M2MTLVSerializer::serialize_resources(const M2MResourceList &resource_list, uint32_t &size, bool &valid)
MACRUM 0:276e7a263c35 62 {
MACRUM 0:276e7a263c35 63 uint8_t *data = NULL;
MACRUM 0:276e7a263c35 64
MACRUM 0:276e7a263c35 65 if(!resource_list.empty()) {
MACRUM 0:276e7a263c35 66 M2MResourceList::const_iterator it;
MACRUM 0:276e7a263c35 67 it = resource_list.begin();
MACRUM 0:276e7a263c35 68 for (; it!=resource_list.end(); it++) {
MACRUM 0:276e7a263c35 69 if((*it)->name_id() == -1) {
MACRUM 0:276e7a263c35 70 valid = false;
MACRUM 0:276e7a263c35 71 break;
MACRUM 0:276e7a263c35 72 }
MACRUM 0:276e7a263c35 73 }
MACRUM 0:276e7a263c35 74 if(valid) {
MACRUM 0:276e7a263c35 75 it = resource_list.begin();
MACRUM 0:276e7a263c35 76 for (; it!=resource_list.end(); it++) {
MACRUM 0:276e7a263c35 77 if (((*it)->operation() & M2MBase::GET_ALLOWED) == M2MBase::GET_ALLOWED) {
MACRUM 0:276e7a263c35 78 if(!serialize(*it, data, size)) {
MACRUM 0:276e7a263c35 79 /* serializing has failed */
MACRUM 0:276e7a263c35 80 /* free data so far */
MACRUM 0:276e7a263c35 81 free(data);
MACRUM 0:276e7a263c35 82 /* invalidate */
MACRUM 0:276e7a263c35 83 valid = false;
MACRUM 0:276e7a263c35 84 /* return NULL immediately */
MACRUM 0:276e7a263c35 85 return NULL;
MACRUM 0:276e7a263c35 86 }
MACRUM 0:276e7a263c35 87 }
MACRUM 0:276e7a263c35 88 }
MACRUM 0:276e7a263c35 89 }
MACRUM 0:276e7a263c35 90 }
MACRUM 0:276e7a263c35 91 return data;
MACRUM 0:276e7a263c35 92 }
MACRUM 0:276e7a263c35 93
MACRUM 0:276e7a263c35 94 bool M2MTLVSerializer::serialize(uint16_t id, const M2MObjectInstance *object_instance, uint8_t *&data, uint32_t &size)
MACRUM 0:276e7a263c35 95 {
MACRUM 0:276e7a263c35 96 uint8_t *resource_data = NULL;
MACRUM 0:276e7a263c35 97 uint32_t resource_size = 0;
MACRUM 0:276e7a263c35 98 bool success;
MACRUM 0:276e7a263c35 99
MACRUM 0:276e7a263c35 100 bool valid = true;
MACRUM 0:276e7a263c35 101 resource_data = serialize_resources(object_instance->resources(),resource_size,valid);
MACRUM 0:276e7a263c35 102 if(valid) {
MACRUM 0:276e7a263c35 103 if(serialize_TILV(TYPE_OBJECT_INSTANCE, id, resource_data, resource_size, data, size)) {
MACRUM 0:276e7a263c35 104 success = true;
MACRUM 0:276e7a263c35 105 } else {
MACRUM 0:276e7a263c35 106 /* serializing object instance failed */
MACRUM 0:276e7a263c35 107 success = false;
MACRUM 0:276e7a263c35 108 }
MACRUM 0:276e7a263c35 109 free(resource_data);
MACRUM 0:276e7a263c35 110 } else {
MACRUM 0:276e7a263c35 111 /* serializing resources failed */
MACRUM 0:276e7a263c35 112 success = false;
MACRUM 0:276e7a263c35 113 }
MACRUM 0:276e7a263c35 114 return success;
MACRUM 0:276e7a263c35 115 }
MACRUM 0:276e7a263c35 116
MACRUM 0:276e7a263c35 117 bool M2MTLVSerializer::serialize(const M2MResource *resource, uint8_t *&data, uint32_t &size)
MACRUM 0:276e7a263c35 118 {
MACRUM 0:276e7a263c35 119 bool success = false;
MACRUM 0:276e7a263c35 120 if(resource->name_id() != -1) {
MACRUM 0:276e7a263c35 121 success = resource->supports_multiple_instances() ?
MACRUM 0:276e7a263c35 122 serialize_multiple_resource(resource, data, size) :
MACRUM 0:276e7a263c35 123 serialize_resource(resource, data, size);
MACRUM 0:276e7a263c35 124 }
MACRUM 0:276e7a263c35 125 return success;
MACRUM 0:276e7a263c35 126 }
MACRUM 0:276e7a263c35 127
MACRUM 0:276e7a263c35 128 bool M2MTLVSerializer::serialize_resource(const M2MResource *resource, uint8_t *&data, uint32_t &size)
MACRUM 0:276e7a263c35 129 {
MACRUM 0:276e7a263c35 130 bool success = false;
MACRUM 0:276e7a263c35 131 if(resource->name_id() != -1) {
MACRUM 0:276e7a263c35 132 if ( (resource->resource_instance_type() == M2MResourceBase::INTEGER) ||
MACRUM 0:276e7a263c35 133 (resource->resource_instance_type() == M2MResourceBase::BOOLEAN) ||
MACRUM 0:276e7a263c35 134 (resource->resource_instance_type() == M2MResourceBase::TIME) ) {
MACRUM 0:276e7a263c35 135 success = serialize_TLV_binary_int(resource, TYPE_RESOURCE, resource->name_id(), data, size);
MACRUM 0:276e7a263c35 136 }
MACRUM 0:276e7a263c35 137 else {
MACRUM 0:276e7a263c35 138 success = serialize_TILV(TYPE_RESOURCE, resource->name_id(),
MACRUM 0:276e7a263c35 139 resource->value(), resource->value_length(), data, size);
MACRUM 0:276e7a263c35 140 }
MACRUM 0:276e7a263c35 141 }
MACRUM 0:276e7a263c35 142 return success;
MACRUM 0:276e7a263c35 143 }
MACRUM 0:276e7a263c35 144
MACRUM 0:276e7a263c35 145 bool M2MTLVSerializer::serialize_multiple_resource(const M2MResource *resource, uint8_t *&data, uint32_t &size)
MACRUM 0:276e7a263c35 146 {
MACRUM 0:276e7a263c35 147 bool success = false;
MACRUM 0:276e7a263c35 148 uint8_t *nested_data = NULL;
MACRUM 0:276e7a263c35 149 uint32_t nested_data_size = 0;
MACRUM 0:276e7a263c35 150
MACRUM 0:276e7a263c35 151 const M2MResourceInstanceList &instance_list = resource->resource_instances();
MACRUM 0:276e7a263c35 152 if(!instance_list.empty()) {
MACRUM 0:276e7a263c35 153 M2MResourceInstanceList::const_iterator it;
MACRUM 0:276e7a263c35 154 it = instance_list.begin();
MACRUM 0:276e7a263c35 155 for (; it!=instance_list.end(); it++) {
MACRUM 0:276e7a263c35 156 uint16_t id = (*it)->instance_id();
MACRUM 0:276e7a263c35 157 if (((*it)->operation() & M2MBase::GET_ALLOWED) == M2MBase::GET_ALLOWED) {
MACRUM 0:276e7a263c35 158 if(!serialize_resource_instance(id, (*it), nested_data, nested_data_size)) {
MACRUM 0:276e7a263c35 159 /* serializing instance has failed */
MACRUM 0:276e7a263c35 160 /* free data so far allocated */
MACRUM 0:276e7a263c35 161 free(nested_data);
MACRUM 0:276e7a263c35 162 /* return fail immediately*/
MACRUM 0:276e7a263c35 163 success = false;
MACRUM 0:276e7a263c35 164 return success;
MACRUM 0:276e7a263c35 165 }
MACRUM 0:276e7a263c35 166 }
MACRUM 0:276e7a263c35 167 }
MACRUM 0:276e7a263c35 168 }
MACRUM 0:276e7a263c35 169 if(resource->name_id() != -1 &&
MACRUM 0:276e7a263c35 170 (resource->operation() & M2MBase::GET_ALLOWED) == M2MBase::GET_ALLOWED) {
MACRUM 0:276e7a263c35 171 success = serialize_TILV(TYPE_MULTIPLE_RESOURCE, resource->name_id(),
MACRUM 0:276e7a263c35 172 nested_data, nested_data_size, data, size);
MACRUM 0:276e7a263c35 173 }
MACRUM 0:276e7a263c35 174
MACRUM 0:276e7a263c35 175 free(nested_data);
MACRUM 0:276e7a263c35 176 return success;
MACRUM 0:276e7a263c35 177 }
MACRUM 0:276e7a263c35 178
MACRUM 0:276e7a263c35 179 bool M2MTLVSerializer::serialize_resource_instance(uint16_t id, const M2MResourceInstance *resource, uint8_t *&data, uint32_t &size)
MACRUM 0:276e7a263c35 180 {
MACRUM 0:276e7a263c35 181 bool success;
MACRUM 0:276e7a263c35 182
MACRUM 0:276e7a263c35 183 if ( (resource->resource_instance_type() == M2MResourceBase::INTEGER) ||
MACRUM 0:276e7a263c35 184 (resource->resource_instance_type() == M2MResourceBase::BOOLEAN) ||
MACRUM 0:276e7a263c35 185 (resource->resource_instance_type() == M2MResourceBase::TIME) ) {
MACRUM 0:276e7a263c35 186 success=serialize_TLV_binary_int(resource, TYPE_RESOURCE_INSTANCE, id, data, size);
MACRUM 0:276e7a263c35 187 }
MACRUM 0:276e7a263c35 188 else {
MACRUM 0:276e7a263c35 189 success=serialize_TILV(TYPE_RESOURCE_INSTANCE, id, resource->value(), resource->value_length(), data, size);
MACRUM 0:276e7a263c35 190 }
MACRUM 0:276e7a263c35 191
MACRUM 0:276e7a263c35 192 return success;
MACRUM 0:276e7a263c35 193 }
MACRUM 0:276e7a263c35 194
MACRUM 0:276e7a263c35 195 /* See, OMA-TS-LightweightM2M-V1_0-20170208-A, Appendix C,
MACRUM 0:276e7a263c35 196 * Data Types, Integer, Boolean and TY
MACRUM 0:276e7a263c35 197 * Yime, TLV Format */
MACRUM 0:276e7a263c35 198 bool M2MTLVSerializer::serialize_TLV_binary_int(const M2MResourceBase *resource, uint8_t type, uint16_t id, uint8_t *&data, uint32_t &size)
MACRUM 0:276e7a263c35 199 {
MACRUM 0:276e7a263c35 200 int64_t valueInt = resource->get_value_int();
MACRUM 0:276e7a263c35 201 uint32_t buffer_size;
MACRUM 0:276e7a263c35 202 /* max len 8 bytes */
MACRUM 0:276e7a263c35 203 uint8_t buffer[8];
MACRUM 0:276e7a263c35 204
MACRUM 0:276e7a263c35 205 if (resource->resource_instance_type() == M2MResourceBase::BOOLEAN) {
MACRUM 0:276e7a263c35 206 buffer_size = 1;
MACRUM 0:276e7a263c35 207 buffer[0] = valueInt;
MACRUM 0:276e7a263c35 208 } else {
MACRUM 0:276e7a263c35 209 buffer_size = 8;
MACRUM 0:276e7a263c35 210 common_write_64_bit(valueInt, buffer);
MACRUM 0:276e7a263c35 211 }
MACRUM 0:276e7a263c35 212
MACRUM 0:276e7a263c35 213 return serialize_TILV(type, id, buffer, buffer_size, data, size);
MACRUM 0:276e7a263c35 214 }
MACRUM 0:276e7a263c35 215
MACRUM 0:276e7a263c35 216
MACRUM 0:276e7a263c35 217 bool M2MTLVSerializer::serialize_TILV(uint8_t type, uint16_t id, uint8_t *value, uint32_t value_length, uint8_t *&data, uint32_t &size)
MACRUM 0:276e7a263c35 218 {
MACRUM 0:276e7a263c35 219 uint8_t *tlv = 0;
MACRUM 0:276e7a263c35 220 const uint32_t type_length = TLV_TYPE_SIZE;
MACRUM 0:276e7a263c35 221 type += id < 256 ? 0 : ID16;
MACRUM 0:276e7a263c35 222 type += value_length < 8 ? value_length :
MACRUM 0:276e7a263c35 223 value_length < 256 ? LENGTH8 :
MACRUM 0:276e7a263c35 224 value_length < 65536 ? LENGTH16 : LENGTH24;
MACRUM 0:276e7a263c35 225 uint8_t tlv_type;
MACRUM 0:276e7a263c35 226 tlv_type = type & 0xFF;
MACRUM 0:276e7a263c35 227
MACRUM 0:276e7a263c35 228 uint32_t id_size;
MACRUM 0:276e7a263c35 229 uint8_t id_array[MAX_TLV_ID_SIZE];
MACRUM 0:276e7a263c35 230 serialize_id(id, id_size, id_array);
MACRUM 0:276e7a263c35 231
MACRUM 0:276e7a263c35 232 uint32_t length_size;
MACRUM 0:276e7a263c35 233 uint8_t length_array[MAX_TLV_LENGTH_SIZE];
MACRUM 0:276e7a263c35 234 serialize_length(value_length, length_size, length_array);
MACRUM 0:276e7a263c35 235
MACRUM 0:276e7a263c35 236 tlv = (uint8_t*)malloc(size + type_length + id_size + length_size + value_length);
MACRUM 0:276e7a263c35 237 if (!tlv) {
MACRUM 0:276e7a263c35 238 /* memory allocation has failed */
MACRUM 0:276e7a263c35 239 /* return failure immediately */
MACRUM 0:276e7a263c35 240 return false;
MACRUM 0:276e7a263c35 241 /* eventually NULL will be returned to serializer public method caller */
MACRUM 0:276e7a263c35 242 }
MACRUM 0:276e7a263c35 243 if(data) {
MACRUM 0:276e7a263c35 244 memcpy(tlv, data, size);
MACRUM 0:276e7a263c35 245 free(data);
MACRUM 0:276e7a263c35 246 }
MACRUM 0:276e7a263c35 247 memcpy(tlv+size, &tlv_type, type_length);
MACRUM 0:276e7a263c35 248 memcpy(tlv+size+type_length, id_array, id_size);
MACRUM 0:276e7a263c35 249 memcpy(tlv+size+type_length+id_size, length_array, length_size);
MACRUM 0:276e7a263c35 250 memcpy(tlv+size+type_length+id_size+length_size, value, value_length);
MACRUM 0:276e7a263c35 251
MACRUM 0:276e7a263c35 252 data = tlv;
MACRUM 0:276e7a263c35 253 size += type_length + id_size + length_size + value_length;
MACRUM 0:276e7a263c35 254 return true;
MACRUM 0:276e7a263c35 255 }
MACRUM 0:276e7a263c35 256
MACRUM 0:276e7a263c35 257 void M2MTLVSerializer::serialize_id(uint16_t id, uint32_t &size, uint8_t *id_ptr)
MACRUM 0:276e7a263c35 258 {
MACRUM 0:276e7a263c35 259 if(id > 255) {
MACRUM 0:276e7a263c35 260 size=2;
MACRUM 0:276e7a263c35 261 id_ptr[0] = (id & 0xFF00) >> 8;
MACRUM 0:276e7a263c35 262 id_ptr[1] = id & 0xFF;
MACRUM 0:276e7a263c35 263 } else {
MACRUM 0:276e7a263c35 264 size=1;
MACRUM 0:276e7a263c35 265 id_ptr[0] = id & 0xFF;
MACRUM 0:276e7a263c35 266 }
MACRUM 0:276e7a263c35 267 }
MACRUM 0:276e7a263c35 268
MACRUM 0:276e7a263c35 269 void M2MTLVSerializer::serialize_length(uint32_t length, uint32_t &size, uint8_t *length_ptr)
MACRUM 0:276e7a263c35 270 {
MACRUM 0:276e7a263c35 271 if (length > 65535) {
MACRUM 0:276e7a263c35 272 size = 3;
MACRUM 0:276e7a263c35 273 length_ptr[0] = (length & 0xFF0000) >> 16;
MACRUM 0:276e7a263c35 274 length_ptr[1] = (length & 0xFF00) >> 8;
MACRUM 0:276e7a263c35 275 length_ptr[2] = length & 0xFF;
MACRUM 0:276e7a263c35 276 } else if (length > 255) {
MACRUM 0:276e7a263c35 277 size = 2;
MACRUM 0:276e7a263c35 278 length_ptr[0] = (length & 0xFF00) >> 8;
MACRUM 0:276e7a263c35 279 length_ptr[1] = length & 0xFF;
MACRUM 0:276e7a263c35 280 } else if (length > 7) {
MACRUM 0:276e7a263c35 281 size = 1;
MACRUM 0:276e7a263c35 282 length_ptr[0] = length & 0xFF;
MACRUM 0:276e7a263c35 283 } else {
MACRUM 0:276e7a263c35 284 size=0;
MACRUM 0:276e7a263c35 285 }
MACRUM 0:276e7a263c35 286 }
MACRUM 0:276e7a263c35 287