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.
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:58:28 by
1.7.2