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 "mbed-trace/mbed_trace.h" 00029 #include <assert.h> 00030 #include <ctype.h> 00031 #include <string.h> 00032 #include <stdlib.h> 00033 00034 #define TRACE_GROUP "mClt" 00035 00036 M2MBase::M2MBase(const String& resource_name, 00037 M2MBase::Mode mode, 00038 const String &resource_type, 00039 char *path, 00040 bool external_blockwise_store) 00041 : 00042 _sn_resource(NULL), 00043 _report_handler(NULL), 00044 _observation_handler(NULL), 00045 _token(NULL), 00046 _function_pointer(NULL), 00047 _value_updated_callback(NULL), 00048 _observation_number(0), 00049 _token_length(0), 00050 _observation_level(M2MBase::None), 00051 _is_under_observation(false) 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->dynamic_resource_params = 00061 (sn_nsdl_dynamic_resource_parameters_s*)memory_alloc(sizeof(sn_nsdl_dynamic_resource_parameters_s)); 00062 if(_sn_resource->dynamic_resource_params) { 00063 memset(_sn_resource->dynamic_resource_params, 00064 0, sizeof(sn_nsdl_dynamic_resource_parameters_s)); 00065 _sn_resource->dynamic_resource_params->static_resource_parameters = 00066 (sn_nsdl_static_resource_parameters_s*)memory_alloc(sizeof(sn_nsdl_static_resource_parameters_s)); 00067 00068 // Set callback function in case of dynamic resource 00069 if (M2MBase::Dynamic == mode) { 00070 _sn_resource->dynamic_resource_params->sn_grs_dyn_res_callback = __nsdl_c_callback; 00071 } 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 params->resource_type_ptr = (char*) 00081 alloc_string_copy((uint8_t*) resource_type.c_str(), len); 00082 } 00083 params->path = (uint8_t*)path; 00084 params->pathlen = strlen(path); 00085 00086 00087 params->mode = (const uint8_t)mode; 00088 params->free_on_delete = true; 00089 params->external_memory_block = external_blockwise_store; 00090 _sn_resource->dynamic_resource_params->static_resource_parameters = params; 00091 } 00092 } 00093 00094 _sn_resource->name = stringdup((char*)resource_name.c_str()); 00095 _sn_resource->dynamic_resource_params->publish_uri = true; 00096 _sn_resource->dynamic_resource_params->free_on_delete = true; 00097 00098 if(is_integer(resource_name) && resource_name.size() <= MAX_ALLOWED_STRING_LENGTH) { 00099 _sn_resource->name_id = strtoul(resource_name.c_str(), NULL, 10); 00100 if(_sn_resource->name_id > 65535){ 00101 _sn_resource->name_id = -1; 00102 } 00103 } else { 00104 _sn_resource->name_id = -1; 00105 } 00106 } 00107 } 00108 00109 M2MBase::M2MBase(const lwm2m_parameters_s *s): 00110 _sn_resource((lwm2m_parameters_s*) s), 00111 _report_handler(NULL), 00112 _observation_handler(NULL), 00113 _token(NULL), 00114 _function_pointer(NULL), 00115 _value_updated_callback(NULL), 00116 _observation_number(0), 00117 _token_length(0), 00118 _observation_level(M2MBase::None), 00119 _is_under_observation(false) 00120 { 00121 // Set callback function in case of dynamic resource 00122 if (M2MBase::Dynamic == _sn_resource->dynamic_resource_params->static_resource_parameters->mode) { 00123 _sn_resource->dynamic_resource_params->sn_grs_dyn_res_callback = __nsdl_c_callback; 00124 } 00125 } 00126 00127 M2MBase::~M2MBase() 00128 { 00129 delete _report_handler; 00130 free_resources(); 00131 free(_token); 00132 delete _function_pointer; 00133 delete _value_updated_callback; 00134 } 00135 00136 char* M2MBase::create_path(const M2MObject &parent, uint16_t object_instance) 00137 { 00138 StringBuffer<5> obj_inst_id; 00139 obj_inst_id.append_int(object_instance); 00140 00141 return create_path(parent, obj_inst_id.c_str()); 00142 } 00143 00144 char* M2MBase::create_path(const M2MObject &parent, const char *name) 00145 { 00146 char * result = NULL; 00147 StringBuffer<(MAX_NAME_SIZE * 2 + (2 + 1))> path; 00148 00149 const char* obj_name = parent.name(); 00150 00151 // XXX: ensure space 00152 path.append(obj_name); 00153 path.append('/'); 00154 path.append(name); 00155 00156 result = stringdup(path.c_str()); 00157 return result; 00158 } 00159 00160 char* M2MBase::create_path(const M2MResource &parent, uint16_t resource_instance) 00161 { 00162 StringBuffer<5> res_inst; 00163 res_inst.append_int(resource_instance); 00164 00165 return create_path(parent, res_inst.c_str()); 00166 } 00167 00168 char* M2MBase::create_path(const M2MResource &parent, const char *name) 00169 { 00170 char * result = NULL; 00171 StringBuffer<(MAX_NAME_SIZE * 4 + (3 + 1))> path; 00172 M2MObjectInstance& parent_object_instance = parent.get_parent_object_instance(); 00173 M2MObject& parent_object = parent_object_instance.get_parent_object(); 00174 00175 const char* obj_name = parent_object.name(); 00176 00177 // Note: the parent_object_instance.name() contains name of its parent object, not the name of instance, 00178 // so we need to skip that here 00179 const uint16_t obj_inst_id = parent_object_instance.instance_id(); 00180 00181 const char* resource_name = parent.name(); 00182 00183 // XXX: ensure space 00184 path.append(obj_name); 00185 path.append('/'); 00186 path.append_int(obj_inst_id); 00187 path.append('/'); 00188 path.append(resource_name); 00189 path.append('/'); 00190 path.append(name); 00191 00192 result = stringdup(path.c_str()); 00193 return result; 00194 } 00195 00196 char* M2MBase::create_path(const M2MObjectInstance &parent, const char *name) 00197 { 00198 char * result = NULL; 00199 StringBuffer<(MAX_NAME_SIZE * 3 + (2 + 1))> path; 00200 M2MObject& parent_object = parent.get_parent_object(); 00201 00202 const char* obj_name = parent_object.name(); 00203 // Note: the parent_object_instance.name() contains name of its parent object, not the name of instance, 00204 // so we need to skip that here 00205 const uint16_t obj_inst_id = parent.instance_id(); 00206 00207 // XXX: ensure space 00208 path.append(obj_name); 00209 path.append('/'); 00210 path.append_int(obj_inst_id); 00211 path.append('/'); 00212 path.append(name); 00213 00214 result = stringdup(path.c_str()); 00215 return result; 00216 } 00217 00218 00219 void M2MBase::set_operation(M2MBase::Operation opr) 00220 { 00221 // If the mode is Static, there is only GET_ALLOWED supported. 00222 if(M2MBase::Static == mode()) { 00223 _sn_resource->dynamic_resource_params->access = M2MBase::GET_ALLOWED; 00224 } else { 00225 _sn_resource->dynamic_resource_params->access = opr; 00226 } 00227 } 00228 00229 #ifndef MEMORY_OPTIMIZED_API 00230 void M2MBase::set_interface_description(const char *desc) 00231 { 00232 assert(_sn_resource->dynamic_resource_params->static_resource_parameters->free_on_delete); 00233 free(_sn_resource->dynamic_resource_params->static_resource_parameters->interface_description_ptr); 00234 _sn_resource->dynamic_resource_params->static_resource_parameters->interface_description_ptr = NULL; 00235 const size_t len = strlen(desc); 00236 if (len > 0 ) { 00237 _sn_resource->dynamic_resource_params->static_resource_parameters->interface_description_ptr = 00238 (char*)alloc_string_copy((uint8_t*) desc, len); 00239 } 00240 } 00241 00242 void M2MBase::set_interface_description(const String &desc) 00243 { 00244 assert(_sn_resource->dynamic_resource_params->static_resource_parameters->free_on_delete); 00245 set_interface_description(desc.c_str()); 00246 } 00247 00248 void M2MBase::set_resource_type(const String &res_type) 00249 { 00250 assert(_sn_resource->dynamic_resource_params->static_resource_parameters->free_on_delete); 00251 set_resource_type(res_type.c_str()); 00252 } 00253 00254 void M2MBase::set_resource_type(const char *res_type) 00255 { 00256 assert(_sn_resource->dynamic_resource_params->static_resource_parameters->free_on_delete); 00257 free(_sn_resource->dynamic_resource_params->static_resource_parameters->resource_type_ptr); 00258 _sn_resource->dynamic_resource_params->static_resource_parameters->resource_type_ptr = NULL; 00259 const size_t len = strlen(res_type); 00260 if (len > 0) { 00261 _sn_resource->dynamic_resource_params->static_resource_parameters->resource_type_ptr = (char*) 00262 alloc_string_copy((uint8_t*) res_type, len); 00263 } 00264 } 00265 #endif 00266 00267 void M2MBase::set_coap_content_type(const uint8_t con_type) 00268 { 00269 _sn_resource->dynamic_resource_params->coap_content_type = con_type; 00270 } 00271 00272 void M2MBase::set_observable(bool observable) 00273 { 00274 _sn_resource->dynamic_resource_params->observable = observable; 00275 } 00276 00277 void M2MBase::add_observation_level(M2MBase::Observation obs_level) 00278 { 00279 _observation_level = (M2MBase::Observation)(_observation_level | obs_level); 00280 } 00281 00282 void M2MBase::remove_observation_level(M2MBase::Observation obs_level) 00283 { 00284 _observation_level = (M2MBase::Observation)(_observation_level & ~obs_level); 00285 } 00286 00287 void M2MBase::set_observation_handler(M2MObservationHandler *handler) 00288 { 00289 tr_debug("M2MBase::set_observation_handler - handler: 0x%x", handler); 00290 _observation_handler = handler; 00291 } 00292 00293 00294 void M2MBase::set_under_observation(bool observed, 00295 M2MObservationHandler *handler) 00296 { 00297 tr_debug("M2MBase::set_under_observation - observed: %d", observed); 00298 tr_debug("M2MBase::set_under_observation - base_type: %d", base_type()); 00299 _is_under_observation = observed; 00300 _observation_handler = handler; 00301 if (handler) { 00302 if (base_type() != M2MBase::ResourceInstance) { 00303 // Create report handler only if it does not exist and one wants observation 00304 // This saves 76 bytes of memory on most usual case. 00305 if (observed) { 00306 if(!_report_handler) { 00307 _report_handler = new M2MReportHandler(*this); 00308 } 00309 } 00310 if (_report_handler) { 00311 _report_handler->set_under_observation(observed); 00312 } 00313 } 00314 } else { 00315 delete _report_handler; 00316 _report_handler = NULL; 00317 } 00318 } 00319 00320 void M2MBase::set_observation_token(const uint8_t *token, const uint8_t length) 00321 { 00322 free(_token); 00323 _token = NULL; 00324 _token_length = 0; 00325 00326 if( token != NULL && length > 0 ) { 00327 _token = alloc_string_copy((uint8_t *)token, length); 00328 if(_token) { 00329 _token_length = length; 00330 } 00331 } 00332 } 00333 00334 void M2MBase::set_instance_id(const uint16_t inst_id) 00335 { 00336 _sn_resource->instance_id = inst_id; 00337 } 00338 00339 void M2MBase::set_observation_number(const uint16_t /*observation_number*/) 00340 { 00341 } 00342 00343 void M2MBase::set_max_age(const uint32_t max_age) 00344 { 00345 _sn_resource->max_age = max_age; 00346 } 00347 00348 M2MBase::BaseType M2MBase::base_type() const 00349 { 00350 return (M2MBase::BaseType)_sn_resource->base_type; 00351 } 00352 00353 M2MBase::Operation M2MBase::operation() const 00354 { 00355 return (M2MBase::Operation)_sn_resource->dynamic_resource_params->access; 00356 } 00357 00358 const char* M2MBase::name() const 00359 { 00360 return _sn_resource->name; 00361 } 00362 00363 int32_t M2MBase::name_id() const 00364 { 00365 return _sn_resource->name_id; 00366 } 00367 00368 uint16_t M2MBase::instance_id() const 00369 { 00370 return _sn_resource->instance_id; 00371 } 00372 00373 const char* M2MBase::interface_description() const 00374 { 00375 return (reinterpret_cast<char*>( 00376 _sn_resource->dynamic_resource_params->static_resource_parameters->interface_description_ptr)); 00377 } 00378 00379 const char* M2MBase::resource_type() const 00380 { 00381 return (reinterpret_cast<char*>( 00382 _sn_resource->dynamic_resource_params->static_resource_parameters->resource_type_ptr)); 00383 } 00384 00385 const char* M2MBase::uri_path() const 00386 { 00387 return (reinterpret_cast<char*>( 00388 _sn_resource->dynamic_resource_params->static_resource_parameters->path)); 00389 } 00390 00391 uint8_t M2MBase::coap_content_type() const 00392 { 00393 return _sn_resource->dynamic_resource_params->coap_content_type; 00394 } 00395 00396 bool M2MBase::is_observable() const 00397 { 00398 return _sn_resource->dynamic_resource_params->observable; 00399 } 00400 00401 M2MBase::Observation M2MBase::observation_level() const 00402 { 00403 return _observation_level; 00404 } 00405 00406 void M2MBase::get_observation_token(uint8_t *&token, uint32_t &token_length) 00407 { 00408 token_length = 0; 00409 free(token); 00410 if (_token) { 00411 token = alloc_string_copy((uint8_t *)_token, _token_length); 00412 if(token) { 00413 token_length = _token_length; 00414 } 00415 } 00416 } 00417 00418 M2MBase::Mode M2MBase::mode() const 00419 { 00420 return (M2MBase::Mode)_sn_resource->dynamic_resource_params->static_resource_parameters->mode; 00421 } 00422 00423 uint16_t M2MBase::observation_number() const 00424 { 00425 return _observation_number; 00426 } 00427 00428 uint32_t M2MBase::max_age() const 00429 { 00430 return _sn_resource->max_age; 00431 } 00432 00433 bool M2MBase::handle_observation_attribute(const char *query) 00434 { 00435 tr_debug("M2MBase::handle_observation_attribute - under observation(%d)", is_under_observation()); 00436 bool success = false; 00437 // Create handler if not already exists. Client must able to parse write attributes even when 00438 // observation is not yet set 00439 if (!_report_handler) { 00440 _report_handler = new M2MReportHandler(*this); 00441 } 00442 00443 success = _report_handler->parse_notification_attribute(query,base_type()); 00444 if (success) { 00445 if (is_under_observation()) { 00446 _report_handler->set_under_observation(true); 00447 } 00448 } else { 00449 _report_handler->set_default_values(); 00450 } 00451 return success; 00452 } 00453 00454 void M2MBase::observation_to_be_sent(m2m::Vector<uint16_t> changed_instance_ids, bool send_object) 00455 { 00456 //TODO: Move this to M2MResourceInstance 00457 if(_observation_handler) { 00458 _observation_number++; 00459 _observation_handler->observation_to_be_sent(this, 00460 _observation_number, 00461 changed_instance_ids, 00462 send_object); 00463 } 00464 } 00465 00466 void M2MBase::set_base_type(M2MBase::BaseType type) 00467 { 00468 assert(_sn_resource->free_on_delete); 00469 _sn_resource->base_type = type; 00470 } 00471 00472 sn_coap_hdr_s* M2MBase::handle_get_request(nsdl_s */*nsdl*/, 00473 sn_coap_hdr_s */*received_coap_header*/, 00474 M2MObservationHandler */*observation_handler*/) 00475 { 00476 //Handled in M2MResource, M2MObjectInstance and M2MObject classes 00477 return NULL; 00478 } 00479 00480 sn_coap_hdr_s* M2MBase::handle_put_request(nsdl_s */*nsdl*/, 00481 sn_coap_hdr_s */*received_coap_header*/, 00482 M2MObservationHandler */*observation_handler*/, 00483 bool &) 00484 { 00485 //Handled in M2MResource, M2MObjectInstance and M2MObject classes 00486 return NULL; 00487 } 00488 00489 sn_coap_hdr_s* M2MBase::handle_post_request(nsdl_s */*nsdl*/, 00490 sn_coap_hdr_s */*received_coap_header*/, 00491 M2MObservationHandler */*observation_handler*/, 00492 bool &, 00493 sn_nsdl_addr_s *) 00494 { 00495 //Handled in M2MResource, M2MObjectInstance and M2MObject classes 00496 return NULL; 00497 } 00498 00499 void *M2MBase::memory_alloc(uint32_t size) 00500 { 00501 if(size) 00502 return malloc(size); 00503 else 00504 return 0; 00505 } 00506 00507 void M2MBase::memory_free(void *ptr) 00508 { 00509 free(ptr); 00510 } 00511 00512 char* M2MBase::alloc_string_copy(const char* source) 00513 { 00514 assert(source != NULL); 00515 00516 // Note: the armcc's libc does not have strdup, so we need to implement it here 00517 const size_t len = strlen(source); 00518 00519 return (char*)alloc_string_copy((uint8_t*)source, len); 00520 } 00521 00522 uint8_t* M2MBase::alloc_string_copy(const uint8_t* source, uint32_t size) 00523 { 00524 assert(source != NULL); 00525 00526 uint8_t* result = (uint8_t*)memory_alloc(size + 1); 00527 if (result) { 00528 memcpy(result, source, size); 00529 result[size] = '\0'; 00530 } 00531 return result; 00532 } 00533 00534 uint8_t* M2MBase::alloc_copy(const uint8_t* source, uint32_t size) 00535 { 00536 assert(source != NULL); 00537 00538 uint8_t* result = (uint8_t*)memory_alloc(size); 00539 if (result) { 00540 memcpy(result, source, size); 00541 } 00542 return result; 00543 } 00544 00545 bool M2MBase::validate_string_length(const String &string, size_t min_length, size_t max_length) 00546 { 00547 bool valid = false; 00548 00549 const size_t len = string.length(); 00550 if ((len >= min_length) && (len <= max_length)) { 00551 valid = true; 00552 } 00553 00554 return valid; 00555 } 00556 00557 bool M2MBase::validate_string_length(const char* string, size_t min_length, size_t max_length) 00558 { 00559 bool valid = false; 00560 00561 if (string != NULL) { 00562 const size_t len = strlen(string); 00563 if ((len >= min_length) && (len <= max_length)) { 00564 valid = true; 00565 } 00566 } 00567 00568 return valid; 00569 } 00570 00571 M2MReportHandler* M2MBase::create_report_handler() 00572 { 00573 if (!_report_handler) { 00574 _report_handler = new M2MReportHandler(*this); 00575 } 00576 return _report_handler; 00577 } 00578 00579 M2MReportHandler* M2MBase::report_handler() 00580 { 00581 return _report_handler; 00582 } 00583 00584 M2MObservationHandler* M2MBase::observation_handler() 00585 { 00586 return _observation_handler; 00587 } 00588 00589 void M2MBase::set_register_uri(bool register_uri) 00590 { 00591 _sn_resource->dynamic_resource_params->publish_uri = register_uri; 00592 } 00593 00594 bool M2MBase::register_uri() 00595 { 00596 return _sn_resource->dynamic_resource_params->publish_uri; 00597 } 00598 00599 bool M2MBase::is_integer(const String &value) 00600 { 00601 const char *s = value.c_str(); 00602 if(value.empty() || ((!isdigit(s[0])) && (s[0] != '-') && (s[0] != '+'))) { 00603 return false; 00604 } 00605 char * p; 00606 strtol(value.c_str(), &p, 10); 00607 return (*p == 0); 00608 } 00609 00610 bool M2MBase::is_integer(const char *value) 00611 { 00612 assert(value != NULL); 00613 00614 if((strlen(value) < 1) || ((!isdigit(value[0])) && (value[0] != '-') && (value[0] != '+'))) { 00615 return false; 00616 } 00617 char * p; 00618 strtol(value, &p, 10); 00619 return (*p == 0); 00620 } 00621 00622 bool M2MBase::is_under_observation() const 00623 { 00624 return _is_under_observation; 00625 } 00626 00627 void M2MBase::set_value_updated_function(value_updated_callback callback) 00628 { 00629 delete _value_updated_callback; 00630 // XXX: create a copy of the copy of callback object. Perhaps it would better to 00631 // give a reference as parameter and just store that, as it would save some memory. 00632 _value_updated_callback = new value_updated_callback (callback); 00633 } 00634 00635 void M2MBase::set_value_updated_function(value_updated_callback2 callback) 00636 { 00637 delete _function_pointer; 00638 _function_pointer = new FP1<void, const char*> (callback); 00639 set_value_updated_function(value_updated_callback (_function_pointer, 00640 &FP1<void, const char*>::call)); 00641 } 00642 00643 bool M2MBase::is_value_updated_function_set() 00644 { 00645 return (_value_updated_callback) ? true : false; 00646 } 00647 00648 void M2MBase::execute_value_updated(const String& name) 00649 { 00650 if(_value_updated_callback) { 00651 (*_value_updated_callback)(name.c_str()); 00652 } 00653 } 00654 00655 bool M2MBase::build_path(StringBuffer<MAX_PATH_SIZE> &buffer, const char *s1, uint16_t i1, const char *s2, uint16_t i2) 00656 { 00657 00658 if(!buffer.ensure_space(strlen(s1) + strlen(s2) + (MAX_INSTANCE_SIZE * 2) + 3 + 1)){ 00659 return false; 00660 } 00661 00662 buffer.append(s1); 00663 buffer.append('/'); 00664 buffer.append_int(i1); 00665 buffer.append('/'); 00666 buffer.append(s2); 00667 buffer.append('/'); 00668 buffer.append_int(i2); 00669 00670 return true; 00671 00672 } 00673 00674 bool M2MBase::build_path(StringBuffer<MAX_PATH_SIZE_2> &buffer, const char *s1, uint16_t i1, const char *s2) 00675 { 00676 if(!buffer.ensure_space(strlen(s1) + strlen(s2) + MAX_INSTANCE_SIZE + 2 + 1)){ 00677 return false; 00678 } 00679 00680 buffer.append(s1); 00681 buffer.append('/'); 00682 buffer.append_int(i1); 00683 buffer.append('/'); 00684 buffer.append(s2); 00685 00686 return true; 00687 } 00688 00689 bool M2MBase::build_path(StringBuffer<MAX_PATH_SIZE_3> &buffer, const char *s1, uint16_t i1, uint16_t i2) 00690 { 00691 if(!buffer.ensure_space(strlen(s1) + (MAX_INSTANCE_SIZE * 2) + 2 + 1)){ 00692 return false; 00693 } 00694 00695 buffer.append(s1); 00696 buffer.append('/'); 00697 buffer.append_int(i1); 00698 buffer.append('/'); 00699 buffer.append_int(i2); 00700 00701 return true; 00702 } 00703 00704 bool M2MBase::build_path(StringBuffer<MAX_PATH_SIZE_4> &buffer, const char *s1, uint16_t i1) 00705 { 00706 if(!buffer.ensure_space(strlen(s1) + MAX_INSTANCE_SIZE + 1 + 1)){ 00707 return false; 00708 } 00709 00710 buffer.append(s1); 00711 buffer.append('/'); 00712 buffer.append_int(i1); 00713 00714 return true; 00715 } 00716 00717 char* M2MBase::stringdup(const char* src) 00718 { 00719 assert(src != NULL); 00720 00721 const size_t len = strlen(src) + 1; 00722 00723 char *dest = (char*)malloc(len); 00724 00725 if (dest) { 00726 memcpy(dest, src, len); 00727 } 00728 return dest; 00729 } 00730 00731 void M2MBase::free_resources() 00732 { 00733 // remove the nsdl structures from the nsdlinterface's lists. 00734 if (_observation_handler) { 00735 _observation_handler->resource_to_be_deleted(this); 00736 } 00737 00738 if (_sn_resource->dynamic_resource_params->static_resource_parameters->free_on_delete) { 00739 sn_nsdl_static_resource_parameters_s *params = 00740 const_cast<sn_nsdl_static_resource_parameters_s *>(_sn_resource->dynamic_resource_params->static_resource_parameters); 00741 00742 free(params->path); 00743 free(params->resource); 00744 free(params->resource_type_ptr); 00745 free(params->interface_description_ptr); 00746 free(params); 00747 } 00748 if (_sn_resource->dynamic_resource_params->free_on_delete) { 00749 free(_sn_resource->dynamic_resource_params); 00750 } 00751 00752 if (_sn_resource->free_on_delete) { 00753 free(_sn_resource->name); 00754 free(_sn_resource); 00755 } 00756 } 00757 00758 size_t M2MBase::resource_name_length() const 00759 { 00760 return strlen(_sn_resource->name); 00761 } 00762 00763 sn_nsdl_dynamic_resource_parameters_s* M2MBase::get_nsdl_resource() 00764 { 00765 return _sn_resource->dynamic_resource_params; 00766 }
Generated on Tue Jul 12 2022 21:20:26 by
1.7.2