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