Ram Gandikota / Mbed OS ABCD
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers m2mtlvdeserializer.cpp Source File

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 }