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