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

« Back to documentation index

Show/hide line numbers m2mfirmware.cpp Source File

m2mfirmware.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 
00017 #include "mbed-client/m2mfirmware.h"
00018 #include "mbed-client/m2mconstants.h"
00019 #include "mbed-client/m2mobject.h"
00020 #include "mbed-client/m2mobjectinstance.h"
00021 #include "mbed-client/m2mresource.h"
00022 #include "include/nsdlaccesshelper.h"
00023 
00024 #define BUFFER_SIZE 21
00025 #define TRACE_GROUP "mClt"
00026 
00027 M2MFirmware* M2MFirmware::_instance = NULL;
00028 
00029 M2MFirmware* M2MFirmware::get_instance()
00030 {
00031     if(_instance == NULL) {
00032         _instance = new M2MFirmware();
00033     }
00034     return _instance;
00035 }
00036 
00037 void M2MFirmware::delete_instance()
00038 {
00039     delete _instance;
00040     _instance = NULL;
00041 }
00042 
00043 M2MFirmware::M2MFirmware()
00044 : M2MObject(M2M_FIRMWARE_ID, stringdup(M2M_FIRMWARE_ID))
00045 {
00046     M2MBase::set_register_uri(false);
00047     M2MBase::set_operation(M2MBase::GET_PUT_ALLOWED);
00048     _firmware_instance = M2MObject::create_object_instance();
00049     if(_firmware_instance) {
00050         _firmware_instance->set_operation(M2MBase::GET_PUT_ALLOWED);
00051         create_mandatory_resources();
00052     }
00053 }
00054 
00055 M2MFirmware::~M2MFirmware()
00056 {
00057 }
00058 
00059 // Conditionally put the static part of parameter struct into flash.
00060 // Unfortunately this can't be done yet by default as there is old API which
00061 // may be used to modify the values in sn_nsdl_static_resource_parameters_s.
00062 #ifdef MEMORY_OPTIMIZED_API
00063 #define STATIC_PARAM_TYPE const
00064 #else
00065 #define STATIC_PARAM_TYPE
00066 #endif
00067 
00068 #define PACKAGE_PATH FIRMWARE_PATH_PREFIX FIRMWARE_PACKAGE
00069 
00070 STATIC_PARAM_TYPE
00071 static sn_nsdl_static_resource_parameters_s firmware_package_params_static = {
00072     (char*)OMA_RESOURCE_TYPE,      // resource_type_ptr
00073     (char*)"",                     // interface_description_ptr
00074     (uint8_t*)PACKAGE_PATH,    // path
00075     (uint8_t*)"",           // resource
00076     5,                      // strlen("5/0/0")
00077     0,                      // resourcelen
00078     false,                  // external_memory_block
00079     SN_GRS_DYNAMIC,         // mode
00080     false                   // free_on_delete
00081 };
00082 
00083 #define PACKAGE_URI_PATH FIRMWARE_PATH_PREFIX FIRMWARE_PACKAGE_URI
00084 
00085 STATIC_PARAM_TYPE
00086 static sn_nsdl_static_resource_parameters_s firmware_package_uri_params_static = {
00087     (char*)OMA_RESOURCE_TYPE,      // resource_type_ptr
00088     (char*)"",                     // interface_description_ptr
00089     (uint8_t*)PACKAGE_URI_PATH, // path
00090     (uint8_t*)"",           // resource
00091     5,                      // strlen("5/0/1")
00092     0,                      // resourcelen
00093     false,                  // external_memory_block
00094     SN_GRS_DYNAMIC,         // mode
00095     false                   // free_on_delete
00096 };
00097 
00098 #define UPDATE_PATH FIRMWARE_PATH_PREFIX FIRMWARE_UPDATE
00099 
00100 STATIC_PARAM_TYPE
00101 static sn_nsdl_static_resource_parameters_s firmware_update_params_static = {
00102     (char*)OMA_RESOURCE_TYPE,   // resource_type_ptr
00103     (char*)"",                  // interface_description_ptr
00104     (uint8_t*)UPDATE_PATH,  // path
00105     (uint8_t*)"",           // resource
00106     5,                      // strlen(5/0/2)
00107     0,                      // resourcelen
00108     false,                  // external_memory_block
00109     SN_GRS_DYNAMIC,         // mode
00110     false                   // free_on_delete
00111 };
00112 
00113 #define STATE_URI_PATH FIRMWARE_PATH_PREFIX FIRMWARE_STATE
00114 
00115 STATIC_PARAM_TYPE
00116 static sn_nsdl_static_resource_parameters_s firmware_state_params_static = {
00117     (char*)OMA_RESOURCE_TYPE,   // resource_type_ptr
00118     (char*)"",                  // interface_description_ptr
00119     (uint8_t*)STATE_URI_PATH,   // path
00120     (uint8_t*)"0",          // resource
00121     5,                      // strlen("5/0/3")
00122     1,                      // resourcelen
00123     false,                  // external_memory_block
00124     SN_GRS_DYNAMIC,         // mode
00125     false                   // free_on_delete
00126 };
00127 
00128 #define UPDATE_RESULT_PATH FIRMWARE_PATH_PREFIX FIRMWARE_UPDATE_RESULT
00129 
00130 STATIC_PARAM_TYPE
00131 static sn_nsdl_static_resource_parameters_s firmware_update_result_params_static = {
00132     (char*)OMA_RESOURCE_TYPE,      // resource_type_ptr
00133     (char*)"",                     // interface_description_ptr
00134     (uint8_t*)UPDATE_RESULT_PATH, // path
00135     (uint8_t*)"0",          // resource
00136     5,                      // strlen(5/0/5)
00137     1,                      // resourcelen
00138     false,                  // external_memory_block
00139     SN_GRS_DYNAMIC,         // mode
00140     false                   // free_on_delete
00141 };
00142 
00143 static sn_nsdl_dynamic_resource_parameters_s firmware_package_params_dynamic = {
00144     __nsdl_c_callback,
00145     &firmware_package_params_static,
00146     {NULL, NULL},                     // link
00147     COAP_CONTENT_OMA_PLAIN_TEXT_TYPE, // coap_content_type
00148     M2MBase::PUT_ALLOWED,   // access
00149     0,                      // registered
00150     false,                  // publish_uri
00151     false,                  // free_on_delete
00152     true                    // observable
00153 };
00154 
00155 static sn_nsdl_dynamic_resource_parameters_s firmware_package_uri_params_dynamic = {
00156     __nsdl_c_callback,
00157     &firmware_package_uri_params_static,
00158     {NULL, NULL},                     // link
00159     COAP_CONTENT_OMA_PLAIN_TEXT_TYPE, // coap_content_type
00160     M2MBase::PUT_ALLOWED,   // access
00161     0,                      // registered
00162     false,                  // publish_uri
00163     false,                  // free_on_delete
00164     true                    // observable
00165 };
00166 
00167 static sn_nsdl_dynamic_resource_parameters_s firmware_update_params_dynamic = {
00168     __nsdl_c_callback,
00169     &firmware_update_params_static,
00170     {NULL, NULL},                     // link
00171     COAP_CONTENT_OMA_PLAIN_TEXT_TYPE, // coap_content_type
00172     M2MBase::NOT_ALLOWED,   // access
00173     0,                      // registered
00174     false,                  // publish_uri
00175     false,                  // free_on_delete
00176     true                    // observable
00177 };
00178 
00179 static sn_nsdl_dynamic_resource_parameters_s firmware_state_params_dynamic = {
00180     __nsdl_c_callback,
00181     &firmware_state_params_static,
00182     {NULL, NULL},                     // link
00183     COAP_CONTENT_OMA_PLAIN_TEXT_TYPE, // coap_content_type
00184     M2MBase::GET_ALLOWED,   // access
00185     0,                      // registered
00186     false,                  // publish_uri
00187     false,                  // free_on_delete
00188     true                    // observable
00189 };
00190 
00191 static sn_nsdl_dynamic_resource_parameters_s firmware_update_result_params_dynamic = {
00192     __nsdl_c_callback,
00193     &firmware_update_result_params_static,
00194     {NULL, NULL},                     // link
00195     COAP_CONTENT_OMA_PLAIN_TEXT_TYPE, // coap_content_type
00196     M2MBase::GET_ALLOWED,   // access
00197     0,                      // registered
00198     false,                  // publish_uri
00199     false,                  // free_on_delete
00200     true                    // observable
00201 };
00202 const static M2MBase::lwm2m_parameters firmware_package_params = {
00203     0, // max_age
00204     0, // instance_id
00205     0, // name_id
00206     (char*)FIRMWARE_PACKAGE, // name
00207     &firmware_package_params_dynamic,
00208     M2MBase::Resource, // base_type
00209     false // free_on_delete
00210 };
00211 
00212 const static M2MBase::lwm2m_parameters firmware_package_uri_params = {
00213     0, // max_age
00214     0, // instance_id
00215     0, // name_id
00216     (char*)FIRMWARE_PACKAGE_URI, // name
00217     &firmware_package_uri_params_dynamic,
00218     M2MBase::Resource, // base_type
00219     false // free_on_delete
00220 };
00221 
00222 const static M2MBase::lwm2m_parameters firmware_update_params = {
00223     0, // max_age
00224     0, // instance_id
00225     0, // name_id
00226     (char*)FIRMWARE_UPDATE, // name
00227     &firmware_update_params_dynamic,
00228     M2MBase::Resource, // base_type
00229     false // free_on_delete
00230 };
00231 
00232 const static M2MBase::lwm2m_parameters firmware_state_params = {
00233     0, // max_age
00234     0, // instance_id
00235     0, // name_id
00236     (char*)FIRMWARE_STATE, // name
00237     &firmware_state_params_dynamic,
00238     M2MBase::Resource, // base_type
00239     false // free_on_delete
00240 };
00241 
00242 const static M2MBase::lwm2m_parameters firmware_update_result_params = {
00243     0, // max_age
00244     0, // instance_id
00245     0, // name_id
00246     (char*)FIRMWARE_UPDATE_RESULT, // name
00247     &firmware_update_result_params_dynamic,
00248     M2MBase::Resource, // base_type
00249     false // free_on_delete
00250 };
00251 
00252 void M2MFirmware::create_mandatory_resources()
00253 {
00254     _firmware_instance->set_coap_content_type(COAP_CONTENT_OMA_TLV_TYPE);
00255 
00256     M2MResource* res;
00257 
00258     // todo:
00259     // perhaps we should have a API for batch creation of objects by using a array
00260     // of lwm2m_parameters.
00261 
00262     res = _firmware_instance->create_dynamic_resource(&firmware_package_params,
00263                                                         M2MResourceInstance::OPAQUE,
00264                                                         false);
00265 
00266     res = _firmware_instance->create_dynamic_resource(&firmware_package_uri_params,
00267                                                     M2MResourceInstance::STRING,
00268                                                     false);
00269 
00270     res = _firmware_instance->create_dynamic_resource(&firmware_update_params,
00271                                                     M2MResourceInstance::OPAQUE,
00272                                                     false);
00273 
00274     res = _firmware_instance->create_dynamic_resource(&firmware_state_params,
00275                                                     M2MResourceInstance::INTEGER,
00276                                                     true);
00277 
00278     res = _firmware_instance->create_dynamic_resource(&firmware_update_result_params,
00279                                                     M2MResourceInstance::INTEGER,
00280                                                     true);
00281 }
00282 
00283 M2MResource* M2MFirmware::create_resource(FirmwareResource resource, const String &value)
00284 {
00285     M2MResource* res = NULL;
00286     const char* firmware_id_ptr = "";
00287     M2MBase::Operation operation = M2MBase::GET_ALLOWED;
00288     if(!is_resource_present(resource)) {
00289         switch(resource) {
00290             case PackageName:
00291                 firmware_id_ptr = FIRMWARE_PACKAGE_NAME;
00292                 break;
00293             case PackageVersion:
00294                 firmware_id_ptr = FIRMWARE_PACKAGE_VERSION;
00295                 break;
00296             default:
00297                 break;
00298         }
00299     }
00300     String firmware_id(firmware_id_ptr);
00301 
00302     if(!firmware_id.empty() && value.size() < 256) {
00303         if(_firmware_instance) {
00304             res = _firmware_instance->create_dynamic_resource(firmware_id,
00305                                                             OMA_RESOURCE_TYPE,
00306                                                             M2MResourceInstance::STRING,
00307                                                             false);
00308 
00309             if(res) {
00310                 res->set_register_uri(false);
00311                 res->set_operation(operation);
00312                 if(value.empty()) {
00313                     res->clear_value();
00314                 } else {
00315                     res->set_value((const uint8_t*)value.c_str(),
00316                                    (uint32_t)value.length());
00317                 }
00318             }
00319         }
00320     }
00321     return res;
00322 }
00323 
00324 M2MResource* M2MFirmware::create_resource(FirmwareResource resource, int64_t value)
00325 {
00326     M2MResource* res = NULL;
00327     const char* firmware_id_ptr = "";
00328     M2MBase::Operation operation = M2MBase::GET_ALLOWED;
00329     if(!is_resource_present(resource)) {
00330         switch(resource) {
00331         case UpdateSupportedObjects:
00332             if(check_value_range(resource, value)) {
00333                 firmware_id_ptr = FIRMWARE_UPDATE_SUPPORTED_OBJECTS;
00334                 operation = M2MBase::GET_PUT_ALLOWED;
00335             }
00336             break;
00337         default:
00338             break;
00339         }
00340     }
00341 
00342     const String firmware_id(firmware_id_ptr);
00343 
00344     if(!firmware_id.empty()) {
00345         if(_firmware_instance) {
00346             res = _firmware_instance->create_dynamic_resource(firmware_id,
00347                                                             OMA_RESOURCE_TYPE,
00348                                                             M2MResourceInstance::INTEGER,
00349                                                             false);
00350 
00351             if(res) {
00352                 res->set_register_uri(false);
00353 
00354                 res->set_operation(operation);
00355                 res->set_value(value);
00356             }
00357         }
00358     }
00359     return res;
00360 }
00361 
00362 bool M2MFirmware::set_resource_value(FirmwareResource resource,
00363                                    const String &value)
00364 {
00365     bool success = false;
00366     M2MResource* res = get_resource(resource);
00367     if(res) {
00368         if(M2MFirmware::PackageUri == resource  ||
00369            M2MFirmware::PackageName == resource ||
00370            M2MFirmware::PackageVersion == resource) {
00371             if (value.size() < 256) {
00372                 if(value.empty()) {
00373                     res->clear_value();
00374                     success = true;
00375                 } else {
00376                     success = res->set_value((const uint8_t*)value.c_str(),(uint32_t)value.length());
00377                 }
00378             }
00379         }
00380     }
00381     return success;
00382 }
00383 
00384 bool M2MFirmware::set_resource_value(FirmwareResource resource,
00385                                        int64_t value)
00386 {
00387     bool success = false;
00388     M2MResource* res = get_resource(resource);
00389     if(res) {
00390         if(M2MFirmware::State == resource          ||
00391            M2MFirmware::UpdateSupportedObjects == resource ||
00392            M2MFirmware::UpdateResult == resource) {
00393             // If it is any of the above resource
00394             // set the value of the resource.
00395             if (check_value_range(resource, value)) {
00396 
00397                 success = res->set_value(value);
00398             }
00399         }
00400     }
00401     return success;
00402 }
00403 
00404 bool M2MFirmware::set_resource_value(FirmwareResource resource,
00405                                      const uint8_t *value,
00406                                      const uint32_t length)
00407 {
00408     bool success = false;
00409     M2MResource* res = get_resource(resource);
00410     if(res) {
00411         if(M2MFirmware::Package == resource) {
00412             success = res->set_value(value,length);
00413         }
00414     }
00415     return success;
00416 }
00417 
00418 bool M2MFirmware::is_resource_present(FirmwareResource resource) const
00419 {
00420     bool success = false;
00421     M2MResource* res = get_resource(resource);
00422     if(res) {
00423         success = true;
00424     }
00425     return success;
00426 }
00427 
00428 const char* M2MFirmware::resource_name(FirmwareResource resource)
00429 {
00430     const char* res_name = "";
00431     switch(resource) {
00432         case Package:
00433             res_name = FIRMWARE_PACKAGE;
00434             break;
00435         case PackageUri:
00436             res_name = FIRMWARE_PACKAGE_URI;
00437             break;
00438         case Update:
00439             res_name = FIRMWARE_UPDATE;
00440             break;
00441         case State:
00442             res_name = FIRMWARE_STATE;
00443             break;
00444         case UpdateSupportedObjects:
00445             res_name = FIRMWARE_UPDATE_SUPPORTED_OBJECTS;
00446             break;
00447         case UpdateResult:
00448             res_name = FIRMWARE_UPDATE_RESULT;
00449             break;
00450         case PackageName:
00451             res_name = FIRMWARE_PACKAGE_NAME;
00452             break;
00453         case PackageVersion:
00454             res_name = FIRMWARE_PACKAGE_VERSION;
00455             break;
00456     }
00457     return res_name;
00458 }
00459 
00460 uint16_t M2MFirmware::per_resource_count(FirmwareResource res) const
00461 {
00462     uint16_t count = 0;
00463     if(_firmware_instance) {
00464         count = _firmware_instance->resource_count(resource_name(res));
00465     }
00466     return count;
00467 }
00468 
00469 uint16_t M2MFirmware::total_resource_count() const
00470 {
00471     uint16_t count = 0;
00472     if(_firmware_instance) {
00473         count = _firmware_instance->resources().size();
00474     }
00475     return count;
00476 }
00477 
00478 uint32_t M2MFirmware::resource_value_buffer(FirmwareResource resource,
00479                                uint8_t *&data) const
00480 {
00481     uint32_t size = 0;
00482     M2MResource* res = get_resource(resource);
00483     if(res) {
00484         if(M2MFirmware::Package == resource) {
00485             res->get_value(data,size);
00486         }
00487     }
00488     return size;
00489 }
00490 
00491 M2MResource* M2MFirmware::get_resource(FirmwareResource res) const
00492 {
00493     M2MResource* res_object = NULL;
00494     if(_firmware_instance) {
00495         const char* res_name_ptr = "";
00496         switch(res) {
00497             case Package:
00498                 res_name_ptr = FIRMWARE_PACKAGE;
00499                 break;
00500             case PackageUri:
00501                 res_name_ptr = FIRMWARE_PACKAGE_URI;
00502                 break;
00503             case Update:
00504                 res_name_ptr = FIRMWARE_UPDATE;
00505                 break;
00506             case State:
00507                 res_name_ptr = FIRMWARE_STATE;
00508                 break;
00509             case UpdateSupportedObjects:
00510                 res_name_ptr = FIRMWARE_UPDATE_SUPPORTED_OBJECTS;
00511                 break;
00512             case UpdateResult:
00513                 res_name_ptr = FIRMWARE_UPDATE_RESULT;
00514                 break;
00515             case PackageName:
00516                 res_name_ptr = FIRMWARE_PACKAGE_NAME;
00517                 break;
00518             case PackageVersion:
00519                 res_name_ptr = FIRMWARE_PACKAGE_VERSION;
00520                 break;
00521         }
00522 
00523         res_object = _firmware_instance->resource(res_name_ptr);
00524     }
00525     return res_object;
00526 }
00527 
00528 bool M2MFirmware::delete_resource(FirmwareResource resource)
00529 {
00530     bool success = false;
00531     if(M2MFirmware::UpdateSupportedObjects == resource ||
00532        M2MFirmware::PackageName == resource            ||
00533        M2MFirmware::PackageVersion == resource) {
00534         if(_firmware_instance) {
00535             success = _firmware_instance->remove_resource(resource_name(resource));
00536         }
00537     }
00538     return success;
00539 }
00540 
00541 int64_t M2MFirmware::resource_value_int(FirmwareResource resource) const
00542 {
00543     int64_t value = -1;
00544     M2MResource* res = get_resource(resource);
00545     if(res) {
00546         if(M2MFirmware::State == resource          ||
00547            M2MFirmware::UpdateSupportedObjects == resource         ||
00548            M2MFirmware::UpdateResult == resource) {
00549 
00550             value = res->get_value_int();
00551         }
00552     }
00553     return value;
00554 }
00555 
00556 String M2MFirmware::resource_value_string(FirmwareResource resource) const
00557 {
00558     String value = "";
00559     M2MResource* res = get_resource(resource);
00560     if(res) {
00561         if(M2MFirmware::PackageUri == resource          ||
00562            M2MFirmware::PackageName == resource           ||
00563            M2MFirmware::PackageVersion == resource) {
00564 
00565             value = res->get_value_string();
00566         }
00567     }
00568     return value;
00569 }
00570 
00571 bool M2MFirmware::check_value_range(FirmwareResource resource, int64_t value) const
00572 {
00573     bool success = false;
00574     switch (resource) {
00575         case UpdateSupportedObjects:
00576             if(value == 0 || value == 1) {
00577                 success = true;
00578             }
00579             break;
00580         case State:
00581             if (value >= 0 && value <= 3) {
00582                 success = true;
00583                 M2MResource* updateRes = get_resource(M2MFirmware::Update);
00584                 if (updateRes){
00585                     if (value == M2MFirmware::Downloaded) {
00586                         updateRes->set_operation(M2MBase::POST_ALLOWED);
00587                     }
00588                     else {
00589                         updateRes->set_operation(M2MBase::NOT_ALLOWED);
00590                     }
00591                 }
00592             }
00593             break;
00594         case UpdateResult:
00595             if (value >= 0 && value <= 7) {
00596                 success = true;
00597             }
00598             break;
00599     default:
00600         break;
00601     }
00602     return success;
00603 }
00604