Mbed Cloud example program for workshop in W27 2018.

Dependencies:   MMA7660 LM75B

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_instance = 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_instance = _device_instance->create_dynamic_resource_instance(device_id,OMA_RESOURCE_TYPE,
00243                                                                      M2MResourceInstance::INTEGER,
00244                                                                      true, instance_id);
00245 
00246             M2MResource *res = _device_instance->resource(device_id);
00247             if(res) {
00248                 res->set_register_uri(false);
00249             }
00250             if(res_instance) {
00251                 res_instance->set_value(value);
00252                 // Only read operation is allowed for above resources
00253                 res_instance->set_operation(M2MBase::GET_ALLOWED);
00254 
00255                 res_instance->set_register_uri(false);
00256             }
00257         }
00258     }
00259     return res_instance;
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             if(res) {
00279                 res->set_operation(M2MBase::POST_ALLOWED);
00280                 res->set_register_uri(false);
00281             }
00282         }
00283     }
00284     return res;
00285 }
00286 
00287 bool M2MDevice::delete_resource(DeviceResource resource)
00288 {
00289     bool success = false;
00290     if(M2MDevice::Reboot != resource             &&
00291        M2MDevice::ErrorCode != resource          &&
00292        M2MDevice::SupportedBindingMode != resource) {
00293         if(_device_instance) {
00294             success = _device_instance->remove_resource(resource_name(resource));
00295         }
00296     }
00297     return success;
00298 }
00299 
00300 bool M2MDevice::delete_resource_instance(DeviceResource resource,
00301                                          uint16_t instance_id)
00302 {
00303     bool success = false;
00304     if(M2MDevice::Reboot != resource             &&
00305        M2MDevice::ErrorCode != resource          &&
00306        M2MDevice::SupportedBindingMode != resource) {
00307         if(_device_instance) {
00308             success = _device_instance->remove_resource_instance(resource_name(resource),instance_id);
00309         }
00310     }
00311     return success;
00312 }
00313 
00314 bool M2MDevice::set_resource_value(DeviceResource resource,
00315                                    const String &value,
00316                                    uint16_t instance_id)
00317 {
00318     bool success = false;
00319     M2MResourceBase* res = get_resource_instance(resource, instance_id);
00320     if(res && value.size() <= MAX_ALLOWED_STRING_LENGTH) {
00321         if(M2MDevice::Manufacturer == resource          ||
00322            M2MDevice::ModelNumber == resource           ||
00323            M2MDevice::DeviceType == resource            ||
00324            M2MDevice::SerialNumber == resource          ||
00325            M2MDevice::HardwareVersion == resource       ||
00326            M2MDevice::FirmwareVersion == resource       ||
00327            M2MDevice::SoftwareVersion == resource       ||
00328            M2MDevice::UTCOffset == resource             ||
00329            M2MDevice::Timezone == resource              ||
00330            M2MDevice::SupportedBindingMode == resource) {
00331                 if (value.empty()) {
00332                     res->clear_value();
00333                     success = true;
00334                 } else {
00335                     success = res->set_value((const uint8_t*)value.c_str(),(uint32_t)value.length());
00336                 }
00337         }
00338     }
00339     return success;
00340 }
00341 
00342 bool M2MDevice::set_resource_value(DeviceResource resource,
00343                                        int64_t value,
00344                                        uint16_t instance_id)
00345 {
00346     bool success = false;
00347     M2MResourceBase* res = get_resource_instance(resource, instance_id);
00348     if(res) {
00349         if(M2MDevice::BatteryLevel == resource          ||
00350            M2MDevice::BatteryStatus == resource         ||
00351            M2MDevice::MemoryFree == resource            ||
00352            M2MDevice::MemoryTotal == resource           ||
00353            M2MDevice::ErrorCode == resource             ||
00354            M2MDevice::CurrentTime == resource           ||
00355            M2MDevice::AvailablePowerSources == resource ||
00356            M2MDevice::PowerSourceVoltage == resource    ||
00357            M2MDevice::PowerSourceCurrent == resource) {
00358             // If it is any of the above resource
00359             // set the value of the resource.
00360             if (check_value_range(resource, value)) {
00361 
00362                 success = res->set_value(value);
00363             }
00364         }
00365     }
00366     return success;
00367 }
00368 
00369 String M2MDevice::resource_value_string(DeviceResource resource,
00370                                         uint16_t instance_id) const
00371 {
00372     String value = "";
00373     const M2MResourceBase* res = get_resource_instance(resource, instance_id);
00374     if(res) {
00375         if(M2MDevice::Manufacturer == resource          ||
00376            M2MDevice::ModelNumber == resource           ||
00377            M2MDevice::DeviceType == resource            ||
00378            M2MDevice::SerialNumber == resource          ||
00379            M2MDevice::HardwareVersion == resource       ||
00380            M2MDevice::FirmwareVersion == resource       ||
00381            M2MDevice::SoftwareVersion == resource       ||
00382            M2MDevice::UTCOffset == resource             ||
00383            M2MDevice::Timezone == resource              ||
00384            M2MDevice::SupportedBindingMode == resource) {
00385 
00386 
00387             value = res->get_value_string();
00388         }
00389     }
00390     return value;
00391 }
00392 
00393 int64_t M2MDevice::resource_value_int(DeviceResource resource,
00394                                       uint16_t instance_id) const
00395 {
00396     int64_t value = -1;
00397     M2MResourceBase* res = get_resource_instance(resource, instance_id);
00398     if(res) {
00399         if(M2MDevice::BatteryLevel == resource          ||
00400            M2MDevice::BatteryStatus == resource         ||
00401            M2MDevice::MemoryFree == resource            ||
00402            M2MDevice::MemoryTotal == resource           ||
00403            M2MDevice::ErrorCode == resource             ||
00404            M2MDevice::CurrentTime == resource           ||
00405            M2MDevice::AvailablePowerSources == resource ||
00406            M2MDevice::PowerSourceVoltage == resource    ||
00407            M2MDevice::PowerSourceCurrent == resource) {
00408 
00409             // note: the value may be 32bit int on 32b archs.
00410             value = res->get_value_int();
00411         }
00412     }
00413     return value;
00414 }
00415 
00416 bool M2MDevice::is_resource_present(DeviceResource resource) const
00417 {
00418     bool success = false;
00419     const M2MResourceBase* res = get_resource_instance(resource,0);
00420     if(res) {
00421         success = true;
00422     }
00423     return success;
00424 }
00425 
00426 uint16_t M2MDevice::per_resource_count(DeviceResource res) const
00427 {
00428     uint16_t count = 0;
00429     if(_device_instance) {
00430         count = _device_instance->resource_count(resource_name(res));
00431     }
00432     return count;
00433 }
00434 
00435 uint16_t M2MDevice::total_resource_count() const
00436 {
00437     uint16_t count = 0;
00438     if(_device_instance) {
00439         count = _device_instance->resources().size();
00440     }
00441     return count;
00442 }
00443 
00444 M2MResourceBase* M2MDevice::get_resource_instance(DeviceResource dev_res,
00445                                                       uint16_t instance_id) const
00446 {
00447     M2MResource* res = NULL;
00448     M2MResourceBase* inst = NULL;
00449     if(_device_instance) {
00450         res = _device_instance->resource(resource_name(dev_res));
00451         if(res) {
00452             if(res->supports_multiple_instances()) {
00453                inst = res->resource_instance(instance_id);
00454             } else {
00455                 inst = res;
00456             }
00457         }
00458     }
00459     return inst;
00460 }
00461 
00462 const char* M2MDevice::resource_name(DeviceResource resource)
00463 {
00464     const char* res_name = "";
00465     switch(resource) {
00466         case Manufacturer:
00467             res_name = DEVICE_MANUFACTURER;
00468             break;
00469         case DeviceType:
00470             res_name = DEVICE_DEVICE_TYPE;
00471             break;
00472         case ModelNumber:
00473             res_name = DEVICE_MODEL_NUMBER;
00474             break;
00475         case SerialNumber:
00476             res_name = DEVICE_SERIAL_NUMBER;
00477             break;
00478         case HardwareVersion:
00479             res_name = DEVICE_HARDWARE_VERSION;
00480             break;
00481         case FirmwareVersion:
00482             res_name = DEVICE_FIRMWARE_VERSION;
00483             break;
00484         case SoftwareVersion:
00485             res_name = DEVICE_SOFTWARE_VERSION;
00486             break;
00487         case Reboot:
00488             res_name = DEVICE_REBOOT;
00489             break;
00490         case FactoryReset:
00491             res_name = DEVICE_FACTORY_RESET;
00492             break;
00493         case AvailablePowerSources:
00494             res_name = DEVICE_AVAILABLE_POWER_SOURCES;
00495             break;
00496         case PowerSourceVoltage:
00497             res_name = DEVICE_POWER_SOURCE_VOLTAGE;
00498             break;
00499         case PowerSourceCurrent:
00500             res_name = DEVICE_POWER_SOURCE_CURRENT;
00501             break;
00502         case BatteryLevel:
00503             res_name = DEVICE_BATTERY_LEVEL;
00504             break;
00505         case BatteryStatus:
00506             res_name = DEVICE_BATTERY_STATUS;
00507             break;
00508         case MemoryFree:
00509             res_name = DEVICE_MEMORY_FREE;
00510             break;
00511         case MemoryTotal:
00512             res_name = DEVICE_MEMORY_TOTAL;
00513             break;
00514         case ErrorCode:
00515             res_name = DEVICE_ERROR_CODE;
00516             break;
00517         case ResetErrorCode:
00518             res_name = DEVICE_RESET_ERROR_CODE;
00519             break;
00520         case CurrentTime:
00521             res_name = DEVICE_CURRENT_TIME;
00522             break;
00523         case UTCOffset:
00524             res_name = DEVICE_UTC_OFFSET;
00525             break;
00526         case Timezone:
00527             res_name = DEVICE_TIMEZONE;
00528             break;
00529         case SupportedBindingMode:
00530             res_name = DEVICE_SUPPORTED_BINDING_MODE;
00531             break;
00532     }
00533     return res_name;
00534 }
00535 
00536 bool M2MDevice::check_value_range(DeviceResource resource, int64_t value)
00537 {
00538     bool success = false;
00539     switch (resource) {
00540         case AvailablePowerSources:
00541             if(value >= 0 && value <= 7) {
00542                 success = true;
00543             }
00544             break;
00545         case BatteryLevel:
00546             if (value >= 0 && value <= 100) {
00547                 success = true;
00548             }
00549             break;
00550         case BatteryStatus:
00551             if (value >= 0 && value <= 6) {
00552                 success = true;
00553             }
00554             break;
00555         case ErrorCode:
00556             if (value >= 0 && value <= 8) {
00557                 success = true;
00558             }
00559             break;
00560     default:
00561         success = true;
00562         break;
00563     }
00564     return success;
00565 }
00566