Austin Blackstone / Mbed 2 deprecated mbed-client-classic-example-lwip

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

Fork of mbed-client-classic-example-lwip by sandbox

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