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.
Dependencies: MAX44000 PWM_Tone_Library nexpaq_mdk
Fork of LED_Demo by
m2mnsdlinterface.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 // Note: this macro is needed on armcc to get the the PRI*32 macros 00018 // from inttypes.h in a C++ code. 00019 #ifndef __STDC_FORMAT_MACROS 00020 #define __STDC_FORMAT_MACROS 00021 #endif 00022 00023 // Note: this macro is needed on armcc to get the the limit macros like UINT16_MAX 00024 #ifndef __STDC_LIMIT_MACROS 00025 #define __STDC_LIMIT_MACROS 00026 #endif 00027 00028 00029 #include "include/nsdlaccesshelper.h" 00030 #include "include/m2mnsdlobserver.h" 00031 #include "include/m2mtlvdeserializer.h" 00032 #include "include/m2mtlvserializer.h" 00033 #include "include/m2mnsdlinterface.h" 00034 #include "mbed-client/m2mstring.h" 00035 #include "mbed-client/m2msecurity.h" 00036 #include "mbed-client/m2mserver.h" 00037 #include "mbed-client/m2mobject.h" 00038 #include "mbed-client/m2mobjectinstance.h" 00039 #include "mbed-client/m2mresource.h" 00040 #include "mbed-client/m2mconstants.h" 00041 #include "mbed-trace/mbed_trace.h" 00042 #include "mbed-client/m2mtimer.h" 00043 #include "source/libNsdl/src/include/sn_grs.h" 00044 00045 #include <assert.h> 00046 #include <inttypes.h> 00047 00048 #define BUFFER_SIZE 21 00049 #define TRACE_GROUP "mClt" 00050 00051 M2MNsdlInterface::M2MNsdlInterface(M2MNsdlObserver &observer) 00052 : _observer(observer), 00053 _server(NULL), 00054 _security(NULL), 00055 _nsdl_exceution_timer(new M2MTimer(*this)), 00056 _registration_timer(new M2MTimer(*this)), 00057 _endpoint(NULL), 00058 _resource(NULL), 00059 _nsdl_handle(NULL), 00060 _counter_for_nsdl(0), 00061 _bootstrap_id(0), 00062 _register_ongoing(false), 00063 _unregister_ongoing(false), 00064 _update_register_ongoing(false) 00065 { 00066 tr_debug("M2MNsdlInterface::M2MNsdlInterface()"); 00067 __nsdl_interface_list.push_back(this); 00068 _sn_nsdl_address.addr_len = 0; 00069 _sn_nsdl_address.addr_ptr = NULL; 00070 _sn_nsdl_address.port = 0; 00071 00072 // This initializes libCoap and libNsdl 00073 // Parameters are function pointers to used memory allocation 00074 // and free functions in structure and used functions for sending 00075 // and receiving purposes. 00076 _nsdl_handle = sn_nsdl_init(&(__nsdl_c_send_to_server), &(__nsdl_c_received_from_server), 00077 &(__nsdl_c_memory_alloc), &(__nsdl_c_memory_free)); 00078 00079 00080 _server = new M2MServer(); 00081 initialize(); 00082 } 00083 00084 M2MNsdlInterface::~M2MNsdlInterface() 00085 { 00086 tr_debug("M2MNsdlInterface::~M2MNsdlInterface() - IN"); 00087 if(_resource) { 00088 memory_free(_resource->resource_parameters_ptr); 00089 memory_free(_resource); 00090 } 00091 if(_endpoint) { 00092 memory_free(_endpoint->endpoint_name_ptr); 00093 memory_free(_endpoint->lifetime_ptr); 00094 memory_free(_endpoint->location_ptr); 00095 memory_free(_endpoint); 00096 } 00097 delete _nsdl_exceution_timer; 00098 delete _registration_timer; 00099 _object_list.clear(); 00100 delete _server; 00101 _security = NULL; 00102 00103 sn_nsdl_destroy(_nsdl_handle); 00104 _nsdl_handle = NULL; 00105 00106 M2MNsdlInterfaceList::const_iterator it; 00107 it = __nsdl_interface_list.begin(); 00108 int index = 0; 00109 for (; it!=__nsdl_interface_list.end(); it++) { 00110 if ((*it) == this) { 00111 __nsdl_interface_list.erase(index); 00112 break; 00113 } 00114 index++; 00115 } 00116 tr_debug("M2MNsdlInterface::~M2MNsdlInterface() - OUT"); 00117 } 00118 00119 bool M2MNsdlInterface::initialize() 00120 { 00121 tr_debug("M2MNsdlInterface::initialize()"); 00122 bool success = false; 00123 00124 //Sets the packet retransmission attempts and time interval 00125 sn_nsdl_set_retransmission_parameters(_nsdl_handle, 00126 MBED_CLIENT_RECONNECTION_COUNT, 00127 MBED_CLIENT_RECONNECTION_INTERVAL); 00128 00129 // We want to parse and handle bootstrap messages 00130 if (_nsdl_handle) { 00131 _nsdl_handle->handle_bootstrap_msg = false; 00132 } 00133 00134 // Allocate the memory for resources 00135 _resource = (sn_nsdl_resource_info_s*)memory_alloc(sizeof(sn_nsdl_resource_info_s)); 00136 if(_resource) { 00137 memset(_resource, 0, sizeof(sn_nsdl_resource_info_s)); 00138 _resource->resource_parameters_ptr = (sn_nsdl_resource_parameters_s*)memory_alloc(sizeof(sn_nsdl_resource_parameters_s)); 00139 if(_resource->resource_parameters_ptr) { 00140 memset(_resource->resource_parameters_ptr, 0, sizeof(sn_nsdl_resource_parameters_s)); 00141 } 00142 } 00143 00144 //Allocate the memory for endpoint 00145 _endpoint = (sn_nsdl_ep_parameters_s*)memory_alloc(sizeof(sn_nsdl_ep_parameters_s)); 00146 if(_endpoint) { 00147 memset(_endpoint, 0, sizeof(sn_nsdl_ep_parameters_s)); 00148 success = true; 00149 } 00150 return success; 00151 } 00152 00153 void M2MNsdlInterface::create_endpoint(const String &name, 00154 const String &type, 00155 const int32_t life_time, 00156 const String &domain, 00157 const uint8_t mode, 00158 const String &/*context_address*/) 00159 { 00160 tr_debug("M2MNsdlInterface::create_endpoint( name %s type %s lifetime %" PRId32 ", domain %s, mode %d)", 00161 name.c_str(), type.c_str(), life_time, domain.c_str(), mode); 00162 _endpoint_name = name; 00163 if(_endpoint){ 00164 memset(_endpoint, 0, sizeof(sn_nsdl_ep_parameters_s)); 00165 if(!_endpoint_name.empty()) { 00166 memory_free(_endpoint->endpoint_name_ptr); 00167 _endpoint->endpoint_name_ptr = alloc_string_copy((uint8_t*)_endpoint_name.c_str(), _endpoint_name.length()); 00168 _endpoint->endpoint_name_len = _endpoint_name.length(); 00169 } 00170 if(!type.empty()) { 00171 _endpoint->type_ptr = (uint8_t*)type.c_str(); 00172 _endpoint->type_len = type.length(); 00173 } 00174 if(!domain.empty()) { 00175 _endpoint->domain_name_ptr = (uint8_t*)domain.c_str(); 00176 _endpoint->domain_name_len = domain.length(); 00177 } 00178 _endpoint->binding_and_mode = (sn_nsdl_oma_binding_and_mode_t)mode; 00179 00180 // If lifetime is less than zero then leave the field empty 00181 if( life_time > 0) { 00182 set_endpoint_lifetime_buffer(life_time); 00183 } 00184 } 00185 } 00186 00187 void M2MNsdlInterface::set_endpoint_lifetime_buffer(int lifetime) 00188 { 00189 // max len of "-9223372036854775808" plus zero termination 00190 char buffer[20+1]; 00191 00192 uint32_t size = m2m::itoa_c(lifetime, buffer); 00193 00194 if (size <= sizeof(buffer)) { 00195 _endpoint->lifetime_ptr = alloc_string_copy((uint8_t*)buffer, size); 00196 if(_endpoint->lifetime_ptr) { 00197 _endpoint->lifetime_len = size; 00198 } else { 00199 _endpoint->lifetime_len = 0; 00200 } 00201 } 00202 } 00203 00204 00205 void M2MNsdlInterface::delete_endpoint() 00206 { 00207 tr_debug("M2MNsdlInterface::delete_endpoint()"); 00208 if(_endpoint) { 00209 free(_endpoint->lifetime_ptr); 00210 00211 memory_free(_endpoint); 00212 _endpoint = NULL; 00213 } 00214 } 00215 00216 bool M2MNsdlInterface::create_nsdl_list_structure(const M2MObjectList &object_list) 00217 { 00218 tr_debug("M2MNsdlInterface::create_nsdl_list_structure()"); 00219 bool success = false; 00220 if(!object_list.empty()) { 00221 tr_debug("M2MNsdlInterface::create_nsdl_list_structure - Object count is %d", object_list.size()); 00222 M2MObjectList::const_iterator it; 00223 it = object_list.begin(); 00224 for ( ; it != object_list.end(); it++ ) { 00225 // Create NSDL structure for all Objects inside 00226 success = create_nsdl_object_structure(*it); 00227 add_object_to_list(*it); 00228 } 00229 } 00230 return success; 00231 } 00232 00233 bool M2MNsdlInterface::delete_nsdl_resource(const String &resource_name) 00234 { 00235 tr_debug("M2MNsdlInterface::delete_nsdl_resource( %s)", resource_name.c_str()); 00236 return (sn_nsdl_delete_resource(_nsdl_handle, 00237 resource_name.length(), 00238 (uint8_t *)resource_name.c_str()) == 0) ? true : false; 00239 } 00240 00241 00242 bool M2MNsdlInterface::create_bootstrap_resource(sn_nsdl_addr_s *address, const String &bootstrap_endpoint_name) 00243 { 00244 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00245 tr_debug("M2MNsdlInterface::create_bootstrap_resource()"); 00246 bool success = false; 00247 sn_nsdl_bs_ep_info_t bootstrap_endpoint; 00248 tr_debug("M2MNsdlInterface::create_bootstrap_resource() - endpoint name: %s", bootstrap_endpoint_name.c_str()); 00249 if (_endpoint->endpoint_name_ptr) { 00250 memory_free(_endpoint->endpoint_name_ptr); 00251 } 00252 //_endpoint->endpoint_name_ptr = (uint8_t*)bootstrap_endpoint_name.c_str(); 00253 _endpoint->endpoint_name_ptr = alloc_string_copy((uint8_t*)bootstrap_endpoint_name.c_str(), bootstrap_endpoint_name.length()); 00254 _endpoint->endpoint_name_len = bootstrap_endpoint_name.length(); 00255 if(_bootstrap_id == 0) { 00256 _bootstrap_id = sn_nsdl_oma_bootstrap(_nsdl_handle, 00257 address, 00258 _endpoint, 00259 &bootstrap_endpoint); 00260 tr_debug("M2MNsdlInterface::create_bootstrap_resource - _bootstrap_id %d", _bootstrap_id); 00261 success = _bootstrap_id != 0; 00262 00263 } 00264 return success; 00265 #else 00266 (void)address; 00267 (void)bootstrap_endpoint_name; 00268 return false; 00269 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00270 } 00271 00272 bool M2MNsdlInterface::send_register_message(uint8_t* address, 00273 const uint16_t port, 00274 sn_nsdl_addr_type_e address_type) 00275 { 00276 tr_debug("M2MNsdlInterface::send_register_message()"); 00277 _nsdl_exceution_timer->stop_timer(); 00278 _nsdl_exceution_timer->start_timer(ONE_SECOND_TIMER * 1000, 00279 M2MTimerObserver::NsdlExecution, 00280 false); 00281 bool success = false; 00282 if(set_NSP_address(_nsdl_handle,address, port, address_type) == 0) { 00283 if(!_register_ongoing) { 00284 _register_ongoing = true; 00285 success = sn_nsdl_register_endpoint(_nsdl_handle,_endpoint) != 0; 00286 } 00287 } 00288 return success; 00289 } 00290 00291 bool M2MNsdlInterface::send_update_registration(const uint32_t lifetime) 00292 { 00293 if (_update_register_ongoing) { 00294 tr_debug("M2MNsdlInterface::send_update_registration - update already in progress"); 00295 return true; 00296 } 00297 tr_debug("M2MNsdlInterface::send_update_registration( lifetime %" PRIu32 ")", lifetime); 00298 bool success = false; 00299 00300 create_nsdl_list_structure(_object_list); 00301 //If Lifetime value is 0, then don't change the existing lifetime value 00302 if(lifetime != 0) { 00303 if(_endpoint->lifetime_ptr) { 00304 memory_free(_endpoint->lifetime_ptr); 00305 _endpoint->lifetime_ptr = NULL; 00306 _endpoint->lifetime_len = 0; 00307 } 00308 set_endpoint_lifetime_buffer(lifetime); 00309 00310 _registration_timer->stop_timer(); 00311 _registration_timer->start_timer(registration_time() * 1000, 00312 M2MTimerObserver::Registration, 00313 false); 00314 if(_nsdl_handle && 00315 _endpoint && _endpoint->lifetime_ptr) { 00316 tr_debug("M2MNsdlInterface::send_update_registration - new lifetime value"); 00317 _update_register_ongoing = true; 00318 success = sn_nsdl_update_registration(_nsdl_handle, 00319 _endpoint->lifetime_ptr, 00320 _endpoint->lifetime_len) != 0; 00321 } 00322 } else { 00323 if(_nsdl_handle) { 00324 tr_debug("M2MNsdlInterface::send_update_registration - regular update"); 00325 _update_register_ongoing = true; 00326 success = sn_nsdl_update_registration(_nsdl_handle, NULL, 0) != 0; 00327 } 00328 } 00329 return success; 00330 } 00331 00332 bool M2MNsdlInterface::send_unregister_message() 00333 { 00334 tr_debug("M2MNsdlInterface::send_unregister_message"); 00335 if (_unregister_ongoing) { 00336 tr_debug("M2MNsdlInterface::send_unregister_message - unregistration already in progress"); 00337 return true; 00338 } 00339 00340 bool success = false; 00341 _unregister_ongoing = true; 00342 success = sn_nsdl_unregister_endpoint(_nsdl_handle) != 0; 00343 return success; 00344 } 00345 00346 // XXX: move these to common place, no need to copy these wrappers to multiple places: 00347 void *M2MNsdlInterface::memory_alloc(uint16_t size) 00348 { 00349 if(size) 00350 return malloc(size); 00351 else 00352 return 0; 00353 } 00354 00355 void M2MNsdlInterface::memory_free(void *ptr) 00356 { 00357 if(ptr) 00358 free(ptr); 00359 } 00360 00361 uint8_t* M2MNsdlInterface::alloc_string_copy(const uint8_t* source, uint16_t size) 00362 { 00363 assert(source != NULL); 00364 00365 uint8_t* result = (uint8_t*)memory_alloc(size + 1); 00366 if (result) { 00367 memcpy(result, source, size); 00368 result[size] = '\0'; 00369 } 00370 return result; 00371 } 00372 00373 uint8_t M2MNsdlInterface::send_to_server_callback(struct nsdl_s * /*nsdl_handle*/, 00374 sn_nsdl_capab_e /*protocol*/, 00375 uint8_t *data_ptr, 00376 uint16_t data_len, 00377 sn_nsdl_addr_s *address) 00378 { 00379 tr_debug("M2MNsdlInterface::send_to_server_callback()"); 00380 _observer.coap_message_ready(data_ptr,data_len,address); 00381 return 1; 00382 } 00383 00384 uint8_t M2MNsdlInterface::received_from_server_callback(struct nsdl_s * nsdl_handle, 00385 sn_coap_hdr_s *coap_header, 00386 sn_nsdl_addr_s *address) 00387 { 00388 tr_debug("M2MNsdlInterface::received_from_server_callback - msg id:%" PRIu16, coap_header->msg_id); 00389 tr_debug("M2MNsdlInterface::received_from_server_callback - registration id:%" PRIu16, nsdl_handle->register_msg_id); 00390 tr_debug("M2MNsdlInterface::received_from_server_callback - unregistration id:%" PRIu16, nsdl_handle->unregister_msg_id); 00391 tr_debug("M2MNsdlInterface::received_from_server_callback - update registration id:%" PRIu16, nsdl_handle->update_register_msg_id); 00392 _observer.coap_data_processed(); 00393 uint8_t value = 0; 00394 if(nsdl_handle && coap_header) { 00395 bool is_bootstrap_msg = address && (nsdl_handle->oma_bs_address_len == address->addr_len) && 00396 (nsdl_handle->oma_bs_port == address->port) && 00397 !memcmp(nsdl_handle->oma_bs_address_ptr, address->addr_ptr, nsdl_handle->oma_bs_address_len); 00398 if(coap_header->msg_id == nsdl_handle->register_msg_id) { 00399 _register_ongoing = false; 00400 if(coap_header->msg_code == COAP_MSG_CODE_RESPONSE_CREATED) { 00401 tr_debug("M2MNsdlInterface::received_from_server_callback - registration callback"); 00402 _observer.client_registered(_server); 00403 // If lifetime is less than zero then leave the field empty 00404 if(coap_header->options_list_ptr) { 00405 if(coap_header->options_list_ptr->max_age_ptr) { 00406 memory_free(_endpoint->lifetime_ptr); 00407 _endpoint->lifetime_ptr = NULL; 00408 _endpoint->lifetime_len = 0; 00409 00410 uint32_t max_time = 0; 00411 for(int i=0;i < coap_header->options_list_ptr->max_age_len; i++) { 00412 max_time += (*(coap_header->options_list_ptr->max_age_ptr + i) & 0xff) << 00413 8*(coap_header->options_list_ptr->max_age_len- 1 - i); 00414 } 00415 // If lifetime is less than zero then leave the field empty 00416 if( max_time > 0) { 00417 set_endpoint_lifetime_buffer(max_time); 00418 } 00419 } 00420 if(coap_header->options_list_ptr->location_path_ptr) { 00421 00422 memory_free(_endpoint->location_ptr); 00423 00424 _endpoint->location_ptr = alloc_string_copy(coap_header->options_list_ptr->location_path_ptr, coap_header->options_list_ptr->location_path_len); 00425 if (_endpoint->location_ptr != NULL) { 00426 _endpoint->location_len = coap_header->options_list_ptr->location_path_len; 00427 } 00428 sn_nsdl_set_endpoint_location(_nsdl_handle,_endpoint->location_ptr,_endpoint->location_len); 00429 } 00430 } 00431 if(_endpoint->lifetime_ptr) { 00432 _registration_timer->stop_timer(); 00433 _registration_timer->start_timer(registration_time() * 1000, 00434 M2MTimerObserver::Registration, 00435 false); 00436 } 00437 } else { 00438 tr_error("M2MNsdlInterface::received_from_server_callback - registration error %d", coap_header->msg_code); 00439 // Try to do clean register again 00440 if(COAP_MSG_CODE_RESPONSE_BAD_REQUEST == coap_header->msg_code || 00441 COAP_MSG_CODE_RESPONSE_FORBIDDEN == coap_header->msg_code) { 00442 _observer.registration_error(M2MInterface::InvalidParameters, false); 00443 } else { 00444 _observer.registration_error(M2MInterface::NetworkError, true); 00445 } 00446 00447 } 00448 } else if(coap_header->msg_id == nsdl_handle->unregister_msg_id) { 00449 _unregister_ongoing = false; 00450 tr_debug("M2MNsdlInterface::received_from_server_callback - unregistration callback"); 00451 if(coap_header->msg_code == COAP_MSG_CODE_RESPONSE_DELETED) { 00452 _registration_timer->stop_timer(); 00453 _observer.client_unregistered(); 00454 } else { 00455 tr_error("M2MNsdlInterface::received_from_server_callback - unregistration error %d", coap_header->msg_code); 00456 M2MInterface::Error error = interface_error(coap_header); 00457 _observer.registration_error(error); 00458 } 00459 } else if(coap_header->msg_id == nsdl_handle->update_register_msg_id) { 00460 _update_register_ongoing = false; 00461 if(coap_header->msg_code == COAP_MSG_CODE_RESPONSE_CHANGED) { 00462 tr_debug("M2MNsdlInterface::received_from_server_callback - registration_updated successfully"); 00463 _observer.registration_updated(*_server); 00464 } else { 00465 tr_error("M2MNsdlInterface::received_from_server_callback - registration_updated failed %d", coap_header->msg_code); 00466 _registration_timer->stop_timer(); 00467 _register_ongoing = true; 00468 sn_nsdl_register_endpoint(_nsdl_handle,_endpoint); 00469 } 00470 } 00471 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00472 else if(coap_header->msg_id == nsdl_handle->bootstrap_msg_id) { 00473 tr_debug("M2MNsdlInterface::received_from_server_callback - bootstrap"); 00474 _bootstrap_id = 0; 00475 M2MInterface::Error error = interface_error(coap_header); 00476 if(error != M2MInterface::ErrorNone) { 00477 handle_bootstrap_error(); 00478 } 00479 } 00480 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00481 else { 00482 if(COAP_MSG_CODE_REQUEST_PUT == coap_header->msg_code) { 00483 if (is_bootstrap_msg) { 00484 handle_bootstrap_put_message(coap_header, address); 00485 } 00486 } 00487 else if(COAP_MSG_CODE_REQUEST_DELETE == coap_header->msg_code) { 00488 if (is_bootstrap_msg) { 00489 handle_bootstrap_delete(coap_header, address); 00490 } 00491 } 00492 else if(COAP_MSG_CODE_REQUEST_POST == coap_header->msg_code) { 00493 if(is_bootstrap_msg) { 00494 handle_bootstrap_finished(coap_header, address); 00495 } 00496 else if(coap_header->uri_path_ptr) { 00497 sn_coap_hdr_s *coap_response = NULL; 00498 bool execute_value_updated = false; 00499 M2MObjectInstance *obj_instance = NULL; 00500 String resource_name = coap_to_string(coap_header->uri_path_ptr, 00501 coap_header->uri_path_len); 00502 00503 String object_name; 00504 int slash_found = resource_name.find_last_of('/'); 00505 //The POST operation here is only allowed for non-existing object instances 00506 if(slash_found != -1) { 00507 object_name = resource_name.substr(0,slash_found); 00508 if( object_name.find_last_of('/') != -1){ 00509 coap_response = sn_nsdl_build_response(_nsdl_handle, 00510 coap_header, 00511 COAP_MSG_CODE_RESPONSE_NOT_FOUND); 00512 } else { 00513 int32_t instance_id = atoi(resource_name.substr(slash_found+1, 00514 resource_name.size()-object_name.size()).c_str()); 00515 M2MBase* base = find_resource(object_name); 00516 if(base && (instance_id >= 0) && (instance_id < UINT16_MAX)) { 00517 if(coap_header->payload_ptr) { 00518 M2MObject* object = static_cast<M2MObject*> (base); 00519 obj_instance = object->create_object_instance(instance_id); 00520 if(obj_instance) { 00521 obj_instance->set_operation(M2MBase::GET_PUT_POST_ALLOWED); 00522 coap_response = obj_instance->handle_post_request(_nsdl_handle, 00523 coap_header, 00524 this, 00525 execute_value_updated); 00526 } 00527 if(coap_response && coap_response->msg_code != COAP_MSG_CODE_RESPONSE_CREATED) { 00528 //Invalid request so remove created ObjectInstance 00529 object->remove_object_instance(instance_id); 00530 } else { 00531 tr_debug("M2MNsdlInterface::received_from_server_callback - Send Update registration for Create"); 00532 send_update_registration(); 00533 } 00534 } else { 00535 tr_debug("M2MNsdlInterface::received_from_server_callback - Missing Payload - Cannot create"); 00536 coap_response = sn_nsdl_build_response(_nsdl_handle, 00537 coap_header, 00538 COAP_MSG_CODE_RESPONSE_BAD_REQUEST); 00539 } 00540 } else { //if(base) 00541 tr_debug("M2MNsdlInterface::received_from_server_callback - Missing BASE - Cannot create"); 00542 coap_response = sn_nsdl_build_response(_nsdl_handle, 00543 coap_header, 00544 COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED); 00545 } 00546 } 00547 } else{ // if(slash_found != -1) 00548 tr_debug("M2MNsdlInterface::received_from_server_callback - slash_found - Cannot create"); 00549 coap_response = sn_nsdl_build_response(_nsdl_handle, 00550 coap_header, 00551 COAP_MSG_CODE_RESPONSE_NOT_FOUND); 00552 } 00553 if(coap_response) { 00554 tr_debug("M2MNsdlInterface::received_from_server_callback - send CoAP response"); 00555 (sn_nsdl_send_coap_message(_nsdl_handle, address, coap_response) == 0) ? value = 0 : value = 1; 00556 sn_nsdl_release_allocated_coap_msg_mem(_nsdl_handle, coap_response); 00557 } 00558 if (execute_value_updated) { 00559 value_updated(obj_instance, obj_instance->name()); 00560 } 00561 } 00562 } 00563 } 00564 } 00565 return value; 00566 } 00567 00568 uint8_t M2MNsdlInterface::resource_callback(struct nsdl_s */*nsdl_handle*/, 00569 sn_coap_hdr_s *received_coap_header, 00570 sn_nsdl_addr_s *address, 00571 sn_nsdl_capab_e /*nsdl_capab*/) 00572 { 00573 tr_debug("M2MNsdlInterface::resource_callback()"); 00574 _observer.coap_data_processed(); 00575 uint8_t result = 1; 00576 sn_coap_hdr_s *coap_response = NULL; 00577 sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; // 4.00 00578 String resource_name = coap_to_string(received_coap_header->uri_path_ptr, 00579 received_coap_header->uri_path_len); 00580 tr_debug("M2MNsdlInterface::resource_callback() - resource_name %s", resource_name.c_str()); 00581 bool execute_value_updated = false; 00582 M2MBase* base = find_resource(resource_name); 00583 if(base) { 00584 base->set_uri_path(resource_name); 00585 if(COAP_MSG_CODE_REQUEST_GET == received_coap_header->msg_code) { 00586 coap_response = base->handle_get_request(_nsdl_handle, received_coap_header,this); 00587 } else if(COAP_MSG_CODE_REQUEST_PUT == received_coap_header->msg_code) { 00588 coap_response = base->handle_put_request(_nsdl_handle, received_coap_header, this, execute_value_updated); 00589 } else if(COAP_MSG_CODE_REQUEST_POST == received_coap_header->msg_code) { 00590 if(base->base_type() == M2MBase::ResourceInstance) { 00591 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; 00592 } else { 00593 coap_response = base->handle_post_request(_nsdl_handle, received_coap_header,this, execute_value_updated); 00594 } 00595 } else if(COAP_MSG_CODE_REQUEST_DELETE == received_coap_header->msg_code) { 00596 // Delete the object instance 00597 tr_debug("M2MNsdlInterface::resource_callback() - DELETE the object instance"); 00598 M2MBase::BaseType type = base->base_type(); 00599 if(M2MBase::ObjectInstance == type) { 00600 M2MBase* base_object = find_resource(base->name()); 00601 if(base_object) { 00602 M2MObject *object = static_cast<M2MObject*> (base_object); 00603 int slash_found = resource_name.find_last_of('/'); 00604 // Object instance validty checks done in upper level, no need for error handling 00605 if(slash_found != -1) { 00606 String object_name; 00607 object_name = resource_name.substr(slash_found + 1, resource_name.length()); 00608 if (object->remove_object_instance(strtoul( 00609 object_name.c_str(), 00610 NULL, 00611 10))) { 00612 msg_code = COAP_MSG_CODE_RESPONSE_DELETED; 00613 } 00614 } 00615 } 00616 } else { 00617 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; // 4.00 00618 } 00619 } else if(COAP_MSG_TYPE_RESET == received_coap_header->msg_type) { 00620 // Cancel ongoing observation 00621 tr_error("M2MNsdlInterface::resource_callback() - RESET message"); 00622 M2MBase::BaseType type = base->base_type(); 00623 switch (type) { 00624 case M2MBase::Object: 00625 base->remove_observation_level(M2MBase::O_Attribute); 00626 break; 00627 case M2MBase::Resource: 00628 base->remove_observation_level(M2MBase::R_Attribute); 00629 break; 00630 case M2MBase::ObjectInstance: 00631 base->remove_observation_level(M2MBase::OI_Attribute); 00632 break; 00633 default: 00634 break; 00635 } 00636 base->set_under_observation(false, this); 00637 } 00638 } else { 00639 tr_debug("M2MNsdlInterface::resource_callback() - Resource NOT FOUND"); 00640 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; // 4.00 00641 } 00642 if(!coap_response) { 00643 coap_response = sn_nsdl_build_response(_nsdl_handle, 00644 received_coap_header, 00645 msg_code); 00646 } 00647 00648 if(coap_response) { 00649 tr_debug("M2MNsdlInterface::resource_callback() - send CoAP response"); 00650 (sn_nsdl_send_coap_message(_nsdl_handle, address, coap_response) == 0) ? result = 0 : result = 1; 00651 if(coap_response->payload_ptr) { 00652 free(coap_response->payload_ptr); 00653 coap_response->payload_ptr = NULL; 00654 } 00655 sn_nsdl_release_allocated_coap_msg_mem(_nsdl_handle, coap_response); 00656 } 00657 if (execute_value_updated) { 00658 value_updated(base,base->uri_path()); 00659 } 00660 00661 return result; 00662 } 00663 00664 bool M2MNsdlInterface::process_received_data(uint8_t *data, 00665 uint16_t data_size, 00666 sn_nsdl_addr_s *address) 00667 { 00668 tr_debug("M2MNsdlInterface::process_received_data( data size %d)", data_size); 00669 return (0 == sn_nsdl_process_coap(_nsdl_handle, 00670 data, 00671 data_size, 00672 address)) ? true : false; 00673 } 00674 00675 void M2MNsdlInterface::stop_timers() 00676 { 00677 tr_debug("M2MNsdlInterface::stop_timers()"); 00678 if(_registration_timer) { 00679 _registration_timer->stop_timer(); 00680 } 00681 if (_nsdl_exceution_timer) { 00682 _nsdl_exceution_timer->stop_timer(); 00683 } 00684 _bootstrap_id = 0; 00685 _register_ongoing = false; 00686 _unregister_ongoing = false; 00687 _update_register_ongoing = false; 00688 } 00689 00690 void M2MNsdlInterface::timer_expired(M2MTimerObserver::Type type) 00691 { 00692 if(M2MTimerObserver::NsdlExecution == type) { 00693 sn_nsdl_exec(_nsdl_handle, _counter_for_nsdl); 00694 _counter_for_nsdl++; 00695 } else if(M2MTimerObserver::Registration == type) { 00696 tr_debug("M2MNsdlInterface::timer_expired - M2MTimerObserver::Registration - Send update registration"); 00697 send_update_registration(); 00698 } 00699 } 00700 00701 void M2MNsdlInterface::observation_to_be_sent(M2MBase *object, 00702 uint16_t obs_number, 00703 m2m::Vector<uint16_t> changed_instance_ids, 00704 bool send_object) 00705 { 00706 __mutex_claim(); 00707 tr_debug("M2MNsdlInterface::observation_to_be_sent(), %s", object->uri_path().c_str()); 00708 if(object) { 00709 M2MBase::BaseType type = object->base_type(); 00710 if(type == M2MBase::Object) { 00711 send_object_observation(static_cast<M2MObject*> (object), 00712 obs_number, 00713 changed_instance_ids, 00714 send_object); 00715 } else if(type == M2MBase::ObjectInstance) { 00716 send_object_instance_observation(static_cast<M2MObjectInstance*> (object), obs_number); 00717 } else if(type == M2MBase::Resource) { 00718 send_resource_observation(static_cast<M2MResource*> (object), obs_number); 00719 } 00720 } 00721 __mutex_release(); 00722 } 00723 00724 void M2MNsdlInterface::send_delayed_response(M2MBase *base) 00725 { 00726 __mutex_claim(); 00727 tr_debug("M2MNsdlInterface::send_delayed_response()"); 00728 M2MResource *resource = NULL; 00729 if(base) { 00730 if(M2MBase::Resource == base->base_type()) { 00731 resource = static_cast<M2MResource *> (base); 00732 } 00733 if(resource) { 00734 sn_coap_hdr_s * coap_response = static_cast<sn_coap_hdr_s *>(malloc(sizeof(sn_coap_hdr_s))); 00735 if(coap_response) { 00736 memset(coap_response,0,sizeof(sn_coap_hdr_s)); 00737 00738 coap_response->msg_type = COAP_MSG_TYPE_CONFIRMABLE; 00739 coap_response->msg_code = COAP_MSG_CODE_RESPONSE_CONTENT; 00740 resource->get_delayed_token(coap_response->token_ptr,coap_response->token_len); 00741 00742 uint32_t length = 0; 00743 resource->get_value(coap_response->payload_ptr, length); 00744 coap_response->payload_len = length; 00745 00746 sn_nsdl_send_coap_message(_nsdl_handle, _nsdl_handle->nsp_address_ptr->omalw_address_ptr, coap_response); 00747 00748 if(coap_response->payload_ptr) { 00749 free(coap_response->payload_ptr); 00750 coap_response->payload_ptr = NULL; 00751 } 00752 if(coap_response->token_ptr) { 00753 free(coap_response->token_ptr); 00754 coap_response->token_ptr = NULL; 00755 } 00756 free(coap_response); 00757 } 00758 } 00759 } 00760 __mutex_release(); 00761 } 00762 00763 void M2MNsdlInterface::resource_to_be_deleted(const String &resource_name) 00764 { 00765 __mutex_claim(); 00766 tr_debug("M2MNsdlInterface::resource_to_be_deleted(resource_name %s)", resource_name.c_str()); 00767 delete_nsdl_resource(resource_name); 00768 __mutex_release(); 00769 } 00770 00771 void M2MNsdlInterface::value_updated(M2MBase *base, 00772 const String &object_name) 00773 { 00774 tr_debug("M2MNsdlInterface::value_updated()"); 00775 if(base) { 00776 switch(base->base_type()) { 00777 case M2MBase::Object: 00778 create_nsdl_object_structure(static_cast<M2MObject*> (base)); 00779 break; 00780 case M2MBase::ObjectInstance: 00781 create_nsdl_object_instance_structure(static_cast<M2MObjectInstance*> (base)); 00782 break; 00783 case M2MBase::Resource: { 00784 M2MResource* resource = static_cast<M2MResource*> (base); 00785 create_nsdl_resource_structure(resource,object_name, 00786 resource->supports_multiple_instances()); 00787 } 00788 break; 00789 case M2MBase::ResourceInstance: { 00790 M2MResourceInstance* instance = static_cast<M2MResourceInstance*> (base); 00791 create_nsdl_resource(instance,object_name); 00792 } 00793 break; 00794 } 00795 } 00796 00797 if (base->is_value_updated_function_set()) { 00798 base->execute_value_updated(base->name()); 00799 } 00800 else { 00801 _observer.value_updated(base); 00802 } 00803 } 00804 00805 void M2MNsdlInterface::remove_object(M2MBase *object) 00806 { 00807 __mutex_claim(); 00808 tr_debug("M2MNsdlInterface::remove_object()"); 00809 M2MObject* rem_object = static_cast<M2MObject*> (object); 00810 if(rem_object && !_object_list.empty()) { 00811 M2MObjectList::const_iterator it; 00812 it = _object_list.begin(); 00813 int index = 0; 00814 for ( ; it != _object_list.end(); it++, index++ ) { 00815 if((*it) == rem_object) { 00816 _object_list.erase(index); 00817 break; 00818 } 00819 } 00820 } 00821 if(_object_list.empty()) { 00822 _object_list.clear(); 00823 } 00824 __mutex_release(); 00825 } 00826 00827 bool M2MNsdlInterface::create_nsdl_object_structure(M2MObject *object) 00828 { 00829 tr_debug("M2MNsdlInterface::create_nsdl_object_structure()"); 00830 bool success = false; 00831 if(object) { 00832 M2MObjectInstanceList instance_list = object->instances(); 00833 tr_debug("M2MNsdlInterface::create_nsdl_object_structure - Object Instance count %d", instance_list.size()); 00834 if(!instance_list.empty()) { 00835 M2MObjectInstanceList::const_iterator it; 00836 it = instance_list.begin(); 00837 for ( ; it != instance_list.end(); it++ ) { 00838 // Create NSDL structure for all object instances inside 00839 success = create_nsdl_object_instance_structure(*it); 00840 } 00841 } 00842 } 00843 if((object->operation() != M2MBase::NOT_ALLOWED)) { 00844 success = create_nsdl_resource(object,object->name(),object->register_uri()); 00845 } 00846 return success; 00847 } 00848 00849 bool M2MNsdlInterface::create_nsdl_object_instance_structure(M2MObjectInstance *object_instance) 00850 { 00851 tr_debug("M2MNsdlInterface::create_nsdl_object_instance_structure()"); 00852 bool success = false; 00853 if( object_instance) { 00854 00855 // Append object instance id to the object name. 00856 String object_name = object_instance->name(); 00857 object_name.push_back('/'); 00858 object_name.append_int(object_instance->instance_id()); 00859 00860 M2MResourceList res_list = object_instance->resources(); 00861 tr_debug("M2MNsdlInterface::create_nsdl_object_instance_structure - ResourceBase count %d", res_list.size()); 00862 if(!res_list.empty()) { 00863 M2MResourceList::const_iterator it; 00864 it = res_list.begin(); 00865 for ( ; it != res_list.end(); it++ ) { 00866 // Create NSDL structure for all resources inside 00867 success = create_nsdl_resource_structure(*it,object_name, 00868 (*it)->supports_multiple_instances()); 00869 } 00870 } 00871 if(object_instance->operation() != M2MBase::NOT_ALLOWED) { 00872 success = create_nsdl_resource(object_instance,object_name,object_instance->register_uri()); 00873 } 00874 } 00875 return success; 00876 } 00877 00878 bool M2MNsdlInterface::create_nsdl_resource_structure(M2MResource *res, 00879 const String &object_name, 00880 bool multiple_instances) 00881 { 00882 tr_debug("M2MNsdlInterface::create_nsdl_resource_structure(object_name %s)", object_name.c_str()); 00883 bool success = false; 00884 if(res) { 00885 // Append object name to the resource. 00886 // Take out the instance Id and append to the 00887 // resource name like "object/0/+ resource + / + 0" 00888 String res_name = object_name; 00889 if (strcmp(res_name.c_str(), res->uri_path().c_str()) != 0) { 00890 res_name.push_back('/'); 00891 res_name.append(res->name().c_str(),res->name().length()); 00892 } 00893 00894 // if there are multiple instances supported 00895 // then add instance Id into creating resource path 00896 // else normal /object_id/object_instance/resource_id format. 00897 if(multiple_instances) { 00898 M2MResourceInstanceList res_list = res->resource_instances(); 00899 tr_debug("M2MNsdlInterface::create_nsdl_resource_structure - ResourceInstance count %d", res_list.size()); 00900 if(!res_list.empty()) { 00901 M2MResourceInstanceList::const_iterator it; 00902 it = res_list.begin(); 00903 for ( ; it != res_list.end(); it++ ) { 00904 String inst_name = res_name; 00905 // Create NSDL structure for all resources inside 00906 inst_name.push_back('/'); 00907 inst_name.append_int((*it)->instance_id()); 00908 00909 success = create_nsdl_resource((*it),inst_name,(*it)->register_uri()); 00910 } 00911 // Register the main Resource as well along with ResourceInstances 00912 success = create_nsdl_resource(res,res_name,res->register_uri()); 00913 } 00914 } else { 00915 tr_debug("M2MNsdlInterface::create_nsdl_resource_structure - res_name %s", res_name.c_str()); 00916 success = create_nsdl_resource(res,res_name,res->register_uri()); 00917 } 00918 } 00919 return success; 00920 } 00921 00922 bool M2MNsdlInterface::create_nsdl_resource(M2MBase *base, const String &name, bool publish_uri) 00923 { 00924 __mutex_claim(); 00925 tr_debug("M2MNsdlInterface::create_nsdl_resource(name %s)", name.c_str()); 00926 bool success = false; 00927 uint8_t* buffer = 0; 00928 uint32_t length = 0; 00929 00930 // Create the NSDL Resource Pointer... 00931 if(base) { 00932 sn_nsdl_resource_info_s* resource = sn_nsdl_get_resource(_nsdl_handle, 00933 name.length(), 00934 (uint8_t*)name.c_str()); 00935 00936 if(resource) { 00937 bool changed = false; 00938 success = true; 00939 if(resource->mode == SN_GRS_STATIC) { 00940 if((M2MBase::Resource == base->base_type() || 00941 M2MBase::ResourceInstance == base->base_type()) && 00942 M2MBase::Static == base->mode()) { 00943 M2MResourceInstance *res = (M2MResourceInstance*) base; 00944 res->get_value(buffer,length); 00945 if(resource->resource) { 00946 memory_free(resource->resource); 00947 } 00948 resource->resource = buffer; 00949 resource->resourcelen = length; 00950 resource->publish_uri = publish_uri; 00951 } 00952 } 00953 // Check if the access level for the resource has changed. 00954 if(resource->access != (sn_grs_resource_acl_e)base->operation()) { 00955 changed = true; 00956 resource->access = (sn_grs_resource_acl_e)base->operation(); 00957 } 00958 if(resource->resource_parameters_ptr) { 00959 // Check if the observation parameter for the resource has changed. 00960 if(resource->resource_parameters_ptr->observable != (uint8_t)base->is_observable()) { 00961 changed = true; 00962 resource->resource_parameters_ptr->observable = (uint8_t)base->is_observable(); 00963 } 00964 } 00965 if(changed && resource->resource_parameters_ptr) { 00966 resource->resource_parameters_ptr->registered = SN_NDSL_RESOURCE_NOT_REGISTERED; 00967 } 00968 } else if(_resource) { 00969 base->set_under_observation(false,this); 00970 //TODO: implement access control 00971 // Currently complete access is given 00972 _resource->access = (sn_grs_resource_acl_e)base->operation(); 00973 00974 if((M2MBase::Resource == base->base_type() || 00975 M2MBase::ResourceInstance == base->base_type()) && 00976 M2MBase::Static == base->mode()) { 00977 M2MResourceInstance *res = (M2MResourceInstance*)base; 00978 // Static resource is updated 00979 _resource->mode = SN_GRS_STATIC; 00980 00981 res->get_value(buffer,length); 00982 _resource->resource = buffer; 00983 _resource->resourcelen = length; 00984 } 00985 00986 if(M2MBase::Dynamic == base->mode()){ 00987 // Dynamic resource is updated 00988 _resource->mode = SN_GRS_DYNAMIC; 00989 _resource->sn_grs_dyn_res_callback = __nsdl_c_callback; 00990 } 00991 00992 if( _resource->path != NULL ){ 00993 memory_free(_resource->path); 00994 _resource->path = NULL; 00995 } 00996 if(name.length() > 0 ){ 00997 _resource->path = alloc_string_copy((uint8_t*)name.c_str(), name.length()); 00998 if(_resource->path) { 00999 _resource->pathlen = name.length(); 01000 } 01001 } 01002 if(!base->resource_type().empty() && _resource->resource_parameters_ptr) { 01003 _resource->resource_parameters_ptr->resource_type_ptr = 01004 alloc_string_copy((uint8_t*)base->resource_type().c_str(), 01005 base->resource_type().length()); 01006 if(_resource->resource_parameters_ptr->resource_type_ptr) { 01007 _resource->resource_parameters_ptr->resource_type_len = 01008 base->resource_type().length(); 01009 } 01010 } 01011 if(!base->interface_description().empty() && _resource->resource_parameters_ptr) { 01012 _resource->resource_parameters_ptr->interface_description_ptr = 01013 alloc_string_copy((uint8_t*)base->interface_description().c_str(), 01014 base->interface_description().length()); 01015 if(_resource->resource_parameters_ptr->interface_description_ptr) { 01016 _resource->resource_parameters_ptr->interface_description_len = 01017 base->interface_description().length(); 01018 } 01019 } 01020 if(_resource->resource_parameters_ptr) { 01021 _resource->resource_parameters_ptr->coap_content_type = base->coap_content_type(); 01022 _resource->resource_parameters_ptr->observable = (uint8_t)base->is_observable(); 01023 } 01024 _resource->publish_uri = publish_uri; 01025 int8_t result = sn_nsdl_create_resource(_nsdl_handle,_resource); 01026 tr_debug("M2MNsdlInterface::create_nsdl_resource - Creating in NSDL-C result %d", result); 01027 01028 // Either the resource is created or it already 01029 // exists , then result is success. 01030 if (result == 0 || 01031 result == -2){ 01032 success = true; 01033 } 01034 01035 if(_resource->path) { 01036 memory_free(_resource->path); 01037 } 01038 if(_resource->resource_parameters_ptr->resource_type_ptr){ 01039 memory_free(_resource->resource_parameters_ptr->resource_type_ptr); 01040 } 01041 if(_resource->resource_parameters_ptr->interface_description_ptr){ 01042 memory_free(_resource->resource_parameters_ptr->interface_description_ptr); 01043 } 01044 if (_resource->resource) { 01045 memory_free(_resource->resource); 01046 } 01047 01048 //Clear up the filled resource to fill up new resource. 01049 clear_resource(_resource); 01050 01051 if(success) { 01052 base->set_under_observation(false,this); 01053 } 01054 } 01055 } 01056 __mutex_release(); 01057 return success; 01058 } 01059 01060 // convenience method to get the URI from its buffer field... 01061 String M2MNsdlInterface::coap_to_string(uint8_t *coap_data,int coap_data_length) 01062 { 01063 String value = ""; 01064 if (coap_data != NULL && coap_data_length > 0) { 01065 value.append_raw((char *)coap_data,coap_data_length); 01066 } 01067 return value; 01068 } 01069 01070 uint64_t M2MNsdlInterface::registration_time() 01071 { 01072 uint64_t value = 0; 01073 if(_endpoint->lifetime_ptr) { 01074 value = atol((const char*)_endpoint->lifetime_ptr); 01075 } 01076 01077 if(value >= OPTIMUM_LIFETIME) { 01078 value = value - REDUCE_LIFETIME; 01079 } else { 01080 value = REDUCTION_FACTOR * value; 01081 } 01082 tr_debug("M2MNsdlInterface::registration_time - value (in seconds) %ld", value); 01083 return value; 01084 } 01085 01086 M2MBase* M2MNsdlInterface::find_resource(const String &object_name) 01087 { 01088 M2MBase *object = NULL; 01089 if(!_object_list.empty()) { 01090 M2MObjectList::const_iterator it; 01091 it = _object_list.begin(); 01092 for ( ; it != _object_list.end(); it++ ) { 01093 if((*it)->name() == object_name) { 01094 object = (*it); 01095 tr_debug("M2MNsdlInterface::find_resource(%s) found", object_name.c_str()); 01096 break; 01097 } 01098 object = find_resource((*it),object_name); 01099 if(object != NULL) { 01100 tr_debug("M2MNsdlInterface::find_resource(%s) found", object_name.c_str()); 01101 break; 01102 } 01103 } 01104 } 01105 return object; 01106 } 01107 01108 M2MBase* M2MNsdlInterface::find_resource(const M2MObject *object, 01109 const String &object_instance) 01110 { 01111 M2MBase *instance = NULL; 01112 if(object) { 01113 M2MObjectInstanceList list = object->instances(); 01114 if(!list.empty()) { 01115 M2MObjectInstanceList::const_iterator it; 01116 it = list.begin(); 01117 for ( ; it != list.end(); it++ ) { 01118 // Append object instance id to the object name. 01119 String name = (*it)->name(); 01120 name.push_back('/'); 01121 name.append_int((*it)->instance_id()); 01122 01123 if(name == object_instance){ 01124 instance = (*it); 01125 break; 01126 } 01127 instance = find_resource((*it),object_instance); 01128 if(instance != NULL){ 01129 break; 01130 } 01131 } 01132 } 01133 } 01134 return instance; 01135 } 01136 01137 M2MBase* M2MNsdlInterface::find_resource(const M2MObjectInstance *object_instance, 01138 const String &resource_instance) 01139 { 01140 M2MBase *instance = NULL; 01141 if(object_instance) { 01142 M2MResourceList list = object_instance->resources(); 01143 if(!list.empty()) { 01144 M2MResourceList::const_iterator it; 01145 it = list.begin(); 01146 for ( ; it != list.end(); it++ ) { 01147 String name = object_instance->name(); 01148 // Append object instance id to the object name. 01149 name.push_back('/'); 01150 name.append_int(object_instance->instance_id()); 01151 01152 name.push_back('/'); 01153 name+= (*it)->name(); 01154 01155 if(name == resource_instance) { 01156 instance = *it; 01157 break; 01158 } else if((*it)->supports_multiple_instances()) { 01159 instance = find_resource((*it),name, resource_instance); 01160 if(instance != NULL){ 01161 break; 01162 } 01163 } 01164 } 01165 } 01166 } 01167 return instance; 01168 } 01169 01170 M2MBase* M2MNsdlInterface::find_resource(const M2MResource *resource, 01171 const String &object_name, 01172 const String &resource_instance) 01173 { 01174 M2MBase *res = NULL; 01175 if(resource) { 01176 if(resource->supports_multiple_instances()) { 01177 M2MResourceInstanceList list = resource->resource_instances(); 01178 if(!list.empty()) { 01179 M2MResourceInstanceList::const_iterator it; 01180 it = list.begin(); 01181 for ( ; it != list.end(); it++ ) { 01182 String name = object_name; 01183 // if there are multiple instances supported 01184 // then add instance Id into creating resource path 01185 // else normal /object_id/object_instance/resource_id format. 01186 01187 name.push_back('/'); 01188 name.append_int((*it)->instance_id()); 01189 01190 if(name == resource_instance){ 01191 res = (*it); 01192 break; 01193 } 01194 } 01195 } 01196 } 01197 } 01198 return res; 01199 } 01200 01201 bool M2MNsdlInterface::object_present(M2MObject* object) const 01202 { 01203 bool success = false; 01204 if(object && !_object_list.empty()) { 01205 M2MObjectList::const_iterator it; 01206 it = _object_list.begin(); 01207 for ( ; it != _object_list.end(); it++ ) { 01208 if((*it) == object) { 01209 success = true; 01210 break; 01211 } 01212 } 01213 } 01214 return success; 01215 } 01216 01217 bool M2MNsdlInterface::add_object_to_list(M2MObject* object) 01218 { 01219 bool success = false; 01220 if(object && !object_present(object)) { 01221 _object_list.push_back(object); 01222 success = true; 01223 } 01224 return success; 01225 } 01226 01227 void M2MNsdlInterface::clear_resource(sn_nsdl_resource_info_s *&resource) 01228 { 01229 //Clear up the filled resource to fill up new resource. 01230 if(resource && resource->resource_parameters_ptr) { 01231 sn_nsdl_resource_parameters_s *temp_resource_parameter = resource->resource_parameters_ptr; 01232 memset(resource->resource_parameters_ptr, 0, sizeof(sn_nsdl_resource_parameters_s)); 01233 memset(resource,0, sizeof(sn_nsdl_resource_info_s)); 01234 resource->resource_parameters_ptr = temp_resource_parameter; 01235 } 01236 } 01237 01238 M2MInterface::Error M2MNsdlInterface::interface_error(sn_coap_hdr_s *coap_header) 01239 { 01240 M2MInterface::Error error = M2MInterface::ErrorNone; 01241 if(coap_header) { 01242 switch(coap_header->msg_code) { 01243 case COAP_MSG_CODE_RESPONSE_BAD_REQUEST: 01244 case COAP_MSG_CODE_RESPONSE_BAD_OPTION: 01245 case COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_INCOMPLETE: 01246 case COAP_MSG_CODE_RESPONSE_PRECONDITION_FAILED: 01247 case COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE: 01248 case COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT: 01249 error = M2MInterface::InvalidParameters; 01250 break; 01251 case COAP_MSG_CODE_RESPONSE_UNAUTHORIZED: 01252 case COAP_MSG_CODE_RESPONSE_FORBIDDEN: 01253 case COAP_MSG_CODE_RESPONSE_NOT_ACCEPTABLE: 01254 case COAP_MSG_CODE_RESPONSE_NOT_FOUND: 01255 case COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED: 01256 error = M2MInterface::NotAllowed; 01257 break; 01258 case COAP_MSG_CODE_RESPONSE_CREATED: 01259 case COAP_MSG_CODE_RESPONSE_DELETED: 01260 case COAP_MSG_CODE_RESPONSE_VALID: 01261 case COAP_MSG_CODE_RESPONSE_CHANGED: 01262 case COAP_MSG_CODE_RESPONSE_CONTENT: 01263 error = M2MInterface::ErrorNone; 01264 break; 01265 default: 01266 error = M2MInterface::UnknownError; 01267 break; 01268 } 01269 if(coap_header->coap_status == COAP_STATUS_BUILDER_MESSAGE_SENDING_FAILED) { 01270 error = M2MInterface::NetworkError; 01271 } 01272 } 01273 return error; 01274 } 01275 01276 void M2MNsdlInterface::send_object_observation(M2MObject *object, 01277 uint16_t obs_number, 01278 m2m::Vector<uint16_t> changed_instance_ids, 01279 bool send_object) 01280 { 01281 tr_debug("M2MNsdlInterface::send_object_observation"); 01282 if(object) { 01283 uint8_t *value = 0; 01284 uint32_t length = 0; 01285 uint8_t *token = 0; 01286 uint32_t token_length = 0; 01287 01288 M2MTLVSerializer serializer; 01289 // Send whole object structure 01290 if (send_object) { 01291 value = serializer.serialize(object->instances(), length); 01292 } 01293 // Send only changed object instances 01294 else { 01295 M2MObjectInstanceList list; 01296 Vector<uint16_t>::const_iterator it; 01297 it = changed_instance_ids.begin(); 01298 for (; it != changed_instance_ids.end(); it++){ 01299 M2MObjectInstance* obj_instance = object->object_instance(*it); 01300 if (obj_instance){ 01301 list.push_back(obj_instance); 01302 } 01303 } 01304 if (!list.empty()) { 01305 value = serializer.serialize(list, length); 01306 list.clear(); 01307 } 01308 } 01309 01310 object->get_observation_token(token,token_length); 01311 01312 send_notification(token, 01313 token_length, 01314 value, 01315 length, 01316 obs_number, 01317 object->max_age(), 01318 object->coap_content_type(), 01319 object->uri_path()); 01320 01321 memory_free(value); 01322 memory_free(token); 01323 } 01324 } 01325 01326 void M2MNsdlInterface::send_object_instance_observation(M2MObjectInstance *object_instance, 01327 uint16_t obs_number) 01328 { 01329 tr_debug("M2MNsdlInterface::send_object_instance_observation"); 01330 if(object_instance) { 01331 uint8_t *value = 0; 01332 uint32_t length = 0; 01333 uint8_t *token = 0; 01334 uint32_t token_length = 0; 01335 01336 M2MTLVSerializer serializer; 01337 value = serializer.serialize(object_instance->resources(), length); 01338 01339 object_instance->get_observation_token(token,token_length); 01340 01341 send_notification(token, 01342 token_length, 01343 value, 01344 length, 01345 obs_number, 01346 object_instance->max_age(), 01347 object_instance->coap_content_type(), 01348 object_instance->uri_path()); 01349 01350 memory_free(value); 01351 memory_free(token); 01352 } 01353 } 01354 01355 void M2MNsdlInterface::send_resource_observation(M2MResource *resource, 01356 uint16_t obs_number) 01357 { 01358 tr_debug("M2MNsdlInterface::send_resource_observation"); 01359 if(resource) { 01360 uint8_t *value = 0; 01361 uint32_t length = 0; 01362 uint8_t *token = 0; 01363 uint32_t token_length = 0; 01364 01365 resource->get_observation_token(token,token_length); 01366 uint8_t content_type = 0; 01367 if(M2MResourceInstance::OPAQUE == resource->resource_instance_type()) { 01368 content_type = COAP_CONTENT_OMA_OPAQUE_TYPE; 01369 } 01370 if (resource->resource_instance_count() > 0) { 01371 content_type = COAP_CONTENT_OMA_TLV_TYPE; 01372 M2MTLVSerializer serializer; 01373 value = serializer.serialize(resource, length); 01374 } else { 01375 resource->get_value(value,length); 01376 } 01377 send_notification(token, 01378 token_length, 01379 value, 01380 length, 01381 obs_number, 01382 resource->max_age(), 01383 content_type, 01384 resource->uri_path()); 01385 01386 memory_free(value); 01387 memory_free(token); 01388 } 01389 } 01390 01391 void M2MNsdlInterface::build_observation_number(uint8_t *obs_number, 01392 uint8_t *obs_len, 01393 uint16_t number) 01394 { 01395 if(number > 0xFF) { 01396 *obs_len = 2; 01397 *(obs_number) = (number >> 8) & 0x00FF; 01398 obs_number[1] = number & 0x00FF; 01399 } else { 01400 *obs_len = 1; 01401 *(obs_number) = number & 0x00FF; 01402 } 01403 } 01404 01405 void M2MNsdlInterface::send_notification(uint8_t *token, 01406 uint8_t token_length, 01407 uint8_t *value, 01408 uint32_t value_length, 01409 uint16_t observation, 01410 uint32_t max_age, 01411 uint8_t coap_content_type, 01412 const String &uri_path) 01413 01414 { 01415 tr_debug("M2MNsdlInterface::send_notification"); 01416 sn_coap_hdr_s *notification_message_ptr; 01417 01418 /* Allocate and initialize memory for header struct */ 01419 notification_message_ptr = static_cast<sn_coap_hdr_s *>(memory_alloc(sizeof(sn_coap_hdr_s))); 01420 if (notification_message_ptr) { 01421 memset(notification_message_ptr, 0, sizeof(sn_coap_hdr_s)); 01422 01423 notification_message_ptr->options_list_ptr = (sn_coap_options_list_s *)memory_alloc(sizeof(sn_coap_options_list_s)); 01424 if (notification_message_ptr->options_list_ptr) { 01425 01426 memset(notification_message_ptr->options_list_ptr , 0, sizeof(sn_coap_options_list_s)); 01427 01428 /* Fill header */ 01429 notification_message_ptr->msg_type = COAP_MSG_TYPE_CONFIRMABLE; 01430 notification_message_ptr->msg_code = COAP_MSG_CODE_RESPONSE_CONTENT; 01431 01432 /* Fill token */ 01433 notification_message_ptr->token_len = token_length; 01434 notification_message_ptr->token_ptr = token; 01435 01436 /* Fill payload */ 01437 notification_message_ptr->payload_len = value_length; 01438 notification_message_ptr->payload_ptr = value; 01439 01440 /* Fill uri path */ 01441 notification_message_ptr->uri_path_len = uri_path.size(); 01442 notification_message_ptr->uri_path_ptr = (uint8_t *)uri_path.c_str(); 01443 01444 /* Fill observe */ 01445 uint8_t observation_number[2]; 01446 uint8_t observation_number_length = 0; 01447 01448 build_observation_number(observation_number, 01449 &observation_number_length, 01450 observation); 01451 notification_message_ptr->options_list_ptr->observe_len = observation_number_length; 01452 notification_message_ptr->options_list_ptr->observe_ptr = observation_number; 01453 01454 notification_message_ptr->options_list_ptr->max_age_ptr = 01455 m2m::String::convert_integer_to_array(max_age, 01456 notification_message_ptr->options_list_ptr->max_age_len); 01457 01458 notification_message_ptr->content_type_ptr = 01459 m2m::String::convert_integer_to_array(coap_content_type, 01460 notification_message_ptr->content_type_len); 01461 01462 /* Send message */ 01463 sn_nsdl_send_coap_message(_nsdl_handle, 01464 _nsdl_handle->nsp_address_ptr->omalw_address_ptr, 01465 notification_message_ptr); 01466 01467 /* Free memory */ 01468 notification_message_ptr->uri_path_ptr = NULL; 01469 notification_message_ptr->payload_ptr = NULL; 01470 notification_message_ptr->options_list_ptr->observe_ptr = NULL; 01471 notification_message_ptr->token_ptr = NULL; 01472 if (notification_message_ptr->content_type_ptr) { 01473 free(notification_message_ptr->content_type_ptr); 01474 } 01475 notification_message_ptr->content_type_ptr = NULL; 01476 if (notification_message_ptr->options_list_ptr->max_age_ptr) { 01477 free(notification_message_ptr->options_list_ptr->max_age_ptr); 01478 } 01479 notification_message_ptr->options_list_ptr->max_age_ptr = NULL; 01480 } 01481 sn_nsdl_release_allocated_coap_msg_mem(_nsdl_handle, notification_message_ptr); 01482 } 01483 } 01484 01485 nsdl_s * M2MNsdlInterface::get_nsdl_handle() 01486 { 01487 return _nsdl_handle; 01488 } 01489 01490 void M2MNsdlInterface::handle_bootstrap_put_message(sn_coap_hdr_s *coap_header, 01491 sn_nsdl_addr_s *address) { 01492 #ifndef M2M_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01493 tr_debug("M2MNsdlInterface::handle_bootstrap_message"); 01494 uint8_t response_code = COAP_MSG_CODE_RESPONSE_CHANGED; 01495 sn_coap_hdr_s *coap_response = NULL; 01496 bool success = false; 01497 bool security_object = false; 01498 uint16_t content_type = 0; 01499 01500 if (!_security) { 01501 _security = new M2MSecurity(M2MSecurity::M2MServer); 01502 } 01503 01504 String resource_name = coap_to_string(coap_header->uri_path_ptr, 01505 coap_header->uri_path_len); 01506 tr_debug("M2MNsdlInterface::handle_bootstrap_message - uri %s", resource_name.c_str()); 01507 01508 // Check incoming object 01509 if (resource_name.compare(0,1,"0") == 0) { 01510 security_object = true; 01511 if(_security) { 01512 success = true; 01513 // Not mandatory resource that's why it must be created first 01514 _security->create_resource(M2MSecurity::ShortServerID, 1); 01515 // Change operation mode 01516 M2MResourceList list = _security->object_instance()->resources(); 01517 if(!list.empty()) { 01518 M2MResourceList::const_iterator it; 01519 it = list.begin(); 01520 for ( ; it != list.end(); it++ ) { 01521 (*it)->set_operation(M2MBase::PUT_ALLOWED); 01522 } 01523 } 01524 } 01525 } 01526 else if (resource_name.compare(0,1,"1") == 0) { 01527 success = true; 01528 } 01529 01530 if (success) { 01531 // Send delayed response if token is part of the message 01532 if (coap_header->token_ptr) { 01533 tr_debug("M2MNsdlInterface::handle_bootstrap_message - send delayed response"); 01534 coap_response = sn_nsdl_build_response(_nsdl_handle, 01535 coap_header, 01536 COAP_MSG_CODE_EMPTY); 01537 if (coap_response) { 01538 coap_response->msg_type = COAP_MSG_TYPE_ACKNOWLEDGEMENT; 01539 sn_nsdl_send_coap_message(_nsdl_handle, address, coap_response); 01540 sn_nsdl_release_allocated_coap_msg_mem(_nsdl_handle, coap_response); 01541 } 01542 } 01543 01544 if(coap_header->content_type_ptr) { 01545 content_type = String::convert_array_to_integer(coap_header->content_type_ptr, 01546 coap_header->content_type_len); 01547 } 01548 01549 tr_debug("M2MNsdlInterface::handle_bootstrap_message - content_type %d", content_type); 01550 if (content_type != COAP_CONTENT_OMA_TLV_TYPE) { 01551 success = false; 01552 } 01553 if (success) { 01554 success = parse_bootstrap_message(coap_header, security_object); 01555 // Set operation back to default ones 01556 if (_security) { 01557 M2MResourceList list = _security->object_instance()->resources(); 01558 if(!list.empty()) { 01559 M2MResourceList::const_iterator it; 01560 it = list.begin(); 01561 for ( ; it != list.end(); it++ ) { 01562 (*it)->set_operation(M2MBase::NOT_ALLOWED); 01563 } 01564 } 01565 } 01566 } 01567 } 01568 01569 if (!success) { 01570 response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; 01571 handle_bootstrap_error(); 01572 } 01573 coap_response = sn_nsdl_build_response(_nsdl_handle, 01574 coap_header, 01575 response_code); 01576 if (coap_response) { 01577 sn_nsdl_send_coap_message(_nsdl_handle, address, coap_response); 01578 sn_nsdl_release_allocated_coap_msg_mem(_nsdl_handle, coap_response); 01579 } 01580 #else 01581 (void) coap_header; 01582 (void) address; 01583 #endif 01584 } 01585 01586 bool M2MNsdlInterface::parse_bootstrap_message(sn_coap_hdr_s *coap_header, bool is_security_object) 01587 { 01588 #ifndef M2M_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01589 tr_debug("M2MNsdlInterface::parse_bootstrap_put_message"); 01590 M2MTLVDeserializer *deserializer = new M2MTLVDeserializer(); 01591 bool ret = false; 01592 bool is_obj_instance = false; 01593 uint16_t instance_id = 0; 01594 if (deserializer && _security) { 01595 ret = is_obj_instance = deserializer->is_object_instance(coap_header->payload_ptr); 01596 if (!is_obj_instance) { 01597 ret = deserializer->is_resource(coap_header->payload_ptr); 01598 } 01599 01600 if (ret) { 01601 M2MTLVDeserializer::Error error = M2MTLVDeserializer::None; 01602 if (is_obj_instance) { 01603 if (is_security_object) { 01604 error = deserializer->deserialise_object_instances(coap_header->payload_ptr, 01605 coap_header->payload_len, 01606 *_security, 01607 M2MTLVDeserializer::Put); 01608 } 01609 else { 01610 error = deserializer->deserialise_object_instances(coap_header->payload_ptr, 01611 coap_header->payload_len, 01612 *_server, 01613 M2MTLVDeserializer::Put); 01614 } 01615 } 01616 else { 01617 if (is_security_object) { 01618 instance_id = deserializer->instance_id(coap_header->payload_ptr); 01619 error = deserializer->deserialize_resources(coap_header->payload_ptr, 01620 coap_header->payload_len, 01621 *_security->object_instance(instance_id), 01622 M2MTLVDeserializer::Put); 01623 } 01624 else { 01625 instance_id = deserializer->instance_id(coap_header->payload_ptr); 01626 error = deserializer->deserialize_resources(coap_header->payload_ptr, 01627 coap_header->payload_len, 01628 *_server->object_instance(instance_id), 01629 M2MTLVDeserializer::Post); 01630 } 01631 } 01632 01633 if (error != M2MTLVDeserializer::None) { 01634 tr_error("M2MNsdlInterface::parse_bootstrap_put_message - error %d", error); 01635 ret = false; 01636 } 01637 } 01638 } 01639 delete deserializer; 01640 return ret; 01641 #else 01642 (void) coap_header; 01643 (void) is_security_object; 01644 return false; 01645 #endif 01646 } 01647 01648 void M2MNsdlInterface::handle_bootstrap_finished(sn_coap_hdr_s *coap_header,sn_nsdl_addr_s *address) 01649 { 01650 #ifndef M2M_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01651 String object_name = coap_to_string(coap_header->uri_path_ptr, 01652 coap_header->uri_path_len); 01653 tr_debug("M2MNsdlInterface::handle_bootstrap_finished - path: %s", object_name.c_str()); 01654 sn_coap_hdr_s *coap_response = NULL; 01655 uint8_t msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; 01656 01657 // Accept only '/bs' path and check that needed data is in security object 01658 if (object_name.size() != 2 || 01659 object_name.compare(0,2,BOOTSTRAP_URI) != 0 || 01660 !validate_security_object()) { 01661 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; 01662 } else { 01663 // Add short server id to server object 01664 _server->set_resource_value(M2MServer::ShortServerID, 01665 _security->resource_value_int(M2MSecurity::ShortServerID)); 01666 } 01667 01668 coap_response = sn_nsdl_build_response(_nsdl_handle, 01669 coap_header, 01670 msg_code); 01671 if(coap_response) { 01672 sn_nsdl_send_coap_message(_nsdl_handle, address, coap_response); 01673 sn_nsdl_release_allocated_coap_msg_mem(_nsdl_handle, coap_response); 01674 } 01675 if (COAP_MSG_CODE_RESPONSE_CHANGED == msg_code) { 01676 // Switch back to original ep name 01677 if (_endpoint->endpoint_name_ptr) { 01678 memory_free(_endpoint->endpoint_name_ptr); 01679 } 01680 _endpoint->endpoint_name_ptr = alloc_string_copy((uint8_t*)_endpoint_name.c_str(), _endpoint_name.length()); 01681 _endpoint->endpoint_name_len = _endpoint_name.length(); 01682 _observer.bootstrap_done(_security); 01683 } else { 01684 handle_bootstrap_error(); 01685 } 01686 #else 01687 (void) coap_header; 01688 (void) address; 01689 #endif 01690 } 01691 01692 void M2MNsdlInterface::handle_bootstrap_delete(sn_coap_hdr_s *coap_header,sn_nsdl_addr_s *address) 01693 { 01694 #ifndef M2M_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01695 sn_coap_hdr_s *coap_response = NULL; 01696 uint8_t msg_code = COAP_MSG_CODE_RESPONSE_DELETED; 01697 String object_name = coap_to_string(coap_header->uri_path_ptr, 01698 coap_header->uri_path_len); 01699 tr_debug("M2MNsdlInterface::handle_bootstrap_delete - obj %s", object_name.c_str()); 01700 01701 // Only following paths are accepted, 0, 0/0 01702 if (object_name.size() == 2 || object_name.size() > 3) { 01703 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; 01704 } 01705 else if ((object_name.size() == 1 && object_name.compare(0,1,"0") != 0) || 01706 (object_name.size() == 3 && object_name.compare(0,3,"0/0") != 0)) { 01707 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; 01708 } 01709 01710 coap_response = sn_nsdl_build_response(_nsdl_handle, 01711 coap_header, 01712 msg_code); 01713 01714 if(coap_response) { 01715 sn_nsdl_send_coap_message(_nsdl_handle, address, coap_response); 01716 sn_nsdl_release_allocated_coap_msg_mem(_nsdl_handle, coap_response); 01717 if(_security) { 01718 _security->clear_resources(); 01719 } 01720 } else { 01721 handle_bootstrap_error(); 01722 } 01723 #else 01724 (void) coap_header; 01725 (void) address; 01726 #endif 01727 } 01728 01729 bool M2MNsdlInterface::validate_security_object() 01730 { 01731 #ifndef M2M_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01732 tr_debug("M2MNsdlInterface::validate_security_object"); 01733 if (_security) { 01734 String address = _security->resource_value_string(M2MSecurity::M2MServerUri); 01735 uint32_t sec_mode = _security->resource_value_int(M2MSecurity::SecurityMode); 01736 bool is_bs_server = _security->resource_value_int(M2MSecurity::BootstrapServer); 01737 uint32_t public_key_size = _security->get_resource(M2MSecurity::PublicKey)->value_length(); 01738 uint32_t server_key_size = _security->get_resource(M2MSecurity::ServerPublicKey)->value_length(); 01739 uint32_t pkey_size = _security->get_resource(M2MSecurity::Secretkey)->value_length(); 01740 tr_debug("M2MNsdlInterface::validate_security_object - Server URI /0/0: %s", address.c_str()); 01741 tr_debug("M2MNsdlInterface::validate_security_object - is bs server /0/1: %d", is_bs_server); 01742 tr_debug("M2MNsdlInterface::validate_security_object - Security Mode /0/2: %d", sec_mode); 01743 tr_debug("M2MNsdlInterface::validate_security_object - Public key size /0/3: %d", public_key_size); 01744 tr_debug("M2MNsdlInterface::validate_security_object - Server Public key size /0/4: %d", server_key_size); 01745 tr_debug("M2MNsdlInterface::validate_security_object - Secret key size /0/5: %d", pkey_size); 01746 // Only NoSec and Certificate modes are supported 01747 if (!address.empty() && !is_bs_server) { 01748 if (M2MSecurity::Certificate == sec_mode) { 01749 if (!public_key_size || !server_key_size || !pkey_size) { 01750 return false; 01751 } else { 01752 return true; 01753 } 01754 } else if (M2MSecurity::NoSecurity == sec_mode){ 01755 return true; 01756 } else { 01757 return false; 01758 } 01759 } else { 01760 return false; 01761 } 01762 } 01763 return false; 01764 #else 01765 return false; 01766 #endif 01767 } 01768 01769 void M2MNsdlInterface::handle_bootstrap_error() 01770 { 01771 tr_debug("M2MNsdlInterface::handle_bootstrap_error()"); 01772 if (_security) { 01773 delete _security; 01774 _security = NULL; 01775 } 01776 _observer.bootstrap_error(); 01777 } 01778 01779 const String& M2MNsdlInterface::endpoint_name() const 01780 { 01781 return _endpoint_name; 01782 }
Generated on Tue Jul 12 2022 12:28:38 by
1.7.2
