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.
m2mtlvdeserializer.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/m2mtlvdeserializer.h" 00017 #include "mbed-client/m2mconstants.h" 00018 #include "include/nsdllinker.h" 00019 #include "mbed-trace/mbed_trace.h" 00020 00021 #define TRACE_GROUP "mClt" 00022 #define BUFFER_SIZE 10 00023 00024 M2MTLVDeserializer::M2MTLVDeserializer() 00025 { 00026 } 00027 00028 M2MTLVDeserializer::~M2MTLVDeserializer() 00029 { 00030 } 00031 00032 bool M2MTLVDeserializer::is_object_instance(uint8_t *tlv) 00033 { 00034 return is_object_instance(tlv, 0); 00035 } 00036 00037 bool M2MTLVDeserializer::is_resource(uint8_t *tlv) 00038 { 00039 return is_resource(tlv, 0); 00040 } 00041 00042 bool M2MTLVDeserializer::is_multiple_resource(uint8_t *tlv) 00043 { 00044 return is_multiple_resource(tlv, 0); 00045 } 00046 00047 bool M2MTLVDeserializer::is_resource_instance(uint8_t *tlv) 00048 { 00049 return is_resource_instance(tlv, 0); 00050 } 00051 00052 M2MTLVDeserializer::Error M2MTLVDeserializer::deserialise_object_instances(uint8_t* tlv, 00053 uint32_t tlv_size, 00054 M2MObject &object, 00055 M2MTLVDeserializer::Operation operation) 00056 { 00057 M2MTLVDeserializer::Error error = M2MTLVDeserializer::None; 00058 if (is_object_instance(tlv) ) { 00059 tr_debug("M2MTLVDeserializer::deserialise_object_instances"); 00060 error = deserialize_object_instances(tlv, tlv_size, 0, object,operation,false); 00061 if(M2MTLVDeserializer::None == error) { 00062 error = deserialize_object_instances(tlv, tlv_size, 0, object,operation,true); 00063 } 00064 } else { 00065 tr_debug("M2MTLVDeserializer::deserialise_object_instances ::NotValid"); 00066 error = M2MTLVDeserializer::NotValid; 00067 } 00068 return error; 00069 } 00070 00071 M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_resources(uint8_t *tlv, 00072 uint32_t tlv_size, 00073 M2MObjectInstance &object_instance, 00074 M2MTLVDeserializer::Operation operation) 00075 { 00076 M2MTLVDeserializer::Error error = M2MTLVDeserializer::None; 00077 if (!is_resource(tlv) && !is_multiple_resource(tlv)) { 00078 error = M2MTLVDeserializer::NotValid; 00079 } else { 00080 error = deserialize_resources(tlv, tlv_size, 0, object_instance, operation,false); 00081 if(M2MTLVDeserializer::None == error) { 00082 error = deserialize_resources(tlv, tlv_size, 0, object_instance, operation,true); 00083 } 00084 } 00085 return error; 00086 } 00087 00088 M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_resource_instances(uint8_t *tlv, 00089 uint32_t tlv_size, 00090 M2MResource &resource, 00091 M2MTLVDeserializer::Operation operation) 00092 { 00093 M2MTLVDeserializer::Error error = M2MTLVDeserializer::None; 00094 if (!is_multiple_resource(tlv)) { 00095 error = M2MTLVDeserializer::NotValid; 00096 } else { 00097 tr_debug("M2MTLVDeserializer::deserialize_resource_instances()"); 00098 uint8_t offset = 2; 00099 00100 ((tlv[0] & 0x20) == 0) ? offset : offset++; 00101 00102 uint8_t length = tlv[0] & 0x18; 00103 if(length == 0x08) { 00104 offset+= 1; 00105 } else if(length == 0x10) { 00106 offset+= 2; 00107 } else if(length == 0x18) { 00108 offset+= 3; 00109 } 00110 00111 tr_debug("M2MTLVDeserializer::deserialize_resource_instances() Offset %d", offset); 00112 error = deserialize_resource_instances(tlv, tlv_size, offset, resource, operation,false); 00113 if(M2MTLVDeserializer::None == error) { 00114 error = deserialize_resource_instances(tlv, tlv_size, offset, resource, operation,true); 00115 } 00116 } 00117 return error; 00118 } 00119 00120 M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_object_instances(uint8_t *tlv, 00121 uint32_t tlv_size, 00122 uint32_t offset, 00123 M2MObject &object, 00124 M2MTLVDeserializer::Operation operation, 00125 bool update_value) 00126 { 00127 tr_debug("M2MTLVDeserializer::deserialize_object_instances()"); 00128 M2MTLVDeserializer::Error error = M2MTLVDeserializer::None; 00129 TypeIdLength *til = TypeIdLength::createTypeIdLength(tlv, offset)->deserialize(); 00130 offset = til->_offset; 00131 00132 M2MObjectInstanceList list = object.instances(); 00133 M2MObjectInstanceList::const_iterator it; 00134 it = list.begin(); 00135 00136 if (TYPE_OBJECT_INSTANCE == til->_type) { 00137 for (; it!=list.end(); it++) { 00138 if((*it)->instance_id() == til->_id) { 00139 error = deserialize_resources(tlv, tlv_size, offset, (**it),operation, update_value); 00140 } 00141 } 00142 offset += til->_length; 00143 00144 if(offset < tlv_size) { 00145 error = deserialize_object_instances(tlv, tlv_size, offset, object, operation, update_value); 00146 } 00147 } 00148 delete til; 00149 return error; 00150 } 00151 00152 M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_resources(uint8_t *tlv, 00153 uint32_t tlv_size, 00154 uint32_t offset, 00155 M2MObjectInstance &object_instance, 00156 M2MTLVDeserializer::Operation operation, 00157 bool update_value) 00158 { 00159 tr_debug("M2MTLVDeserializer::deserialize_resources()"); 00160 M2MTLVDeserializer::Error error = M2MTLVDeserializer::None; 00161 TypeIdLength *til = TypeIdLength::createTypeIdLength(tlv, offset)->deserialize(); 00162 offset = til->_offset; 00163 00164 M2MResourceList list = object_instance.resources(); 00165 M2MResourceList::const_iterator it; 00166 it = list.begin(); 00167 00168 if (TYPE_RESOURCE == til->_type || TYPE_RESOURCE_INSTANCE == til->_type) { 00169 bool found = false; 00170 for (; it!=list.end(); it++) { 00171 if((*it)->name_id() == til->_id){ 00172 tr_debug("M2MTLVDeserializer::deserialize_resources() - Resource ID %d ", til->_id); 00173 found = true; 00174 if(update_value) { 00175 if(til->_length > 0) { 00176 tr_debug("M2MTLVDeserializer::deserialize_resources() - Update value"); 00177 (*it)->set_value(tlv+offset, til->_length); 00178 } else { 00179 tr_debug("M2MTLVDeserializer::deserialize_resources() - Clear Value"); 00180 (*it)->clear_value(); 00181 } 00182 break; 00183 } else if(0 == ((*it)->operation() & SN_GRS_PUT_ALLOWED)) { 00184 tr_debug("M2MTLVDeserializer::deserialize_resources() - NOT_ALLOWED"); 00185 error = M2MTLVDeserializer::NotAllowed; 00186 break; 00187 } 00188 } 00189 } 00190 if(!found) { 00191 if(M2MTLVDeserializer::Post == operation) { 00192 //Create a new Resource 00193 String id; 00194 id.append_int(til->_id); 00195 M2MResource *resource = object_instance.create_dynamic_resource(id,"",M2MResourceInstance::INTEGER,true,false); 00196 if(resource) { 00197 resource->set_operation(M2MBase::GET_PUT_POST_DELETE_ALLOWED); 00198 } 00199 } else if(M2MTLVDeserializer::Put == operation) { 00200 error = M2MTLVDeserializer::NotFound; 00201 } 00202 } 00203 } else if (TYPE_MULTIPLE_RESOURCE == til->_type) { 00204 for (; it!=list.end(); it++) { 00205 if((*it)->supports_multiple_instances()) { 00206 error = deserialize_resource_instances(tlv, tlv_size-offset, offset, (**it), object_instance, operation, update_value); 00207 } 00208 } 00209 00210 } else { 00211 delete til; 00212 error = M2MTLVDeserializer::NotValid; 00213 return error; 00214 } 00215 offset += til->_length; 00216 00217 delete til; 00218 if(offset < tlv_size) { 00219 error = deserialize_resources(tlv, tlv_size, offset, object_instance, operation, update_value); 00220 } 00221 return error; 00222 } 00223 00224 M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_resource_instances(uint8_t *tlv, 00225 uint32_t tlv_size, 00226 uint32_t offset, 00227 M2MResource &resource, 00228 M2MObjectInstance &object_instance, 00229 M2MTLVDeserializer::Operation operation, 00230 bool update_value) 00231 { 00232 M2MTLVDeserializer::Error error = M2MTLVDeserializer::None; 00233 TypeIdLength *til = TypeIdLength::createTypeIdLength(tlv, offset)->deserialize(); 00234 offset = til->_offset; 00235 00236 if (TYPE_MULTIPLE_RESOURCE == til->_type || TYPE_RESOURCE_INSTANCE == til->_type) { 00237 M2MResourceInstanceList list = resource.resource_instances(); 00238 M2MResourceInstanceList::const_iterator it; 00239 it = list.begin(); 00240 bool found = false; 00241 for (; it!=list.end(); it++) { 00242 if((*it)->instance_id() == til->_id) { 00243 found = true; 00244 if(update_value) { 00245 if(til->_length > 0) { 00246 (*it)->set_value(tlv+offset, til->_length); 00247 } else { 00248 (*it)->clear_value(); 00249 } 00250 break; 00251 } else if(0 == ((*it)->operation() & SN_GRS_PUT_ALLOWED)) { 00252 error = M2MTLVDeserializer::NotAllowed; 00253 break; 00254 } 00255 } 00256 } 00257 if(!found) { 00258 if(M2MTLVDeserializer::Post == operation) { 00259 // Create a new Resource Instance 00260 M2MResourceInstance *res_instance = object_instance.create_dynamic_resource_instance(resource.name(),"", 00261 M2MResourceInstance::INTEGER, 00262 true, 00263 til->_id); 00264 if(res_instance) { 00265 res_instance->set_operation(M2MBase::GET_PUT_POST_DELETE_ALLOWED); 00266 } 00267 } else if(M2MTLVDeserializer::Put == operation) { 00268 error = M2MTLVDeserializer::NotFound; 00269 } 00270 } 00271 } else { 00272 delete til; 00273 error = M2MTLVDeserializer::NotValid; 00274 return error; 00275 } 00276 00277 offset += til->_length; 00278 00279 delete til; 00280 if(offset < tlv_size) { 00281 error = deserialize_resource_instances(tlv, tlv_size-offset, offset, resource, object_instance, operation, update_value); 00282 } 00283 return error; 00284 } 00285 00286 M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_resource_instances(uint8_t *tlv, 00287 uint32_t tlv_size, 00288 uint32_t offset, 00289 M2MResource &resource, 00290 M2MTLVDeserializer::Operation operation, 00291 bool update_value) 00292 { 00293 M2MTLVDeserializer::Error error = M2MTLVDeserializer::None; 00294 TypeIdLength *til = TypeIdLength::createTypeIdLength(tlv, offset)->deserialize(); 00295 offset = til->_offset; 00296 00297 if (TYPE_RESOURCE_INSTANCE == til->_type) { 00298 M2MResourceInstanceList list = resource.resource_instances(); 00299 M2MResourceInstanceList::const_iterator it; 00300 it = list.begin(); 00301 bool found = false; 00302 for (; it!=list.end(); it++) { 00303 if((*it)->instance_id() == til->_id) { 00304 found = true; 00305 if(update_value) { 00306 if(til->_length > 0) { 00307 (*it)->set_value(tlv+offset, til->_length); 00308 } else { 00309 (*it)->clear_value(); 00310 } 00311 break; 00312 } else if(0 == ((*it)->operation() & SN_GRS_PUT_ALLOWED)) { 00313 error = M2MTLVDeserializer::NotAllowed; 00314 break; 00315 } 00316 } 00317 } 00318 if(!found) { 00319 if(M2MTLVDeserializer::Post == operation) { 00320 error = M2MTLVDeserializer::NotAllowed; 00321 } else if(M2MTLVDeserializer::Put == operation) { 00322 error = M2MTLVDeserializer::NotFound; 00323 } 00324 } 00325 } else { 00326 delete til; 00327 error = M2MTLVDeserializer::NotValid; 00328 return error; 00329 } 00330 00331 offset += til->_length; 00332 00333 delete til; 00334 if(offset < tlv_size) { 00335 error = deserialize_resource_instances(tlv, tlv_size-offset, offset, resource, operation, update_value); 00336 } 00337 return error; 00338 } 00339 00340 bool M2MTLVDeserializer::is_object_instance(uint8_t *tlv, uint32_t offset) 00341 { 00342 bool ret = false; 00343 if (tlv) { 00344 uint8_t value = tlv[offset]; 00345 ret = (TYPE_OBJECT_INSTANCE == (value & TYPE_RESOURCE)); 00346 } 00347 return ret; 00348 } 00349 00350 uint16_t M2MTLVDeserializer::instance_id(uint8_t *tlv) 00351 { 00352 TypeIdLength *til = TypeIdLength::createTypeIdLength(tlv, 0)->deserialize(); 00353 uint16_t id = til->_id; 00354 delete til; 00355 return id; 00356 } 00357 00358 bool M2MTLVDeserializer::is_resource(uint8_t *tlv, uint32_t offset) 00359 { 00360 bool ret = false; 00361 if (tlv) { 00362 ret = (TYPE_RESOURCE == (tlv[offset] & TYPE_RESOURCE)); 00363 } 00364 return ret; 00365 } 00366 00367 bool M2MTLVDeserializer::is_multiple_resource(uint8_t *tlv, uint32_t offset) 00368 { 00369 bool ret = false; 00370 if (tlv) { 00371 ret = (TYPE_MULTIPLE_RESOURCE == (tlv[offset] & TYPE_RESOURCE)); 00372 } 00373 return ret; 00374 } 00375 00376 bool M2MTLVDeserializer::is_resource_instance(uint8_t *tlv, uint32_t offset) 00377 { 00378 bool ret = false; 00379 if (tlv) { 00380 ret = (TYPE_RESOURCE_INSTANCE == (tlv[offset] & TYPE_RESOURCE)); 00381 } 00382 return ret; 00383 } 00384 00385 TypeIdLength* TypeIdLength::createTypeIdLength(uint8_t *tlv, uint32_t offset) 00386 { 00387 TypeIdLength *til = new TypeIdLength(); 00388 til->_tlv = tlv; 00389 til->_offset = offset; 00390 til->_type = tlv[offset] & 0xC0; 00391 til->_id = 0; 00392 til->_length = 0; 00393 return til; 00394 } 00395 00396 TypeIdLength* TypeIdLength::deserialize() 00397 { 00398 uint32_t idLength = _tlv[_offset] & ID16; 00399 uint32_t lengthType = _tlv[_offset] & LENGTH24; 00400 if (0 == lengthType) { 00401 _length = _tlv[_offset] & 0x07; 00402 } 00403 _offset++; 00404 00405 deserialiseID(idLength); 00406 deserialiseLength(lengthType); 00407 00408 return this; 00409 } 00410 00411 void TypeIdLength::deserialiseID(uint32_t idLength) 00412 { 00413 _id = _tlv[_offset++] & 0xFF; 00414 if (ID16 == idLength) { 00415 _id = (_id << 8) + (_tlv[_offset++] & 0xFF); 00416 } 00417 } 00418 00419 void TypeIdLength::deserialiseLength(uint32_t lengthType) 00420 { 00421 if (lengthType > 0) { 00422 _length = _tlv[_offset++] & 0xFF; 00423 } 00424 if (lengthType > LENGTH8) { 00425 _length = (_length << 8) + (_tlv[_offset++] & 0xFF); 00426 } 00427 if (lengthType > LENGTH16) { 00428 _length = (_length << 8) + (_tlv[_offset++] & 0xFF); 00429 } 00430 }
Generated on Tue Jul 12 2022 21:20:28 by
