Jim Carver
/
mbed-cloud-workshop-connect-HTS221
bug fix
Embed:
(wiki syntax)
Show/hide line numbers
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 Tue Jul 12 2022 21:04:56 by 1.7.2