Simple interface for Mbed Cloud Client
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 { 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