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: mbed Socket lwip-eth lwip-sys lwip
Fork of 6_songs-from-the-cloud 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 #include "include/nsdlaccesshelper.h" 00017 #include "include/m2mnsdlobserver.h" 00018 #include "mbed-client/m2msecurity.h" 00019 #include "mbed-client/m2mserver.h" 00020 #include "mbed-client/m2mobject.h" 00021 #include "mbed-client/m2mobjectinstance.h" 00022 #include "mbed-client/m2mresource.h" 00023 #include "mbed-client/m2mconstants.h" 00024 #include "include/m2mtlvserializer.h" 00025 #include "ip6string.h" 00026 #include "ns_trace.h" 00027 #include "mbed-client/m2mtimer.h" 00028 00029 M2MNsdlInterface::M2MNsdlInterface(M2MNsdlObserver &observer) 00030 : _observer(observer), 00031 _server(NULL), 00032 _nsdl_exceution_timer(new M2MTimer(*this)), 00033 _registration_timer(new M2MTimer(*this)), 00034 _nsdl_handle(NULL), 00035 _counter_for_nsdl(0), 00036 _register_id(0), 00037 _unregister_id(0), 00038 _update_id(0), 00039 _bootstrap_id(0) 00040 { 00041 tr_debug("M2MNsdlInterface::M2MNsdlInterface()"); 00042 _endpoint = NULL; 00043 _resource = NULL; 00044 __nsdl_interface = this; 00045 00046 _bootstrap_endpoint.device_object = NULL; 00047 _bootstrap_endpoint.oma_bs_status_cb = NULL; 00048 00049 _bootstrap_device_setup.sn_oma_device_boot_callback = NULL; 00050 _bootstrap_device_setup.error_code = NO_ERROR; 00051 00052 _sn_nsdl_address.addr_len = 0; 00053 _sn_nsdl_address.addr_ptr = NULL; 00054 _sn_nsdl_address.port = 0; 00055 00056 // This initializes libCoap and libNsdl 00057 // Parameters are function pointers to used memory allocation 00058 // and free functions in structure and used functions for sending 00059 // and receiving purposes. 00060 _nsdl_handle = sn_nsdl_init(&(__nsdl_c_send_to_server), &(__nsdl_c_received_from_server), 00061 &(__nsdl_c_memory_alloc), &(__nsdl_c_memory_free)); 00062 00063 initialize(); 00064 } 00065 00066 M2MNsdlInterface::~M2MNsdlInterface() 00067 { 00068 tr_debug("M2MNsdlInterface::~M2MNsdlInterface() - IN"); 00069 if(_resource) { 00070 if(_resource->resource_parameters_ptr) { 00071 memory_free(_resource->resource_parameters_ptr); 00072 _resource->resource_parameters_ptr = NULL; 00073 } 00074 memory_free(_resource); 00075 _resource = NULL; 00076 } 00077 if(_endpoint) { 00078 if(_endpoint->lifetime_ptr) { 00079 memory_free(_endpoint->lifetime_ptr); 00080 _endpoint->lifetime_ptr = NULL; 00081 } 00082 if(_endpoint->location_ptr) { 00083 memory_free(_endpoint->location_ptr); 00084 _endpoint->location_ptr = NULL; 00085 } 00086 memory_free(_endpoint); 00087 _endpoint = NULL; 00088 00089 } 00090 delete _nsdl_exceution_timer; 00091 delete _registration_timer; 00092 _object_list.clear(); 00093 00094 if(_server){ 00095 delete _server; 00096 _server = NULL; 00097 } 00098 sn_nsdl_destroy(_nsdl_handle); 00099 _nsdl_handle = NULL; 00100 __nsdl_interface = NULL; 00101 tr_debug("M2MNsdlInterface::~M2MNsdlInterface() - OUT"); 00102 } 00103 00104 bool M2MNsdlInterface::initialize() 00105 { 00106 tr_debug("M2MNsdlInterface::initialize()"); 00107 bool success = false; 00108 00109 //Sets the packet retransmission attempts and time interval 00110 sn_coap_protocol_set_retransmission_parameters(RETRY_COUNT,RETRY_INTERVAL); 00111 00112 _nsdl_exceution_timer->start_timer(ONE_SECOND_TIMER * 1000, 00113 M2MTimerObserver::NsdlExecution, 00114 false); 00115 00116 // Allocate the memory for resources 00117 _resource = (sn_nsdl_resource_info_s*)memory_alloc(sizeof(sn_nsdl_resource_info_s)); 00118 if(_resource) { 00119 memset(_resource, 0, sizeof(sn_nsdl_resource_info_s)); 00120 _resource->resource_parameters_ptr = (sn_nsdl_resource_parameters_s*)memory_alloc(sizeof(sn_nsdl_resource_parameters_s)+1); 00121 if(_resource->resource_parameters_ptr) { 00122 memset(_resource->resource_parameters_ptr, 0, sizeof(sn_nsdl_resource_parameters_s)+1); 00123 } 00124 } 00125 00126 //Allocate the memory for endpoint 00127 _endpoint = (sn_nsdl_ep_parameters_s*)memory_alloc(sizeof(sn_nsdl_ep_parameters_s)+1); 00128 if(_endpoint) { 00129 memset(_endpoint, 0, sizeof(sn_nsdl_ep_parameters_s)+1); 00130 success = true; 00131 } 00132 return success; 00133 } 00134 00135 void M2MNsdlInterface::create_endpoint(const String &name, 00136 const String &type, 00137 const int32_t life_time, 00138 const String &domain, 00139 const uint8_t mode, 00140 const String &/*context_address*/) 00141 { 00142 tr_debug("M2MNsdlInterface::create_endpoint( name %s type %s lifetime %d, domain %s, mode %d)", 00143 name.c_str(), type.c_str(), life_time, domain.c_str(), mode); 00144 if(_endpoint){ 00145 memset(_endpoint, 0, sizeof(sn_nsdl_ep_parameters_s)+1); 00146 if(!name.empty()) { 00147 _endpoint->endpoint_name_ptr = (uint8_t*)name.c_str(); 00148 _endpoint->endpoint_name_len = name.length(); 00149 } 00150 if(!type.empty()) { 00151 _endpoint->type_ptr = (uint8_t*)type.c_str(); 00152 _endpoint->type_len = type.length(); 00153 } 00154 if(!domain.empty()) { 00155 _endpoint->domain_name_ptr = (uint8_t*)domain.c_str(); 00156 _endpoint->domain_name_len = domain.length(); 00157 } 00158 _endpoint->binding_and_mode = (sn_nsdl_oma_binding_and_mode_t)mode; 00159 00160 // If lifetime is less than zero then leave the field empty 00161 if( life_time > 0) { 00162 char *buffer = (char*)memory_alloc(20); 00163 int size = snprintf(buffer, 20,"%ld",(long int)life_time); 00164 if( _endpoint->lifetime_ptr == NULL ){ 00165 _endpoint->lifetime_ptr = (uint8_t*)memory_alloc(size+1); 00166 } 00167 if(_endpoint->lifetime_ptr) { 00168 memset(_endpoint->lifetime_ptr, 0, size+1); 00169 memcpy(_endpoint->lifetime_ptr,buffer,size); 00170 _endpoint->lifetime_len = size; 00171 } 00172 memory_free(buffer); 00173 } 00174 } 00175 } 00176 00177 void M2MNsdlInterface::delete_endpoint() 00178 { 00179 tr_debug("M2MNsdlInterface::delete_endpoint()"); 00180 if(_endpoint) { 00181 if(_endpoint->lifetime_ptr) { 00182 free(_endpoint->lifetime_ptr); 00183 _endpoint->lifetime_ptr = NULL; 00184 } 00185 memory_free(_endpoint); 00186 _endpoint = NULL; 00187 } 00188 } 00189 00190 bool M2MNsdlInterface::create_nsdl_list_structure(const M2MObjectList &object_list) 00191 { 00192 tr_debug("M2MNsdlInterface::create_nsdl_list_structure()"); 00193 bool success = false; 00194 if(!object_list.empty()) { 00195 tr_debug("M2MNsdlInterface::create_nsdl_list_structure - Object count is %d", object_list.size()); 00196 M2MObjectList::const_iterator it; 00197 it = object_list.begin(); 00198 for ( ; it != object_list.end(); it++ ) { 00199 // Create NSDL structure for all Objects inside 00200 success = create_nsdl_object_structure(*it); 00201 add_object_to_list(*it); 00202 } 00203 } 00204 return success; 00205 } 00206 00207 bool M2MNsdlInterface::delete_nsdl_resource(const String &resource_name) 00208 { 00209 tr_debug("M2MNsdlInterface::delete_nsdl_resource( %s)", resource_name.c_str()); 00210 return (sn_nsdl_delete_resource(_nsdl_handle, 00211 resource_name.length(), 00212 (uint8_t *)resource_name.c_str()) == 0) ? true : false; 00213 } 00214 00215 bool M2MNsdlInterface::create_bootstrap_resource(sn_nsdl_addr_s *address) 00216 { 00217 tr_debug("M2MNsdlInterface::create_bootstrap_resource()"); 00218 bool success = false; 00219 _bootstrap_device_setup.error_code = NO_ERROR; 00220 _bootstrap_device_setup.sn_oma_device_boot_callback = 0; 00221 00222 _bootstrap_endpoint.device_object = &_bootstrap_device_setup; 00223 _bootstrap_endpoint.oma_bs_status_cb = &__nsdl_c_bootstrap_done; 00224 00225 if(_bootstrap_id == 0) { 00226 _bootstrap_id = sn_nsdl_oma_bootstrap(_nsdl_handle, 00227 address, 00228 _endpoint, 00229 &_bootstrap_endpoint); 00230 tr_debug("M2MNsdlInterface::create_bootstrap_resource - _bootstrap_id %d", _bootstrap_id); 00231 success = _bootstrap_id != 0; 00232 00233 } 00234 return success; 00235 } 00236 00237 bool M2MNsdlInterface::send_register_message(uint8_t* address, 00238 const uint16_t port, 00239 sn_nsdl_addr_type_e address_type) 00240 { 00241 tr_debug("M2MNsdlInterface::send_register_message()"); 00242 bool success = false; 00243 if(set_NSP_address(_nsdl_handle,address, port, address_type) == 0) { 00244 if(_register_id == 0) { 00245 _register_id = sn_nsdl_register_endpoint(_nsdl_handle,_endpoint); 00246 tr_debug("M2MNsdlInterface::send_register_message - _register_id %d", _register_id); 00247 success = _register_id != 0; 00248 } 00249 } 00250 return success; 00251 } 00252 00253 bool M2MNsdlInterface::send_update_registration(const uint32_t lifetime) 00254 { 00255 tr_debug("M2MNsdlInterface::send_update_registration( lifetime %d)", lifetime); 00256 bool success = false; 00257 00258 create_nsdl_list_structure(_object_list); 00259 //If Lifetime value is 0, then don't change the existing lifetime value 00260 if(lifetime != 0) { 00261 char *buffer = (char*)memory_alloc(20); 00262 int size = snprintf(buffer, 20,"%ld",(long int)lifetime); 00263 if(_endpoint->lifetime_ptr) { 00264 memory_free(_endpoint->lifetime_ptr); 00265 _endpoint->lifetime_ptr = NULL; 00266 _endpoint->lifetime_len = 0; 00267 } 00268 00269 if(_endpoint->lifetime_ptr == NULL){ 00270 _endpoint->lifetime_ptr = (uint8_t*)memory_alloc(size+1); 00271 } 00272 if(_endpoint->lifetime_ptr) { 00273 memset(_endpoint->lifetime_ptr, 0, size+1); 00274 memcpy(_endpoint->lifetime_ptr,buffer,size); 00275 _endpoint->lifetime_len = size; 00276 } 00277 memory_free(buffer); 00278 00279 _registration_timer->stop_timer(); 00280 _registration_timer->start_timer(registration_time() * 1000, 00281 M2MTimerObserver::Registration, 00282 false); 00283 if(_nsdl_handle && 00284 _endpoint && _endpoint->lifetime_ptr) { 00285 _update_id = sn_nsdl_update_registration(_nsdl_handle, 00286 _endpoint->lifetime_ptr, 00287 _endpoint->lifetime_len); 00288 tr_debug("M2MNsdlInterface::send_update_registration - New lifetime value _update_id %d", _update_id); 00289 success = _update_id != 0; 00290 } 00291 } else { 00292 if(_nsdl_handle) { 00293 _update_id = sn_nsdl_update_registration(_nsdl_handle, NULL, 0); 00294 tr_debug("M2MNsdlInterface::send_update_registration - regular update- _update_id %d", _update_id); 00295 success = _update_id != 0; 00296 } 00297 } 00298 return success; 00299 } 00300 00301 bool M2MNsdlInterface::send_unregister_message() 00302 { 00303 tr_debug("M2MNsdlInterface::send_unregister_message"); 00304 bool success = false; 00305 //Does not clean resources automatically 00306 if(_unregister_id == 0) { 00307 _unregister_id = sn_nsdl_unregister_endpoint(_nsdl_handle); 00308 tr_debug("M2MNsdlInterface::send_unregister_message - _unregister_id %d", _unregister_id); 00309 success = _unregister_id != 0; 00310 } 00311 return success; 00312 } 00313 00314 void *M2MNsdlInterface::memory_alloc(uint16_t size) 00315 { 00316 if(size) 00317 return malloc(size); 00318 else 00319 return 0; 00320 } 00321 00322 void M2MNsdlInterface::memory_free(void *ptr) 00323 { 00324 if(ptr) 00325 free(ptr); 00326 } 00327 00328 uint8_t M2MNsdlInterface::send_to_server_callback(struct nsdl_s * /*nsdl_handle*/, 00329 sn_nsdl_capab_e /*protocol*/, 00330 uint8_t *data_ptr, 00331 uint16_t data_len, 00332 sn_nsdl_addr_s *address) 00333 { 00334 tr_debug("M2MNsdlInterface::send_to_server_callback()"); 00335 _observer.coap_message_ready(data_ptr,data_len,address); 00336 return 1; 00337 } 00338 00339 uint8_t M2MNsdlInterface::received_from_server_callback(struct nsdl_s * /*nsdl_handle*/, 00340 sn_coap_hdr_s *coap_header, 00341 sn_nsdl_addr_s *address) 00342 { 00343 tr_debug("M2MNsdlInterface::received_from_server_callback()"); 00344 _observer.coap_data_processed(); 00345 uint8_t value = 0; 00346 if(coap_header) { 00347 if(coap_header->msg_id == _register_id) { 00348 _register_id = 0; 00349 if(coap_header->msg_code == COAP_MSG_CODE_RESPONSE_CREATED) { 00350 if(_server) { 00351 delete _server; 00352 _server = NULL; 00353 } 00354 tr_debug("M2MNsdlInterface::received_from_server_callback - registration callback"); 00355 _server = new M2MServer(); 00356 _server->set_resource_value(M2MServer::ShortServerID,1); 00357 00358 _observer.client_registered(_server); 00359 // If lifetime is less than zero then leave the field empty 00360 if(coap_header->options_list_ptr) { 00361 if(coap_header->options_list_ptr->max_age_ptr) { 00362 if(_endpoint->lifetime_ptr) { 00363 memory_free(_endpoint->lifetime_ptr); 00364 _endpoint->lifetime_ptr = NULL; 00365 _endpoint->lifetime_len = 0; 00366 } 00367 uint32_t max_time = 0; 00368 for(int i=0;i < coap_header->options_list_ptr->max_age_len; i++) { 00369 max_time += (*(coap_header->options_list_ptr->max_age_ptr + i) & 0xff) << 00370 8*(coap_header->options_list_ptr->max_age_len- 1 - i); 00371 } 00372 // If lifetime is less than zero then leave the field empty 00373 if( max_time > 0) { 00374 char *buffer = (char*)memory_alloc(20); 00375 if(buffer) { 00376 int size = snprintf(buffer, 20,"%ld",(long int)max_time); 00377 _endpoint->lifetime_ptr = (uint8_t*)memory_alloc(size+1); 00378 00379 if(_endpoint->lifetime_ptr) { 00380 memset(_endpoint->lifetime_ptr, 0, size+1); 00381 memcpy(_endpoint->lifetime_ptr,buffer,size); 00382 _endpoint->lifetime_len = size; 00383 } 00384 memory_free(buffer); 00385 } 00386 } 00387 } 00388 if(coap_header->options_list_ptr->location_path_ptr) { 00389 _endpoint->location_ptr = (uint8_t*)memory_alloc(coap_header->options_list_ptr->location_path_len+1); 00390 memset(_endpoint->location_ptr,0,coap_header->options_list_ptr->location_path_len+1); 00391 memcpy(_endpoint->location_ptr, 00392 coap_header->options_list_ptr->location_path_ptr, 00393 coap_header->options_list_ptr->location_path_len); 00394 _endpoint->location_len = coap_header->options_list_ptr->location_path_len ; 00395 sn_nsdl_set_endpoint_location(_nsdl_handle,_endpoint->location_ptr,_endpoint->location_len); 00396 } 00397 } 00398 if(_endpoint->lifetime_ptr) { 00399 _registration_timer->stop_timer(); 00400 _registration_timer->start_timer(registration_time() * 1000, 00401 M2MTimerObserver::Registration, 00402 false); 00403 } 00404 } else { 00405 if(_server) { 00406 delete _server; 00407 _server = NULL; 00408 } 00409 tr_error("M2MNsdlInterface::received_from_server_callback - registration error %d", coap_header->msg_code); 00410 M2MInterface::Error error = interface_error(coap_header); 00411 _observer.registration_error(error); 00412 } 00413 } else if(coap_header->msg_id == _unregister_id) { 00414 _unregister_id = 0; 00415 if(coap_header->msg_code == COAP_MSG_CODE_RESPONSE_DELETED) { 00416 _registration_timer->stop_timer(); 00417 if(_server) { 00418 delete _server; 00419 _server = NULL; 00420 } 00421 tr_debug("M2MNsdlInterface::received_from_server_callback - unregistration callback"); 00422 _observer.client_unregistered(); 00423 } else { 00424 tr_error("M2MNsdlInterface::received_from_server_callback - unregistration error %d", coap_header->msg_code); 00425 M2MInterface::Error error = interface_error(coap_header); 00426 _observer.registration_error(error); 00427 } 00428 } else if(coap_header->msg_id == _update_id) { 00429 _update_id = 0; 00430 00431 if(coap_header->msg_code == COAP_MSG_CODE_RESPONSE_CHANGED) { 00432 tr_debug("M2MNsdlInterface::received_from_server_callback - registration_updated successfully"); 00433 _observer.registration_updated(*_server); 00434 } else { 00435 tr_error("M2MNsdlInterface::received_from_server_callback - registration_updated failed %d", coap_header->msg_code); 00436 M2MInterface::Error error = interface_error(coap_header); 00437 // In case, the error for update registration is not allowed implies the client is no longer registered in 00438 // server hence the error returns should be NotRegistered. 00439 if(M2MInterface::NotAllowed == error) { 00440 error = M2MInterface::NotRegistered; 00441 } 00442 _observer.registration_error(error); 00443 } 00444 }else if(coap_header->msg_id == _bootstrap_id) { 00445 _bootstrap_id = 0; 00446 M2MInterface::Error error = interface_error(coap_header); 00447 if(error != M2MInterface::ErrorNone) { 00448 _observer.bootstrap_error(); 00449 } 00450 } else { 00451 if(COAP_MSG_CODE_REQUEST_POST == coap_header->msg_code) { 00452 if(coap_header->uri_path_ptr) { 00453 String resource_name = coap_to_string(coap_header->uri_path_ptr, 00454 coap_header->uri_path_len); 00455 00456 sn_coap_hdr_s *coap_response = NULL; 00457 String object_name; 00458 int slash_found = resource_name.find_last_of('/'); 00459 //The POST operation here is only allowed for non-existing object instances 00460 if(slash_found != -1) { 00461 object_name = resource_name.substr(0,slash_found); 00462 if( object_name.find_last_of('/') != -1){ 00463 coap_response = sn_nsdl_build_response(_nsdl_handle, 00464 coap_header, 00465 COAP_MSG_CODE_RESPONSE_NOT_FOUND); 00466 } else { 00467 int32_t instance_id = atoi(resource_name.substr(slash_found+1, 00468 resource_name.size()-object_name.size()).c_str()); 00469 M2MBase* base = find_resource(object_name); 00470 if(base && (instance_id >= 0) && (instance_id < 65535)) { 00471 if(coap_header->payload_ptr) { 00472 M2MObject* object = (M2MObject*)base; 00473 M2MObjectInstance *obj_instance = object->create_object_instance(instance_id); 00474 if(obj_instance) { 00475 obj_instance->set_operation(M2MBase::GET_PUT_POST_ALLOWED); 00476 coap_response = obj_instance->handle_post_request(_nsdl_handle,coap_header,this); 00477 } 00478 if(coap_response && coap_response->msg_code != COAP_MSG_CODE_RESPONSE_CREATED) { 00479 //Invalid request so remove created ObjectInstance 00480 object->remove_object_instance(instance_id); 00481 } 00482 } else { 00483 tr_debug("M2MNsdlInterface::received_from_server_callback - Missing Payload - Cannot create"); 00484 coap_response = sn_nsdl_build_response(_nsdl_handle, 00485 coap_header, 00486 COAP_MSG_CODE_RESPONSE_BAD_REQUEST); 00487 } 00488 } else { //if(base) 00489 tr_debug("M2MNsdlInterface::received_from_server_callback - Missing BASE - Cannot create"); 00490 coap_response = sn_nsdl_build_response(_nsdl_handle, 00491 coap_header, 00492 COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED); 00493 } 00494 } 00495 } else{ // if(slash_found != -1) 00496 tr_debug("M2MNsdlInterface::received_from_server_callback - slash_found - Cannot create"); 00497 coap_response = sn_nsdl_build_response(_nsdl_handle, 00498 coap_header, 00499 COAP_MSG_CODE_RESPONSE_NOT_FOUND); 00500 } 00501 if(coap_response) { 00502 tr_debug("M2MNsdlInterface::received_from_server_callback - send CoAP response"); 00503 (sn_nsdl_send_coap_message(_nsdl_handle, address, coap_response) == 0) ? value = 0 : value = 1; 00504 sn_nsdl_release_allocated_coap_msg_mem(_nsdl_handle, coap_response); 00505 } 00506 } 00507 } 00508 } 00509 } 00510 return value; 00511 } 00512 00513 uint8_t M2MNsdlInterface::resource_callback(struct nsdl_s */*nsdl_handle*/, 00514 sn_coap_hdr_s *received_coap_header, 00515 sn_nsdl_addr_s *address, 00516 sn_nsdl_capab_e /*nsdl_capab*/) 00517 { 00518 tr_debug("M2MNsdlInterface::resource_callback()"); 00519 _observer.coap_data_processed(); 00520 uint8_t result = 1; 00521 sn_coap_hdr_s *coap_response = NULL; 00522 sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; // 4.00 00523 String resource_name = coap_to_string(received_coap_header->uri_path_ptr, 00524 received_coap_header->uri_path_len); 00525 tr_debug("M2MNsdlInterface::resource_callback() - resource_name %s", resource_name.c_str()); 00526 M2MBase* base = find_resource(resource_name); 00527 00528 if(base) { 00529 if(COAP_MSG_CODE_REQUEST_GET == received_coap_header->msg_code) { 00530 coap_response = base->handle_get_request(_nsdl_handle, received_coap_header,this); 00531 } else if(COAP_MSG_CODE_REQUEST_PUT == received_coap_header->msg_code) { 00532 coap_response = base->handle_put_request(_nsdl_handle, received_coap_header,this); 00533 } else if(COAP_MSG_CODE_REQUEST_POST == received_coap_header->msg_code) { 00534 if(base->base_type() == M2MBase::ResourceInstance) { 00535 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; 00536 } else { 00537 coap_response = base->handle_post_request(_nsdl_handle, received_coap_header,this); 00538 } 00539 } else if(COAP_MSG_CODE_REQUEST_DELETE == received_coap_header->msg_code) { 00540 // Delete the object instance 00541 tr_debug("M2MNsdlInterface::resource_callback() - DELETE the object instance"); 00542 M2MBase::BaseType type = base->base_type(); 00543 if(M2MBase::ObjectInstance == type) { 00544 M2MBase* base_object = find_resource(base->name()); 00545 if(base_object) { 00546 M2MObject *object = (M2MObject*)base_object; 00547 int slash_found = resource_name.find_last_of('/'); 00548 // Object instance validty checks done in upper level, no need for error handling 00549 if(slash_found != -1) { 00550 String object_name; 00551 object_name = resource_name.substr(slash_found + 1, resource_name.length()); 00552 if (object->remove_object_instance(strtoul( 00553 object_name.c_str(), NULL, 10))) { 00554 msg_code = COAP_MSG_CODE_RESPONSE_DELETED; 00555 } 00556 } 00557 } 00558 } else { 00559 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; // 4.00 00560 } 00561 } 00562 } else { 00563 tr_debug("M2MNsdlInterface::resource_callback() - Resource NOT FOUND"); 00564 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; // 4.00 00565 } 00566 if(!coap_response) { 00567 coap_response = sn_nsdl_build_response(_nsdl_handle, 00568 received_coap_header, 00569 msg_code); 00570 } 00571 if(coap_response) { 00572 tr_debug("M2MNsdlInterface::resource_callback() - send CoAP response"); 00573 (sn_nsdl_send_coap_message(_nsdl_handle, address, coap_response) == 0) ? result = 0 : result = 1; 00574 if(coap_response->payload_ptr) { 00575 free(coap_response->payload_ptr); 00576 coap_response->payload_ptr = NULL; 00577 } 00578 sn_nsdl_release_allocated_coap_msg_mem(_nsdl_handle, coap_response); 00579 } 00580 return result; 00581 } 00582 00583 void M2MNsdlInterface::bootstrap_done_callback(sn_nsdl_oma_server_info_t *server_info) 00584 { 00585 tr_debug("M2MNsdlInterface::bootstrap_done_callback()"); 00586 _bootstrap_id = 0; 00587 M2MSecurity* security = NULL; 00588 if(server_info && server_info->omalw_address_ptr->addr_ptr) { 00589 security = new M2MSecurity(M2MSecurity::M2MServer); 00590 uint16_t port = server_info->omalw_address_ptr->port; 00591 char *buffer = (char*)memory_alloc(20); 00592 snprintf(buffer, 20,"%d",port); 00593 String server_uri(COAP); 00594 String server_address; 00595 //TODO: currently only supports IPV4 Mapping, fix to support IPV6 as well 00596 if(SN_NSDL_ADDRESS_TYPE_IPV4 == server_info->omalw_address_ptr->type) { 00597 int val = 0; 00598 for(int index = 0; index < server_info->omalw_address_ptr->addr_len; index++) { 00599 char *server_buffer = (char*)memory_alloc(20); 00600 val = (int)server_info->omalw_address_ptr->addr_ptr[index]; 00601 snprintf(server_buffer, 20,"%d",val); 00602 server_address +=String(server_buffer); 00603 00604 memory_free(server_buffer); 00605 00606 if(index < server_info->omalw_address_ptr->addr_len-1) { 00607 server_address += String("."); 00608 } 00609 } 00610 00611 tr_debug("M2MNsdlInterface::bootstrap_done_callback - IPv4 Server address received %s", server_address.c_str()); 00612 } else if(SN_NSDL_ADDRESS_TYPE_HOSTNAME == server_info->omalw_address_ptr->type) { 00613 char *hostname = (char*)memory_alloc(server_info->omalw_address_ptr->addr_len); 00614 if(hostname) { 00615 memset(hostname, 0, server_info->omalw_address_ptr->addr_len); 00616 memcpy(hostname, 00617 server_info->omalw_address_ptr->addr_ptr, 00618 server_info->omalw_address_ptr->addr_len); 00619 server_address += String(hostname); 00620 memory_free(hostname); 00621 hostname = NULL; 00622 tr_debug("M2MNsdlInterface::bootstrap_done_callback - Hostname Server address received %s", server_address.c_str()); 00623 } 00624 } else if(SN_NSDL_ADDRESS_TYPE_IPV6 == server_info->omalw_address_ptr->type) { 00625 char ipv6_address[40]; 00626 ip6tos(server_info->omalw_address_ptr->addr_ptr, ipv6_address); 00627 server_address += String(ipv6_address); 00628 tr_debug("M2MNsdlInterface::bootstrap_done_callback - IPv6 Server address received %s", server_address.c_str()); 00629 } 00630 00631 server_uri += server_address; 00632 server_uri +=String(":"); 00633 server_uri += String(buffer); 00634 00635 memory_free(buffer); 00636 security->set_resource_value(M2MSecurity::M2MServerUri, server_uri); 00637 security->set_resource_value(M2MSecurity::BootstrapServer, 0); 00638 00639 M2MSecurity::SecurityModeType security_mode = M2MSecurity::SecurityNotSet; 00640 00641 switch(server_info->omalw_server_security) { 00642 case SEC_NOT_SET: 00643 security_mode = M2MSecurity::SecurityNotSet; 00644 break; 00645 case PSK: 00646 //Not supported at the moment 00647 break; 00648 case RPK: 00649 //Not supported at the moment 00650 break; 00651 case CERTIFICATE: 00652 security_mode = M2MSecurity::Certificate; 00653 break; 00654 case NO_SEC: 00655 security_mode = M2MSecurity::NoSecurity; 00656 break; 00657 } 00658 security->set_resource_value(M2MSecurity::SecurityMode,security_mode); 00659 00660 //TODO: This is mandatory parameter for LWM2M server, 00661 // why is it missing from nsdl-c API ? 00662 security->set_resource_value(M2MSecurity::ShortServerID,1); 00663 00664 // Check certiticates only if the mode is Certificate 00665 // else it is in NoSecurity Mode, Psk and Rsk are not supported. 00666 if(M2MSecurity::Certificate == security_mode) { 00667 omalw_certificate_list_t *certificates = sn_nsdl_get_certificates(_nsdl_handle); 00668 if(certificates) { 00669 security->set_resource_value(M2MSecurity::ServerPublicKey,certificates->certificate_ptr[0],certificates->certificate_len[0]); 00670 security->set_resource_value(M2MSecurity::PublicKey,certificates->certificate_ptr[1],certificates->certificate_len[1]); 00671 security->set_resource_value(M2MSecurity::Secretkey,certificates->own_private_key_ptr,certificates->own_private_key_len); 00672 } else { 00673 // Mode is certificate but certificates are missing so its bootstrap error. 00674 delete security; 00675 security = NULL; 00676 } 00677 } 00678 } 00679 if(security) { 00680 tr_debug("M2MNsdlInterface::bootstrap_done_callback - bootstrap_done"); 00681 // Inform that bootstrap is done and LWM2M server object is available. 00682 _observer.bootstrap_done(security); 00683 } else { 00684 tr_error("M2MNsdlInterface::bootstrap_done_callback - bootstrap_error"); 00685 // Bootstrap error inform to the application. 00686 _observer.bootstrap_error(); 00687 } 00688 } 00689 00690 bool M2MNsdlInterface::process_received_data(uint8_t *data, 00691 uint16_t data_size, 00692 sn_nsdl_addr_s *address) 00693 { 00694 tr_debug("M2MNsdlInterface::process_received_data( data size %d)", data_size); 00695 return (0 == sn_nsdl_process_coap(_nsdl_handle, 00696 data, 00697 data_size, 00698 address)) ? true : false; 00699 } 00700 00701 void M2MNsdlInterface::stop_timers() 00702 { 00703 tr_debug("M2MNsdlInterface::stop_timers()"); 00704 if(_registration_timer) { 00705 _registration_timer->stop_timer(); 00706 } 00707 } 00708 00709 void M2MNsdlInterface::timer_expired(M2MTimerObserver::Type type) 00710 { 00711 if(M2MTimerObserver::NsdlExecution == type) { 00712 sn_nsdl_exec(_nsdl_handle, _counter_for_nsdl); 00713 _counter_for_nsdl++; 00714 } else if(M2MTimerObserver::Registration == type) { 00715 tr_debug("M2MNsdlInterface::timer_expired - M2MTimerObserver::Registration - Send update registration"); 00716 send_update_registration(); 00717 } 00718 } 00719 00720 void M2MNsdlInterface::observation_to_be_sent(M2MBase *object) 00721 { 00722 tr_debug("M2MNsdlInterface::observation_to_be_sent()"); 00723 if(object) { 00724 M2MBase::BaseType type = object->base_type(); 00725 if(type == M2MBase::Object) { 00726 send_object_observation((M2MObject*)object); 00727 } else if(type == M2MBase::ObjectInstance) { 00728 send_object_instance_observation((M2MObjectInstance*)object); 00729 } else if(type == M2MBase::Resource) { 00730 send_resource_observation((M2MResource*)object); 00731 } 00732 } 00733 } 00734 00735 void M2MNsdlInterface::resource_to_be_deleted(const String &resource_name) 00736 { 00737 tr_debug("M2MNsdlInterface::resource_to_be_deleted(resource_name %s)", resource_name.c_str()); 00738 delete_nsdl_resource(resource_name); 00739 } 00740 00741 void M2MNsdlInterface::value_updated(M2MBase *base, 00742 const String &object_name) 00743 { 00744 tr_debug("M2MNsdlInterface::value_updated()"); 00745 if(base) { 00746 switch(base->base_type()) { 00747 case M2MBase::Object: 00748 create_nsdl_object_structure((M2MObject*)base); 00749 break; 00750 case M2MBase::ObjectInstance: 00751 create_nsdl_object_instance_structure((M2MObjectInstance*)base); 00752 break; 00753 case M2MBase::Resource: { 00754 M2MResource* resource = (M2MResource*)base; 00755 create_nsdl_resource_structure(resource,object_name, 00756 resource->supports_multiple_instances()); 00757 } 00758 break; 00759 case M2MBase::ResourceInstance: { 00760 M2MResourceInstance* instance = (M2MResourceInstance*)base; 00761 create_nsdl_resource(instance,object_name); 00762 } 00763 break; 00764 } 00765 } 00766 _observer.value_updated(base); 00767 } 00768 00769 void M2MNsdlInterface::remove_object(M2MBase *object) 00770 { 00771 tr_debug("M2MNsdlInterface::remove_object()"); 00772 M2MObject* rem_object = (M2MObject*)object; 00773 if(rem_object && !_object_list.empty()) { 00774 M2MObjectList::const_iterator it; 00775 it = _object_list.begin(); 00776 int index = 0; 00777 for ( ; it != _object_list.end(); it++, index++ ) { 00778 if((*it) == rem_object) { 00779 _object_list.erase(index); 00780 break; 00781 } 00782 } 00783 } 00784 if(_object_list.empty()) { 00785 _object_list.clear(); 00786 } 00787 } 00788 00789 bool M2MNsdlInterface::create_nsdl_object_structure(M2MObject *object) 00790 { 00791 tr_debug("M2MNsdlInterface::create_nsdl_object_structure()"); 00792 bool success = false; 00793 if(object) { 00794 //object->set_under_observation(false,this); 00795 M2MObjectInstanceList instance_list = object->instances(); 00796 tr_debug("M2MNsdlInterface::create_nsdl_object_structure - Object Instance count %d", instance_list.size()); 00797 if(!instance_list.empty()) { 00798 M2MObjectInstanceList::const_iterator it; 00799 it = instance_list.begin(); 00800 for ( ; it != instance_list.end(); it++ ) { 00801 // Create NSDL structure for all object instances inside 00802 success = create_nsdl_object_instance_structure(*it); 00803 } 00804 } 00805 } 00806 if((object->operation() != M2MBase::NOT_ALLOWED)) { 00807 success = create_nsdl_resource(object,object->name()); 00808 } 00809 return success; 00810 } 00811 00812 bool M2MNsdlInterface::create_nsdl_object_instance_structure(M2MObjectInstance *object_instance) 00813 { 00814 tr_debug("M2MNsdlInterface::create_nsdl_object_instance_structure()"); 00815 bool success = false; 00816 if( object_instance) { 00817 00818 char *inst_id = (char*)malloc(20); 00819 snprintf(inst_id, 20,"%d",object_instance->instance_id()); 00820 00821 // Append object instance id to the object name. 00822 String object_name = object_instance->name(); 00823 object_name += String("/"); 00824 object_name += String(inst_id); 00825 free(inst_id); 00826 00827 00828 //object_instance->set_under_observation(false,this); 00829 00830 M2MResourceList res_list = object_instance->resources(); 00831 tr_debug("M2MNsdlInterface::create_nsdl_object_instance_structure - ResourceBase count %d", res_list.size()); 00832 if(!res_list.empty()) { 00833 M2MResourceList::const_iterator it; 00834 it = res_list.begin(); 00835 for ( ; it != res_list.end(); it++ ) { 00836 // Create NSDL structure for all resources inside 00837 success = create_nsdl_resource_structure(*it,object_name, 00838 (*it)->supports_multiple_instances()); 00839 } 00840 } 00841 if(object_instance->operation() != M2MBase::NOT_ALLOWED) { 00842 success = create_nsdl_resource(object_instance,object_name); 00843 } 00844 } 00845 return success; 00846 } 00847 00848 bool M2MNsdlInterface::create_nsdl_resource_structure(M2MResource *res, 00849 const String &object_name, 00850 bool multiple_instances) 00851 { 00852 tr_debug("M2MNsdlInterface::create_nsdl_resource_structure(object_name %s)", object_name.c_str()); 00853 bool success = false; 00854 if(res) { 00855 // Append object name to the resource. 00856 // Take out the instance Id and append to the 00857 // resource name like "object/0/+ resource + / + 0" 00858 String res_name = object_name; 00859 res_name+= String("/"); 00860 res_name.append(res->name().c_str(),res->name().length()); 00861 00862 // if there are multiple instances supported 00863 // then add instance Id into creating resource path 00864 // else normal /object_id/object_instance/resource_id format. 00865 if(multiple_instances) { 00866 M2MResourceInstanceList res_list = res->resource_instances(); 00867 tr_debug("M2MNsdlInterface::create_nsdl_resource_structure - ResourceInstance count %d", res_list.size()); 00868 if(!res_list.empty()) { 00869 M2MResourceInstanceList::const_iterator it; 00870 it = res_list.begin(); 00871 for ( ; it != res_list.end(); it++ ) { 00872 String inst_name = res_name; 00873 // Create NSDL structure for all resources inside 00874 char *inst_id = (char*)memory_alloc(20); 00875 snprintf(inst_id, 20,"%d",(*it)->instance_id()); 00876 inst_name+= String("/") ; 00877 inst_name+= String(inst_id); 00878 00879 memory_free(inst_id); 00880 00881 success = create_nsdl_resource((*it),inst_name); 00882 } 00883 // Register the main Resource as well along with ResourceInstances 00884 success = create_nsdl_resource(res,res_name); 00885 } 00886 } else { 00887 tr_debug("M2MNsdlInterface::create_nsdl_resource_structure - res_name %s", res_name.c_str()); 00888 success = create_nsdl_resource(res,res_name); 00889 } 00890 } 00891 return success; 00892 } 00893 00894 bool M2MNsdlInterface::create_nsdl_resource(M2MBase *base, const String &name) 00895 { 00896 tr_debug("M2MNsdlInterface::create_nsdl_resource(name %s)", name.c_str()); 00897 bool success = false; 00898 uint8_t* buffer = 0; 00899 uint32_t length = 0; 00900 00901 // Create the NSDL Resource Pointer... 00902 if(base) { 00903 sn_nsdl_resource_info_s* resource = sn_nsdl_get_resource(_nsdl_handle, 00904 name.length(), 00905 (uint8_t*)name.c_str()); 00906 if(resource) { 00907 success = true; 00908 if(resource->mode == SN_GRS_STATIC) { 00909 if((M2MBase::Resource == base->base_type() || 00910 M2MBase::ResourceInstance == base->base_type()) && 00911 M2MBase::Static == base->mode()) { 00912 M2MResourceInstance *res = (M2MResourceInstance*)base; 00913 res->get_value(buffer,length); 00914 if(resource->resource) { 00915 memory_free(resource->resource); 00916 } 00917 resource->resource = buffer; 00918 resource->resourcelen = length; 00919 sn_nsdl_update_resource(_nsdl_handle,resource); 00920 } 00921 } 00922 // Update Resource access everytime for existing resource. 00923 resource->access = (sn_grs_resource_acl_e)base->operation(); 00924 } else if(_resource) { 00925 base->set_under_observation(false,this); 00926 //TODO: implement access control 00927 // Currently complete access is given 00928 _resource->access = (sn_grs_resource_acl_e)base->operation(); 00929 00930 if((M2MBase::Resource == base->base_type() || 00931 M2MBase::ResourceInstance == base->base_type()) && 00932 M2MBase::Static == base->mode()) { 00933 M2MResourceInstance *res = (M2MResourceInstance*)base; 00934 // Static resource is updated 00935 _resource->mode = SN_GRS_STATIC; 00936 00937 res->get_value(buffer,length); 00938 _resource->resource = buffer; 00939 _resource->resourcelen = length; 00940 } 00941 00942 if(M2MBase::Dynamic == base->mode()){ 00943 // Dynamic resource is updated 00944 _resource->mode = SN_GRS_DYNAMIC; 00945 _resource->sn_grs_dyn_res_callback = __nsdl_c_callback; 00946 } else { 00947 _resource->mode = SN_GRS_DIRECTORY; 00948 } 00949 00950 if( _resource->path != NULL ){ 00951 memory_free(_resource->path); 00952 _resource->path = NULL; 00953 } 00954 if(name.length() > 0 ){ 00955 _resource->path = ((uint8_t*)memory_alloc(name.length()+1)); 00956 if(_resource->path) { 00957 memset(_resource->path, 0, name.length()+1); 00958 memcpy(_resource->path, (uint8_t*)name.c_str(), name.length()); 00959 _resource->pathlen = name.length(); 00960 } 00961 } 00962 00963 if(!base->resource_type().empty() && _resource->resource_parameters_ptr) { 00964 _resource->resource_parameters_ptr->resource_type_ptr = 00965 ((uint8_t*)memory_alloc(base->resource_type().length()+1)); 00966 if(_resource->resource_parameters_ptr->resource_type_ptr) { 00967 memset(_resource->resource_parameters_ptr->resource_type_ptr, 00968 0, base->resource_type().length()+1); 00969 memcpy(_resource->resource_parameters_ptr->resource_type_ptr, 00970 (uint8_t*)base->resource_type().c_str(), 00971 base->resource_type().length()); 00972 _resource->resource_parameters_ptr->resource_type_len = 00973 base->resource_type().length(); 00974 } 00975 } 00976 if(!base->interface_description().empty() && _resource->resource_parameters_ptr) { 00977 _resource->resource_parameters_ptr->interface_description_ptr = 00978 ((uint8_t*)memory_alloc(base->interface_description().length()+1)); 00979 if(_resource->resource_parameters_ptr->interface_description_ptr) { 00980 memset(_resource->resource_parameters_ptr->interface_description_ptr, 00981 0, base->interface_description().length()+1); 00982 memcpy(_resource->resource_parameters_ptr->interface_description_ptr, 00983 (uint8_t*)base->interface_description().c_str(), 00984 base->interface_description().length()); 00985 _resource->resource_parameters_ptr->interface_description_len = 00986 base->interface_description().length(); 00987 } 00988 } 00989 if(_resource->resource_parameters_ptr) { 00990 _resource->resource_parameters_ptr->coap_content_type = base->coap_content_type(); 00991 _resource->resource_parameters_ptr->observable = (uint8_t)base->is_observable(); 00992 } 00993 00994 int8_t result = sn_nsdl_create_resource(_nsdl_handle,_resource); 00995 tr_debug("M2MNsdlInterface::create_nsdl_resource - Creating in NSDL-C result %d", result); 00996 00997 // Either the resource is created or it already 00998 // exists , then result is success. 00999 if (result == 0 || 01000 result == -2){ 01001 success = true; 01002 } 01003 01004 if(_resource->path) { 01005 memory_free(_resource->path); 01006 } 01007 if(_resource->resource_parameters_ptr->resource_type_ptr){ 01008 memory_free(_resource->resource_parameters_ptr->resource_type_ptr); 01009 } 01010 if(_resource->resource_parameters_ptr->interface_description_ptr){ 01011 memory_free(_resource->resource_parameters_ptr->interface_description_ptr); 01012 } 01013 01014 //Clear up the filled resource to fill up new resource. 01015 clear_resource(_resource); 01016 01017 if(success) { 01018 base->set_under_observation(false,this); 01019 } 01020 } 01021 } 01022 if(buffer) { 01023 free(buffer); 01024 } 01025 return success; 01026 } 01027 01028 // convenience method to get the URI from its buffer field... 01029 String M2MNsdlInterface::coap_to_string(uint8_t *coap_data,int coap_data_length) 01030 { 01031 String value = ""; 01032 if (coap_data != NULL && coap_data_length > 0) { 01033 char buf[256+1]; 01034 memset(buf,0,256+1); 01035 memcpy(buf,(char *)coap_data,coap_data_length); 01036 value = String(buf); 01037 } 01038 return value; 01039 } 01040 01041 uint64_t M2MNsdlInterface::registration_time() 01042 { 01043 uint64_t value = 0; 01044 if(_endpoint->lifetime_ptr) { 01045 value = atol((const char*)_endpoint->lifetime_ptr); 01046 } 01047 01048 if(value >= OPTIMUM_LIFETIME) { 01049 value = value - REDUCE_LIFETIME; 01050 } else { 01051 value = REDUCTION_FACTOR * value; 01052 } 01053 tr_debug("M2MNsdlInterface::registration_time - value (in seconds) %ld", value); 01054 return value; 01055 } 01056 01057 M2MBase* M2MNsdlInterface::find_resource(const String &object_name) 01058 { 01059 M2MBase *object = NULL; 01060 if(!_object_list.empty()) { 01061 M2MObjectList::const_iterator it; 01062 it = _object_list.begin(); 01063 for ( ; it != _object_list.end(); it++ ) { 01064 if((*it)->name() == object_name) { 01065 object = (*it); 01066 tr_debug("M2MNsdlInterface::find_resource(%s) found", object_name.c_str()); 01067 break; 01068 } 01069 object = find_resource((*it),object_name); 01070 if(object != NULL) { 01071 tr_debug("M2MNsdlInterface::find_resource(%s) found", object_name.c_str()); 01072 break; 01073 } 01074 } 01075 } 01076 return object; 01077 } 01078 01079 M2MBase* M2MNsdlInterface::find_resource(const M2MObject *object, 01080 const String &object_instance) 01081 { 01082 M2MBase *instance = NULL; 01083 if(object) { 01084 M2MObjectInstanceList list = object->instances(); 01085 if(!list.empty()) { 01086 M2MObjectInstanceList::const_iterator it; 01087 it = list.begin(); 01088 for ( ; it != list.end(); it++ ) { 01089 char *inst_id = (char*)memory_alloc(20); 01090 snprintf(inst_id, 20,"%d",(*it)->instance_id()); 01091 01092 // Append object instance id to the object name. 01093 String name = (*it)->name(); 01094 name+= String("/"); 01095 name+= String(inst_id); 01096 01097 memory_free(inst_id); 01098 01099 if(name == object_instance){ 01100 instance = (*it); 01101 break; 01102 } 01103 instance = find_resource((*it),object_instance); 01104 if(instance != NULL){ 01105 break; 01106 } 01107 } 01108 } 01109 } 01110 return instance; 01111 } 01112 01113 M2MBase* M2MNsdlInterface::find_resource(const M2MObjectInstance *object_instance, 01114 const String &resource_instance) 01115 { 01116 M2MBase *instance = NULL; 01117 if(object_instance) { 01118 M2MResourceList list = object_instance->resources(); 01119 if(!list.empty()) { 01120 M2MResourceList::const_iterator it; 01121 it = list.begin(); 01122 for ( ; it != list.end(); it++ ) { 01123 String name = object_instance->name(); 01124 char *obj_inst_id = (char*)memory_alloc(20); 01125 snprintf(obj_inst_id, 20,"%d",object_instance->instance_id()); 01126 01127 // Append object instance id to the object name. 01128 name+= String("/"); 01129 name+= String(obj_inst_id); 01130 01131 memory_free(obj_inst_id); 01132 01133 name+= String("/"); 01134 name+= (*it)->name(); 01135 01136 if(name == resource_instance) { 01137 instance = *it; 01138 break; 01139 } else if((*it)->supports_multiple_instances()) { 01140 instance = find_resource((*it),name, resource_instance); 01141 if(instance != NULL){ 01142 break; 01143 } 01144 } 01145 } 01146 } 01147 } 01148 return instance; 01149 } 01150 01151 M2MBase* M2MNsdlInterface::find_resource(const M2MResource *resource, 01152 const String &object_name, 01153 const String &resource_instance) 01154 { 01155 M2MBase *res = NULL; 01156 if(resource) { 01157 if(resource->supports_multiple_instances()) { 01158 M2MResourceInstanceList list = resource->resource_instances(); 01159 if(!list.empty()) { 01160 M2MResourceInstanceList::const_iterator it; 01161 it = list.begin(); 01162 for ( ; it != list.end(); it++ ) { 01163 String name = object_name; 01164 // if there are multiple instances supported 01165 // then add instance Id into creating resource path 01166 // else normal /object_id/object_instance/resource_id format. 01167 01168 char *inst_id = (char*)memory_alloc(20); 01169 snprintf(inst_id, 20,"%d",(*it)->instance_id()); 01170 01171 name+= String("/") ; 01172 name+= String(inst_id); 01173 01174 memory_free(inst_id); 01175 01176 if(name == resource_instance){ 01177 res = (*it); 01178 break; 01179 } 01180 } 01181 } 01182 } 01183 } 01184 return res; 01185 } 01186 01187 bool M2MNsdlInterface::object_present(M2MObject* object) const 01188 { 01189 bool success = false; 01190 if(object && !_object_list.empty()) { 01191 M2MObjectList::const_iterator it; 01192 it = _object_list.begin(); 01193 for ( ; it != _object_list.end(); it++ ) { 01194 if((*it) == object) { 01195 success = true; 01196 break; 01197 } 01198 } 01199 } 01200 return success; 01201 } 01202 01203 bool M2MNsdlInterface::add_object_to_list(M2MObject* object) 01204 { 01205 bool success = false; 01206 if(object && !object_present(object)) { 01207 _object_list.push_back(object); 01208 success = true; 01209 } 01210 return success; 01211 } 01212 01213 void M2MNsdlInterface::clear_resource(sn_nsdl_resource_info_s *&resource) 01214 { 01215 //Clear up the filled resource to fill up new resource. 01216 if(resource && resource->resource_parameters_ptr) { 01217 sn_nsdl_resource_parameters_s *temp_resource_parameter = resource->resource_parameters_ptr; 01218 memset(resource->resource_parameters_ptr, 0, sizeof(sn_nsdl_resource_parameters_s)); 01219 memset(resource,0, sizeof(sn_nsdl_resource_info_s)); 01220 resource->resource_parameters_ptr = temp_resource_parameter; 01221 } 01222 } 01223 01224 M2MInterface::Error M2MNsdlInterface::interface_error(sn_coap_hdr_s *coap_header) 01225 { 01226 M2MInterface::Error error = M2MInterface::ErrorNone; 01227 if(coap_header) { 01228 switch(coap_header->msg_code) { 01229 case COAP_MSG_CODE_RESPONSE_BAD_REQUEST: 01230 case COAP_MSG_CODE_RESPONSE_BAD_OPTION: 01231 case COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_INCOMPLETE: 01232 case COAP_MSG_CODE_RESPONSE_PRECONDITION_FAILED: 01233 case COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE: 01234 case COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT: 01235 error = M2MInterface::InvalidParameters; 01236 break; 01237 case COAP_MSG_CODE_RESPONSE_UNAUTHORIZED: 01238 case COAP_MSG_CODE_RESPONSE_FORBIDDEN: 01239 case COAP_MSG_CODE_RESPONSE_NOT_ACCEPTABLE: 01240 case COAP_MSG_CODE_RESPONSE_NOT_FOUND: 01241 case COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED: 01242 error = M2MInterface::NotAllowed; 01243 break; 01244 case COAP_MSG_CODE_RESPONSE_CREATED: 01245 case COAP_MSG_CODE_RESPONSE_DELETED: 01246 case COAP_MSG_CODE_RESPONSE_VALID: 01247 case COAP_MSG_CODE_RESPONSE_CHANGED: 01248 case COAP_MSG_CODE_RESPONSE_CONTENT: 01249 error = M2MInterface::ErrorNone; 01250 break; 01251 default: 01252 error = M2MInterface::UnknownError; 01253 break; 01254 } 01255 if(coap_header->coap_status == COAP_STATUS_BUILDER_MESSAGE_SENDING_FAILED) { 01256 error = M2MInterface::NetworkError; 01257 } 01258 } 01259 return error; 01260 } 01261 01262 void M2MNsdlInterface::send_object_observation(M2MObject *object) 01263 { 01264 tr_debug("M2MNsdlInterface::send_object_observation"); 01265 if(object) { 01266 uint8_t *value = 0; 01267 uint32_t length = 0; 01268 uint8_t *token = 0; 01269 uint32_t token_length = 0; 01270 uint8_t observation_number[2]; 01271 uint8_t observation_number_length = 1; 01272 01273 uint16_t number = object->observation_number(); 01274 01275 observation_number[0] = ((number>>8) & 0xFF); 01276 observation_number[1] = (number & 0xFF); 01277 01278 if(number > 0xFF) { 01279 observation_number_length = 2; 01280 } 01281 01282 M2MTLVSerializer *serializer = new M2MTLVSerializer(); 01283 if(serializer) { 01284 value = serializer->serialize(object->instances(), length); 01285 delete serializer; 01286 } 01287 01288 object->get_observation_token(token,token_length); 01289 01290 sn_nsdl_send_observation_notification(_nsdl_handle, 01291 token, 01292 token_length, 01293 value,length, 01294 observation_number, 01295 observation_number_length, 01296 COAP_MSG_TYPE_CONFIRMABLE, 01297 object->coap_content_type()); 01298 memory_free(value); 01299 memory_free(token); 01300 } 01301 } 01302 01303 void M2MNsdlInterface::send_object_instance_observation(M2MObjectInstance *object_instance) 01304 { 01305 tr_debug("M2MNsdlInterface::send_object_instance_observation"); 01306 if(object_instance) { 01307 uint8_t *value = 0; 01308 uint32_t length = 0; 01309 uint8_t *token = 0; 01310 uint32_t token_length = 0; 01311 uint8_t observation_number[2]; 01312 uint8_t observation_number_length = 1; 01313 01314 uint16_t number = object_instance->observation_number(); 01315 01316 observation_number[0] = ((number>>8) & 0xFF); 01317 observation_number[1] = (number & 0xFF); 01318 01319 if(number > 0xFF) { 01320 observation_number_length = 2; 01321 } 01322 01323 M2MTLVSerializer *serializer = new M2MTLVSerializer(); 01324 if(serializer) { 01325 value = serializer->serialize(object_instance->resources(), length); 01326 delete serializer; 01327 } 01328 01329 object_instance->get_observation_token(token,token_length); 01330 01331 sn_nsdl_send_observation_notification(_nsdl_handle, 01332 token, 01333 token_length, 01334 value,length, 01335 observation_number, 01336 observation_number_length, 01337 COAP_MSG_TYPE_CONFIRMABLE, 01338 object_instance->coap_content_type()); 01339 memory_free(value); 01340 memory_free(token); 01341 } 01342 } 01343 01344 void M2MNsdlInterface::send_resource_observation(M2MResource *resource) 01345 { 01346 tr_debug("M2MNsdlInterface::send_resource_observation"); 01347 if(resource) { 01348 uint8_t *value = 0; 01349 uint32_t length = 0; 01350 uint8_t *token = 0; 01351 uint32_t token_length = 0; 01352 uint8_t observation_number[2]; 01353 uint8_t observation_number_length = 1; 01354 01355 uint16_t number = resource->observation_number(); 01356 01357 observation_number[0] = ((number>>8) & 0xFF); 01358 observation_number[1] = (number & 0xFF); 01359 01360 if(number > 0xFF) { 01361 observation_number_length = 2; 01362 } 01363 01364 resource->get_observation_token(token,token_length); 01365 uint8_t content_type = 0; 01366 if (resource->resource_instance_count() > 0) { 01367 M2MTLVSerializer *serializer = new M2MTLVSerializer(); 01368 content_type = COAP_CONTENT_OMA_TLV_TYPE; 01369 if(serializer) { 01370 value = serializer->serialize(resource, length); 01371 delete serializer; 01372 } 01373 } else { 01374 resource->get_value(value,length); 01375 } 01376 01377 sn_nsdl_send_observation_notification(_nsdl_handle, 01378 token, 01379 token_length, 01380 value,length, 01381 observation_number, 01382 observation_number_length, 01383 COAP_MSG_TYPE_CONFIRMABLE, 01384 content_type); 01385 memory_free(value); 01386 memory_free(token); 01387 } 01388 }
Generated on Tue Jul 12 2022 12:47:47 by
