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 { 00138 success = serialize_TILV(TYPE_RESOURCE, resource->name_id(), 00139 resource->value(), resource->value_length(), data, size); 00140 } 00141 } 00142 return success; 00143 } 00144 00145 bool M2MTLVSerializer::serialize_multiple_resource(const M2MResource *resource, uint8_t *&data, uint32_t &size) 00146 { 00147 bool success = false; 00148 uint8_t *nested_data = NULL; 00149 uint32_t nested_data_size = 0; 00150 00151 const M2MResourceInstanceList &instance_list = resource->resource_instances(); 00152 if(!instance_list.empty()) { 00153 M2MResourceInstanceList::const_iterator it; 00154 it = instance_list.begin(); 00155 for (; it!=instance_list.end(); it++) { 00156 uint16_t id = (*it)->instance_id(); 00157 if (((*it)->operation() & M2MBase::GET_ALLOWED) == M2MBase::GET_ALLOWED) { 00158 if(!serialize_resource_instance(id, (*it), nested_data, nested_data_size)) { 00159 /* serializing instance has failed */ 00160 /* free data so far allocated */ 00161 free(nested_data); 00162 /* return fail immediately*/ 00163 success = false; 00164 return success; 00165 } 00166 } 00167 } 00168 } 00169 if(resource->name_id() != -1 && 00170 (resource->operation() & M2MBase::GET_ALLOWED) == M2MBase::GET_ALLOWED) { 00171 success = serialize_TILV(TYPE_MULTIPLE_RESOURCE, resource->name_id(), 00172 nested_data, nested_data_size, data, size); 00173 } 00174 00175 free(nested_data); 00176 return success; 00177 } 00178 00179 bool M2MTLVSerializer::serialize_resource_instance(uint16_t id, const M2MResourceInstance *resource, uint8_t *&data, uint32_t &size) 00180 { 00181 bool success; 00182 00183 if ( (resource->resource_instance_type() == M2MResourceBase::INTEGER) || 00184 (resource->resource_instance_type() == M2MResourceBase::BOOLEAN) || 00185 (resource->resource_instance_type() == M2MResourceBase::TIME) ) { 00186 success=serialize_TLV_binary_int(resource, TYPE_RESOURCE_INSTANCE, id, data, size); 00187 } 00188 else { 00189 success=serialize_TILV(TYPE_RESOURCE_INSTANCE, id, resource->value(), resource->value_length(), data, size); 00190 } 00191 00192 return success; 00193 } 00194 00195 /* See, OMA-TS-LightweightM2M-V1_0-20170208-A, Appendix C, 00196 * Data Types, Integer, Boolean and TY 00197 * Yime, TLV Format */ 00198 bool M2MTLVSerializer::serialize_TLV_binary_int(const M2MResourceBase *resource, uint8_t type, uint16_t id, uint8_t *&data, uint32_t &size) 00199 { 00200 int64_t valueInt = resource->get_value_int(); 00201 uint32_t buffer_size; 00202 /* max len 8 bytes */ 00203 uint8_t buffer[8]; 00204 00205 if (resource->resource_instance_type() == M2MResourceBase::BOOLEAN) { 00206 buffer_size = 1; 00207 buffer[0] = valueInt; 00208 } else { 00209 buffer_size = 8; 00210 common_write_64_bit(valueInt, buffer); 00211 } 00212 00213 return serialize_TILV(type, id, buffer, buffer_size, data, size); 00214 } 00215 00216 00217 bool M2MTLVSerializer::serialize_TILV(uint8_t type, uint16_t id, uint8_t *value, uint32_t value_length, uint8_t *&data, uint32_t &size) 00218 { 00219 uint8_t *tlv = 0; 00220 const uint32_t type_length = TLV_TYPE_SIZE; 00221 type += id < 256 ? 0 : ID16; 00222 type += value_length < 8 ? value_length : 00223 value_length < 256 ? LENGTH8 : 00224 value_length < 65536 ? LENGTH16 : LENGTH24; 00225 uint8_t tlv_type; 00226 tlv_type = type & 0xFF; 00227 00228 uint32_t id_size; 00229 uint8_t id_array[MAX_TLV_ID_SIZE]; 00230 serialize_id(id, id_size, id_array); 00231 00232 uint32_t length_size; 00233 uint8_t length_array[MAX_TLV_LENGTH_SIZE]; 00234 serialize_length(value_length, length_size, length_array); 00235 00236 tlv = (uint8_t*)malloc(size + type_length + id_size + length_size + value_length); 00237 if (!tlv) { 00238 /* memory allocation has failed */ 00239 /* return failure immediately */ 00240 return false; 00241 /* eventually NULL will be returned to serializer public method caller */ 00242 } 00243 if(data) { 00244 memcpy(tlv, data, size); 00245 free(data); 00246 } 00247 memcpy(tlv+size, &tlv_type, type_length); 00248 memcpy(tlv+size+type_length, id_array, id_size); 00249 memcpy(tlv+size+type_length+id_size, length_array, length_size); 00250 memcpy(tlv+size+type_length+id_size+length_size, value, value_length); 00251 00252 data = tlv; 00253 size += type_length + id_size + length_size + value_length; 00254 return true; 00255 } 00256 00257 void M2MTLVSerializer::serialize_id(uint16_t id, uint32_t &size, uint8_t *id_ptr) 00258 { 00259 if(id > 255) { 00260 size=2; 00261 id_ptr[0] = (id & 0xFF00) >> 8; 00262 id_ptr[1] = id & 0xFF; 00263 } else { 00264 size=1; 00265 id_ptr[0] = id & 0xFF; 00266 } 00267 } 00268 00269 void M2MTLVSerializer::serialize_length(uint32_t length, uint32_t &size, uint8_t *length_ptr) 00270 { 00271 if (length > 65535) { 00272 size = 3; 00273 length_ptr[0] = (length & 0xFF0000) >> 16; 00274 length_ptr[1] = (length & 0xFF00) >> 8; 00275 length_ptr[2] = length & 0xFF; 00276 } else if (length > 255) { 00277 size = 2; 00278 length_ptr[0] = (length & 0xFF00) >> 8; 00279 length_ptr[1] = length & 0xFF; 00280 } else if (length > 7) { 00281 size = 1; 00282 length_ptr[0] = length & 0xFF; 00283 } else { 00284 size=0; 00285 } 00286 } 00287
Generated on Tue Jul 12 2022 19:01:35 by
1.7.2