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