Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
m2mtlvserializer.cpp
00001 /* 00002 * Copyright (c) 2015 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include "include/m2mtlvserializer.h" 00017 #include "mbed-client/m2mconstants.h" 00018 00019 #include <stdlib.h> 00020 #include "common_functions.h" 00021 00022 #define TRACE_GROUP "mClt" 00023 00024 #define MAX_TLV_LENGTH_SIZE 3 00025 #define MAX_TLV_ID_SIZE 2 00026 #define TLV_TYPE_SIZE 1 00027 00028 uint8_t* M2MTLVSerializer::serialize(const M2MObjectInstanceList &object_instance_list, uint32_t &size) 00029 { 00030 return serialize_object_instances(object_instance_list, size); 00031 } 00032 00033 uint8_t* M2MTLVSerializer::serialize(const M2MResourceList &resource_list, uint32_t &size) 00034 { 00035 bool valid = true; 00036 return serialize_resources(resource_list, size,valid); 00037 } 00038 00039 uint8_t* M2MTLVSerializer::serialize(const M2MResource *resource, uint32_t &size) 00040 { 00041 uint8_t* data = NULL; 00042 serialize(resource, data, size); 00043 return data; 00044 } 00045 00046 uint8_t* M2MTLVSerializer::serialize_object_instances(const M2MObjectInstanceList &object_instance_list, uint32_t &size) 00047 { 00048 uint8_t *data = NULL; 00049 00050 if(!object_instance_list.empty()) { 00051 M2MObjectInstanceList::const_iterator it; 00052 it = object_instance_list.begin(); 00053 for (; it!=object_instance_list.end(); it++) { 00054 uint16_t id = (*it)->instance_id(); 00055 serialize(id, *it, data, size); 00056 } 00057 } 00058 return data; 00059 } 00060 00061 uint8_t* M2MTLVSerializer::serialize_resources(const M2MResourceList &resource_list, uint32_t &size, bool &valid) 00062 { 00063 uint8_t *data = NULL; 00064 00065 if(!resource_list.empty()) { 00066 M2MResourceList::const_iterator it; 00067 it = resource_list.begin(); 00068 for (; it!=resource_list.end(); it++) { 00069 if((*it)->name_id() == -1) { 00070 valid = false; 00071 break; 00072 } 00073 } 00074 if(valid) { 00075 it = resource_list.begin(); 00076 for (; it!=resource_list.end(); it++) { 00077 if (((*it)->operation() & M2MBase::GET_ALLOWED) == M2MBase::GET_ALLOWED) { 00078 if(!serialize(*it, data, size)) { 00079 /* serializing has failed */ 00080 /* free data so far */ 00081 free(data); 00082 /* invalidate */ 00083 valid = false; 00084 /* return NULL immediately */ 00085 return NULL; 00086 } 00087 } 00088 } 00089 } 00090 } 00091 return data; 00092 } 00093 00094 bool M2MTLVSerializer::serialize(uint16_t id, const M2MObjectInstance *object_instance, uint8_t *&data, uint32_t &size) 00095 { 00096 uint8_t *resource_data = NULL; 00097 uint32_t resource_size = 0; 00098 bool success; 00099 00100 bool valid = true; 00101 resource_data = serialize_resources(object_instance->resources(),resource_size,valid); 00102 if(valid) { 00103 if(serialize_TILV(TYPE_OBJECT_INSTANCE, id, resource_data, resource_size, data, size)) { 00104 success = true; 00105 } else { 00106 /* serializing object instance failed */ 00107 success = false; 00108 } 00109 free(resource_data); 00110 } else { 00111 /* serializing resources failed */ 00112 success = false; 00113 } 00114 return success; 00115 } 00116 00117 bool M2MTLVSerializer::serialize(const M2MResource *resource, uint8_t *&data, uint32_t &size) 00118 { 00119 bool success = false; 00120 if(resource->name_id() != -1) { 00121 success = resource->supports_multiple_instances() ? 00122 serialize_multiple_resource(resource, data, size) : 00123 serialize_resource(resource, data, size); 00124 } 00125 return success; 00126 } 00127 00128 bool M2MTLVSerializer::serialize_resource(const M2MResource *resource, uint8_t *&data, uint32_t &size) 00129 { 00130 bool success = false; 00131 if(resource->name_id() != -1) { 00132 if ( (resource->resource_instance_type() == M2MResourceBase::INTEGER) || 00133 (resource->resource_instance_type() == M2MResourceBase::BOOLEAN) || 00134 (resource->resource_instance_type() == M2MResourceBase::TIME) ) { 00135 success = serialize_TLV_binary_int(resource, TYPE_RESOURCE, resource->name_id(), data, size); 00136 } 00137 else if (resource->resource_instance_type() == M2MResourceBase::FLOAT) { 00138 success = serialize_TLV_binary_float(resource, TYPE_RESOURCE, resource->name_id(), data, size); 00139 } 00140 else { 00141 success = serialize_TILV(TYPE_RESOURCE, resource->name_id(), 00142 resource->value(), resource->value_length(), data, size); 00143 } 00144 } 00145 return success; 00146 } 00147 00148 bool M2MTLVSerializer::serialize_multiple_resource(const M2MResource *resource, uint8_t *&data, uint32_t &size) 00149 { 00150 bool success = false; 00151 uint8_t *nested_data = NULL; 00152 uint32_t nested_data_size = 0; 00153 00154 const M2MResourceInstanceList &instance_list = resource->resource_instances(); 00155 if(!instance_list.empty()) { 00156 M2MResourceInstanceList::const_iterator it; 00157 it = instance_list.begin(); 00158 for (; it!=instance_list.end(); it++) { 00159 uint16_t id = (*it)->instance_id(); 00160 if (((*it)->operation() & M2MBase::GET_ALLOWED) == M2MBase::GET_ALLOWED) { 00161 if(!serialize_resource_instance(id, (*it), nested_data, nested_data_size)) { 00162 /* serializing instance has failed */ 00163 /* free data so far allocated */ 00164 free(nested_data); 00165 /* return fail immediately*/ 00166 success = false; 00167 return success; 00168 } 00169 } 00170 } 00171 } 00172 if(resource->name_id() != -1 && 00173 (resource->operation() & M2MBase::GET_ALLOWED) == M2MBase::GET_ALLOWED) { 00174 success = serialize_TILV(TYPE_MULTIPLE_RESOURCE, resource->name_id(), 00175 nested_data, nested_data_size, data, size); 00176 } 00177 00178 free(nested_data); 00179 return success; 00180 } 00181 00182 bool M2MTLVSerializer::serialize_resource_instance(uint16_t id, const M2MResourceInstance *resource, uint8_t *&data, uint32_t &size) 00183 { 00184 bool success; 00185 00186 if ( (resource->resource_instance_type() == M2MResourceBase::INTEGER) || 00187 (resource->resource_instance_type() == M2MResourceBase::BOOLEAN) || 00188 (resource->resource_instance_type() == M2MResourceBase::TIME) ) { 00189 success=serialize_TLV_binary_int(resource, TYPE_RESOURCE_INSTANCE, id, data, size); 00190 } 00191 else if (resource->resource_instance_type() == M2MResourceBase::FLOAT) { 00192 success=serialize_TLV_binary_float(resource, TYPE_RESOURCE_INSTANCE, id, data, size); 00193 } 00194 else { 00195 success=serialize_TILV(TYPE_RESOURCE_INSTANCE, id, resource->value(), resource->value_length(), data, size); 00196 } 00197 00198 return success; 00199 } 00200 00201 /* See, OMA-TS-LightweightM2M-V1_0-20170208-A, Appendix C, 00202 * Data Types, Integer, Boolean and Time TLV Format */ 00203 bool M2MTLVSerializer::serialize_TLV_binary_int(const M2MResourceBase *resource, uint8_t type, uint16_t id, uint8_t *&data, uint32_t &size) 00204 { 00205 int64_t valueInt = resource->get_value_int(); 00206 uint32_t buffer_size; 00207 /* max len 8 bytes */ 00208 uint8_t buffer[8]; 00209 00210 if (resource->resource_instance_type() == M2MResourceBase::BOOLEAN) { 00211 buffer_size = 1; 00212 buffer[0] = valueInt; 00213 } else { 00214 buffer_size = 8; 00215 common_write_64_bit(valueInt, buffer); 00216 } 00217 00218 return serialize_TILV(type, id, buffer, buffer_size, data, size); 00219 } 00220 00221 /* See, OMA-TS-LightweightM2M-V1_0-20170208-A, Appendix C, 00222 * Data Type Float (32 bit only) TLV Format */ 00223 bool M2MTLVSerializer::serialize_TLV_binary_float(const M2MResourceBase *resource, uint8_t type, uint16_t id, uint8_t *&data, uint32_t &size) 00224 { 00225 float valueFloat = resource->get_value_float(); 00226 /* max len 8 bytes */ 00227 uint8_t buffer[4]; 00228 00229 common_write_32_bit(*(uint32_t*)&valueFloat, buffer); 00230 00231 return serialize_TILV(type, id, buffer, 4, data, size); 00232 } 00233 00234 00235 bool M2MTLVSerializer::serialize_TILV(uint8_t type, uint16_t id, uint8_t *value, uint32_t value_length, uint8_t *&data, uint32_t &size) 00236 { 00237 uint8_t *tlv = 0; 00238 const uint32_t type_length = TLV_TYPE_SIZE; 00239 type += id < 256 ? 0 : ID16; 00240 type += value_length < 8 ? value_length : 00241 value_length < 256 ? LENGTH8 : 00242 value_length < 65536 ? LENGTH16 : LENGTH24; 00243 uint8_t tlv_type; 00244 tlv_type = type & 0xFF; 00245 00246 uint32_t id_size; 00247 uint8_t id_array[MAX_TLV_ID_SIZE]; 00248 serialize_id(id, id_size, id_array); 00249 00250 uint32_t length_size; 00251 uint8_t length_array[MAX_TLV_LENGTH_SIZE]; 00252 serialize_length(value_length, length_size, length_array); 00253 00254 tlv = (uint8_t*)malloc(size + type_length + id_size + length_size + value_length); 00255 if (!tlv) { 00256 /* memory allocation has failed */ 00257 /* return failure immediately */ 00258 return false; 00259 /* eventually NULL will be returned to serializer public method caller */ 00260 } 00261 if(data) { 00262 memcpy(tlv, data, size); 00263 free(data); 00264 } 00265 memcpy(tlv+size, &tlv_type, type_length); 00266 memcpy(tlv+size+type_length, id_array, id_size); 00267 memcpy(tlv+size+type_length+id_size, length_array, length_size); 00268 memcpy(tlv+size+type_length+id_size+length_size, value, value_length); 00269 00270 data = tlv; 00271 size += type_length + id_size + length_size + value_length; 00272 return true; 00273 } 00274 00275 void M2MTLVSerializer::serialize_id(uint16_t id, uint32_t &size, uint8_t *id_ptr) 00276 { 00277 if(id > 255) { 00278 size=2; 00279 id_ptr[0] = (id & 0xFF00) >> 8; 00280 id_ptr[1] = id & 0xFF; 00281 } else { 00282 size=1; 00283 id_ptr[0] = id & 0xFF; 00284 } 00285 } 00286 00287 void M2MTLVSerializer::serialize_length(uint32_t length, uint32_t &size, uint8_t *length_ptr) 00288 { 00289 if (length > 65535) { 00290 size = 3; 00291 length_ptr[0] = (length & 0xFF0000) >> 16; 00292 length_ptr[1] = (length & 0xFF00) >> 8; 00293 length_ptr[2] = length & 0xFF; 00294 } else if (length > 255) { 00295 size = 2; 00296 length_ptr[0] = (length & 0xFF00) >> 8; 00297 length_ptr[1] = length & 0xFF; 00298 } else if (length > 7) { 00299 size = 1; 00300 length_ptr[0] = length & 0xFF; 00301 } else { 00302 size=0; 00303 } 00304 } 00305
Generated on Mon Aug 29 2022 19:53:40 by
