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.
thread_leader_service.c
00001 /* 00002 * Copyright (c) 2016-2017, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: BSD-3-Clause 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the copyright holder nor the 00014 * names of its contributors may be used to endorse or promote products 00015 * derived from this software without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00018 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00021 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00022 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00023 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00024 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00025 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00026 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00027 * POSSIBILITY OF SUCH DAMAGE. 00028 */ 00029 00030 #include "nsconfig.h" 00031 00032 #include <string.h> 00033 #include "ns_types.h" 00034 #include <nsdynmemLIB.h> 00035 #include <ns_list.h> 00036 #include "randLIB.h" 00037 #include "ns_trace.h" 00038 #include "common_functions.h" 00039 #include "thread_management_if.h" 00040 #include "thread_border_router_api.h" 00041 #include "6LoWPAN/Thread/thread_config.h" 00042 #include "6LoWPAN/Thread/thread_common.h" 00043 #include "6LoWPAN/Thread/thread_bootstrap.h" 00044 #include "6LoWPAN/Thread/thread_dhcpv6_client.h" 00045 #include "6LoWPAN/Thread/thread_discovery.h" 00046 #include "6LoWPAN/Thread/thread_joiner_application.h" 00047 #include "6LoWPAN/Thread/thread_network_data_lib.h" 00048 #include "6LoWPAN/Thread/thread_nd.h" 00049 #include "6LoWPAN/Thread/thread_tmfcop_lib.h" 00050 #include "6LoWPAN/Thread/thread_management_internal.h" 00051 #include "6LoWPAN/Thread/thread_management_server.h" 00052 #include "6LoWPAN/Thread/thread_commissioning_if.h" 00053 #include "6LoWPAN/Thread/thread_extension.h" 00054 #include "6LoWPAN/Thread/thread_leader_service.h" 00055 #include "6LoWPAN/Thread/thread_router_bootstrap.h" 00056 #include "6LoWPAN/Thread/thread_network_synch.h" 00057 #include "6LoWPAN/Thread/thread_nvm_store.h" 00058 #include "Service_Libs/mle_service/mle_service_api.h" 00059 #include "6LoWPAN/Thread/thread_host_bootstrap.h" 00060 #include "6LoWPAN/Thread/thread_border_router_api_internal.h" 00061 #include "MPL/mpl.h" 00062 #include "MLE/mle.h" 00063 #include "6LoWPAN/MAC/mac_helper.h" 00064 #include "mac_api.h" 00065 #include "6LoWPAN/MAC/mac_data_poll.h" 00066 #include "coap_service_api.h" 00067 00068 #define TRACE_GROUP "tLdr" 00069 00070 #ifdef HAVE_THREAD_LEADER_SERVICE 00071 00072 /* 00073 * Leader instance data. 00074 */ 00075 typedef struct thread_leader_service { 00076 int8_t interface_id; 00077 int8_t coap_service_id; 00078 bool leader_enabled: 1; 00079 ns_list_link_t link; 00080 } thread_leader_service_t; 00081 00082 /* 00083 * Helper structure for router_id handling 00084 */ 00085 typedef struct { 00086 uint8_t routerID[8]; 00087 uint32_t validLifeTime; 00088 uint32_t preferredLifeTime; 00089 uint16_t shortAddress; 00090 uint8_t dataSeq; 00091 } thread_leader_service_router_id_resp_t; 00092 00093 static NS_LIST_DEFINE(leader_service_instance_list, thread_leader_service_t, link); 00094 00095 static void thread_leader_service_commissioner_timeout_cb(void* arg); 00096 00097 /* Private functions */ 00098 static thread_leader_service_t *thread_leader_service_find_by_interface(int8_t interface_id) 00099 { 00100 thread_leader_service_t *this = NULL; 00101 ns_list_foreach(thread_leader_service_t, cur_br, &leader_service_instance_list) { 00102 if (cur_br->interface_id == interface_id) { 00103 this = cur_br; 00104 break; 00105 } 00106 } 00107 return this; 00108 } 00109 00110 static thread_leader_service_t *thread_leader_service_find_by_service(int8_t service_id) 00111 { 00112 thread_leader_service_t *this = NULL; 00113 ns_list_foreach(thread_leader_service_t, cur_br, &leader_service_instance_list) { 00114 if (cur_br->coap_service_id == service_id) { 00115 this = cur_br; 00116 break; 00117 } 00118 } 00119 return this; 00120 } 00121 00122 static char* thread_commissioning_if_commissioner_id_get(int8_t interface_id) 00123 { 00124 protocol_interface_info_entry_t *cur; 00125 00126 cur = protocol_stack_interface_info_get_by_id(interface_id); 00127 if (!cur || !cur->thread_info || !cur->thread_info->registered_commissioner.commissioner_valid) { 00128 return NULL; 00129 } 00130 00131 return cur->thread_info->registered_commissioner.commissioner_id_ptr; 00132 } 00133 00134 00135 static bool thread_leader_service_commissioner_address_changed(int8_t interface_id, uint8_t border_router_address[static 16]) 00136 { 00137 protocol_interface_info_entry_t *cur; 00138 00139 cur = protocol_stack_interface_info_get_by_id(interface_id); 00140 if (!cur || !cur->thread_info || !cur->thread_info->registered_commissioner.commissioner_valid) { 00141 return false; 00142 } 00143 00144 if(!memcmp(cur->thread_info->registered_commissioner.border_router_address, border_router_address, 16)) { 00145 // Border router address is same 00146 return false; 00147 } 00148 if( common_read_16_bit(&border_router_address[14]) >= 0xfc00 ) { 00149 // Address is not valid RLOC we dont change address to this. 00150 return false; 00151 } 00152 memcpy(cur->thread_info->registered_commissioner.border_router_address, border_router_address, 16); 00153 thread_leader_service_network_data_changed(cur,false,true); 00154 // This will trigger advertisement either from following commands or from leader tick 00155 return true; 00156 } 00157 static int thread_leader_service_steering_data_set(int8_t interface_id, uint8_t *buf_ptr, uint16_t length) 00158 { 00159 protocol_interface_info_entry_t *cur; 00160 link_configuration_s *linkConfiguration; 00161 00162 linkConfiguration = thread_joiner_application_get_config(interface_id); 00163 if (!linkConfiguration) { 00164 return -1; 00165 } 00166 00167 cur = protocol_stack_interface_info_get_by_id(interface_id); 00168 if (!cur || !cur->thread_info || !cur->thread_info->leader_private_data || !cur->thread_info->registered_commissioner.commissioner_valid) { 00169 return -1; 00170 } 00171 if (length > 16) { 00172 return -2; 00173 } 00174 00175 tr_debug("Save new steering data %s", trace_array(buf_ptr, length)); 00176 00177 cur->thread_info->registered_commissioner.steering_data_len = 0; 00178 00179 if (buf_ptr && length > 0) { 00180 memcpy(cur->thread_info->registered_commissioner.steering_data, buf_ptr, length); 00181 cur->thread_info->registered_commissioner.steering_data_len = length; 00182 } 00183 00184 thread_leader_service_network_data_changed(cur, false, true); 00185 00186 return 0; 00187 } 00188 00189 static bool thread_leader_service_commissioner_unregister(int8_t interface_id, uint16_t session_id) 00190 { 00191 protocol_interface_info_entry_t *cur; 00192 link_configuration_s *linkConfiguration; 00193 00194 linkConfiguration = thread_joiner_application_get_config(interface_id); 00195 if(!linkConfiguration) 00196 return false; 00197 00198 cur = protocol_stack_interface_info_get_by_id(interface_id); 00199 if (!cur || !cur->thread_info || !cur->thread_info->leader_private_data) 00200 return false; 00201 00202 if (cur->thread_info->registered_commissioner.session_id != session_id) { 00203 tr_debug("Commissioner session id not valid - unregister failed"); 00204 return false; 00205 } 00206 // Removing commissioner we need to increase the session id 00207 cur->thread_info->registered_commissioner.session_id++; 00208 00209 if(cur->thread_info->registered_commissioner.commissioner_id_ptr){ 00210 ns_dyn_mem_free(cur->thread_info->registered_commissioner.commissioner_id_ptr); 00211 cur->thread_info->registered_commissioner.commissioner_id_ptr = NULL; 00212 } 00213 00214 cur->thread_info->registered_commissioner.commissioner_valid = false; 00215 cur->thread_info->registered_commissioner.steering_data_len = 0; 00216 00217 /* Send unregistration without delay */ 00218 thread_leader_service_network_data_changed(cur, false, true); 00219 00220 eventOS_timeout_cancel(cur->thread_info->registered_commissioner.commissioner_timeout); 00221 cur->thread_info->registered_commissioner.commissioner_timeout = NULL; 00222 cur->thread_info->registered_commissioner.commissioner_registration = THREAD_COMMISSIONER_NOT_REGISTERED; 00223 00224 return true; 00225 } 00226 00227 static bool thread_leader_service_commissioner_session_refresh(int8_t interface_id, uint16_t session_id) 00228 { 00229 protocol_interface_info_entry_t *cur; 00230 00231 // Check pointers 00232 cur = protocol_stack_interface_info_get_by_id(interface_id); 00233 if (!cur || !cur->thread_info || !cur->thread_info->leader_private_data || !cur->thread_info->registered_commissioner.commissioner_valid) { 00234 return false; 00235 } 00236 00237 if(cur->thread_info->registered_commissioner.commissioner_registration == THREAD_COMMISSIONER_NOT_REGISTERED) { 00238 tr_debug("Commissioner not registered - refresh failed"); 00239 return false; 00240 } 00241 00242 if (cur->thread_info->registered_commissioner.session_id != session_id) { 00243 tr_debug("Commissioner session id not valid - refresh failed"); 00244 return false; 00245 } 00246 00247 cur->thread_info->registered_commissioner.commissioner_registration = THREAD_COMMISSIONER_REGISTERED; 00248 00249 eventOS_timeout_cancel(cur->thread_info->registered_commissioner.commissioner_timeout); 00250 cur->thread_info->registered_commissioner.commissioner_timeout = eventOS_timeout_ms(thread_leader_service_commissioner_timeout_cb, COMMISSIONER_OBSOLETE_TIMEOUT, cur->thread_info); 00251 00252 return true; 00253 } 00254 00255 static void thread_leader_service_commissioner_timeout_cb(void* arg) 00256 { 00257 thread_info_t *thread_ptr = arg; 00258 00259 thread_ptr->registered_commissioner.commissioner_timeout = NULL; 00260 00261 if (!thread_ptr->registered_commissioner.commissioner_valid) { 00262 return; 00263 } 00264 00265 if (!thread_ptr->leader_private_data) { 00266 return; 00267 } 00268 00269 switch(thread_ptr->registered_commissioner.commissioner_registration) 00270 { 00271 case THREAD_COMMISSIONER_REGISTRATION_OBSOLETE: 00272 thread_ptr->registered_commissioner.commissioner_registration = THREAD_COMMISSIONER_NOT_REGISTERED; 00273 if(false == thread_leader_service_commissioner_unregister(thread_ptr->interface_id, thread_ptr->registered_commissioner.session_id)){ 00274 tr_debug("Commissioner registration remove failed"); 00275 } 00276 else{ 00277 tr_debug("Commissioner registration removed"); 00278 } 00279 break; 00280 case THREAD_COMMISSIONER_REGISTERED: 00281 tr_debug("Commissioner registration obsoleted"); 00282 thread_ptr->registered_commissioner.commissioner_registration = THREAD_COMMISSIONER_REGISTRATION_OBSOLETE; 00283 thread_ptr->registered_commissioner.commissioner_timeout = eventOS_timeout_ms(thread_leader_service_commissioner_timeout_cb, COMMISSIONER_REMOVE_TIMEOUT, thread_ptr); 00284 break; 00285 case THREAD_COMMISSIONER_NOT_REGISTERED: 00286 default: 00287 break; 00288 } 00289 } 00290 00291 00292 static int thread_leader_service_commissioner_register(int8_t interface_id, uint8_t border_router_address[static 16], 00293 uint8_t *commissioner_id_ptr, uint16_t commissioner_id_len, 00294 uint16_t *session_id) 00295 { 00296 /* Save commissioner data to new commissioner structure and start advertise it 00297 Commissioner session id 00298 commissioner timestamp 00299 commissioner credentials -> static configuration 00300 security policy -> static configuration 00301 network name -> static configuration 00302 border router locator 00303 steering data 00304 */ 00305 protocol_interface_info_entry_t *cur; 00306 link_configuration_s *linkConfiguration; 00307 00308 tr_debug("Register interface %d commissioner: %s", interface_id, trace_ipv6(border_router_address)); 00309 00310 linkConfiguration = thread_joiner_application_get_config(interface_id); 00311 if (!linkConfiguration) { 00312 return -1; 00313 } 00314 00315 cur = protocol_stack_interface_info_get_by_id(interface_id); 00316 if (!cur || !cur->thread_info || !cur->thread_info->leader_private_data) { 00317 return -1; 00318 } 00319 00320 /* If commissioner already registered */ 00321 if(cur->thread_info->registered_commissioner.commissioner_valid && 00322 cur->thread_info->registered_commissioner.commissioner_registration == THREAD_COMMISSIONER_REGISTERED) { 00323 return -2; 00324 } 00325 00326 ns_dyn_mem_free(cur->thread_info->registered_commissioner.commissioner_id_ptr); 00327 cur->thread_info->registered_commissioner.commissioner_id_ptr = ns_dyn_mem_alloc(commissioner_id_len + 1); 00328 if (!cur->thread_info->registered_commissioner.commissioner_id_ptr) { 00329 return -1; 00330 } 00331 memcpy(cur->thread_info->registered_commissioner.commissioner_id_ptr, commissioner_id_ptr, commissioner_id_len); 00332 cur->thread_info->registered_commissioner.commissioner_id_ptr[commissioner_id_len] = 0; 00333 00334 // Initialise values 00335 cur->thread_info->registered_commissioner.session_id++; 00336 if (cur->thread_info->registered_commissioner.session_id == 0) { 00337 cur->thread_info->registered_commissioner.session_id++; 00338 } 00339 00340 if (session_id) { 00341 *session_id = cur->thread_info->registered_commissioner.session_id; 00342 } 00343 00344 //SET Border Router Locator 00345 memcpy(cur->thread_info->registered_commissioner.border_router_address, border_router_address, 16); 00346 cur->thread_info->registered_commissioner.commissioner_valid = true; 00347 00348 cur->thread_info->registered_commissioner.commissioner_registration = THREAD_COMMISSIONER_REGISTERED; 00349 00350 eventOS_timeout_cancel(cur->thread_info->registered_commissioner.commissioner_timeout); 00351 cur->thread_info->registered_commissioner.commissioner_timeout = eventOS_timeout_ms(thread_leader_service_commissioner_timeout_cb, COMMISSIONER_OBSOLETE_TIMEOUT, cur->thread_info); 00352 00353 /* Delay network data propagation, perhaps we receive more data */ 00354 thread_leader_service_network_data_changed(cur, false, true); 00355 00356 return 0; 00357 } 00358 00359 00360 00361 static int thread_leader_service_active_set_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr) 00362 { 00363 thread_leader_service_t *this = thread_leader_service_find_by_service(service_id); 00364 link_configuration_s *linkConfiguration; 00365 sn_coap_msg_code_e response_code = COAP_MSG_CODE_RESPONSE_CHANGED; 00366 uint16_t session_id; 00367 uint8_t payload[5]; // 4 + 1 00368 uint8_t *ptr; 00369 uint8_t *response_ptr; 00370 uint64_t timestamp; 00371 bool msg_from_commissioner = false; 00372 bool changing_connectivity = false; 00373 (void) source_address; 00374 (void) source_port; 00375 int ret = 0; 00376 00377 if (!this) { 00378 return -1; 00379 } 00380 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(this->interface_id); 00381 linkConfiguration = thread_joiner_application_get_config(this->interface_id); 00382 if(!cur || !cur->thread_info || !linkConfiguration || !cur->thread_info->leader_private_data){ 00383 return -1; 00384 } 00385 00386 tr_info("thread management Active set"); 00387 00388 response_ptr = payload; 00389 00390 if (!thread_management_server_source_address_check(this->interface_id, source_address)) { 00391 response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; 00392 goto send_error_response; 00393 } 00394 00395 if (3 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_CHANNEL, &ptr) && 00396 (linkConfiguration->rfChannel != common_read_16_bit(&ptr[1]) || linkConfiguration->channel_page != *ptr)){ 00397 tr_debug("Channel changed"); 00398 changing_connectivity = true; 00399 // validity check for channel page 00400 if (*ptr != 0 || common_read_16_bit(&ptr[1]) < 11 || common_read_16_bit(&ptr[1]) > 26) { 00401 tr_warn("invalid channel"); 00402 ret = -1; 00403 goto send_response; 00404 } 00405 } 00406 if (2 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_PANID, &ptr) && 00407 linkConfiguration->panId != common_read_16_bit(ptr)){ 00408 tr_debug("PANID changed"); 00409 changing_connectivity = true; 00410 if (common_read_16_bit(ptr) > 0xfffe) { 00411 tr_warn("invalid panid"); 00412 ret = -1; 00413 goto send_response; 00414 } 00415 } 00416 if (3 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_SECURITY_POLICY, &ptr)) { 00417 if (common_read_16_bit(ptr) < 3600) { 00418 tr_warn("invalid security policy"); 00419 ret = -1; 00420 goto send_response; 00421 } 00422 } 00423 00424 if ( 8 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_NETWORK_MESH_LOCAL_ULA, &ptr) && 00425 memcmp(linkConfiguration->mesh_local_ula_prefix,ptr,8) != 0) { 00426 tr_debug("ML prefix changed"); 00427 changing_connectivity = true; 00428 } 00429 if ( 16 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_NETWORK_MASTER_KEY, &ptr) && 00430 memcmp(linkConfiguration->master_key,ptr,16) != 0) { 00431 tr_debug("Master key changed"); 00432 changing_connectivity = true; 00433 } 00434 00435 if (2 <= thread_meshcop_tlv_data_get_uint16(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_COMMISSIONER_SESSION_ID, &session_id)) { 00436 // Session id present must be valid 00437 tr_info("message from commissioner"); 00438 msg_from_commissioner = true; 00439 if (cur->thread_info->registered_commissioner.session_id != session_id) { 00440 tr_warn("Invalid commissioner session id"); 00441 ret = -1; 00442 goto send_response; 00443 } 00444 thread_leader_service_commissioner_address_changed(this->interface_id, source_address); 00445 // Check if address changed 00446 if (changing_connectivity == true) { 00447 tr_warn("Changes affecting connectivity rejected"); 00448 ret = -1; 00449 goto send_response; 00450 } 00451 } 00452 00453 if(8 > thread_meshcop_tlv_data_get_uint64(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_ACTIVE_TIME_STAMP, ×tamp)){ 00454 tr_warn("no timestamp"); 00455 ret = -1; 00456 goto send_response; 00457 } 00458 if (timestamp < linkConfiguration->timestamp){ 00459 tr_warn("older timestamp"); 00460 ret = -1; 00461 goto send_response; 00462 } 00463 if (timestamp == linkConfiguration->timestamp){ 00464 tr_warn("same timestamp"); 00465 ret = -1; 00466 goto send_response; 00467 } 00468 if (!msg_from_commissioner) { 00469 tr_debug("message from end device"); 00470 if (cur->thread_info->registered_commissioner.commissioner_registration != THREAD_COMMISSIONER_NOT_REGISTERED) { 00471 // Node changed settings and Registered commissioner send changed_notify to commissioner 00472 tr_info("Notify commissioner that settings are changed"); 00473 coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, cur->thread_info->registered_commissioner.border_router_address, 00474 THREAD_MANAGEMENT_PORT, COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_DATASET_CHANGED, 00475 COAP_CT_OCTET_STREAM, NULL, 0, NULL); 00476 } 00477 } 00478 if (changing_connectivity) { 00479 00480 tr_info("creating pending configuration"); 00481 00482 if (thread_joiner_application_pending_config_exists(this->interface_id) && 00483 thread_joiner_application_pending_config_timestamp_get(this->interface_id) >= timestamp ) { 00484 tr_info("Pending config is newer we reject"); 00485 ret = -1; 00486 goto send_response; 00487 } 00488 if (thread_joiner_application_pending_config_create(this->interface_id, request_ptr->payload_ptr, request_ptr->payload_len) != 0) { 00489 tr_error("Could not create pending config"); 00490 response_code = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR; 00491 goto send_error_response; 00492 } 00493 00494 // Start distributing pending configuration 00495 thread_joiner_application_pending_config_add_missing_fields(this->interface_id); 00496 thread_joiner_application_pending_config_timestamp_set(this->interface_id, timestamp); 00497 thread_joiner_application_pending_config_enable(this->interface_id, thread_delay_timer_default*1000); 00498 00499 } else { 00500 tr_info("updating active configuration"); 00501 ret = thread_joiner_application_update_configuration(cur->id, request_ptr->payload_ptr, request_ptr->payload_len, true); 00502 // link configuration is changed, read configuration again 00503 linkConfiguration = thread_joiner_application_get_config(cur->id); 00504 if (!linkConfiguration) { 00505 tr_error("Could not find current config"); 00506 response_code = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR; 00507 goto send_error_response; 00508 } 00509 // Activate new configuration. 00510 thread_configuration_thread_activate(cur, linkConfiguration); 00511 } 00512 thread_joiner_application_configuration_nvm_save(this->interface_id); 00513 00514 // Start timer to propagate new data 00515 thread_leader_service_network_data_changed(cur, true, true); 00516 00517 send_response: 00518 // build response 00519 response_ptr = thread_meshcop_tlv_data_write_uint8(response_ptr, MESHCOP_TLV_STATE, ret == 0 ? 1 : 0xff); 00520 00521 send_error_response: 00522 coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, response_code, COAP_CT_OCTET_STREAM, payload, response_ptr - payload); 00523 return 0; 00524 } 00525 00526 static int thread_leader_service_pending_set_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr) 00527 { 00528 thread_leader_service_t *this = thread_leader_service_find_by_service(service_id); 00529 link_configuration_s *linkConfiguration; 00530 uint8_t *ptr; 00531 sn_coap_msg_code_e response_code = COAP_MSG_CODE_RESPONSE_CHANGED; 00532 uint16_t session_id; 00533 uint8_t payload[5]; // 4 + 1 00534 uint8_t *secret_ptr; 00535 uint64_t active_timestamp; 00536 uint64_t pending_timestamp; 00537 uint32_t delay_timer; 00538 (void) source_address; 00539 (void) source_port; 00540 int ret = 0; 00541 bool msg_from_commissioner = false; 00542 bool master_key_changed = false; 00543 00544 ptr = payload; 00545 if (!this) { 00546 return -1; 00547 } 00548 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(this->interface_id); 00549 linkConfiguration = thread_joiner_application_get_config(this->interface_id); 00550 if(!cur || !cur->thread_info || !linkConfiguration || !cur->thread_info->leader_private_data){ 00551 return -1; 00552 } 00553 00554 tr_info("thread management Pending set"); 00555 00556 if (!thread_management_server_source_address_check(this->interface_id, source_address)) { 00557 response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; 00558 goto send_error_response; 00559 } 00560 00561 if (2 <= thread_meshcop_tlv_data_get_uint16(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_COMMISSIONER_SESSION_ID, &session_id)) { 00562 // Session id present must be valid 00563 if (cur->thread_info->registered_commissioner.session_id != session_id) { 00564 tr_warn("Invalid commissioner session id"); 00565 ret = -1; 00566 goto send_response; 00567 } 00568 thread_leader_service_commissioner_address_changed(this->interface_id, source_address); 00569 msg_from_commissioner = true; 00570 } 00571 if ( 16 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_NETWORK_MASTER_KEY, &secret_ptr) && 00572 memcmp(linkConfiguration->master_key,secret_ptr,16) != 0) { 00573 tr_debug("Master key changed"); 00574 master_key_changed = true; 00575 } 00576 00577 if(8 > thread_meshcop_tlv_data_get_uint64(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_PENDING_TIMESTAMP, &pending_timestamp)){ 00578 tr_warn("no timestamp"); 00579 ret = -1; 00580 goto send_response; 00581 } 00582 if(4 > thread_meshcop_tlv_data_get_uint32(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_DELAY_TIMER, &delay_timer)){ 00583 tr_warn("no delay timer"); 00584 ret = -1; 00585 goto send_response; 00586 } 00587 if(8 > thread_meshcop_tlv_data_get_uint64(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_ACTIVE_TIME_STAMP, &active_timestamp)){ 00588 tr_warn("no active timestamp"); 00589 ret = -1; 00590 goto send_response; 00591 } 00592 if (active_timestamp <= linkConfiguration->timestamp && !master_key_changed) { 00593 tr_warn("Timestamp is lower or same, without Master key change"); 00594 ret = -1; 00595 goto send_response; 00596 } 00597 00598 if (thread_joiner_application_pending_config_exists(this->interface_id) && 00599 pending_timestamp <= thread_joiner_application_pending_config_timestamp_get(this->interface_id)){ 00600 tr_warn("Older or same pending timestamp"); 00601 ret = -1; 00602 goto send_response; 00603 } 00604 00605 if (delay_timer > THREAD_MAX_DELAY_TIMER_SECONDS*1000) { 00606 delay_timer = THREAD_MAX_DELAY_TIMER_SECONDS*1000; 00607 } 00608 00609 if (master_key_changed && 00610 delay_timer < thread_delay_timer_default*1000) { 00611 //If message Changes the master key default value is used 00612 delay_timer = thread_delay_timer_default*1000; 00613 } 00614 if (delay_timer < THREAD_DELAY_TIMER_MINIMAL_SECONDS*1000) { 00615 // Absolute minimum value allowed 00616 delay_timer = THREAD_DELAY_TIMER_MINIMAL_SECONDS*1000; 00617 } 00618 00619 if (thread_joiner_application_pending_config_create(this->interface_id, request_ptr->payload_ptr, request_ptr->payload_len) != 0){ 00620 tr_error("Could not create pending config"); 00621 response_code = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR; 00622 goto send_error_response; 00623 } 00624 00625 if (!msg_from_commissioner) { 00626 tr_debug("pending set from end device"); 00627 if (cur->thread_info->registered_commissioner.commissioner_registration != THREAD_COMMISSIONER_NOT_REGISTERED) { 00628 // Node changed settings and Registered commissioner send changed_notify to commissioner 00629 tr_info("Notify commissioner that settings are changed"); 00630 coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, cur->thread_info->registered_commissioner.border_router_address, 00631 THREAD_MANAGEMENT_PORT, COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_DATASET_CHANGED, 00632 COAP_CT_OCTET_STREAM, NULL, 0, NULL); 00633 } 00634 } 00635 00636 tr_info("creating new pending set delay: %"PRIu32, delay_timer); 00637 // Activate pending configuration 00638 thread_joiner_application_pending_config_add_missing_fields(this->interface_id); 00639 thread_joiner_application_pending_config_timestamp_set(this->interface_id, pending_timestamp); 00640 thread_joiner_application_pending_config_enable(this->interface_id, delay_timer); 00641 00642 // Start timer to propagate new data 00643 thread_leader_service_network_data_changed(cur, true, true); 00644 00645 send_response: 00646 // build response 00647 ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, ret == 0 ? 1 : 0xff); 00648 00649 send_error_response: 00650 coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, response_code, COAP_CT_OCTET_STREAM, payload, ptr - payload); 00651 return 0; 00652 } 00653 00654 static int thread_leader_service_commissioner_set_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr) 00655 { 00656 thread_leader_service_t *this = thread_leader_service_find_by_service(service_id); 00657 sn_coap_msg_code_e response_code = COAP_MSG_CODE_RESPONSE_CHANGED; 00658 uint16_t session_id; 00659 uint16_t br_locator; 00660 uint8_t payload[5]; // 4 + 1 00661 uint8_t *ptr; 00662 uint8_t *steering_data_ptr; 00663 uint16_t steering_data_len; 00664 (void) source_address; 00665 (void) source_port; 00666 int ret = -2; 00667 00668 ptr = payload; 00669 if (!this) { 00670 return -1; 00671 } 00672 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(this->interface_id); 00673 if(!cur || !cur->thread_info || !cur->thread_info->leader_private_data){ 00674 return -1; 00675 } 00676 00677 tr_info("thread management commissioner set"); 00678 00679 if (!thread_management_server_source_address_check(this->interface_id, source_address)) { 00680 response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; 00681 goto send_error_response; 00682 } 00683 //Check if the CoAp payload is greater than maximum commissioner data size and reject 00684 if (request_ptr->payload_len > THREAD_MAX_COMMISSIONER_DATA_SIZE){ 00685 tr_error("Payload length greater than maximum commissioner data size"); 00686 ret = -1; 00687 goto send_response; 00688 } 00689 //TODO must be checked against a list of all non permissible TLVs 00690 if (2 <= thread_meshcop_tlv_data_get_uint16(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_BORDER_ROUTER_LOCATOR, &br_locator)){ 00691 tr_error("BORDER ROUTER TLV should not be present"); 00692 ret = -1; 00693 goto send_response; 00694 } 00695 00696 // TODO must be checked against commissioner address but there is no way to get it. 00697 if (2 != thread_meshcop_tlv_data_get_uint16(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_COMMISSIONER_SESSION_ID, &session_id)) { 00698 // Session id not present must be valid 00699 tr_warn("Commissioner session id not present"); 00700 ret = -1; 00701 goto send_response; 00702 } 00703 if (cur->thread_info->registered_commissioner.session_id != session_id) { 00704 tr_warn("Invalid commissioner session id"); 00705 ret = -1; 00706 goto send_response; 00707 } 00708 00709 /* Set border router address */ 00710 thread_leader_service_commissioner_address_changed(this->interface_id, source_address); 00711 00712 /* Set steering data */ 00713 if(thread_meshcop_tlv_exist(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_STEERING_DATA)){ 00714 steering_data_len = thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_STEERING_DATA, &steering_data_ptr); 00715 ret = thread_leader_service_steering_data_set(this->interface_id, steering_data_ptr, steering_data_len); 00716 tr_info("steering data set : %s, ret %d", trace_array(steering_data_ptr, steering_data_len), ret); 00717 } 00718 00719 send_response: 00720 // build response 00721 ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, ret == 0 ? 1 : 0xff); 00722 00723 send_error_response: 00724 coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, response_code, COAP_CT_OCTET_STREAM, payload, ptr - payload); 00725 return 0; 00726 } 00727 00728 static void thread_leader_allocate_router_id_by_allocated_id(thread_leader_info_t *info, uint8_t router_id, const uint8_t *eui64) 00729 { 00730 memcpy(info->thread_router_id_list[router_id].eui64, eui64, 8); 00731 bit_set(info->master_router_id_mask, router_id); 00732 info->thread_router_id_list[router_id].validLifeTime = 0xffffffff; 00733 info->thread_router_id_list[router_id].reUsePossible = false; 00734 } 00735 00736 void thread_leader_mleid_rloc_map_populate(thread_nvm_mleid_rloc_map *mleid_rloc_map, thread_leader_info_t *leader_private_info) 00737 { 00738 for (uint8_t i = 0; i < 64; i++) { 00739 if (bit_test(leader_private_info->master_router_id_mask, i)) { 00740 memcpy(mleid_rloc_map->mleid_rloc_map[i].mle_id, leader_private_info->thread_router_id_list[i].eui64, 8); 00741 } 00742 } 00743 } 00744 00745 int thread_leader_mleid_rloc_map_to_nvm_write(protocol_interface_info_entry_t *cur) 00746 { 00747 if (!cur->thread_info->leader_private_data) { 00748 return -1; 00749 } 00750 00751 thread_nvm_mleid_rloc_map *mleid_rloc_map = ns_dyn_mem_temporary_alloc(sizeof(thread_nvm_mleid_rloc_map)); 00752 if (!mleid_rloc_map) { 00753 return -2; 00754 } 00755 memset(mleid_rloc_map, 0, sizeof(thread_nvm_mleid_rloc_map)); 00756 thread_leader_mleid_rloc_map_populate(mleid_rloc_map, cur->thread_info->leader_private_data); 00757 thread_nvm_store_mleid_rloc_map_write(mleid_rloc_map); 00758 ns_dyn_mem_free(mleid_rloc_map); 00759 return 0; 00760 } 00761 00762 static int thread_leader_service_router_id_allocate(const uint8_t *eui64, protocol_interface_info_entry_t *cur, thread_leader_service_router_id_resp_t *reponse) 00763 { 00764 int ret_val = -1; 00765 uint8_t allocated_id = 64; 00766 uint8_t i; 00767 uint8_t compareId; 00768 thread_leader_info_t *leader_private_ptr = 0; 00769 thread_info_t *thread_info = cur->thread_info; 00770 uint8_t activeRouterCount; 00771 00772 if (!thread_info || !thread_info->leader_private_data) { 00773 return -1; 00774 } 00775 00776 leader_private_ptr = thread_info->leader_private_data; 00777 //Check if we have already allocated router address for this MAC address 00778 for (i = 0; i < 64; i++) { 00779 if (bit_test(leader_private_ptr->master_router_id_mask, i)) { 00780 //Active ID 00781 if (memcmp(eui64, leader_private_ptr->thread_router_id_list[i].eui64, 8) == 0) { 00782 allocated_id = i; 00783 break; 00784 } 00785 } 00786 } 00787 00788 if (allocated_id < 64) { 00789 goto alloc_ready; 00790 } 00791 activeRouterCount = thread_routing_count_active_routers_from_mask(leader_private_ptr->master_router_id_mask); 00792 if (activeRouterCount >= cur->thread_info->testMaxActiveRouterIdLimit) { 00793 // Only 32 router id allowed for one Thread partition 00794 goto alloc_ready; 00795 } 00796 00797 00798 //Try to allocate the same router ID that was previously used 00799 if (thread_is_router_addr(reponse->shortAddress)) { 00800 compareId = thread_router_id_from_addr(reponse->shortAddress); 00801 tr_debug("HInt: %02x", compareId); 00802 if (!bit_test(leader_private_ptr->master_router_id_mask, compareId)) { 00803 //Take Free entry By Hint if valid lifetime is zero 00804 if (leader_private_ptr->thread_router_id_list[compareId].reUsePossible) { 00805 allocated_id = compareId; 00806 } 00807 } 00808 } 00809 00810 if (allocated_id < 64) { 00811 goto alloc_new; 00812 } 00813 00814 //We need to allocate new Router ID 00815 uint16_t random_base = randLIB_get_random_in_range(0,64); 00816 // New addresses are assigned randomly 00817 for (i = 0; i < 64; i++) { 00818 uint16_t id = (random_base + i) % (MAX_ROUTER_ID + 1); 00819 if (!bit_test(leader_private_ptr->master_router_id_mask, id)) { 00820 if (leader_private_ptr->thread_router_id_list[id].reUsePossible) { 00821 allocated_id = id; 00822 // new id allocated save to nvm after delay 00823 leader_private_ptr->leader_nvm_sync_timer = LEADER_NVM_SYNC_DELAY; 00824 break; 00825 } 00826 } 00827 } 00828 00829 alloc_new: 00830 if (allocated_id < 64) { 00831 //Update Route MASK and push NEW Route Info 00832 thread_leader_allocate_router_id_by_allocated_id(leader_private_ptr, allocated_id, eui64); 00833 00834 //Increment Route TLV data sequency 00835 thread_leader_service_update_id_set(cur); 00836 } 00837 00838 alloc_ready: 00839 00840 if (allocated_id < 64) { 00841 thread_leader_allocate_router_id_by_allocated_id(leader_private_ptr, allocated_id, eui64); 00842 reponse->shortAddress = (allocated_id << 10); 00843 memcpy(reponse->routerID, leader_private_ptr->master_router_id_mask, 8); 00844 reponse->dataSeq = leader_private_ptr->maskSeq; 00845 reponse->preferredLifeTime = 0xffffffff; 00846 reponse->validLifeTime = 0xffffffff; 00847 ret_val = 0; 00848 } 00849 return ret_val; 00850 } 00851 00852 static int thread_leader_service_leader_data_allocate(protocol_interface_info_entry_t *cur) 00853 { 00854 thread_leader_info_t *leader_info = 0; 00855 leader_info = thread_allocate_and_init_leader_private_data(); 00856 if (leader_info == NULL) { 00857 return -1; 00858 } 00859 cur->thread_info->leader_private_data = leader_info; 00860 cur->thread_info->thread_device_mode = THREAD_DEVICE_MODE_ROUTER; 00861 cur->thread_info->thread_attached_state = THREAD_STATE_CONNECTED_ROUTER; 00862 return 0; 00863 } 00864 00865 static int thread_leader_service_router_id_deallocate(const uint8_t *eui64, protocol_interface_info_entry_t *cur) 00866 { 00867 uint8_t i; 00868 thread_leader_info_t *leader_private_ptr = 0; 00869 thread_info_t *thread_info = cur->thread_info; 00870 if (thread_info && thread_info->leader_private_data) { 00871 leader_private_ptr = thread_info->leader_private_data; 00872 //Check by MAC address 00873 for (i = 0; i < 64; i++) { 00874 if (bit_test(leader_private_ptr->master_router_id_mask, i)) { 00875 //Active ID 00876 if (memcmp(eui64, leader_private_ptr->thread_router_id_list[i].eui64, 8) == 0) { 00877 tr_debug("Release Router Id %d", i); 00878 leader_private_ptr->leader_nvm_sync_timer = LEADER_NVM_SYNC_DELAY; 00879 thread_leader_service_route_mask_bit_clear(leader_private_ptr, i); 00880 leader_private_ptr->thread_router_id_list[i].reUsePossible = true; 00881 leader_private_ptr->thread_router_id_list[i].validLifeTime = 0; 00882 //Increment Route TLV data sequency 00883 thread_leader_service_update_id_set(cur); 00884 thread_routing_activate(&cur->thread_info->routing); 00885 return 0; 00886 } 00887 } 00888 } 00889 } 00890 00891 return -1; 00892 } 00893 00894 static int thread_leader_service_routerid_assign(protocol_interface_info_entry_t *cur, const uint8_t mac[8], uint8_t router_id_mask_out[9], uint16_t *router_id) 00895 { 00896 thread_leader_service_router_id_resp_t router_id_response; 00897 tr_debug("RId Server assign"); 00898 router_id_response.shortAddress = *router_id; // Set Hint 00899 00900 if (thread_leader_service_router_id_allocate(mac, cur, &router_id_response) != 0) { 00901 tr_debug("Assign Fail"); 00902 return -1; 00903 } 00904 *router_id = router_id_response.shortAddress; 00905 router_id_mask_out[0] = router_id_response.dataSeq; 00906 memcpy(&router_id_mask_out[1], router_id_response.routerID , 8); 00907 return 0; 00908 } 00909 00910 static int thread_leader_service_routerid_release(int8_t interface_id, uint8_t mac[8], uint16_t router_id) 00911 { 00912 (void) router_id; 00913 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00914 if (!cur) { 00915 tr_error("No Interface"); 00916 return -1; 00917 } 00918 00919 if (!cur->thread_info) { 00920 tr_error("Not Thread Interface"); 00921 return -1; 00922 } 00923 00924 if (!cur->thread_info->leader_private_data) { 00925 tr_error("Not Leader"); 00926 return -1; 00927 } 00928 00929 return thread_leader_service_router_id_deallocate(mac, cur); 00930 } 00931 00932 /** 00933 * Router id assignment callback for leader 00934 * uri = tn/d/as 00935 */ 00936 static int thread_leader_service_assign_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr) 00937 { 00938 thread_leader_service_t *this = thread_leader_service_find_by_service(service_id); 00939 uint8_t payload[24]; //!< response payload 4 + 9, 4 + 2, 4 + 1 00940 uint8_t *mac_ptr = NULL; 00941 uint8_t router_id_mask[9] = {0}; 00942 uint16_t router_id = 0xfffe; 00943 uint8_t *ptr; 00944 uint8_t *status; 00945 (void) source_address; 00946 (void) source_port; 00947 00948 if (!this) { 00949 return -1; 00950 } 00951 00952 tr_debug("Thread router id assign request"); 00953 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(this->interface_id); 00954 00955 if (!cur || !cur->thread_info) { 00956 return -1; 00957 } 00958 00959 // LOCATOR is optional others are mandatory 00960 (void)thread_meshcop_tlv_data_get_uint16(request_ptr->payload_ptr, request_ptr->payload_len, TMFCOP_TLV_RLOC16, &router_id); 00961 00962 if (8 > thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, TMFCOP_TLV_MAC_ADDRESS, &mac_ptr) ) { 00963 // Failure in message 00964 return -1; 00965 } 00966 00967 // Failure in message 00968 if (1 > thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, TMFCOP_TLV_STATUS, &status) ) { 00969 return -1; 00970 } 00971 00972 int ret = -1; 00973 if (*status == THREAD_COAP_STATUS_TLV_TOO_FEW_ROUTERS) { 00974 uint8_t activeRouterCount = 0; 00975 if (cur->thread_info->leader_private_data) { 00976 activeRouterCount = thread_routing_count_active_routers_from_mask(cur->thread_info->leader_private_data->master_router_id_mask); 00977 } 00978 00979 if (activeRouterCount < cur->thread_info->routerSelectParameters.routerUpgradeThresHold) { 00980 ret = thread_leader_service_routerid_assign(cur, mac_ptr, router_id_mask, &router_id); 00981 } else { 00982 tr_info("Router ID not assigned, routers %d >= %d(upgrade threshold)", activeRouterCount, cur->thread_info->routerSelectParameters.routerUpgradeThresHold); 00983 } 00984 } else { 00985 ret = thread_leader_service_routerid_assign(cur, mac_ptr, router_id_mask, &router_id); 00986 } 00987 00988 ptr = payload; 00989 if (ret == 0) { 00990 tr_debug("Thread router id mac %s, mask %s, locator %x", trace_array(mac_ptr, 8), trace_array(router_id_mask, 9), router_id); 00991 ptr = thread_tmfcop_tlv_data_write_uint8(ptr, TMFCOP_TLV_STATUS, THREAD_COAP_STATUS_TLV_SUCCESS); 00992 ptr = thread_tmfcop_tlv_data_write_uint16(ptr, TMFCOP_TLV_RLOC16, router_id); 00993 ptr = thread_tmfcop_tlv_data_write(ptr, TMFCOP_TLV_ROUTER_MASK, 9, router_id_mask); 00994 } else { 00995 ptr = thread_tmfcop_tlv_data_write_uint8(ptr, TMFCOP_TLV_STATUS, THREAD_COAP_STATUS_TLV_NO_ADDRESS_AVAILABLE); 00996 } 00997 00998 coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_OCTET_STREAM, payload, ptr - payload); 00999 return 0; 01000 } 01001 01002 /** 01003 * Router id assignment callback for leader 01004 * uri = tn/d/ar 01005 */ 01006 static int thread_leader_service_release_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr) 01007 { 01008 thread_leader_service_t *this = thread_leader_service_find_by_service(service_id); 01009 uint8_t payload[5]; //!< response payload 4 + 1 01010 uint8_t *mac_ptr; 01011 uint16_t router_id; 01012 uint8_t *ptr; 01013 (void) source_address; 01014 (void) source_port; 01015 01016 if (!this) { 01017 return -1; 01018 } 01019 01020 tr_debug("Thread router id release request"); 01021 if (2 > thread_meshcop_tlv_data_get_uint16(request_ptr->payload_ptr, request_ptr->payload_len, TMFCOP_TLV_RLOC16, &router_id)) { 01022 return -1; 01023 } 01024 01025 if (8 > thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, TMFCOP_TLV_MAC_ADDRESS, &mac_ptr)) { 01026 // Failure in message 01027 return -1; 01028 } 01029 tr_debug("Thread router release id mac %s, locator %x", trace_array(mac_ptr, 8), router_id); 01030 01031 thread_leader_service_routerid_release(this->interface_id, mac_ptr, router_id); 01032 01033 ptr = payload; 01034 ptr = thread_tmfcop_tlv_data_write_uint8(ptr, TMFCOP_TLV_STATUS, 0); 01035 coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_OCTET_STREAM, payload, ptr - payload); 01036 01037 return 0; 01038 } 01039 01040 /** 01041 * Thread commissioning petition handler 01042 * uri = tn/mc/lp 01043 */ 01044 static int thread_leader_service_petition_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr) 01045 { 01046 thread_leader_service_t *this = thread_leader_service_find_by_service(service_id); 01047 sn_coap_msg_code_e response_code = COAP_MSG_CODE_RESPONSE_CHANGED; 01048 uint8_t payload[79];// max length for commissioner id is 64 + 4 byte header + 4 + 1 + 4 + 2 01049 uint8_t *ptr; 01050 uint16_t session_id = 0; 01051 uint8_t *tlv_data_ptr = NULL; 01052 uint16_t tlv_length; 01053 char *commissioner_id_ptr = NULL; 01054 01055 (void) source_port; 01056 01057 ptr = payload; 01058 if (!this) { 01059 return -1; 01060 } 01061 01062 tr_debug("Thread management commissioner petition"); 01063 01064 if (!thread_management_server_source_address_check(this->interface_id, source_address)) { 01065 response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; 01066 goto send_error_response; 01067 } 01068 01069 // save values from message 01070 tlv_length = thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_COMMISSIONER_ID, &tlv_data_ptr); 01071 01072 // register to thread interface 01073 int ret = thread_leader_service_commissioner_register(this->interface_id, source_address, tlv_data_ptr, tlv_length, &session_id); 01074 01075 // Build response 01076 if (ret == 0) { 01077 // Register OK 01078 ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, 1); 01079 ptr = thread_meshcop_tlv_data_write(ptr, MESHCOP_TLV_COMMISSIONER_ID, tlv_length, tlv_data_ptr); 01080 ptr = thread_meshcop_tlv_data_write_uint16(ptr, MESHCOP_TLV_COMMISSIONER_SESSION_ID, session_id); 01081 } else if (ret == -2) { 01082 // Commissioner already registered - reject and send commissioner ID 01083 ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, 0xff); 01084 commissioner_id_ptr = thread_commissioning_if_commissioner_id_get(this->interface_id); 01085 if(commissioner_id_ptr) 01086 ptr = thread_meshcop_tlv_data_write(ptr, MESHCOP_TLV_COMMISSIONER_ID, strlen(commissioner_id_ptr), (uint8_t *)commissioner_id_ptr); 01087 } 01088 else{ 01089 // Reject, anyhow, no commissioner registered - no commissioner ID 01090 ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, 0xff); 01091 } 01092 01093 tr_debug("Petition req recv id %s, RESP session id: %d ret %d", commissioner_id_ptr, session_id, ret); 01094 01095 send_error_response: 01096 coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, response_code, COAP_CT_OCTET_STREAM, payload, ptr - payload); 01097 return 0; 01098 } 01099 01100 /** 01101 * Thread commissioning keep alive handler 01102 * uri = tn/mc/la 01103 */ 01104 static int thread_leader_service_petition_ka_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr) 01105 { 01106 thread_leader_service_t *this = thread_leader_service_find_by_service(service_id); 01107 sn_coap_msg_code_e response_code = COAP_MSG_CODE_RESPONSE_CHANGED; 01108 uint8_t payload[5]; //status 4 + 1 01109 uint8_t *ptr; 01110 uint16_t session_id = 0; 01111 bool state = false; 01112 01113 (void) source_address; 01114 (void) source_port; 01115 01116 if (!this) { 01117 return -1; 01118 } 01119 01120 tr_debug("Thread management commissioner keep alive"); 01121 01122 if (!thread_management_server_source_address_check(this->interface_id, source_address)) { 01123 response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; 01124 ptr = payload; 01125 goto send_error_response; 01126 } 01127 01128 if (2 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_COMMISSIONER_SESSION_ID, &ptr)) { 01129 session_id = common_read_16_bit(ptr); 01130 } 01131 if (1 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_STATE, &ptr)) 01132 { 01133 if (*ptr == 0x01) { 01134 state = thread_leader_service_commissioner_session_refresh(this->interface_id, session_id); 01135 } else if(*ptr == 0xff) { 01136 thread_leader_service_commissioner_unregister(this->interface_id, session_id); 01137 state = false; 01138 } 01139 } 01140 if (state == true) { 01141 thread_leader_service_commissioner_address_changed(this->interface_id, source_address); 01142 } 01143 tr_info("Commissioner keep alive req recv, interface: %d session id %d state %d", this->interface_id, session_id, state); 01144 ptr = payload; 01145 ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, state == true ? 1 : 0xff); 01146 01147 send_error_response: 01148 coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, response_code, COAP_CT_OCTET_STREAM, payload, ptr - payload); 01149 return 0; 01150 } 01151 01152 static int thread_leader_service_network_data_register(protocol_interface_info_entry_t *cur, uint8_t *network_data_ptr, uint16_t network_data_length, uint16_t routerId) 01153 { 01154 tr_debug("Register network data for %x", routerId); 01155 // Mark all data to be cleared 01156 thread_network_data_router_id_mark_delete(&cur->thread_info->networkDataStorage, routerId, true); 01157 01158 // update data from this device 01159 int retVal = thread_bootstrap_network_data_process(cur, network_data_ptr, network_data_length); 01160 01161 if (retVal < 0) { 01162 tr_warn("network data update failed: %s", trace_array(network_data_ptr, network_data_length)); 01163 return retVal; 01164 } 01165 thread_network_data_router_id_free(&cur->thread_info->networkDataStorage, true, cur); 01166 01167 thread_leader_service_network_data_changed(cur, false, false); 01168 return 0; 01169 } 01170 01171 /** 01172 * Thread network data registration handler 01173 * uri = tn/sd 01174 */ 01175 static int thread_leader_service_register_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr) 01176 { 01177 thread_leader_service_t *this = thread_leader_service_find_by_service(service_id); 01178 uint16_t payload_len; 01179 uint8_t *payload_ptr; 01180 uint16_t network_data_len; 01181 uint8_t *network_data_ptr; 01182 protocol_interface_info_entry_t *cur; 01183 sn_coap_msg_code_e response_code = COAP_MSG_CODE_RESPONSE_CHANGED; 01184 int8_t ret = -3; 01185 uint16_t routerId; 01186 uint16_t old_rloc; 01187 (void) source_port; 01188 tr_debug("register network data"); 01189 01190 if (!this) { 01191 return -1; 01192 } 01193 01194 cur = protocol_stack_interface_info_get_by_id(this->interface_id); 01195 if (!cur || !cur->thread_info) { 01196 return -1; 01197 } 01198 01199 //send data to leader api. 01200 routerId = common_read_16_bit(&source_address[14]); 01201 payload_len = request_ptr->payload_len; 01202 payload_ptr = request_ptr->payload_ptr; 01203 request_ptr->payload_ptr = NULL; 01204 01205 01206 if (2 <= thread_tmfcop_tlv_data_get_uint16(payload_ptr, payload_len, TMFCOP_TLV_RLOC16, &old_rloc)) { 01207 // This will delete everything from old rloc 01208 tr_warn("Remove network data from: %x", old_rloc); 01209 ret = thread_leader_service_network_data_register(cur, NULL, 0, old_rloc); 01210 } 01211 01212 if (!thread_tmfcop_tlv_exist(payload_ptr, payload_len, TMFCOP_TLV_NETWORK_DATA)) { 01213 goto send_response; 01214 } 01215 network_data_len = thread_tmfcop_tlv_find(payload_ptr, payload_len, TMFCOP_TLV_NETWORK_DATA, &network_data_ptr); 01216 01217 /* Check that network data does NOT produce Network Data TLV bigger than MAX_NETWORK_DATA_SIZE */ 01218 int32_t len = thread_network_data_resulting_tlv_size(&cur->thread_info->networkDataStorage, network_data_ptr, network_data_len, routerId); 01219 01220 if (len <= 0 || len > THREAD_MAX_NETWORK_DATA_SIZE) { 01221 tr_warn("Network data would produce Network Data TLV size %"PRId32, len); 01222 response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; 01223 goto send_response; 01224 } 01225 01226 if (network_data_len < 256) { 01227 ret = thread_leader_service_network_data_register(cur, network_data_ptr, network_data_len, routerId); 01228 } 01229 if (ret != 0) { 01230 /* error happened*/ 01231 response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; // corruption is the default or not enough room 01232 if (ret == -2) { 01233 response_code = COAP_MSG_CODE_RESPONSE_FORBIDDEN; // Not leader 01234 } 01235 } 01236 01237 send_response: 01238 coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, response_code, COAP_CT_OCTET_STREAM, NULL, 0); 01239 return 0; 01240 } 01241 01242 static int thread_leader_service_leader_start(protocol_interface_info_entry_t *cur) 01243 { 01244 link_configuration_s *linkConfiguration; 01245 linkConfiguration = thread_joiner_application_get_config(cur->id); 01246 if (!linkConfiguration) { 01247 return -1; 01248 } 01249 01250 //Allocate Setup 01251 if (thread_leader_service_leader_data_allocate(cur) != 0) { 01252 return -1; 01253 } 01254 01255 if (thread_leader_service_start(cur->id)) { 01256 thread_nd_service_delete(cur->id); 01257 return -1; 01258 } 01259 if (thread_beacon_create_payload(cur) != 0) { 01260 thread_nd_service_delete(cur->id); 01261 return -1; 01262 } 01263 cur->thread_info->rfc6775 = false; 01264 cur->thread_info->leader_private_data->leader_id_seq_timer = ID_SEQUENCE_PERIOD; 01265 01266 cur->lowpan_info &= ~INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION; 01267 cur->lowpan_info |= INTERFACE_NWK_ROUTER_DEVICE; 01268 cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; 01269 mac_helper_default_security_level_set(cur, SEC_ENC_MIC32); 01270 mac_helper_default_security_key_id_mode_set(cur,MAC_KEY_ID_MODE_IDX); 01271 thread_discovery_responser_enable(cur->id, true); 01272 if (cur->mac_api) { 01273 mlme_start_t start_req; 01274 memset(&start_req, 0, sizeof(mlme_start_t)); 01275 start_req.BeaconOrder = 15; 01276 start_req.SuperframeOrder = 15; 01277 start_req.PANCoordinator = true; 01278 start_req.LogicalChannel = cur->mac_parameters->mac_channel; 01279 start_req.PANId = cur->mac_parameters->pan_id; 01280 cur->mac_api->mlme_req(cur->mac_api, MLME_START , &start_req); 01281 } 01282 return 0; 01283 } 01284 01285 static int thread_leader_service_leader_init(protocol_interface_info_entry_t *cur) 01286 { 01287 //Clean All allocated stuff's 01288 thread_info_t *thread_info = cur->thread_info; 01289 // mark and delete previous leader network data information 01290 thread_network_data_router_id_mark_delete(&thread_info->networkDataStorage,thread_router_addr_from_id(cur->thread_info->thread_leader_data->leaderRouterId), true); 01291 thread_network_data_router_id_free(&thread_info->networkDataStorage, false, cur); 01292 thread_leader_service_leader_data_free(thread_info); 01293 01294 thread_info->rfc6775 = false; 01295 thread_routing_free(&thread_info->routing); 01296 ipv6_route_table_remove_info(cur->id, ROUTE_THREAD, NULL); 01297 ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_BORDER_ROUTER, NULL); 01298 thread_dhcp_client_delete(cur->id); 01299 thread_nd_service_delete(cur->id); 01300 mpl_clear_realm_scope_seeds(cur); 01301 ipv6_neighbour_cache_flush(&cur->ipv6_neighbour_cache); 01302 thread_neighbor_list_clean(cur); 01303 cur->mesh_callbacks = NULL; 01304 cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; 01305 01306 return thread_leader_service_leader_start(cur); 01307 } 01308 01309 static void thread_leader_service_leader_data_initialize(protocol_interface_info_entry_t *cur, uint8_t routerId) 01310 { 01311 thread_leader_data_t *leader_data = cur->thread_info->thread_leader_data; 01312 01313 if (cur->thread_info->thread_leader_data) { 01314 leader_data->partitionId = randLIB_get_32bit(); //Generate Random Instance 01315 leader_data->leaderRouterId = routerId; //Set leader data to zero by Default 01316 leader_data->dataVersion = randLIB_get_8bit(); 01317 leader_data->stableDataVersion = randLIB_get_8bit(); 01318 leader_data->weighting = cur->thread_info->partition_weighting; 01319 } 01320 } 01321 01322 static void thread_leader_service_private_routemask_init(thread_leader_info_t *leader_info) 01323 { 01324 memset(leader_info, 0, sizeof(thread_leader_info_t)); 01325 leader_info->maskSeq = randLIB_get_8bit(); 01326 uint8_t i; 01327 for (i=0; i<64; i++) { 01328 leader_info->thread_router_id_list[i].reUsePossible = true; 01329 leader_info->thread_router_id_list[i].validLifeTime = 0xffffffff; 01330 } 01331 } 01332 01333 static void thread_leader_service_interface_setup_activate(protocol_interface_info_entry_t *cur) 01334 { 01335 uint8_t routerId; 01336 thread_leader_info_t *private = cur->thread_info->leader_private_data; 01337 01338 routerId = thread_router_id_from_addr(cur->thread_info->routerShortAddress); 01339 01340 thread_leader_service_leader_data_initialize(cur, routerId); 01341 // Test code 01342 if(cur->thread_info->testRandomPartitionId != 0){ 01343 cur->thread_info->thread_leader_data->partitionId = cur->thread_info->testRandomPartitionId; 01344 cur->thread_info->testRandomPartitionId = 0; 01345 } 01346 thread_leader_service_private_routemask_init(private); 01347 //SET Router ID 01348 thread_leader_allocate_router_id_by_allocated_id(private, routerId, cur->mac); 01349 thread_old_partition_data_purge(cur); 01350 // remove any existing rloc mapping in nvm 01351 thread_nvm_store_mleid_rloc_map_remove(); 01352 cur->lowpan_address_mode = NET_6LOWPAN_GP16_ADDRESS; 01353 thread_bootstrap_update_ml16_address(cur, cur->thread_info->routerShortAddress); 01354 thread_generate_ml64_address(cur); 01355 thread_extension_address_generate(cur); 01356 thread_bootstrap_routing_activate(cur); 01357 thread_routing_update_id_set(cur, private->maskSeq, private->master_router_id_mask); 01358 thread_routing_activate(&cur->thread_info->routing); 01359 cur->thread_info->leader_private_data->leader_id_seq_timer = ID_SEQUENCE_PERIOD; 01360 } 01361 01362 /* 01363 * Function to clear network data from router children. 01364 * When router is removed, network data from router child must be removed as well. 01365 */ 01366 static void thread_leader_router_child_network_data_clear(protocol_interface_info_entry_t *cur, uint16_t router_short_addr) 01367 { 01368 uint16_t child_short_addr; 01369 01370 child_short_addr = thread_leader_service_child_id_from_networkdata_get(cur->thread_info, router_short_addr); 01371 while (child_short_addr != 0) { 01372 tr_debug("Removing Network data from child %04x", child_short_addr); 01373 thread_leader_service_network_data_register(cur, NULL, 0, child_short_addr); 01374 child_short_addr = thread_leader_service_child_id_from_networkdata_get(cur->thread_info, router_short_addr); 01375 } 01376 } 01377 01378 01379 /* Public functions */ 01380 01381 int thread_leader_service_init(int8_t interface_id, uint8_t coap_service_id) 01382 { 01383 thread_leader_service_t *this = thread_leader_service_find_by_interface(interface_id); 01384 01385 if (this) { 01386 return 0; 01387 } 01388 01389 this = ns_dyn_mem_alloc(sizeof(thread_leader_service_t)); 01390 if (!this) { 01391 return -2; 01392 } 01393 01394 this->interface_id = interface_id; 01395 this->coap_service_id = coap_service_id; 01396 this->leader_enabled = false; 01397 01398 ns_list_add_to_start(&leader_service_instance_list, this); 01399 01400 return 0; 01401 } 01402 01403 void thread_leader_service_delete(int8_t interface_id) 01404 { 01405 thread_leader_service_t *this = thread_leader_service_find_by_interface(interface_id); 01406 if (!this) { 01407 return; 01408 } 01409 01410 if (this->leader_enabled) { 01411 thread_leader_service_stop(interface_id); 01412 } 01413 01414 ns_list_remove(&leader_service_instance_list, this); 01415 ns_dyn_mem_free(this); 01416 } 01417 01418 int thread_leader_service_start(int8_t interface_id) 01419 { 01420 thread_leader_service_t *this = thread_leader_service_find_by_interface(interface_id); 01421 01422 if (!this) { 01423 return -1; 01424 } 01425 01426 this->leader_enabled = true; 01427 /** 01428 * Router id uri register 01429 */ 01430 coap_service_register_uri(this->coap_service_id, THREAD_URI_ROUTER_ID_ASSIGNMENT, COAP_SERVICE_ACCESS_GET_ALLOWED, thread_leader_service_assign_cb); 01431 coap_service_register_uri(this->coap_service_id, THREAD_URI_ROUTER_ID_RELEASE, COAP_SERVICE_ACCESS_GET_ALLOWED, thread_leader_service_release_cb); 01432 /** 01433 * Thread commission registration uri handling 01434 */ 01435 coap_service_register_uri(this->coap_service_id, THREAD_URI_LEADER_PETITION, COAP_SERVICE_ACCESS_GET_ALLOWED, thread_leader_service_petition_cb); 01436 coap_service_register_uri(this->coap_service_id, THREAD_URI_LEADER_KEEP_ALIVE, COAP_SERVICE_ACCESS_GET_ALLOWED, thread_leader_service_petition_ka_cb); 01437 /** 01438 * Thread network data management handler 01439 */ 01440 coap_service_register_uri(this->coap_service_id, THREAD_URI_NETWORK_DATA, COAP_SERVICE_ACCESS_GET_ALLOWED, thread_leader_service_register_cb); 01441 coap_service_register_uri(this->coap_service_id, THREAD_URI_ACTIVE_SET, COAP_SERVICE_ACCESS_GET_ALLOWED, thread_leader_service_active_set_cb); 01442 coap_service_register_uri(this->coap_service_id, THREAD_URI_PENDING_SET, COAP_SERVICE_ACCESS_GET_ALLOWED, thread_leader_service_pending_set_cb); 01443 coap_service_register_uri(this->coap_service_id, THREAD_URI_COMMISSIONER_SET, COAP_SERVICE_ACCESS_GET_ALLOWED, thread_leader_service_commissioner_set_cb); 01444 01445 return 0; 01446 } 01447 01448 void thread_leader_service_stop(int8_t interface_id) 01449 { 01450 thread_leader_service_t *this = thread_leader_service_find_by_interface(interface_id); 01451 01452 if (!this) { 01453 return; 01454 } 01455 01456 this->leader_enabled = false; 01457 coap_service_unregister_uri(this->coap_service_id, THREAD_URI_ROUTER_ID_ASSIGNMENT); 01458 coap_service_unregister_uri(this->coap_service_id, THREAD_URI_ROUTER_ID_RELEASE); 01459 coap_service_unregister_uri(this->coap_service_id, THREAD_URI_LEADER_PETITION); 01460 coap_service_unregister_uri(this->coap_service_id, THREAD_URI_LEADER_KEEP_ALIVE); 01461 coap_service_unregister_uri(this->coap_service_id, THREAD_URI_NETWORK_DATA); 01462 coap_service_unregister_uri(this->coap_service_id, THREAD_URI_ACTIVE_SET); 01463 coap_service_unregister_uri(this->coap_service_id, THREAD_URI_PENDING_SET); 01464 coap_service_unregister_uri(this->coap_service_id, THREAD_URI_COMMISSIONER_SET); 01465 return; 01466 } 01467 void thread_leader_service_network_data_changed(protocol_interface_info_entry_t *cur, bool force_stable_update, bool force_unstable_update) 01468 { 01469 if (!cur->thread_info) { 01470 return; 01471 } 01472 01473 if (force_stable_update) { 01474 cur->thread_info->networkDataStorage.stableUpdatePushed = true; 01475 } 01476 if (force_unstable_update) { 01477 cur->thread_info->networkDataStorage.temporaryUpdatePushed = true; 01478 } 01479 // Generate network data from network data structures 01480 if (cur->thread_info->networkDataStorage.stableUpdatePushed) { 01481 tr_debug("Temporary Network Data Update"); 01482 cur->thread_info->thread_leader_data->stableDataVersion++; 01483 cur->thread_info->thread_leader_data->dataVersion++; 01484 } else if (cur->thread_info->networkDataStorage.temporaryUpdatePushed) { 01485 tr_debug("Stable Network Data Update"); 01486 cur->thread_info->thread_leader_data->dataVersion++; 01487 } else { 01488 // No changes in network data detected 01489 return; 01490 } 01491 tr_debug("network data changed stable:%d, unstable:%d", cur->thread_info->networkDataStorage.stableUpdatePushed, cur->thread_info->networkDataStorage.temporaryUpdatePushed); 01492 thread_leader_service_generate_network_data(cur); 01493 01494 /* set timer to update new network data */ 01495 if (0 == thread_info(cur)->networkDataStorage.network_data_update_delay) { 01496 thread_info(cur)->networkDataStorage.network_data_update_delay = THREAD_COMMISSION_DATA_UPDATE_DELAY; 01497 } 01498 } 01499 01500 void thread_leader_service_timer(protocol_interface_info_entry_t *cur, uint32_t ticks) 01501 { 01502 if (!cur->thread_info->leader_private_data) { 01503 // I am not a leader 01504 return; 01505 } 01506 01507 // check for network data update 01508 if (thread_info(cur)->networkDataStorage.network_data_update_delay) { 01509 if (thread_info(cur)->networkDataStorage.network_data_update_delay > ticks) { 01510 thread_info(cur)->networkDataStorage.network_data_update_delay -= ticks; 01511 } else { 01512 // Send New network data. 01513 thread_info(cur)->networkDataStorage.network_data_update_delay = 0; 01514 thread_bootstrap_network_data_update(cur); 01515 } 01516 } 01517 01518 if (cur->thread_info->leader_private_data->leader_id_seq_timer) { 01519 if (cur->thread_info->leader_private_data->leader_id_seq_timer > ticks) { 01520 cur->thread_info->leader_private_data->leader_id_seq_timer -= ticks; 01521 } else { 01522 cur->thread_info->leader_private_data->leader_id_seq_timer = 0; 01523 } 01524 } else { 01525 // Leader id sequence number updated 01526 cur->thread_info->leader_private_data->leader_id_seq_timer = ID_SEQUENCE_PERIOD; 01527 01528 thread_leader_service_update_id_set(cur); 01529 thread_network_data_context_re_use_timer_update(&cur->thread_info->networkDataStorage, 10, &cur->lowpan_contexts); 01530 // Send update to network data if needed 01531 thread_leader_service_network_data_changed(cur, false, false); 01532 } 01533 01534 if (cur->thread_info->leader_private_data->leader_nvm_sync_timer) { 01535 if ((cur->thread_info->leader_private_data->leader_nvm_sync_timer) > ticks) { 01536 cur->thread_info->leader_private_data->leader_nvm_sync_timer -= ticks; 01537 } 01538 else { 01539 cur->thread_info->leader_private_data->leader_nvm_sync_timer = 0; 01540 thread_leader_mleid_rloc_map_to_nvm_write(cur); 01541 } 01542 } 01543 01544 thread_leader_service_router_id_valid_lifetime_update(cur, ticks); 01545 01546 } 01547 01548 void thread_leader_service_leader_data_free(thread_info_t *thread_info) 01549 { 01550 if (thread_info && thread_info->thread_leader_data) { 01551 ns_dyn_mem_free(thread_info->leader_private_data); 01552 thread_info->leader_private_data = NULL; 01553 } 01554 } 01555 01556 void thread_leader_service_thread_partitition_generate(int8_t interface_id, bool newPartition) 01557 { 01558 protocol_interface_info_entry_t *cur; 01559 link_configuration_s *linkConfiguration = thread_joiner_application_get_config(interface_id); 01560 uint8_t *parent_mac_addr = NULL; 01561 uint16_t leaderRloc; 01562 01563 cur = protocol_stack_interface_info_get_by_id(interface_id); 01564 if (!cur || !cur->thread_info) { 01565 return; 01566 } 01567 01568 if (!linkConfiguration) { 01569 goto failure_exit; 01570 } 01571 01572 mle_service_interface_tx_queue_clean(interface_id); 01573 01574 if (!newPartition) { 01575 if (cur->nwk_bootstrap_state == ER_ACTIVE_SCAN && cur->nwk_nd_re_scan_count < THREAD_NETWORK_ACTIVE_SCAN_COUNTER) { 01576 tr_debug("RE trig Active Scan"); 01577 cur->bootsrap_state_machine_cnt = randLIB_get_random_in_range(1, 6); 01578 return; 01579 } 01580 } 01581 01582 if (cur->thread_info->thread_device_mode != THREAD_DEVICE_MODE_ROUTER) { 01583 tr_debug("End device did not find networks"); 01584 goto failure_exit; 01585 } 01586 leaderRloc = cur->thread_info->routerShortAddress; 01587 01588 //Set For Destination cache clean purpose 01589 cur->mac_parameters->pan_id = linkConfiguration->panId; 01590 01591 if (thread_leader_service_leader_init(cur) != 0) { 01592 tr_debug("Leader allocate Fail"); 01593 goto failure_exit; 01594 } 01595 01596 /* Delete old parent info */ 01597 if (cur->thread_info->thread_endnode_parent) { 01598 ns_dyn_mem_free(cur->thread_info->thread_endnode_parent); 01599 cur->thread_info->thread_endnode_parent = NULL; 01600 } 01601 01602 tr_debug("Leader Link generated & Started"); 01603 01604 //Run Nomal Init 01605 thread_interface_init(cur); 01606 01607 // Init clears the address 01608 cur->thread_info->routerShortAddress = leaderRloc; 01609 01610 if (cur->thread_info->routerShortAddress == 0xfffe || 01611 !thread_is_router_addr(cur->thread_info->routerShortAddress)) { 01612 //If we were REED do not use reed address 01613 cur->thread_info->routerShortAddress = thread_router_addr_from_id(randLIB_get_random_in_range(0,MAX_ROUTER_ID)); 01614 } 01615 01616 // clean network data 01617 thread_network_data_free_and_clean(&cur->thread_info->networkDataStorage); 01618 thread_network_data_base_init(&cur->thread_info->networkDataStorage); 01619 thread_leader_service_interface_setup_activate(cur); 01620 01621 //memset(cur->thread_info->lastValidRouteMask, 0, (N_THREAD_ROUTERS+7)/8); 01622 //SET SHort Address & PAN-ID 01623 cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; 01624 mle_class_mode_set(cur->id, MLE_CLASS_ROUTER); 01625 mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true); 01626 cur->interface_mode = INTERFACE_UP; 01627 cur->nwk_mode = ARM_NWK_GP_IP_MODE; 01628 thread_bootstrap_ready(cur); 01629 thread_configuration_mle_activate(cur); 01630 if (cur->thread_info->thread_endnode_parent) { 01631 parent_mac_addr = cur->thread_info->thread_endnode_parent->mac64; 01632 } 01633 thread_nvm_store_link_info_write(parent_mac_addr, mac_helper_mac16_address_get(cur)); 01634 01635 if (thread_nd_own_service_list_data_size(&cur->thread_info->localServerDataBase)) { 01636 // We publish our services if we have some BUG leader cannot remove old ones 01637 thread_border_router_publish(cur->id); 01638 } 01639 return; 01640 01641 failure_exit: 01642 nwk_bootsrap_state_update(ARM_NWK_NWK_SCAN_FAIL, cur); 01643 } 01644 01645 int thread_leader_service_thread_partitition_restart(int8_t interface_id, mle_tlv_info_t *routing) 01646 { 01647 protocol_interface_info_entry_t *cur; 01648 cur = protocol_stack_interface_info_get_by_id(interface_id); 01649 if (!cur || !cur->thread_info) { 01650 return -1; 01651 } 01652 if (!thread_info(cur)->leader_private_data) { 01653 thread_info(cur)->leader_private_data = thread_allocate_and_init_leader_private_data(); 01654 } 01655 if (!thread_info(cur)->leader_private_data) { 01656 return -1; 01657 } 01658 if (thread_leader_service_start(cur->id)) { 01659 return -1; 01660 } 01661 //Learn network data, we remove own data from here it should be re given by application 01662 //thread_management_network_data_register(cur->id, networkData.dataPtr, networkData.tlvLen, address16 ); 01663 thread_nvm_mleid_rloc_map *mleid_rloc_map = ns_dyn_mem_temporary_alloc(sizeof(thread_nvm_mleid_rloc_map)); 01664 if (!mleid_rloc_map) { 01665 return -1; 01666 } 01667 if (thread_nvm_store_mleid_rloc_map_read(mleid_rloc_map) != THREAD_NVM_FILE_SUCCESS) { 01668 memset(mleid_rloc_map, 0, sizeof(thread_nvm_mleid_rloc_map)); 01669 } 01670 // initialize private data 01671 thread_info(cur)->leader_private_data->maskSeq = *routing->dataPtr; 01672 memcpy(thread_info(cur)->leader_private_data->master_router_id_mask,routing->dataPtr + 1, 8); 01673 for (int i = 0; i < 64; i++) { 01674 if (bit_test(thread_info(cur)->leader_private_data->master_router_id_mask, i)) { 01675 //Active ID 01676 thread_info(cur)->leader_private_data->thread_router_id_list[i].reUsePossible = false; 01677 memcpy(thread_info(cur)->leader_private_data->thread_router_id_list[i].eui64, mleid_rloc_map->mleid_rloc_map[i].mle_id, 8); 01678 } else { 01679 // Free id 01680 thread_info(cur)->leader_private_data->thread_router_id_list[i].reUsePossible = true; 01681 // clear the mleid in both local router id list and nvm 01682 memset(thread_info(cur)->leader_private_data->thread_router_id_list[i].eui64, 0, 8); 01683 memset(mleid_rloc_map->mleid_rloc_map[i].mle_id, 0, 8); 01684 } 01685 thread_info(cur)->leader_private_data->thread_router_id_list[i].validLifeTime = 0xffffffff; 01686 } 01687 // write back updated map to store 01688 thread_nvm_store_mleid_rloc_map_write(mleid_rloc_map); 01689 ns_dyn_mem_free(mleid_rloc_map); 01690 // Clear network data (if exists) and propagate new empty network data 01691 thread_network_data_free_and_clean(&cur->thread_info->networkDataStorage); 01692 thread_network_data_base_init(&cur->thread_info->networkDataStorage); 01693 // Update router sequence id to prevent network fragmentation in case of Leader was temporarily down 01694 // and routers were not able to get new sequence id for NETWORK_ID_TIMEOUT duration. 01695 thread_leader_service_update_id_set(cur); 01696 return 0; 01697 } 01698 01699 void thread_leader_service_update_id_set(protocol_interface_info_entry_t *cur) 01700 { 01701 thread_leader_info_t *leader_private_ptr = cur->thread_info->leader_private_data; 01702 01703 leader_private_ptr->maskSeq++; 01704 thread_routing_update_id_set(cur, leader_private_ptr->maskSeq, leader_private_ptr->master_router_id_mask); 01705 } 01706 01707 void thread_leader_service_router_id_valid_lifetime_update(protocol_interface_info_entry_t *cur, uint32_t tickUpdate) 01708 { 01709 uint8_t i; 01710 bool update_routeTable = false; 01711 thread_info_t *thread_info = cur->thread_info; 01712 thread_leader_info_t *leader_private_ptr = 0; 01713 if (thread_info && thread_info->leader_private_data) { 01714 leader_private_ptr = thread_info->leader_private_data; 01715 01716 for (i = 0; i < 64; i++) { 01717 if (bit_test(leader_private_ptr->master_router_id_mask, i)) { 01718 if (i != thread_info->thread_leader_data->leaderRouterId) { 01719 //Active ID 01720 if (leader_private_ptr->thread_router_id_list[i].validLifeTime != 0xffffffff) { 01721 if (leader_private_ptr->thread_router_id_list[i].validLifeTime > tickUpdate) { 01722 //Increment Time 01723 leader_private_ptr->thread_router_id_list[i].validLifeTime -= tickUpdate; 01724 } else { 01725 //RElease 01726 tr_debug("Router ID bit Release: %x start re assign delay", i); 01727 leader_private_ptr->thread_router_id_list[i].validLifeTime = ROUTER_ID_REUSE_DELAY; 01728 leader_private_ptr->thread_router_id_list[i].reUsePossible = false; 01729 thread_leader_service_route_mask_bit_clear(leader_private_ptr, i); 01730 thread_leader_service_network_data_register(cur, NULL, 0, thread_router_addr_from_id(i)); 01731 thread_leader_router_child_network_data_clear(cur, thread_router_addr_from_id(i)); 01732 thread_routing_activate(&thread_info->routing); 01733 update_routeTable = true; 01734 } 01735 } 01736 } 01737 } else { 01738 if (leader_private_ptr->thread_router_id_list[i].validLifeTime != 0xffffffff) { 01739 if (leader_private_ptr->thread_router_id_list[i].validLifeTime > tickUpdate) { 01740 //Increment Time 01741 leader_private_ptr->thread_router_id_list[i].validLifeTime -= tickUpdate; 01742 } else { 01743 //RElease 01744 tr_debug("Router ID available again: %x", i); 01745 leader_private_ptr->thread_router_id_list[i].validLifeTime = 0xffffffff; 01746 leader_private_ptr->thread_router_id_list[i].reUsePossible = true; 01747 } 01748 } 01749 01750 } 01751 } 01752 if (update_routeTable) { 01753 thread_leader_service_update_id_set(cur); 01754 } 01755 } 01756 } 01757 01758 bool thread_leader_service_route_mask_bit_clear(thread_leader_info_t *info, uint8_t router_id) 01759 { 01760 if (bit_test(info->master_router_id_mask, router_id)) { 01761 bit_clear(info->master_router_id_mask, router_id); 01762 return true; 01763 } 01764 return false; 01765 } 01766 01767 static uint8_t thread_unstable_commission_data_length(protocol_interface_info_entry_t *cur) 01768 { 01769 uint8_t localDataLength = 0; 01770 01771 localDataLength += 4; // Commissioner session ID 01772 01773 if (cur->thread_info->registered_commissioner.commissioner_valid) { 01774 localDataLength += 4; // Border router address 01775 if (cur->thread_info->registered_commissioner.steering_data_len) { 01776 localDataLength += cur->thread_info->registered_commissioner.steering_data_len; 01777 localDataLength += 2; 01778 } 01779 } 01780 return localDataLength; 01781 } 01782 01783 static uint8_t *thread_unstable_commission_data_write(protocol_interface_info_entry_t *cur, uint8_t *ptr) 01784 { 01785 01786 uint8_t length = thread_unstable_commission_data_length(cur); 01787 if( !length) { 01788 // No unstable TLV in thread 1.0 or if TLV is empty we skip it 01789 return ptr; 01790 } 01791 *ptr++ = THREAD_NWK_DATA_TYPE_COMMISSION_DATA ; 01792 *ptr++ = length; 01793 ptr = thread_meshcop_tlv_data_write_uint16(ptr,MESHCOP_TLV_COMMISSIONER_SESSION_ID, cur->thread_info->registered_commissioner.session_id); 01794 if (cur->thread_info->registered_commissioner.commissioner_valid) { 01795 //SET Commision TLV 01796 ptr = thread_meshcop_tlv_data_write(ptr,MESHCOP_TLV_BORDER_ROUTER_LOCATOR, 2, &cur->thread_info->registered_commissioner.border_router_address[14]); 01797 if (cur->thread_info->registered_commissioner.steering_data_len) { 01798 ptr = thread_meshcop_tlv_data_write(ptr,MESHCOP_TLV_STEERING_DATA, cur->thread_info->registered_commissioner.steering_data_len, cur->thread_info->registered_commissioner.steering_data); 01799 } 01800 } 01801 return ptr; 01802 } 01803 01804 static uint16_t thread_leader_service_network_data_length(protocol_interface_info_entry_t *cur, bool fullist) 01805 { 01806 uint16_t networkDataLength = 0; 01807 uint16_t prefixDataLength = 0; 01808 uint16_t commissionDataLength = 0; 01809 01810 prefixDataLength = thread_network_data_prefix_set_size(&cur->thread_info->networkDataStorage, fullist); 01811 if (prefixDataLength) { 01812 networkDataLength += prefixDataLength; 01813 } 01814 prefixDataLength = thread_network_data_service_set_size(&cur->thread_info->networkDataStorage, fullist); 01815 if (prefixDataLength) { 01816 networkDataLength += prefixDataLength; 01817 } 01818 commissionDataLength = thread_unstable_commission_data_length(cur); 01819 if (fullist && commissionDataLength) { 01820 networkDataLength += 2 + commissionDataLength; 01821 } 01822 01823 return networkDataLength; 01824 } 01825 01826 static uint8_t *thread_leader_service_network_data_tlv_write(protocol_interface_info_entry_t *cur, uint8_t *ptr) 01827 { 01828 ptr = thread_network_data_prefix_set_write(&cur->thread_info->networkDataStorage, ptr); 01829 ptr = thread_network_data_service_set_write(&cur->thread_info->networkDataStorage, ptr); 01830 ptr = thread_unstable_commission_data_write(cur, ptr); 01831 01832 return ptr; 01833 } 01834 01835 void thread_leader_service_generate_network_data(protocol_interface_info_entry_t *cur) 01836 { 01837 int16_t size = thread_leader_service_network_data_length(cur, true); 01838 01839 if (size > 0) { 01840 tr_debug("Leader network data size %d", size); 01841 thread_leader_service_network_data_tlv_write(cur, cur->thread_info->networkDataStorage.network_data); 01842 cur->thread_info->networkDataStorage.network_data_len = size; 01843 } 01844 } 01845 01846 uint16_t thread_leader_service_child_id_from_networkdata_get(thread_info_t *thread_info, uint16_t router_short_addr) 01847 { 01848 return thread_network_data_service_child_id_from_networkdata_get(&thread_info->networkDataStorage, router_short_addr); 01849 } 01850 01851 void thread_leader_service_router_state_changed(thread_info_t *thread_info, uint8_t router_id, bool available, int8_t interface_id) 01852 { 01853 thread_leader_info_t *info = thread_info->leader_private_data; 01854 (void)interface_id; 01855 01856 if (!info) { 01857 return; 01858 } 01859 if (available) { 01860 /* Stop the timer */ 01861 info->thread_router_id_list[router_id].validLifeTime = 0xffffffff; 01862 } else { 01863 /* Reset the timer to ROUTER_ID_REUSE_DELAY, if it's not already running. */ 01864 if (info->thread_router_id_list[router_id].validLifeTime == 0xffffffff) { 01865 tr_debug("Router ID: %d cost infinite", router_id); 01866 01867 info->thread_router_id_list[router_id].validLifeTime = ROUTER_ID_INFINITY_DELAY; 01868 info->thread_router_id_list[router_id].reUsePossible = false; 01869 } 01870 } 01871 } 01872 01873 #endif // HAVE_THREAD_LEADER_SERVICE */
Generated on Tue Jul 12 2022 12:45:58 by
