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