Simulated product dispenser
Fork of mbed-cloud-workshop-connect-HTS221 by
m2mbase.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/m2mbase.h" 00018 #include "mbed-client/m2mobservationhandler.h" 00019 #include "mbed-client/m2mconstants.h" 00020 #include "mbed-client/m2mtimer.h" 00021 00022 #include "mbed-client/m2mendpoint.h" 00023 #include "mbed-client/m2mobject.h" 00024 #include "mbed-client/m2mobjectinstance.h" 00025 #include "mbed-client/m2mresource.h" 00026 00027 #include "include/m2mreporthandler.h" 00028 #include "include/nsdlaccesshelper.h" 00029 #include "include/m2mcallbackstorage.h" 00030 #include "mbed-trace/mbed_trace.h" 00031 00032 #include "sn_nsdl_lib.h" 00033 #include <assert.h> 00034 #include <ctype.h> 00035 #include <string.h> 00036 #include <stdlib.h> 00037 #include "common_functions.h" 00038 00039 #define TRACE_GROUP "mClt" 00040 00041 M2MBase::M2MBase(const String& resource_name, 00042 M2MBase::Mode mode, 00043 #ifndef DISABLE_RESOURCE_TYPE 00044 const String &resource_type, 00045 #endif 00046 char *path, 00047 bool external_blockwise_store, 00048 bool multiple_instance, 00049 M2MBase::DataType type) 00050 : 00051 _sn_resource(NULL), 00052 _report_handler(NULL) 00053 { 00054 // Checking the name length properly, i.e returning error is impossible from constructor without exceptions 00055 assert(resource_name.length() <= MAX_ALLOWED_STRING_LENGTH); 00056 00057 _sn_resource = (lwm2m_parameters_s*)memory_alloc(sizeof(lwm2m_parameters_s)); 00058 if(_sn_resource) { 00059 memset(_sn_resource, 0, sizeof(lwm2m_parameters_s)); 00060 _sn_resource->free_on_delete = true; 00061 _sn_resource->multiple_instance = multiple_instance; 00062 _sn_resource->data_type = type; 00063 _sn_resource->read_write_callback_set = false; 00064 _sn_resource->dynamic_resource_params = 00065 (sn_nsdl_dynamic_resource_parameters_s*)memory_alloc(sizeof(sn_nsdl_dynamic_resource_parameters_s)); 00066 if(_sn_resource->dynamic_resource_params) { 00067 memset(_sn_resource->dynamic_resource_params, 00068 0, sizeof(sn_nsdl_dynamic_resource_parameters_s)); 00069 _sn_resource->dynamic_resource_params->static_resource_parameters = 00070 (sn_nsdl_static_resource_parameters_s*)memory_alloc(sizeof(sn_nsdl_static_resource_parameters_s)); 00071 00072 // Set callback function in case of both dynamic and static resource 00073 _sn_resource->dynamic_resource_params->sn_grs_dyn_res_callback = __nsdl_c_callback; 00074 00075 if(_sn_resource->dynamic_resource_params->static_resource_parameters) { 00076 // Cast const away to able to compile using MEMORY_OPTIMIZED_API flag 00077 sn_nsdl_static_resource_parameters_s *params = 00078 const_cast<sn_nsdl_static_resource_parameters_s *>(_sn_resource->dynamic_resource_params->static_resource_parameters); 00079 memset(params, 0, sizeof(sn_nsdl_static_resource_parameters_s)); 00080 const size_t len = strlen(resource_type.c_str()); 00081 params->free_on_delete = true; 00082 if (len > 0) { 00083 #ifndef RESOURCE_ATTRIBUTES_LIST 00084 #ifndef DISABLE_RESOURCE_TYPE 00085 params->resource_type_ptr = (char*)alloc_string_copy((uint8_t*) resource_type.c_str(), len); 00086 #endif 00087 #else 00088 sn_nsdl_attribute_item_s item; 00089 item.attribute_name = ATTR_RESOURCE_TYPE; 00090 item.value = (char*)alloc_string_copy((uint8_t*) resource_type.c_str(), len); 00091 sn_nsdl_set_resource_attribute(_sn_resource->dynamic_resource_params->static_resource_parameters, &item); 00092 #endif 00093 } 00094 params->path = path; 00095 params->mode = (unsigned)mode; 00096 params->external_memory_block = external_blockwise_store; 00097 _sn_resource->dynamic_resource_params->static_resource_parameters = params; 00098 } 00099 } 00100 00101 if((!resource_name.empty())) { 00102 _sn_resource->identifier_int_type = false; 00103 _sn_resource->identifier.name = stringdup((char*)resource_name.c_str()); 00104 } else { 00105 tr_debug("M2MBase::M2Mbase resource name is EMPTY ==========="); 00106 _sn_resource->identifier_int_type = true; 00107 _sn_resource->identifier.instance_id = 0; 00108 } 00109 _sn_resource->dynamic_resource_params->publish_uri = true; 00110 _sn_resource->dynamic_resource_params->free_on_delete = true; 00111 _sn_resource->dynamic_resource_params->auto_observable = false; 00112 _sn_resource->dynamic_resource_params->publish_value = false; 00113 } 00114 } 00115 00116 M2MBase::M2MBase(const lwm2m_parameters_s *s): 00117 _sn_resource((lwm2m_parameters_s*) s), 00118 _report_handler(NULL) 00119 { 00120 tr_debug("M2MBase::M2MBase(const lwm2m_parameters_s *s)"); 00121 // Set callback function in case of both dynamic and static resource 00122 _sn_resource->dynamic_resource_params->sn_grs_dyn_res_callback = __nsdl_c_callback; 00123 } 00124 00125 M2MBase::~M2MBase() 00126 { 00127 tr_debug("M2MBase::~M2MBase() %p", this); 00128 delete _report_handler; 00129 00130 value_updated_callback* callback = (value_updated_callback*)M2MCallbackStorage::remove_callback(*this, M2MCallbackAssociation::M2MBaseValueUpdatedCallback); 00131 delete callback; 00132 00133 M2MCallbackStorage::remove_callback(*this, M2MCallbackAssociation::M2MBaseValueUpdatedCallback2); 00134 M2MCallbackStorage::remove_callback(*this, M2MCallbackAssociation::M2MBaseNotificationDeliveryStatusCallback); 00135 } 00136 00137 char* M2MBase::create_path_base(const M2MBase &parent, const char *name) 00138 { 00139 char * result = NULL; 00140 // Expectation is that every element can be MAX_NAME_SZE, + 4 /'s + \0 00141 StringBuffer<(MAX_NAME_SIZE * 4 + (4 + 1))> path; 00142 path.append(parent.uri_path()); 00143 path.append('/'); 00144 path.append(name); 00145 result = stringdup(path.c_str()); 00146 00147 return result; 00148 } 00149 00150 #ifdef MBED_CLOUD_CLIENT_EDGE_EXTENSION 00151 char* M2MBase::create_path(const M2MEndpoint &parent, const char *name) 00152 { 00153 return create_path_base(parent, name); 00154 } 00155 #endif 00156 00157 char* M2MBase::create_path(const M2MObject &parent, uint16_t object_instance) 00158 { 00159 StringBuffer<6> obj_inst_id; 00160 obj_inst_id.append_int(object_instance); 00161 00162 return create_path_base(parent, obj_inst_id.c_str()); 00163 } 00164 00165 char* M2MBase::create_path(const M2MObject &parent, const char *name) 00166 { 00167 return create_path_base(parent, name); 00168 } 00169 00170 char* M2MBase::create_path(const M2MResource &parent, uint16_t resource_instance) 00171 { 00172 StringBuffer<6> res_inst; 00173 res_inst.append_int(resource_instance); 00174 00175 return create_path_base(parent, res_inst.c_str()); 00176 } 00177 00178 char* M2MBase::create_path(const M2MResource &parent, const char *name) 00179 { 00180 return create_path_base(parent, name); 00181 } 00182 00183 char* M2MBase::create_path(const M2MObjectInstance &parent, const char *name) 00184 { 00185 return create_path_base(parent, name); 00186 } 00187 00188 void M2MBase::set_operation(M2MBase::Operation opr) 00189 { 00190 // If the mode is Static, there is only GET_ALLOWED supported. 00191 if(M2MBase::Static == mode()) { 00192 _sn_resource->dynamic_resource_params->access = M2MBase::GET_ALLOWED; 00193 } else { 00194 _sn_resource->dynamic_resource_params->access = opr; 00195 } 00196 } 00197 00198 #ifndef RESOURCE_ATTRIBUTES_LIST 00199 #ifndef MEMORY_OPTIMIZED_API 00200 #ifndef DISABLE_INTERFACE_DESCRIPTION 00201 void M2MBase::set_interface_description(const char *desc) 00202 { 00203 assert(_sn_resource->dynamic_resource_params->static_resource_parameters->free_on_delete); 00204 free(_sn_resource->dynamic_resource_params->static_resource_parameters->interface_description_ptr); 00205 _sn_resource->dynamic_resource_params->static_resource_parameters->interface_description_ptr = NULL; 00206 const size_t len = strlen(desc); 00207 if (len > 0 ) { 00208 _sn_resource->dynamic_resource_params->static_resource_parameters->interface_description_ptr = 00209 (char*)alloc_string_copy((uint8_t*) desc, len); 00210 } 00211 set_changed(); 00212 } 00213 00214 void M2MBase::set_interface_description(const String &desc) 00215 { 00216 assert(_sn_resource->dynamic_resource_params->static_resource_parameters->free_on_delete); 00217 set_interface_description(desc.c_str()); 00218 } 00219 #endif // DISABLE_INTERFACE_DESCRIPTION 00220 00221 #ifndef DISABLE_RESOURCE_TYPE 00222 void M2MBase::set_resource_type(const String &res_type) 00223 { 00224 assert(_sn_resource->dynamic_resource_params->static_resource_parameters->free_on_delete); 00225 set_resource_type(res_type.c_str()); 00226 } 00227 00228 void M2MBase::set_resource_type(const char *res_type) 00229 { 00230 assert(_sn_resource->dynamic_resource_params->static_resource_parameters->free_on_delete); 00231 free(_sn_resource->dynamic_resource_params->static_resource_parameters->resource_type_ptr); 00232 _sn_resource->dynamic_resource_params->static_resource_parameters->resource_type_ptr = NULL; 00233 const size_t len = strlen(res_type); 00234 if (len > 0) { 00235 _sn_resource->dynamic_resource_params->static_resource_parameters->resource_type_ptr = (char*) 00236 alloc_string_copy((uint8_t*) res_type, len); 00237 } 00238 set_changed(); 00239 } 00240 #endif // DISABLE_RESOURCE_TYPE 00241 #endif //MEMORY_OPTIMIZED_API 00242 #else // RESOURCE_ATTRIBUTES_LIST 00243 void M2MBase::set_interface_description(const char *desc) 00244 { 00245 assert(_sn_resource->dynamic_resource_params->static_resource_parameters->free_on_delete); 00246 const size_t len = strlen(desc); 00247 if (len > 0 ) { 00248 sn_nsdl_attribute_item_s item; 00249 item.attribute_name = ATTR_INTERFACE_DESCRIPTION; 00250 item.value = (char*)alloc_string_copy((uint8_t*) desc, len); 00251 sn_nsdl_set_resource_attribute(_sn_resource->dynamic_resource_params->static_resource_parameters, &item); 00252 set_changed(); 00253 } 00254 } 00255 00256 void M2MBase::set_interface_description(const String &desc) 00257 { 00258 assert(_sn_resource->dynamic_resource_params->static_resource_parameters->free_on_delete); 00259 set_interface_description(desc.c_str()); 00260 } 00261 00262 void M2MBase::set_resource_type(const String &res_type) 00263 { 00264 assert(_sn_resource->dynamic_resource_params->static_resource_parameters->free_on_delete); 00265 set_resource_type(res_type.c_str()); 00266 } 00267 00268 void M2MBase::set_resource_type(const char *res_type) 00269 { 00270 assert(_sn_resource->dynamic_resource_params->static_resource_parameters->free_on_delete); 00271 const size_t len = strlen(res_type); 00272 if (len > 0) { 00273 sn_nsdl_attribute_item_s item; 00274 item.attribute_name = ATTR_RESOURCE_TYPE; 00275 item.value = (char*)alloc_string_copy((uint8_t*) res_type, len); 00276 sn_nsdl_set_resource_attribute(_sn_resource->dynamic_resource_params->static_resource_parameters, &item); 00277 set_changed(); 00278 } 00279 } 00280 #endif // RESOURCE_ATTRIBUTES_LIST 00281 00282 void M2MBase::set_coap_content_type(const uint16_t con_type) 00283 { 00284 _sn_resource->dynamic_resource_params->coap_content_type = con_type; 00285 set_changed(); 00286 } 00287 00288 void M2MBase::set_observable(bool observable) 00289 { 00290 _sn_resource->dynamic_resource_params->observable = observable; 00291 set_changed(); 00292 } 00293 00294 void M2MBase::set_auto_observable(bool auto_observable) 00295 { 00296 _sn_resource->dynamic_resource_params->auto_observable = auto_observable; 00297 set_changed(); 00298 } 00299 00300 void M2MBase::add_observation_level(M2MBase::Observation obs_level) 00301 { 00302 if(_report_handler) { 00303 _report_handler->add_observation_level(obs_level); 00304 } 00305 } 00306 00307 void M2MBase::remove_observation_level(M2MBase::Observation obs_level) 00308 { 00309 if(_report_handler) { 00310 _report_handler->remove_observation_level(obs_level); 00311 } 00312 } 00313 00314 00315 void M2MBase::set_under_observation(bool observed, 00316 M2MObservationHandler *handler) 00317 { 00318 tr_debug("M2MBase::set_under_observation - observed: %d", observed); 00319 tr_debug("M2MBase::set_under_observation - base_type: %d", base_type()); 00320 if(_report_handler) { 00321 _report_handler->set_under_observation(observed); 00322 } 00323 00324 set_observation_handler(handler); 00325 00326 if (handler) { 00327 if (base_type() != M2MBase::ResourceInstance) { 00328 // Create report handler only if it does not exist and one wants observation 00329 // This saves 76 bytes of memory on most usual case. 00330 if (observed) { 00331 if(!_report_handler) { 00332 _report_handler = new M2MReportHandler(*this); 00333 } 00334 } 00335 if (_report_handler) { 00336 _report_handler->set_under_observation(observed); 00337 } 00338 } 00339 } else { 00340 delete _report_handler; 00341 _report_handler = NULL; 00342 } 00343 } 00344 00345 void M2MBase::set_observation_token(const uint8_t *token, const uint8_t length) 00346 { 00347 if (_report_handler) { 00348 _report_handler->set_observation_token(token, length); 00349 // This relates to sn_nsdl_auto_obs_token_callback in sn_nsdl.c 00350 set_changed(); 00351 } 00352 } 00353 00354 void M2MBase::set_instance_id(const uint16_t inst_id) 00355 { 00356 _sn_resource->identifier_int_type = true; 00357 _sn_resource->identifier.instance_id = inst_id; 00358 } 00359 00360 void M2MBase::set_max_age(const uint32_t max_age) 00361 { 00362 _sn_resource->max_age = max_age; 00363 } 00364 00365 M2MBase::BaseType M2MBase::base_type() const 00366 { 00367 return (M2MBase::BaseType)_sn_resource->base_type; 00368 } 00369 00370 M2MBase::Operation M2MBase::operation() const 00371 { 00372 return (M2MBase::Operation)_sn_resource->dynamic_resource_params->access; 00373 } 00374 00375 const char* M2MBase::name() const 00376 { 00377 assert(_sn_resource->identifier_int_type == false); 00378 return _sn_resource->identifier.name; 00379 } 00380 00381 int32_t M2MBase::name_id() const 00382 { 00383 int32_t name_id = -1; 00384 assert(_sn_resource->identifier_int_type == false); 00385 if(is_integer(_sn_resource->identifier.name) && strlen(_sn_resource->identifier.name) <= MAX_ALLOWED_STRING_LENGTH) { 00386 name_id = strtoul(_sn_resource->identifier.name, NULL, 10); 00387 if(name_id > 65535){ 00388 name_id = -1; 00389 } 00390 } 00391 return name_id; 00392 } 00393 00394 uint16_t M2MBase::instance_id() const 00395 { 00396 assert(_sn_resource->identifier_int_type == true); 00397 return _sn_resource->identifier.instance_id; 00398 } 00399 00400 #ifndef RESOURCE_ATTRIBUTES_LIST 00401 #ifndef DISABLE_INTERFACE_DESCRIPTION 00402 const char* M2MBase::interface_description() const 00403 { 00404 return (reinterpret_cast<char*>( 00405 _sn_resource->dynamic_resource_params->static_resource_parameters->interface_description_ptr)); 00406 } 00407 #endif 00408 00409 #ifndef DISABLE_RESOURCE_TYPE 00410 const char* M2MBase::resource_type() const 00411 { 00412 return (reinterpret_cast<char*>( 00413 _sn_resource->dynamic_resource_params->static_resource_parameters->resource_type_ptr)); 00414 } 00415 #endif 00416 #else // RESOURCE_ATTRIBUTES_LIST 00417 #ifndef DISABLE_INTERFACE_DESCRIPTION 00418 const char* M2MBase::interface_description() const 00419 { 00420 return sn_nsdl_get_resource_attribute(_sn_resource->dynamic_resource_params->static_resource_parameters, ATTR_INTERFACE_DESCRIPTION); 00421 } 00422 #endif 00423 00424 #ifndef DISABLE_RESOURCE_TYPE 00425 const char* M2MBase::resource_type() const 00426 { 00427 return sn_nsdl_get_resource_attribute(_sn_resource->dynamic_resource_params->static_resource_parameters, ATTR_RESOURCE_TYPE); 00428 } 00429 #endif 00430 #endif // RESOURCE_ATTRIBUTES_LIST 00431 const char* M2MBase::uri_path() const 00432 { 00433 return (reinterpret_cast<char*>( 00434 _sn_resource->dynamic_resource_params->static_resource_parameters->path)); 00435 } 00436 00437 uint16_t M2MBase::coap_content_type() const 00438 { 00439 return _sn_resource->dynamic_resource_params->coap_content_type; 00440 } 00441 00442 bool M2MBase::is_observable() const 00443 { 00444 if (_sn_resource->dynamic_resource_params->auto_observable) { 00445 return true; 00446 } else { 00447 return _sn_resource->dynamic_resource_params->observable; 00448 } 00449 } 00450 00451 M2MBase::Observation M2MBase::observation_level() const 00452 { 00453 M2MBase::Observation obs_level = M2MBase::None; 00454 if(_report_handler) { 00455 obs_level = _report_handler->observation_level(); 00456 } 00457 return obs_level; 00458 } 00459 00460 void M2MBase::get_observation_token(uint8_t *token, uint8_t &token_length) const 00461 { 00462 if(_report_handler) { 00463 _report_handler->get_observation_token(token, token_length); 00464 } 00465 } 00466 00467 M2MBase::Mode M2MBase::mode() const 00468 { 00469 return (M2MBase::Mode)_sn_resource->dynamic_resource_params->static_resource_parameters->mode; 00470 } 00471 00472 uint16_t M2MBase::observation_number() const 00473 { 00474 uint16_t obs_number = 0; 00475 if(_report_handler) { 00476 obs_number = _report_handler->observation_number(); 00477 } 00478 return obs_number; 00479 } 00480 00481 uint32_t M2MBase::max_age() const 00482 { 00483 return _sn_resource->max_age; 00484 } 00485 00486 bool M2MBase::handle_observation_attribute(const char *query) 00487 { 00488 tr_debug("M2MBase::handle_observation_attribute - under observation(%d)", is_under_observation()); 00489 bool success = false; 00490 // Create handler if not already exists. Client must able to parse write attributes even when 00491 // observation is not yet set 00492 if (!_report_handler) { 00493 _report_handler = new M2MReportHandler(*this); 00494 } 00495 00496 success = _report_handler->parse_notification_attribute(query,base_type()); 00497 if (success) { 00498 if (is_under_observation()) { 00499 _report_handler->set_under_observation(true); 00500 } 00501 } else { 00502 _report_handler->set_default_values(); 00503 } 00504 return success; 00505 } 00506 00507 bool M2MBase::observation_to_be_sent(const m2m::Vector<uint16_t> &changed_instance_ids, 00508 uint16_t obs_number, 00509 bool send_object) 00510 { 00511 //TODO: Move this to M2MResourceInstance 00512 M2MObservationHandler *obs_handler = observation_handler(); 00513 if (obs_handler) { 00514 return obs_handler->observation_to_be_sent(this, 00515 obs_number, 00516 changed_instance_ids, 00517 send_object); 00518 } 00519 return false; 00520 } 00521 00522 void M2MBase::set_base_type(M2MBase::BaseType type) 00523 { 00524 assert(_sn_resource->free_on_delete); 00525 _sn_resource->base_type = type; 00526 } 00527 00528 sn_coap_hdr_s* M2MBase::handle_get_request(nsdl_s */*nsdl*/, 00529 sn_coap_hdr_s */*received_coap_header*/, 00530 M2MObservationHandler */*observation_handler*/) 00531 { 00532 //Handled in M2MResource, M2MObjectInstance and M2MObject classes 00533 return NULL; 00534 } 00535 00536 sn_coap_hdr_s* M2MBase::handle_put_request(nsdl_s */*nsdl*/, 00537 sn_coap_hdr_s */*received_coap_header*/, 00538 M2MObservationHandler */*observation_handler*/, 00539 bool &) 00540 { 00541 //Handled in M2MResource, M2MObjectInstance and M2MObject classes 00542 return NULL; 00543 } 00544 00545 sn_coap_hdr_s* M2MBase::handle_post_request(nsdl_s */*nsdl*/, 00546 sn_coap_hdr_s */*received_coap_header*/, 00547 M2MObservationHandler */*observation_handler*/, 00548 bool &, 00549 sn_nsdl_addr_s *) 00550 { 00551 //Handled in M2MResource, M2MObjectInstance and M2MObject classes 00552 return NULL; 00553 } 00554 00555 void *M2MBase::memory_alloc(uint32_t size) 00556 { 00557 if(size) 00558 return malloc(size); 00559 else 00560 return 0; 00561 } 00562 00563 void M2MBase::memory_free(void *ptr) 00564 { 00565 free(ptr); 00566 } 00567 00568 char* M2MBase::alloc_string_copy(const char* source) 00569 { 00570 assert(source != NULL); 00571 00572 // Note: the armcc's libc does not have strdup, so we need to implement it here 00573 const size_t len = strlen(source); 00574 00575 return (char*)alloc_string_copy((uint8_t*)source, len); 00576 } 00577 00578 uint8_t* M2MBase::alloc_string_copy(const uint8_t* source, uint32_t size) 00579 { 00580 assert(source != NULL); 00581 00582 uint8_t* result = (uint8_t*)memory_alloc(size + 1); 00583 if (result) { 00584 memcpy(result, source, size); 00585 result[size] = '\0'; 00586 } 00587 return result; 00588 } 00589 00590 uint8_t* M2MBase::alloc_copy(const uint8_t* source, uint32_t size) 00591 { 00592 assert(source != NULL); 00593 00594 uint8_t* result = (uint8_t*)memory_alloc(size); 00595 if (result) { 00596 memcpy(result, source, size); 00597 } 00598 return result; 00599 } 00600 00601 bool M2MBase::validate_string_length(const String &string, size_t min_length, size_t max_length) 00602 { 00603 bool valid = false; 00604 00605 const size_t len = string.length(); 00606 if ((len >= min_length) && (len <= max_length)) { 00607 valid = true; 00608 } 00609 00610 return valid; 00611 } 00612 00613 bool M2MBase::validate_string_length(const char* string, size_t min_length, size_t max_length) 00614 { 00615 bool valid = false; 00616 00617 if (string != NULL) { 00618 const size_t len = strlen(string); 00619 if ((len >= min_length) && (len <= max_length)) { 00620 valid = true; 00621 } 00622 } 00623 return valid; 00624 } 00625 00626 M2MReportHandler* M2MBase::create_report_handler() 00627 { 00628 if (!_report_handler) { 00629 _report_handler = new M2MReportHandler(*this); 00630 } 00631 return _report_handler; 00632 } 00633 00634 M2MReportHandler* M2MBase::report_handler() const 00635 { 00636 return _report_handler; 00637 } 00638 00639 void M2MBase::set_register_uri(bool register_uri) 00640 { 00641 _sn_resource->dynamic_resource_params->publish_uri = register_uri; 00642 } 00643 00644 bool M2MBase::register_uri() 00645 { 00646 return _sn_resource->dynamic_resource_params->publish_uri; 00647 } 00648 00649 bool M2MBase::is_integer(const String &value) 00650 { 00651 const char *s = value.c_str(); 00652 if(value.empty() || ((!isdigit(s[0])) && (s[0] != '-') && (s[0] != '+'))) { 00653 return false; 00654 } 00655 char * p; 00656 strtol(value.c_str(), &p, 10); 00657 return (*p == 0); 00658 } 00659 00660 bool M2MBase::is_integer(const char *value) 00661 { 00662 assert(value != NULL); 00663 00664 if((strlen(value) < 1) || ((!isdigit(value[0])) && (value[0] != '-') && (value[0] != '+'))) { 00665 return false; 00666 } 00667 char * p; 00668 strtol(value, &p, 10); 00669 return (*p == 0); 00670 } 00671 00672 bool M2MBase::is_under_observation() const 00673 { 00674 bool under_observation = false; 00675 if(_report_handler) { 00676 under_observation = _report_handler->is_under_observation(); 00677 } 00678 return under_observation; 00679 } 00680 00681 bool M2MBase::set_value_updated_function(value_updated_callback callback) 00682 { 00683 value_updated_callback* old_callback = (value_updated_callback*)M2MCallbackStorage::remove_callback(*this, M2MCallbackAssociation::M2MBaseValueUpdatedCallback); 00684 delete old_callback; 00685 // XXX: create a copy of the copy of callback object. Perhaps it would better to 00686 // give a reference as parameter and just store that, as it would save some memory. 00687 value_updated_callback* new_callback = new value_updated_callback(callback); 00688 00689 return M2MCallbackStorage::add_callback(*this, new_callback, M2MCallbackAssociation::M2MBaseValueUpdatedCallback); 00690 } 00691 00692 bool M2MBase::set_value_updated_function(value_updated_callback2 callback) 00693 { 00694 M2MCallbackStorage::remove_callback(*this, M2MCallbackAssociation::M2MBaseValueUpdatedCallback2); 00695 00696 return M2MCallbackStorage::add_callback(*this, (void*)callback, M2MCallbackAssociation::M2MBaseValueUpdatedCallback2); 00697 } 00698 00699 bool M2MBase::is_value_updated_function_set() const 00700 { 00701 bool func_set = false; 00702 if ((M2MCallbackStorage::does_callback_exist(*this, M2MCallbackAssociation::M2MBaseValueUpdatedCallback) == true) || 00703 (M2MCallbackStorage::does_callback_exist(*this, M2MCallbackAssociation::M2MBaseValueUpdatedCallback2) == true)) { 00704 00705 func_set = true; 00706 } 00707 return func_set; 00708 } 00709 00710 void M2MBase::execute_value_updated(const String& name) 00711 { 00712 // Q: is there a point to call both callback types? Or should we call just one of them? 00713 00714 value_updated_callback* callback = (value_updated_callback*)M2MCallbackStorage::get_callback(*this, 00715 M2MCallbackAssociation::M2MBaseValueUpdatedCallback); 00716 if (callback) { 00717 (*callback)(name.c_str()); 00718 } 00719 00720 value_updated_callback2 callback2 = (value_updated_callback2)M2MCallbackStorage::get_callback(*this, M2MCallbackAssociation::M2MBaseValueUpdatedCallback2); 00721 if (callback2) { 00722 (*callback2)(name.c_str()); 00723 } 00724 } 00725 00726 bool M2MBase::build_path(StringBuffer<MAX_PATH_SIZE> &buffer, const char *s1, uint16_t i1, const char *s2, uint16_t i2) 00727 { 00728 00729 if(!buffer.ensure_space(strlen(s1) + strlen(s2) + (MAX_INSTANCE_SIZE * 2) + 3 + 1)){ 00730 return false; 00731 } 00732 00733 buffer.append(s1); 00734 buffer.append('/'); 00735 buffer.append_int(i1); 00736 buffer.append('/'); 00737 buffer.append(s2); 00738 buffer.append('/'); 00739 buffer.append_int(i2); 00740 00741 return true; 00742 00743 } 00744 00745 bool M2MBase::build_path(StringBuffer<MAX_PATH_SIZE_2> &buffer, const char *s1, uint16_t i1, const char *s2) 00746 { 00747 if(!buffer.ensure_space(strlen(s1) + strlen(s2) + MAX_INSTANCE_SIZE + 2 + 1)){ 00748 return false; 00749 } 00750 00751 buffer.append(s1); 00752 buffer.append('/'); 00753 buffer.append_int(i1); 00754 buffer.append('/'); 00755 buffer.append(s2); 00756 00757 return true; 00758 } 00759 00760 bool M2MBase::build_path(StringBuffer<MAX_PATH_SIZE_3> &buffer, const char *s1, uint16_t i1, uint16_t i2) 00761 { 00762 if(!buffer.ensure_space(strlen(s1) + (MAX_INSTANCE_SIZE * 2) + 2 + 1)){ 00763 return false; 00764 } 00765 00766 buffer.append(s1); 00767 buffer.append('/'); 00768 buffer.append_int(i1); 00769 buffer.append('/'); 00770 buffer.append_int(i2); 00771 00772 return true; 00773 } 00774 00775 bool M2MBase::build_path(StringBuffer<MAX_PATH_SIZE_4> &buffer, const char *s1, uint16_t i1) 00776 { 00777 if(!buffer.ensure_space(strlen(s1) + MAX_INSTANCE_SIZE + 1 + 1)){ 00778 return false; 00779 } 00780 00781 buffer.append(s1); 00782 buffer.append('/'); 00783 buffer.append_int(i1); 00784 00785 return true; 00786 } 00787 00788 char* M2MBase::stringdup(const char* src) 00789 { 00790 assert(src != NULL); 00791 00792 const size_t len = strlen(src) + 1; 00793 00794 char *dest = (char*)malloc(len); 00795 00796 if (dest) { 00797 memcpy(dest, src, len); 00798 } 00799 return dest; 00800 } 00801 00802 void M2MBase::free_resources() 00803 { 00804 // remove the nsdl structures from the nsdlinterface's lists. 00805 M2MObservationHandler *obs_handler = observation_handler(); 00806 if (obs_handler) { 00807 tr_debug("M2MBase::free_resources()"); 00808 obs_handler->resource_to_be_deleted(this); 00809 } 00810 00811 if (_sn_resource->dynamic_resource_params->static_resource_parameters->free_on_delete) { 00812 sn_nsdl_static_resource_parameters_s *params = 00813 const_cast<sn_nsdl_static_resource_parameters_s *>(_sn_resource->dynamic_resource_params->static_resource_parameters); 00814 00815 free(params->path); 00816 //free(params->resource); 00817 #ifndef RESOURCE_ATTRIBUTES_LIST 00818 #ifndef DISABLE_RESOURCE_TYPE 00819 free(params->resource_type_ptr); 00820 #endif 00821 #ifndef DISABLE_INTERFACE_DESCRIPTION 00822 free(params->interface_description_ptr); 00823 #endif 00824 #else 00825 sn_nsdl_free_resource_attributes_list(_sn_resource->dynamic_resource_params->static_resource_parameters); 00826 #endif 00827 free(params); 00828 } 00829 if (_sn_resource->dynamic_resource_params->free_on_delete) { 00830 free(_sn_resource->dynamic_resource_params->resource); 00831 free(_sn_resource->dynamic_resource_params); 00832 } 00833 00834 if(_sn_resource->free_on_delete && _sn_resource->identifier_int_type == false) { 00835 tr_debug("M2MBase::free_resources()"); 00836 free(_sn_resource->identifier.name); 00837 } 00838 if(_sn_resource->free_on_delete) { 00839 free(_sn_resource); 00840 } 00841 } 00842 00843 size_t M2MBase::resource_name_length() const 00844 { 00845 assert(_sn_resource->identifier_int_type == false); 00846 return strlen(_sn_resource->identifier.name); 00847 } 00848 00849 sn_nsdl_dynamic_resource_parameters_s* M2MBase::get_nsdl_resource() const 00850 { 00851 return _sn_resource->dynamic_resource_params; 00852 } 00853 00854 M2MBase::lwm2m_parameters_s* M2MBase::get_lwm2m_parameters() const 00855 { 00856 return _sn_resource; 00857 } 00858 00859 uint16_t M2MBase::get_notification_msgid() const 00860 { 00861 return _sn_resource->dynamic_resource_params->msg_id; 00862 } 00863 00864 void M2MBase::set_notification_msgid(uint16_t msgid) 00865 { 00866 _sn_resource->dynamic_resource_params->msg_id = msgid; 00867 } 00868 00869 bool M2MBase::set_notification_delivery_status_cb(notification_delivery_status_cb callback, void *client_args) 00870 { 00871 M2MCallbackStorage::remove_callback(*this, 00872 M2MCallbackAssociation::M2MBaseNotificationDeliveryStatusCallback); 00873 00874 return M2MCallbackStorage::add_callback(*this, 00875 (void*)callback, 00876 M2MCallbackAssociation::M2MBaseNotificationDeliveryStatusCallback, 00877 client_args); 00878 } 00879 00880 void M2MBase::send_notification_delivery_status(const M2MBase& object, const NotificationDeliveryStatus status) 00881 { 00882 M2MCallbackAssociation* item = M2MCallbackStorage::get_association_item(object, 00883 M2MCallbackAssociation::M2MBaseNotificationDeliveryStatusCallback); 00884 if (item) { 00885 notification_delivery_status_cb callback = (notification_delivery_status_cb)item->_callback; 00886 if (callback) { 00887 (*callback)(object, status, item->_client_args); 00888 } 00889 } 00890 } 00891 00892 void M2MBase::set_changed() 00893 { 00894 #ifdef MBED_CLOUD_CLIENT_EDGE_EXTENSION 00895 M2MBase *parent = get_parent(); 00896 if (parent) { 00897 parent->set_changed(); 00898 } 00899 #endif 00900 } 00901 00902 M2MBase *M2MBase::get_parent() const 00903 { 00904 return NULL; 00905 } 00906
Generated on Tue Jul 12 2022 19:12:12 by 1.7.2