Simple interface for Mbed Cloud Client
Embed:
(wiki syntax)
Show/hide line numbers
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