Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 16:24:13 by
1.7.2