sandbox / mbed-client

Fork of mbed-client by Christopher Haster

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