joey shelton / LED_Demo

Dependencies:   MAX44000 PWM_Tone_Library nexpaq_mdk

Fork of LED_Demo by Maxim nexpaq

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 <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 }