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

« Back to documentation index

Show/hide line numbers m2mdevice.cpp Source File

m2mdevice.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/m2mdevice.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 "mbed-trace/mbed_trace.h"
00023 
00024 #define BUFFER_SIZE 21
00025 #define TRACE_GROUP "mClt"
00026 
00027 M2MDevice* M2MDevice::_instance = NULL;
00028 
00029 M2MDevice* M2MDevice::get_instance()
00030 {
00031     if(_instance == NULL) {
00032         // ownership of this path is transferred to M2MBase.
00033         // Since this object is a singleton, we could use the C-structs to avoid heap
00034         // allocation on a lot of M2MDevice -objects data.
00035         char *path = stringdup(M2M_DEVICE_ID);
00036         if (path) {
00037             _instance = new M2MDevice(path);
00038         }
00039     }
00040     return _instance;
00041 }
00042 
00043 void M2MDevice::delete_instance()
00044 {
00045     delete _instance;
00046     _instance = NULL;
00047 }
00048 
00049 M2MDevice::M2MDevice(char *path)
00050 : M2MObject(M2M_DEVICE_ID, path)
00051 {
00052     M2MBase::set_register_uri(false);
00053     M2MBase::set_operation(M2MBase::GET_ALLOWED);
00054 
00055     _device_instance = M2MObject::create_object_instance();
00056     if(_device_instance) {
00057         _device_instance->set_operation(M2MBase::GET_ALLOWED);
00058         _device_instance->set_register_uri(true);
00059         _device_instance->set_coap_content_type(COAP_CONTENT_OMA_TLV_TYPE);
00060         M2MResource* res = _device_instance->create_dynamic_resource(DEVICE_REBOOT,
00061                                                                      OMA_RESOURCE_TYPE,
00062                                                                      M2MResourceInstance::OPAQUE,
00063                                                                      false);
00064         if(res) {
00065             res->set_operation(M2MBase::POST_ALLOWED);
00066             res->set_register_uri(false);
00067         }
00068 
00069         M2MResourceInstance* instance = _device_instance->create_dynamic_resource_instance(DEVICE_ERROR_CODE,
00070                                                                  OMA_RESOURCE_TYPE,
00071                                                                  M2MResourceInstance::INTEGER,
00072                                                                  true,0);
00073         if(instance) {
00074             M2MResource * dev_res = _device_instance->resource(DEVICE_ERROR_CODE);
00075             if(dev_res) {
00076                 dev_res->set_register_uri(false);
00077             }
00078             instance->set_operation(M2MBase::GET_ALLOWED);
00079 
00080             instance->set_value(0);
00081 
00082             instance->set_register_uri(false);
00083         }
00084         res = _device_instance->create_dynamic_resource(DEVICE_SUPPORTED_BINDING_MODE,
00085                                                         OMA_RESOURCE_TYPE,
00086                                                         M2MResourceInstance::STRING,
00087                                                         true);
00088         if(res) {
00089             res->set_operation(M2MBase::GET_ALLOWED);
00090             res->set_value((const uint8_t*)BINDING_MODE_UDP,sizeof(BINDING_MODE_UDP)-1);
00091             res->set_register_uri(false);
00092         }
00093     }
00094 }
00095 
00096 M2MDevice::~M2MDevice()
00097 {
00098 }
00099 
00100 M2MResource* M2MDevice::create_resource(DeviceResource resource, const String &value)
00101 {
00102     M2MResource* res = NULL;
00103     const char* device_id_ptr = "";
00104     M2MBase::Operation operation = M2MBase::GET_ALLOWED;
00105     if(!is_resource_present(resource) && value.size() <= MAX_ALLOWED_STRING_LENGTH) {
00106         switch(resource) {
00107             case Manufacturer:
00108                device_id_ptr = DEVICE_MANUFACTURER;
00109                break;
00110             case DeviceType:
00111                 device_id_ptr = DEVICE_DEVICE_TYPE;
00112                 break;
00113             case ModelNumber:
00114                 device_id_ptr = DEVICE_MODEL_NUMBER;
00115                 break;
00116             case SerialNumber:
00117                 device_id_ptr = DEVICE_SERIAL_NUMBER;
00118                 break;
00119             case HardwareVersion:
00120                 device_id_ptr = DEVICE_HARDWARE_VERSION;
00121                 break;
00122             case FirmwareVersion:
00123                 device_id_ptr = DEVICE_FIRMWARE_VERSION;
00124                 break;
00125             case SoftwareVersion:
00126                 device_id_ptr = DEVICE_SOFTWARE_VERSION;
00127                 break;
00128             case UTCOffset:
00129                 device_id_ptr = DEVICE_UTC_OFFSET;
00130                 operation = M2MBase::GET_PUT_ALLOWED;
00131                 break;
00132             case Timezone:
00133                 device_id_ptr = DEVICE_TIMEZONE;
00134                 operation = M2MBase::GET_PUT_ALLOWED;
00135                 break;
00136             default:
00137                 break;
00138         }
00139     }
00140     const String device_id(device_id_ptr);
00141 
00142     if(!device_id.empty()) {
00143         if(_device_instance) {
00144             res = _device_instance->create_dynamic_resource(device_id,
00145                                                             OMA_RESOURCE_TYPE,
00146                                                             M2MResourceInstance::STRING,
00147                                                             true);
00148 
00149             if(res ) {
00150                 res->set_operation(operation);
00151                 if (value.empty()) {
00152                     res->clear_value();
00153                 } else {
00154                     res->set_value((const uint8_t*)value.c_str(),
00155                                    (uint32_t)value.length());
00156                 }
00157                 res->set_register_uri(false);
00158             }
00159         }
00160     }
00161     return res;
00162 }
00163 
00164 M2MResource* M2MDevice::create_resource(DeviceResource resource, int64_t value)
00165 {
00166     M2MResource* res = NULL;
00167     const char* device_id_ptr = "";
00168     M2MBase::Operation operation = M2MBase::GET_ALLOWED;
00169     if(!is_resource_present(resource)) {
00170         switch(resource) {
00171         case BatteryLevel:
00172             if(check_value_range(resource, value)) {
00173                 device_id_ptr = DEVICE_BATTERY_LEVEL;
00174             }
00175             break;
00176         case BatteryStatus:
00177             if(check_value_range(resource, value)) {
00178                 device_id_ptr = DEVICE_BATTERY_STATUS;
00179             }
00180             break;
00181         case MemoryFree:
00182             device_id_ptr = DEVICE_MEMORY_FREE;
00183             break;
00184         case MemoryTotal:
00185             device_id_ptr = DEVICE_MEMORY_TOTAL;
00186             break;
00187         case CurrentTime:
00188             device_id_ptr = DEVICE_CURRENT_TIME;
00189             operation = M2MBase::GET_PUT_ALLOWED;
00190             break;
00191         default:
00192             break;
00193         }
00194     }
00195 
00196     const String device_id(device_id_ptr);
00197 
00198     if(!device_id.empty()) {
00199         if(_device_instance) {
00200             res = _device_instance->create_dynamic_resource(device_id,
00201                                                             OMA_RESOURCE_TYPE,
00202                                                             M2MResourceInstance::INTEGER,
00203                                                             true);
00204 
00205             if(res) {
00206 
00207 
00208                 res->set_operation(operation);
00209                 res->set_value(value);
00210 
00211                 res->set_register_uri(false);
00212             }
00213         }
00214     }
00215     return res;
00216 }
00217 
00218 M2MResourceInstance* M2MDevice::create_resource_instance(DeviceResource resource, int64_t value,
00219                                                  uint16_t instance_id)
00220 {
00221     M2MResourceInstance* res = NULL;
00222     const char* device_id_ptr = "";
00223     // For these resources multiple instance can exist
00224     if(AvailablePowerSources == resource) {
00225         if(check_value_range(resource, value)) {
00226             device_id_ptr = DEVICE_AVAILABLE_POWER_SOURCES;
00227         }
00228     } else if(PowerSourceVoltage == resource) {
00229         device_id_ptr = DEVICE_POWER_SOURCE_VOLTAGE;
00230     } else if(PowerSourceCurrent == resource) {
00231         device_id_ptr = DEVICE_POWER_SOURCE_CURRENT;
00232     } else if(ErrorCode == resource) {
00233         if(check_value_range(resource, value)) {
00234             device_id_ptr = DEVICE_ERROR_CODE;
00235         }
00236     }
00237 
00238     const String device_id(device_id_ptr);
00239 
00240     if(!device_id.empty()) {
00241         if(_device_instance) {
00242             res = _device_instance->create_dynamic_resource_instance(device_id,OMA_RESOURCE_TYPE,
00243                                                                      M2MResourceInstance::INTEGER,
00244                                                                      true, instance_id);
00245 
00246             M2MResource *resource = _device_instance->resource(device_id);
00247             if(resource) {
00248                 resource->set_register_uri(false);
00249             }
00250             if(res) {
00251                 res->set_value(value);
00252                 // Only read operation is allowed for above resources
00253                 res->set_operation(M2MBase::GET_ALLOWED);
00254 
00255                 res->set_register_uri(false);
00256             }
00257         }
00258     }
00259     return res;
00260 }
00261 M2MResource* M2MDevice::create_resource(DeviceResource resource)
00262 {
00263     M2MResource* res = NULL;
00264     if(!is_resource_present(resource)) {
00265         const char* device_Id_ptr = "";
00266         if(FactoryReset == resource) {
00267             device_Id_ptr = DEVICE_FACTORY_RESET;
00268         } else if(ResetErrorCode == resource) {
00269             device_Id_ptr = DEVICE_RESET_ERROR_CODE;
00270         }
00271         const String device_Id(device_Id_ptr);
00272 
00273         if(_device_instance && !device_Id.empty()) {
00274             res = _device_instance->create_dynamic_resource(device_Id,
00275                                                             OMA_RESOURCE_TYPE,
00276                                                             M2MResourceInstance::OPAQUE,
00277                                                             true);
00278             M2MResource *resource = _device_instance->resource(device_Id);
00279             if(resource) {
00280                 resource->set_register_uri(false);
00281             }
00282             if(res) {
00283                 res->set_operation(M2MBase::POST_ALLOWED);
00284                 res->set_register_uri(false);
00285             }
00286         }
00287     }
00288     return res;
00289 }
00290 
00291 bool M2MDevice::delete_resource(DeviceResource resource)
00292 {
00293     bool success = false;
00294     if(M2MDevice::Reboot != resource             &&
00295        M2MDevice::ErrorCode != resource          &&
00296        M2MDevice::SupportedBindingMode != resource) {
00297         if(_device_instance) {
00298             success = _device_instance->remove_resource(resource_name(resource));
00299         }
00300     }
00301     return success;
00302 }
00303 
00304 bool M2MDevice::delete_resource_instance(DeviceResource resource,
00305                                          uint16_t instance_id)
00306 {
00307     bool success = false;
00308     if(M2MDevice::Reboot != resource             &&
00309        M2MDevice::ErrorCode != resource          &&
00310        M2MDevice::SupportedBindingMode != resource) {
00311         if(_device_instance) {
00312             success = _device_instance->remove_resource_instance(resource_name(resource),instance_id);
00313         }
00314     }
00315     return success;
00316 }
00317 
00318 bool M2MDevice::set_resource_value(DeviceResource resource,
00319                                    const String &value,
00320                                    uint16_t instance_id)
00321 {
00322     bool success = false;
00323     M2MResourceInstance* res = get_resource_instance(resource,instance_id);
00324     if(res && value.size() <= MAX_ALLOWED_STRING_LENGTH) {
00325         if(M2MDevice::Manufacturer == resource          ||
00326            M2MDevice::ModelNumber == resource           ||
00327            M2MDevice::DeviceType == resource            ||
00328            M2MDevice::SerialNumber == resource          ||
00329            M2MDevice::HardwareVersion == resource       ||
00330            M2MDevice::FirmwareVersion == resource       ||
00331            M2MDevice::SoftwareVersion == resource       ||
00332            M2MDevice::UTCOffset == resource             ||
00333            M2MDevice::Timezone == resource) {
00334                 if (value.empty()) {
00335                     res->clear_value();
00336                     success = true;
00337                 } else {
00338                     success = res->set_value((const uint8_t*)value.c_str(),(uint32_t)value.length());
00339                 }
00340         }
00341     }
00342     return success;
00343 }
00344 
00345 bool M2MDevice::set_resource_value(DeviceResource resource,
00346                                        int64_t value,
00347                                        uint16_t instance_id)
00348 {
00349     bool success = false;
00350     M2MResourceInstance* res = get_resource_instance(resource,instance_id);
00351     if(res) {
00352         if(M2MDevice::BatteryLevel == resource          ||
00353            M2MDevice::BatteryStatus == resource         ||
00354            M2MDevice::MemoryFree == resource            ||
00355            M2MDevice::MemoryTotal == resource           ||
00356            M2MDevice::ErrorCode == resource             ||
00357            M2MDevice::CurrentTime == resource           ||
00358            M2MDevice::AvailablePowerSources == resource ||
00359            M2MDevice::PowerSourceVoltage == resource    ||
00360            M2MDevice::PowerSourceCurrent == resource) {
00361             // If it is any of the above resource
00362             // set the value of the resource.
00363             if (check_value_range(resource, value)) {
00364 
00365                 success = res->set_value(value);
00366             }
00367         }
00368     }
00369     return success;
00370 }
00371 
00372 String M2MDevice::resource_value_string(DeviceResource resource,
00373                                         uint16_t instance_id) const
00374 {
00375     String value = "";
00376     M2MResourceInstance* res = get_resource_instance(resource,instance_id);
00377     if(res) {
00378         if(M2MDevice::Manufacturer == resource          ||
00379            M2MDevice::ModelNumber == resource           ||
00380            M2MDevice::DeviceType == resource            ||
00381            M2MDevice::SerialNumber == resource          ||
00382            M2MDevice::HardwareVersion == resource       ||
00383            M2MDevice::FirmwareVersion == resource       ||
00384            M2MDevice::SoftwareVersion == resource       ||
00385            M2MDevice::UTCOffset == resource             ||
00386            M2MDevice::Timezone == resource) {
00387 
00388 
00389             value = res->get_value_string();
00390         }
00391     }
00392     return value;
00393 }
00394 
00395 int64_t M2MDevice::resource_value_int(DeviceResource resource,
00396                                       uint16_t instance_id) const
00397 {
00398     int64_t value = -1;
00399     M2MResourceInstance* res = get_resource_instance(resource,instance_id);
00400     if(res) {
00401         if(M2MDevice::BatteryLevel == resource          ||
00402            M2MDevice::BatteryStatus == resource         ||
00403            M2MDevice::MemoryFree == resource            ||
00404            M2MDevice::MemoryTotal == resource           ||
00405            M2MDevice::ErrorCode == resource             ||
00406            M2MDevice::CurrentTime == resource           ||
00407            M2MDevice::AvailablePowerSources == resource ||
00408            M2MDevice::PowerSourceVoltage == resource    ||
00409            M2MDevice::PowerSourceCurrent == resource) {
00410 
00411             // note: the value may be 32bit int on 32b archs.
00412             value = res->get_value_int();
00413         }
00414     }
00415     return value;
00416 }
00417 
00418 bool M2MDevice::is_resource_present(DeviceResource resource) const
00419 {
00420     bool success = false;
00421     M2MResourceInstance* res = get_resource_instance(resource,0);
00422     if(res) {
00423         success = true;
00424     }
00425     return success;
00426 }
00427 
00428 uint16_t M2MDevice::per_resource_count(DeviceResource res) const
00429 {
00430     uint16_t count = 0;
00431     if(_device_instance) {
00432         count = _device_instance->resource_count(resource_name(res));
00433     }
00434     return count;
00435 }
00436 
00437 uint16_t M2MDevice::total_resource_count() const
00438 {
00439     uint16_t count = 0;
00440     if(_device_instance) {
00441         count = _device_instance->resources().size();
00442     }
00443     return count;
00444 }
00445 
00446 M2MResourceInstance* M2MDevice::get_resource_instance(DeviceResource dev_res,
00447                                                       uint16_t instance_id) const
00448 {
00449     M2MResource* res = NULL;
00450     M2MResourceInstance* inst = NULL;
00451     if(_device_instance) {
00452         res = _device_instance->resource(resource_name(dev_res));
00453         if(res) {
00454             if(res->supports_multiple_instances()) {
00455                inst = res->resource_instance(instance_id);
00456             } else {
00457                 inst = res;
00458             }
00459         }
00460     }
00461     return inst;
00462 }
00463 
00464 const char* M2MDevice::resource_name(DeviceResource resource)
00465 {
00466     const char* res_name = "";
00467     switch(resource) {
00468         case Manufacturer:
00469             res_name = DEVICE_MANUFACTURER;
00470             break;
00471         case DeviceType:
00472             res_name = DEVICE_DEVICE_TYPE;
00473             break;
00474         case ModelNumber:
00475             res_name = DEVICE_MODEL_NUMBER;
00476             break;
00477         case SerialNumber:
00478             res_name = DEVICE_SERIAL_NUMBER;
00479             break;
00480         case HardwareVersion:
00481             res_name = DEVICE_HARDWARE_VERSION;
00482             break;
00483         case FirmwareVersion:
00484             res_name = DEVICE_FIRMWARE_VERSION;
00485             break;
00486         case SoftwareVersion:
00487             res_name = DEVICE_SOFTWARE_VERSION;
00488             break;
00489         case Reboot:
00490             res_name = DEVICE_REBOOT;
00491             break;
00492         case FactoryReset:
00493             res_name = DEVICE_FACTORY_RESET;
00494             break;
00495         case AvailablePowerSources:
00496             res_name = DEVICE_AVAILABLE_POWER_SOURCES;
00497             break;
00498         case PowerSourceVoltage:
00499             res_name = DEVICE_POWER_SOURCE_VOLTAGE;
00500             break;
00501         case PowerSourceCurrent:
00502             res_name = DEVICE_POWER_SOURCE_CURRENT;
00503             break;
00504         case BatteryLevel:
00505             res_name = DEVICE_BATTERY_LEVEL;
00506             break;
00507         case BatteryStatus:
00508             res_name = DEVICE_BATTERY_STATUS;
00509             break;
00510         case MemoryFree:
00511             res_name = DEVICE_MEMORY_FREE;
00512             break;
00513         case MemoryTotal:
00514             res_name = DEVICE_MEMORY_TOTAL;
00515             break;
00516         case ErrorCode:
00517             res_name = DEVICE_ERROR_CODE;
00518             break;
00519         case ResetErrorCode:
00520             res_name = DEVICE_RESET_ERROR_CODE;
00521             break;
00522         case CurrentTime:
00523             res_name = DEVICE_CURRENT_TIME;
00524             break;
00525         case UTCOffset:
00526             res_name = DEVICE_UTC_OFFSET;
00527             break;
00528         case Timezone:
00529             res_name = DEVICE_TIMEZONE;
00530             break;
00531         case SupportedBindingMode:
00532             res_name = DEVICE_SUPPORTED_BINDING_MODE;
00533             break;
00534     }
00535     return res_name;
00536 }
00537 
00538 bool M2MDevice::check_value_range(DeviceResource resource, int64_t value) const
00539 {
00540     bool success = false;
00541     switch (resource) {
00542         case AvailablePowerSources:
00543             if(value >= 0 && value <= 7) {
00544                 success = true;
00545             }
00546             break;
00547         case BatteryLevel:
00548             if (value >= 0 && value <= 100) {
00549                 success = true;
00550             }
00551             break;
00552         case BatteryStatus:
00553             if (value >= 0 && value <= 6) {
00554                 success = true;
00555             }
00556             break;
00557         case ErrorCode:
00558             if (value >= 0 && value <= 8) {
00559                 success = true;
00560             }
00561             break;
00562     default:
00563         success = true;
00564         break;
00565     }
00566     return success;
00567 }
00568