Mayank Gupta / Mbed OS pelion-example-frdm

Dependencies:   FXAS21002 FXOS8700Q

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