Timothy Beight / Mbed 2 deprecated 6_songs-from-the-cloud

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

Fork of 6_songs-from-the-cloud by MakingMusicWorkshop

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