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_common.c
00001 /* 00002 * Copyright (c) 2014-2015, 2017-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 #include "nsconfig.h" 00030 #ifdef HAVE_THREAD 00031 #include <string.h> 00032 #include <ns_types.h> 00033 #include <nsdynmemLIB.h> 00034 #include "eventOS_event.h" 00035 #include "randLIB.h" 00036 #include "common_functions.h" 00037 00038 #include "NWK_INTERFACE/Include/protocol.h" 00039 #include "net_thread_test.h" 00040 #include "libDHCPv6/libDHCPv6.h" 00041 #include "libDHCPv6/libDHCPv6_server.h" 00042 #include "ns_trace.h" 00043 #include "6LoWPAN/Bootstraps/protocol_6lowpan.h" 00044 #include "6LoWPAN/Bootstraps/protocol_6lowpan_interface.h" 00045 #include "6LoWPAN/Thread/thread_common.h" 00046 #include "6LoWPAN/Thread/thread_beacon.h" 00047 #include "6LoWPAN/Thread/thread_leader_service.h" 00048 #include "6LoWPAN/Thread/thread_routing.h" 00049 #include "6LoWPAN/Thread/thread_dhcpv6_client.h" 00050 #include "6LoWPAN/Thread/thread_discovery.h" 00051 #include "6LoWPAN/Thread/thread_bootstrap.h" 00052 #include "6LoWPAN/Thread/thread_router_bootstrap.h" 00053 #include "6LoWPAN/Thread/thread_lowpower_private_api.h" 00054 #include "6LoWPAN/Thread/thread_extension.h" 00055 #include "6LoWPAN/Thread/thread_bbr_api_internal.h" 00056 #include "6LoWPAN/Thread/thread_border_router_api_internal.h" 00057 #include "6LoWPAN/Thread/thread_nd.h" 00058 #include "6LoWPAN/Thread/thread_network_data_lib.h" 00059 #include "6LoWPAN/Thread/thread_joiner_application.h" 00060 #include "6LoWPAN/Thread/thread_management_internal.h" 00061 #include "6LoWPAN/Thread/thread_management_client.h" 00062 #include "6LoWPAN/Thread/thread_management_server.h" 00063 #include "6LoWPAN/Thread/thread_resolution_client.h" 00064 #include "6LoWPAN/Thread/thread_address_registration_client.h" 00065 #include "6LoWPAN/Thread/thread_resolution_client.h" 00066 #include <6LoWPAN/Thread/thread_extension_bootstrap.h> 00067 #include "6LoWPAN/Thread/thread_neighbor_class.h" 00068 #include "MLE/mle.h" 00069 #include "Service_Libs/mle_service/mle_service_security.h" 00070 #include "Service_Libs/blacklist/blacklist.h" 00071 #include "6LoWPAN/Thread/thread_network_synch.h" 00072 #include "6LoWPAN/Thread/thread_config.h" 00073 #include "6LoWPAN/Thread/thread_tmfcop_lib.h" 00074 #include "thread_meshcop_lib.h" 00075 #include "thread_management_if.h" 00076 #include "ipv6_stack/protocol_ipv6.h" 00077 #include "Common_Protocols/ipv6.h" 00078 #include "Common_Protocols/icmpv6.h" 00079 #include "MLE/mle.h" 00080 #include "MLE/mle_tlv.h" 00081 #include "Service_Libs/nd_proxy/nd_proxy.h" 00082 #include "Service_Libs/mle_service/mle_service_api.h" 00083 #include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" 00084 #include "6LoWPAN/MAC/mac_helper.h" 00085 #include "6LoWPAN/MAC/mac_pairwise_key.h" 00086 #include "6LoWPAN/MAC/mac_data_poll.h" 00087 #include "Service_Libs/etx/etx.h" 00088 #include "Core/include/address.h" 00089 #include "6LoWPAN/Thread/thread_nvm_store.h" 00090 00091 #define TRACE_GROUP "thrd" 00092 00093 #define ID_MASK_UPDATE_MIN (10 * 10) /* 1 minute */ 00094 #define LEADER_DATA_UPDATE_MIN (10 * 10) /* 10 seconds */ 00095 00096 /* Parent priority bits in Connectivity TLV flags byte */ 00097 #define CONNECTIVITY_PP_MASK 0xC0 // Parent priority 00098 #define CONNECTIVITY_PP_LOW 0xC0 00099 #define CONNECTIVITY_PP_MEDIUM 0x00 00100 #define CONNECTIVITY_PP_HIGH 0x40 00101 #define CONNECTIVITY_PP_INVALID 0x80 00102 00103 uint8_t thread_version = THREAD_PROTOCOL_VERSION; 00104 00105 thread_leader_data_t *thread_leader_data_generate(void); 00106 thread_parent_info_t *thread_parent_data_allocate(thread_info_t *info); 00107 static uint8_t * thread_joining_port_tlv_write(uint16_t port, uint8_t *ptr); 00108 static uint8_t * thread_commissioner_port_tlv_write(uint16_t port, uint8_t *ptr); 00109 static void thread_tx_failure_handler(int8_t nwk_id, uint8_t accumulated_failures, uint8_t attribute_index); 00110 static void thread_address_notification_cb(struct protocol_interface_info_entry *interface, const struct if_address_entry *addr, if_address_callback_t reason); 00111 00112 /* Helper functions*/ 00113 /* Ceil log2 function */ 00114 uint16_t thread_log2_aprx(uint32_t n) 00115 { 00116 if (n == 0) { 00117 return 0; 00118 } 00119 uint16_t val = 0; 00120 --n; 00121 while (n > 0 && val < 255) { 00122 ++val; 00123 n >>= 1; 00124 } 00125 return val; 00126 } 00127 00128 00129 00130 void thread_anycast_address_policy_update(const thread_info_t *thread_info, bool addPolicy) 00131 { 00132 uint8_t ipv6_address[16] = {0}; 00133 00134 thread_addr_write_mesh_local_16(ipv6_address, 0xfc00, thread_info); 00135 00136 if (addPolicy) { 00137 tr_debug("Thread Add AnycastAddress Policy"); 00138 addr_policy_table_add_entry(ipv6_address, 118, 20, 40); 00139 } else { 00140 addr_policy_table_delete_entry(ipv6_address, 118); 00141 } 00142 } 00143 00144 /** 00145 * Thread key request for MLE Message 00146 * 00147 */ 00148 uint8_t *thread_management_key_request_with_sequence(int8_t interface_id, uint8_t keyId, uint32_t keySequnce) 00149 { 00150 protocol_interface_info_entry_t *cur; 00151 uint8_t *keyPtr = NULL; 00152 link_configuration_s *linkConfiguration; 00153 linkConfiguration = thread_joiner_application_get_config(interface_id); 00154 if (!linkConfiguration) { 00155 return NULL; 00156 } 00157 //tr_debug("MLE key request by sequence id %"PRIu8" seq %"PRIu32, keyId, keySequnce); 00158 00159 cur = protocol_stack_interface_info_get_by_id(interface_id); 00160 if (!cur || !cur->thread_info) { 00161 return NULL; 00162 } 00163 if (!cur->thread_info->masterSecretMaterial.valid_Info) { 00164 return NULL; 00165 } 00166 if (keySequnce == linkConfiguration->key_sequence) { 00167 if (mle_service_security_default_key_id_get(interface_id) == keyId) { 00168 keyPtr = mle_service_security_default_key_get(interface_id); 00169 } 00170 } else if (keySequnce == (linkConfiguration->key_sequence + 1)) { 00171 if (mle_service_security_next_key_id_get(interface_id) == keyId) { 00172 keyPtr = mle_service_security_next_key_get(interface_id); 00173 } 00174 } 00175 00176 if (!keyPtr) { 00177 tr_debug("Gen temporary key id %"PRIu8" seq %"PRIu32, keyId, keySequnce); 00178 thread_key_get(linkConfiguration->master_key, cur->thread_info->masterSecretMaterial.historyKey, keySequnce); 00179 cur->thread_info->masterSecretMaterial.historyKeyId = keyId; 00180 cur->thread_info->masterSecretMaterial.historyKeyValid = false; 00181 keyPtr = cur->thread_info->masterSecretMaterial.historyKey; 00182 } 00183 return keyPtr; 00184 } 00185 uint8_t * thread_mle_service_security_notify_cb(int8_t interface_id, mle_security_event_t event, uint8_t keyId) 00186 { 00187 (void)keyId; 00188 protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); 00189 if (!interface) { 00190 return NULL; 00191 } 00192 switch (event) { 00193 case MLE_SEC_MAX_FRAME_COUNTER_REACHED : 00194 00195 break; 00196 case MLE_SEC_KEY_UPDATE_NOTIFY : 00197 00198 mac_helper_security_key_swap_next_to_default(interface); 00199 00200 if (thread_info(interface)) { 00201 thread_security_update_from_mac(interface); 00202 } 00203 break; 00204 00205 case MLE_SEC_UNKNOWN_KEY : 00206 return NULL; 00207 } 00208 return NULL; 00209 } 00210 int8_t thread_bootstrap_up(protocol_interface_info_entry_t *cur) 00211 { 00212 int8_t ret_val = -1; 00213 00214 if (!cur) { 00215 return -1; 00216 } 00217 00218 if ((cur->configure_flags & INTERFACE_SETUP_MASK) != INTERFACE_SETUP_READY) { 00219 tr_debug("Interface not yet fully configured"); 00220 return -5; 00221 } 00222 00223 protocol_6lowpan_register_handlers(cur); 00224 addr_interface_set_ll64(cur, NULL); 00225 thread_interface_up(cur); 00226 ret_val = nwk_6lowpan_up(cur); 00227 00228 cur->nwk_nd_re_scan_count = 0; 00229 00230 return ret_val; 00231 } 00232 00233 int8_t thread_bootstrap_down(protocol_interface_info_entry_t *cur) 00234 { 00235 if (!cur || !(cur->lowpan_info & INTERFACE_NWK_ACTIVE)) { 00236 return -1; 00237 } 00238 00239 tr_debug("SET thread Idle"); 00240 //stop polling 00241 mac_data_poll_disable(cur); 00242 //Clean mle table 00243 thread_neighbor_list_clean(cur); 00244 // store frame counters 00245 if (cur->thread_info) { 00246 thread_nvm_fast_data_t fast_data; 00247 memset(&fast_data,0,sizeof(thread_nvm_fast_data_t)); 00248 link_configuration_s *linkConfiguration = thread_joiner_application_get_config(cur->id); 00249 if(linkConfiguration) { 00250 fast_data.seq_counter = linkConfiguration->key_sequence; 00251 } 00252 mac_helper_link_frame_counter_read(cur->id, &fast_data.mac_frame_counter); 00253 fast_data.mle_frame_counter=mle_service_security_get_frame_counter(cur->id); 00254 thread_nvm_store_fast_data_write(&fast_data); 00255 thread_joiner_application_configuration_nvm_save(cur->id); 00256 mac_pairwise_key_flush_list(cur->id); 00257 thread_discovery_reset(cur->id); 00258 thread_leader_mleid_rloc_map_to_nvm_write(cur); 00259 thread_bootstrap_stop(cur); 00260 mle_service_interface_unregister(cur->id); 00261 thread_management_server_delete(cur->id); 00262 thread_joiner_application_deinit(cur->id); 00263 thread_management_client_delete(cur->id); 00264 //free network Data 00265 thread_network_data_free_and_clean(&cur->thread_info->networkDataStorage); 00266 //free local also here 00267 thread_network_local_data_free_and_clean(&cur->thread_info->localServerDataBase, cur->id); 00268 thread_network_data_base_init(&cur->thread_info->networkDataStorage); 00269 cur->thread_info->thread_attached_state = THREAD_STATE_NETWORK_DISCOVER; 00270 } 00271 00272 if (nd_proxy_downstream_interface_unregister(cur->id) == -1) { 00273 tr_warn("nd proxy unregister failed"); 00274 } 00275 return nwk_6lowpan_down(cur); 00276 } 00277 00278 00279 bool thread_addr_is_mesh_local(const uint8_t *addr, const protocol_interface_info_entry_t *cur) 00280 { 00281 thread_info_t *info = cur ? cur->thread_info : NULL; 00282 if (info && info->threadPrivatePrefixInfo.ulaValid) { 00283 return memcmp(info->threadPrivatePrefixInfo.ulaPrefix, addr, 8) == 0; 00284 } 00285 return false; 00286 } 00287 00288 bool thread_on_mesh_route_possible_add(thread_attach_device_mode_e threadMode) 00289 { 00290 bool addRoute; 00291 if ((threadMode == THREAD_DEVICE_MODE_SLEEPY_END_DEVICE) || (threadMode == THREAD_DEVICE_MODE_END_DEVICE)) { 00292 addRoute = false; 00293 } else { 00294 addRoute = true; 00295 } 00296 00297 return addRoute; 00298 } 00299 00300 bool thread_addr_is_mesh_local_16(const uint8_t *addr, const protocol_interface_info_entry_t *cur) 00301 { 00302 return thread_addr_is_mesh_local(addr, cur) && memcmp(addr + 8, ADDR_SHORT_ADR_SUFFIC, 6) == 0; 00303 } 00304 00305 uint8_t *thread_addr_write_mesh_local_16(uint8_t ip_addr_out[16], uint16_t addr16, const thread_info_t *info) 00306 { 00307 if (!info->threadPrivatePrefixInfo.ulaValid) { 00308 return NULL; 00309 } 00310 memcpy(ip_addr_out + 8, ADDR_SHORT_ADR_SUFFIC, 6); 00311 common_write_16_bit(addr16, ip_addr_out + 14); 00312 return memcpy(ip_addr_out, info->threadPrivatePrefixInfo.ulaPrefix, 8); 00313 } 00314 00315 bool thread_leader_data_parse(uint8_t *ptr, uint16_t dataLength, thread_leader_data_t *leaderDataBuf) 00316 { 00317 mle_tlv_info_t mle_tlv_info; 00318 if (mle_tlv_option_discover(ptr, dataLength, MLE_TYPE_LEADER_DATA, &mle_tlv_info) == 8) { 00319 uint8_t *t_ptr = mle_tlv_info.dataPtr; 00320 leaderDataBuf->partitionId = common_read_32_bit(t_ptr); 00321 t_ptr += 4; 00322 leaderDataBuf->weighting = *t_ptr++; 00323 leaderDataBuf->dataVersion = *t_ptr++; 00324 leaderDataBuf->stableDataVersion = *t_ptr++; 00325 leaderDataBuf->leaderRouterId = *t_ptr; 00326 return true; 00327 } 00328 return false; 00329 } 00330 00331 bool thread_connectivity_tlv_parse(uint8_t *ptr, uint16_t dataLength, thread_connectivity_t *connectivityTlv) 00332 { 00333 mle_tlv_info_t mle_tlv_info; 00334 int tlv_length = mle_tlv_option_discover(ptr, dataLength, MLE_TYPE_CONNECTIVITY, &mle_tlv_info); 00335 if (tlv_length >= 7) { 00336 uint8_t *t_ptr = mle_tlv_info.dataPtr; 00337 uint8_t flags = *t_ptr++; 00338 switch (flags & CONNECTIVITY_PP_MASK) { 00339 case CONNECTIVITY_PP_LOW: 00340 connectivityTlv->parentPriority = THREAD_CONNECTIVITY_TLV_PARENT_PRIORITY_LOW; 00341 break; 00342 case CONNECTIVITY_PP_HIGH: 00343 connectivityTlv->parentPriority = THREAD_CONNECTIVITY_TLV_PARENT_PRIORITY_HIGH; 00344 break; 00345 case CONNECTIVITY_PP_MEDIUM: 00346 default: 00347 connectivityTlv->parentPriority = THREAD_CONNECTIVITY_TLV_PARENT_PRIORITY_MEDIUM; 00348 break; 00349 } 00350 connectivityTlv->linkQuality3 = *t_ptr++; 00351 connectivityTlv->linkQuality2 = *t_ptr++; 00352 connectivityTlv->linkQuality1 = *t_ptr++; 00353 connectivityTlv->leaderCost = *t_ptr++; 00354 connectivityTlv->idSequence = *t_ptr++; 00355 connectivityTlv->activeRouters = *t_ptr++; 00356 if (tlv_length >= 10) { 00357 connectivityTlv->SEDBufferSize = common_read_16_bit(t_ptr); 00358 t_ptr += 2; 00359 connectivityTlv->SEDDatagramCount = *t_ptr++; 00360 } else { 00361 connectivityTlv->SEDBufferSize = THREAD_SED_BUFFER_MIN_SIZE; 00362 connectivityTlv->SEDDatagramCount = THREAD_SED_DATAGRAM_MIN_COUNT; 00363 } 00364 return true; 00365 } 00366 return false; 00367 } 00368 00369 void thread_key_guard_timer_calculate(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration, bool is_init) 00370 { 00371 uint32_t key_rotation = linkConfiguration ? linkConfiguration->key_rotation : 0; 00372 00373 if (is_init && key_rotation < 1) { 00374 tr_warn("Attempted to set key rotation time smaller than 1 hour."); 00375 key_rotation = 1; 00376 } 00377 00378 cur->thread_info->masterSecretMaterial.keyRotation = key_rotation * 3600; // setting value is hours converting to seconds 00379 cur->thread_info->masterSecretMaterial.keySwitchGuardTimer = is_init ? 0 : (key_rotation * 3600 * 0.93); 00380 } 00381 00382 void thread_key_guard_timer_reset(protocol_interface_info_entry_t *cur) 00383 { 00384 cur->thread_info->masterSecretMaterial.keySwitchGuardTimer = 0; 00385 } 00386 00387 thread_leader_data_t *thread_leader_data_generate(void) 00388 { 00389 thread_leader_data_t *leader_data; 00390 leader_data = ns_dyn_mem_alloc(sizeof(thread_leader_data_t)); 00391 if (leader_data) { 00392 memset(leader_data,0,sizeof(thread_leader_data_t)); 00393 } 00394 return leader_data; 00395 } 00396 00397 thread_leader_data_t *thread_leader_data_get(thread_info_t *info) 00398 { 00399 if (info->thread_leader_data == NULL) { 00400 info->thread_leader_data = thread_leader_data_generate(); 00401 } 00402 return info->thread_leader_data; 00403 } 00404 00405 thread_parent_info_t *thread_parent_data_allocate(thread_info_t *info) 00406 { 00407 thread_parent_info_t *parent_data; 00408 if (!info->thread_endnode_parent) { 00409 info->thread_endnode_parent = ns_dyn_mem_alloc(sizeof(thread_parent_info_t)); 00410 } 00411 00412 parent_data = info->thread_endnode_parent; 00413 if (parent_data) { 00414 memset(parent_data,0,sizeof(thread_parent_info_t)); 00415 } 00416 return parent_data; 00417 } 00418 00419 void thread_dynamic_reed_initialize(thread_router_select_t *routerSelect) 00420 { 00421 routerSelect->jitterTimerActive = false; 00422 routerSelect->possibleDefaultParent = 0xff; 00423 routerSelect->routerDowngradeThresHold = ROUTER_DOWNGRADE_THRESHOLD; 00424 routerSelect->routerUpgradeThresHold = ROUTER_UPGRADE_THRESHOLD; 00425 routerSelect->reedAdvertisementInterval = REED_ADVERTISEMENT_INTERVAL; 00426 routerSelect->reedAdvertisementJitterInterval = REED_ADVERTISEMENT_MAX_JITTER; 00427 routerSelect->reedAdvertisementTimeout = NULL; 00428 } 00429 00430 bool thread_leader_commissioner_create(thread_info_t *thread_info) 00431 { 00432 thread_info->registered_commissioner.commissioner_valid = false; 00433 thread_info->registered_commissioner.session_id = randLIB_get_16bit(); 00434 ns_dyn_mem_free(thread_info->registered_commissioner.commissioner_id_ptr); 00435 thread_info->registered_commissioner.commissioner_id_ptr = NULL; 00436 eventOS_timeout_cancel(thread_info->registered_commissioner.commissioner_timeout); 00437 thread_info->registered_commissioner.commissioner_timeout = NULL; 00438 thread_info->registered_commissioner.commissioner_registration = THREAD_COMMISSIONER_NOT_REGISTERED; 00439 thread_info->registered_commissioner.steering_data_len = 0; 00440 return true; 00441 } 00442 00443 00444 void thread_data_base_init(thread_info_t *thread_info, int8_t interfaceId) 00445 { 00446 if (!thread_info) { 00447 return; 00448 } 00449 (void) interfaceId; 00450 00451 thread_leader_commissioner_create(thread_info); 00452 thread_info->rfc6775 = false; 00453 thread_info->threadPrivatePrefixInfo.ulaValid = false; 00454 thread_info->routerIdReqCoapID = 0; 00455 thread_info->networkDataRequested = false; 00456 thread_info->proactive_an_timer = 0; 00457 00458 thread_info->thread_device_mode = THREAD_DEVICE_MODE_END_DEVICE; 00459 thread_info->thread_attached_state = THREAD_STATE_NETWORK_DISCOVER; 00460 thread_routing_reset(&thread_info->routing); 00461 } 00462 00463 int thread_info_allocate_and_init(protocol_interface_info_entry_t *cur) 00464 { 00465 if (thread_bootstrap_tasklet_init(cur) != 0) { 00466 return -1; 00467 } 00468 00469 if (!cur->thread_info) { 00470 cur->thread_info = ns_dyn_mem_alloc(sizeof(thread_info_t)); 00471 if (!cur->thread_info) { 00472 return -1; 00473 } 00474 memset(cur->thread_info, 0, sizeof(thread_info_t)); 00475 00476 cur->thread_info->interface_id = cur->id; 00477 cur->thread_info->testMaxActiveRouterIdLimit = 32; 00478 cur->thread_info->version = thread_version; // Default implementation version 00479 cur->thread_info->thread_device_mode = THREAD_DEVICE_MODE_END_DEVICE; 00480 cur->thread_info->childUpdateReqTimer = -1; 00481 00482 thread_routing_init(&cur->thread_info->routing); 00483 thread_network_local_server_data_base_init(&cur->thread_info->localServerDataBase); 00484 memset(&cur->thread_info->registered_commissioner,0,sizeof(thread_commissioner_t)); 00485 thread_dynamic_reed_initialize(&cur->thread_info->routerSelectParameters); 00486 thread_extension_allocate(cur); 00487 ns_list_init(&cur->thread_info->childIdReqPending); 00488 ns_list_init(&cur->thread_info->child_mcast_list); 00489 if (!thread_leader_data_get(cur->thread_info)){ 00490 return -1; 00491 } 00492 } else { 00493 thread_network_data_free_and_clean(&cur->thread_info->networkDataStorage); 00494 thread_network_local_data_free_and_clean(&cur->thread_info->localServerDataBase, cur->id); 00495 thread_leader_service_leader_data_free(cur->thread_info); 00496 thread_data_base_init(cur->thread_info, cur->id); 00497 thread_dynamic_reed_initialize(&cur->thread_info->routerSelectParameters); 00498 } 00499 thread_network_data_base_init(&cur->thread_info->networkDataStorage); 00500 //SET Thread Bootstrap Up & Down 00501 cur->if_up = thread_bootstrap_up; 00502 cur->if_down = thread_bootstrap_down; 00503 cur->mac_parameters->beacon_ind = thread_beacon_indication; 00504 cur->mac_parameters->mac_in_direct_entry_timeout = 30000; 00505 cur->thread_info->routerShortAddress = 0xfffe; //Default value Not Router 00506 //memset(cur->thread_info->lastValidRouteMask, 0, (N_THREAD_ROUTERS+7)/8); 00507 cur->thread_info->releaseRouterId = false; 00508 00509 // Test data 00510 cur->thread_info->testRandomPartitionId = 0; 00511 00512 return 0; 00513 } 00514 00515 void thread_info_deallocate(protocol_interface_info_entry_t *cur) 00516 { 00517 if (cur->thread_info) { 00518 //Release DHCPv6 leasequery Service 00519 thread_nd_service_delete(cur->id); 00520 thread_network_data_free_and_clean(&cur->thread_info->networkDataStorage); 00521 thread_network_local_data_free_and_clean(&cur->thread_info->localServerDataBase, cur->id); 00522 thread_leader_service_leader_data_free(cur->thread_info); 00523 thread_data_base_init(cur->thread_info, cur->id); 00524 thread_routing_free(&cur->thread_info->routing); 00525 thread_extension_free(cur); 00526 thread_extension_bootstrap_free(cur); 00527 if (cur->thread_info->thread_endnode_parent) { 00528 ns_dyn_mem_free(cur->thread_info->thread_endnode_parent); 00529 cur->thread_info->thread_endnode_parent = NULL; 00530 } 00531 ns_dyn_mem_free(cur->thread_info); 00532 cur->thread_info = 0; 00533 cur->mesh_callbacks = NULL; 00534 } 00535 } 00536 00537 thread_leader_info_t *thread_allocate_and_init_leader_private_data(void) 00538 { 00539 thread_leader_info_t *leader_info = ns_dyn_mem_alloc(sizeof(thread_leader_info_t)); 00540 if (leader_info) { 00541 leader_info->leader_id_seq_timer = ID_SEQUENCE_PERIOD; 00542 leader_info->leader_nvm_sync_timer = 0; 00543 } 00544 return leader_info; 00545 } 00546 00547 thread_route_cost_t thread_link_quality_to_cost(thread_link_quality_e quality) 00548 { 00549 switch (quality) { 00550 case QUALITY_20dB: 00551 return 1; 00552 case QUALITY_10dB: 00553 return 2; 00554 case QUALITY_2dB: 00555 return 4; 00556 default: 00557 case QUALITY_BAD: 00558 return THREAD_COST_INFINITE; 00559 } 00560 } 00561 00562 thread_route_cost_t thread_link_cost_sum(thread_route_cost_t a, thread_route_cost_t b) 00563 { 00564 if (a == THREAD_COST_INFINITE || b == THREAD_COST_INFINITE) { 00565 return THREAD_COST_INFINITE; 00566 } 00567 00568 if (a + b > THREAD_MAX_ROUTE_COST) { 00569 return THREAD_COST_INFINITE; 00570 } 00571 00572 return a + b; 00573 } 00574 00575 thread_link_quality_e thread_link_margin_to_quality(thread_link_margin_t margin) 00576 { 00577 if (margin > (20 << THREAD_LINK_MARGIN_SCALING)) { 00578 return QUALITY_20dB; 00579 } else if (margin > (10 << THREAD_LINK_MARGIN_SCALING)) { 00580 return QUALITY_10dB; 00581 } else if (margin > (2 << THREAD_LINK_MARGIN_SCALING)) { 00582 return QUALITY_2dB; 00583 } else { 00584 return QUALITY_BAD; 00585 } 00586 } 00587 00588 uint_fast8_t thread_sum_rx_path_cost_and_link_cost(uint8_t inMargim, uint8_t outMargin, uint8_t pathCost) 00589 { 00590 thread_route_cost_t linkCost, rxCost; 00591 if (inMargim < outMargin) { 00592 linkCost = thread_link_quality_to_cost(thread_link_margin_to_quality(inMargim)); 00593 } else { 00594 linkCost = thread_link_quality_to_cost(thread_link_margin_to_quality(outMargin)); 00595 } 00596 rxCost = pathCost; 00597 00598 return thread_link_cost_sum(linkCost, rxCost); 00599 } 00600 00601 thread_registered_mcast_addr_t *thread_registered_mcast_addr_entry_allocate(void) 00602 { 00603 thread_registered_mcast_addr_t *addr = ns_dyn_mem_alloc(sizeof(thread_registered_mcast_addr_t)); 00604 00605 if (addr) { 00606 memset(addr, 0, sizeof(thread_registered_mcast_addr_t)); 00607 ns_list_init(&addr->children); 00608 } 00609 00610 return addr; 00611 } 00612 00613 thread_mcast_child_t *thread_mcast_addr_child_entry_allocate(void) 00614 { 00615 thread_mcast_child_t *child = ns_dyn_mem_alloc(sizeof(thread_mcast_child_t)); 00616 00617 if (child) { 00618 memset(child, 0, sizeof(thread_mcast_child_t)); 00619 } 00620 00621 return child; 00622 } 00623 00624 void thread_registered_mcast_addr_entry_clean(protocol_interface_info_entry_t *cur) 00625 { 00626 ns_list_foreach_safe(thread_registered_mcast_addr_t, entry, &cur->thread_info->child_mcast_list) { 00627 ns_list_remove(&cur->thread_info->child_mcast_list, entry); 00628 00629 ns_list_foreach_safe(thread_mcast_child_t, child, &entry->children) { 00630 ns_list_remove(&entry->children, child); 00631 ns_dyn_mem_free(child); 00632 } 00633 00634 ns_dyn_mem_free(entry); 00635 } 00636 } 00637 00638 void thread_child_mcast_entries_remove(protocol_interface_info_entry_t *cur, const uint8_t *mac64) 00639 { 00640 ns_list_foreach_safe(thread_registered_mcast_addr_t, entry, &cur->thread_info->child_mcast_list) { 00641 ns_list_foreach_safe(thread_mcast_child_t, child, &entry->children) { 00642 if (memcmp(child->mac64, mac64, 8) == 0) { 00643 ns_list_remove(&entry->children, child); 00644 ns_dyn_mem_free(child); 00645 } 00646 } 00647 } 00648 00649 // Remove empty multicast address entries 00650 ns_list_foreach_safe(thread_registered_mcast_addr_t, entry, &cur->thread_info->child_mcast_list) { 00651 if (ns_list_is_empty(&entry->children)) { 00652 ns_list_remove(&cur->thread_info->child_mcast_list, entry); 00653 ns_dyn_mem_free(entry); 00654 } 00655 } 00656 } 00657 00658 thread_registered_mcast_addr_t *thread_registered_mcast_addr_entry_find(protocol_interface_info_entry_t *cur, const uint8_t *mcast_addr) 00659 { 00660 ns_list_foreach(thread_registered_mcast_addr_t, entry, &cur->thread_info->child_mcast_list) { 00661 if (memcmp(entry->address, mcast_addr, 16) == 0) { 00662 return entry; 00663 } 00664 } 00665 00666 return NULL; 00667 } 00668 00669 thread_mcast_child_t *thread_child_mcast_entry_find(thread_mcast_children_list_t *children, const uint8_t *mac64) 00670 { 00671 ns_list_foreach(thread_mcast_child_t, entry, children) { 00672 if (memcmp(entry->mac64, mac64, 8) == 0) { 00673 return entry; 00674 } 00675 } 00676 00677 return NULL; 00678 } 00679 00680 bool thread_stable_context_check(protocol_interface_info_entry_t *cur, buffer_t *buf) 00681 { 00682 mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur),buf->dst_sa .address + 2 , buf->dst_sa .addr_type ); 00683 if (entry && thread_addr_is_child(mac_helper_mac16_address_get(cur), entry->mac16 )) { 00684 00685 /* Check if the child can handle only stable network data (e.g. sleepy device) */ 00686 return !(thread_neighbor_class_request_full_data_setup(&cur->thread_info->neighbor_class, entry->index )); 00687 } 00688 return false; 00689 } 00690 00691 thread_mcast_child_t *thread_child_mcast_entry_get(protocol_interface_info_entry_t *cur, const uint8_t *mcast_addr, const uint8_t *mac64) 00692 { 00693 mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), mac64, ADDR_802_15_4_LONG ); 00694 00695 if (!entry) { 00696 tr_error("No MLE entry."); 00697 return NULL; 00698 } 00699 00700 if (entry->rx_on_idle ) { 00701 /* Not a sleepy child */ 00702 tr_debug("Not a sleepy child"); 00703 return NULL; 00704 } 00705 00706 thread_registered_mcast_addr_t *addr = thread_registered_mcast_addr_entry_find(cur, mcast_addr); 00707 00708 if (!addr) { 00709 addr = thread_registered_mcast_addr_entry_allocate(); 00710 00711 if (addr) { 00712 memcpy(addr->address, mcast_addr, 16); 00713 ns_list_add_to_end(&cur->thread_info->child_mcast_list, addr); 00714 } else { 00715 return NULL; 00716 } 00717 } 00718 00719 thread_mcast_child_t *child = thread_child_mcast_entry_find(&addr->children, mac64); 00720 00721 if (!child) { 00722 child = thread_mcast_addr_child_entry_allocate(); 00723 00724 if (child) { 00725 memcpy(child->mac64, mac64, 8); 00726 ns_list_add_to_end(&addr->children, child); 00727 } else { 00728 return NULL; 00729 } 00730 } 00731 00732 return child; 00733 } 00734 00735 void thread_child_id_request_info_init(thread_pending_child_id_req_t *child_info) 00736 { 00737 if (child_info) { 00738 child_info->routeReq = false; 00739 child_info->networkDataReq = false; 00740 child_info->shortAddressReq = false; 00741 } 00742 } 00743 00744 thread_pending_child_id_req_t *thread_child_id_request_allocate(void) 00745 { 00746 thread_pending_child_id_req_t *req = ns_dyn_mem_alloc(sizeof(thread_pending_child_id_req_t)); 00747 memset(req->eiid, 0 , 8); 00748 thread_child_id_request_info_init(req); 00749 return req; 00750 } 00751 00752 void thread_child_id_request_entry_clean(protocol_interface_info_entry_t *cur) 00753 { 00754 ns_list_foreach_safe(thread_pending_child_id_req_t, entry, &cur->thread_info->childIdReqPending) { 00755 ns_list_remove(&cur->thread_info->childIdReqPending, entry); 00756 ns_dyn_mem_free(entry); 00757 } 00758 } 00759 00760 thread_pending_child_id_req_t *thread_child_id_request_entry_get(protocol_interface_info_entry_t *cur, uint8_t *euid64) 00761 { 00762 thread_pending_child_id_req_t *req; 00763 ns_list_foreach(thread_pending_child_id_req_t, entry, &cur->thread_info->childIdReqPending) { 00764 if (memcmp(entry->euid64, euid64, 8) == 0) { 00765 thread_child_id_request_info_init(entry); 00766 return entry; 00767 } 00768 } 00769 req = thread_child_id_request_allocate(); 00770 if (req) { 00771 tr_debug("Add to list ID REQ"); 00772 memcpy(req->euid64, euid64, 8); 00773 ns_list_add_to_end(&cur->thread_info->childIdReqPending, req); 00774 } 00775 return req; 00776 } 00777 00778 thread_pending_child_id_req_t *thread_child_id_request_entry_get_from_the_list(protocol_interface_info_entry_t *cur) 00779 { 00780 thread_pending_child_id_req_t *req; 00781 00782 req = ns_list_get_first(&cur->thread_info->childIdReqPending); 00783 if (req) { 00784 ns_list_remove(&cur->thread_info->childIdReqPending, req); 00785 } 00786 00787 return req; 00788 00789 } 00790 00791 void thread_child_id_request_entry_remove(protocol_interface_info_entry_t *cur, thread_pending_child_id_req_t *entry) 00792 { 00793 if (entry) { 00794 ns_list_remove(&cur->thread_info->childIdReqPending, entry); 00795 ns_dyn_mem_free(entry); 00796 } 00797 } 00798 00799 int thread_init(protocol_interface_info_entry_t *cur) 00800 { 00801 if (!cur->thread_info) { 00802 return -1; 00803 } 00804 00805 if (thread_mle_class_init(cur->id) != 0) { 00806 return -1; 00807 } 00808 00809 // set mle security - first allocate instance and then set security 00810 mle_service_security_instance_allocate(cur->id); 00811 if (mle_service_security_init(cur->id, 5, 00812 0, 00813 thread_management_key_request_with_sequence, 00814 thread_mle_service_security_notify_cb) != 0) { 00815 tr_error("Mle Service security init Fail"); 00816 return -1; 00817 } 00818 00819 if (etx_accum_failures_callback_register(cur->nwk_id, cur->id, 1, thread_tx_failure_handler) != 1) { 00820 return -1; 00821 } 00822 00823 addr_notification_register(thread_address_notification_cb); 00824 00825 thread_leader_service_leader_data_free(cur->thread_info); 00826 thread_data_base_init(cur->thread_info, cur->id); 00827 mac_helper_pib_boolean_set(cur,macThreadForceLongAddressForBeacon , true); 00828 mac_helper_mac16_address_set(cur, 0xffff); 00829 return 0; 00830 } 00831 00832 int thread_attach_ready(protocol_interface_info_entry_t *cur) 00833 { 00834 if (!cur->thread_info) { 00835 return -1; 00836 } 00837 00838 switch (cur->thread_info->thread_attached_state) { 00839 case THREAD_STATE_CONNECTED: 00840 case THREAD_STATE_CONNECTED_ROUTER: 00841 return 0; 00842 /* break; */ 00843 default: 00844 break; 00845 } 00846 00847 return -1; 00848 } 00849 00850 bool thread_attach_active_router(protocol_interface_info_entry_t *cur) 00851 { 00852 if(cur->thread_info->thread_attached_state == THREAD_STATE_CONNECTED_ROUTER) { 00853 return true; 00854 } 00855 00856 return false; 00857 } 00858 00859 bool thread_scan_mask_validation(protocol_interface_info_entry_t *cur, uint8_t mask) 00860 { 00861 uint8_t maskCompare = 0; 00862 00863 if (cur->thread_info->thread_device_mode != THREAD_DEVICE_MODE_ROUTER) { 00864 return false; 00865 } 00866 00867 switch (cur->thread_info->thread_attached_state) { 00868 case THREAD_STATE_CONNECTED_ROUTER: 00869 maskCompare = 0x80; 00870 break; 00871 case THREAD_STATE_CONNECTED: 00872 maskCompare = 0x40; 00873 break; 00874 default: 00875 maskCompare = 0; 00876 break; 00877 } 00878 return (mask & maskCompare); 00879 } 00880 00881 int thread_route_ready_to_leader(protocol_interface_info_entry_t *cur) 00882 { 00883 int retVal = -1; 00884 switch (cur->thread_info->thread_attached_state) { 00885 case THREAD_STATE_CONNECTED_ROUTER: 00886 if (cur->thread_info->leader_private_data) { 00887 //We are the leader 00888 retVal = 0; 00889 } else if (thread_routing_cost_get_by_router_id(&cur->thread_info->routing, cur->thread_info->thread_leader_data->leaderRouterId) != 0) { 00890 retVal = 0; 00891 } 00892 break; 00893 case THREAD_STATE_CONNECTED: 00894 if (cur->thread_info->thread_endnode_parent) { 00895 retVal = 0; 00896 } 00897 break; 00898 default: 00899 break; 00900 } 00901 return retVal; 00902 } 00903 static void thread_child_update_req_timer(protocol_interface_info_entry_t *cur, uint16_t seconds) 00904 { 00905 if (cur->thread_info->childUpdateReqTimer == -1) { 00906 return; 00907 } 00908 if (cur->thread_info->childUpdateReqTimer > seconds) { 00909 cur->thread_info->childUpdateReqTimer -= seconds; 00910 } else { 00911 cur->thread_info->childUpdateReqTimer = 0; 00912 } 00913 00914 if (cur->thread_info->childUpdateReqTimer == 0) { 00915 thread_bootstrap_child_update_trig(cur); 00916 cur->thread_info->childUpdateReqTimer = -1; // disable 00917 } 00918 } 00919 00920 static void thread_key_switch_timer(protocol_interface_info_entry_t *cur, uint16_t seconds) 00921 { 00922 if (cur->thread_info->masterSecretMaterial.keySwitchGuardTimer > seconds) { 00923 cur->thread_info->masterSecretMaterial.keySwitchGuardTimer -= seconds; 00924 } else { 00925 cur->thread_info->masterSecretMaterial.keySwitchGuardTimer = 0; 00926 } 00927 00928 if (cur->thread_info->masterSecretMaterial.keyRotation > seconds) { 00929 cur->thread_info->masterSecretMaterial.keyRotation -= seconds; 00930 } else { 00931 cur->thread_info->masterSecretMaterial.keyRotation = 0; 00932 } 00933 00934 if (cur->thread_info->masterSecretMaterial.keyRotation == 0) { 00935 link_configuration_s *linkConfiguration; 00936 linkConfiguration = thread_joiner_application_get_config(cur->id); 00937 00938 if (!linkConfiguration) { 00939 return; 00940 } 00941 00942 tr_debug("thrKeyRotation == 0: sync key material by %"PRIu32, linkConfiguration->key_sequence + 1); 00943 thread_management_key_sets_calc(cur, linkConfiguration, linkConfiguration->key_sequence + 1); 00944 thread_key_guard_timer_calculate(cur, linkConfiguration, false); 00945 } 00946 } 00947 00948 void thread_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t ticks) 00949 { 00950 uint8_t leader_address[16]; 00951 uint8_t commissioner_address[16]; 00952 uint16_t commissioner_port; 00953 thread_info_t *thread_info = cur->thread_info; 00954 00955 if (!thread_info) { 00956 return; 00957 } 00958 00959 blacklist_ttl_update(ticks); 00960 00961 // if we have pending configurations timer is made for it. 00962 thread_joiner_application_seconds_timer(cur->id, ticks); 00963 thread_resolution_client_timer(cur->id, ticks); 00964 thread_key_switch_timer(cur, ticks); 00965 thread_child_update_req_timer(cur, ticks); 00966 00967 if (!thread_bootstrap_should_register_address(cur)) { 00968 /* Only FTD refreshes the address registration timer */ 00969 thread_address_registration_timer(cur, ticks); 00970 } 00971 00972 if (thread_attach_ready(cur) != 0) { 00973 return; 00974 } 00975 // Store all Dynamic information periodically. Now saved every 1s 00976 thread_bootstrap_dynamic_configuration_save(cur); 00977 00978 // TODO should this be somewhere else? in joiner application? 00979 if (thread_joiner_application_next_active_config_exists(cur->id)) { 00980 thread_management_get_leader_address(cur->id, leader_address); 00981 thread_management_client_active_set(cur->id, leader_address); 00982 thread_joiner_application_next_active_config_delete(cur->id); 00983 } 00984 00985 if (thread_joiner_application_next_pending_config_exists(cur->id)) { 00986 thread_management_get_leader_address(cur->id, leader_address); 00987 thread_management_client_pending_set(cur->id, leader_address ); 00988 thread_joiner_application_next_pending_config_delete(cur->id); 00989 } 00990 00991 // Check if we need to make application provisioning 00992 if (PROVISIONING_STATUS_NOT_DONE == thread_joiner_application_provisioning_get(cur->id) && 00993 thread_management_get_commissioner_address(cur->id, commissioner_address, &commissioner_port) == 0) { 00994 // Provisioning not done and commissioner is present 00995 thread_management_client_provision_request(cur->id, commissioner_address, commissioner_port); 00996 } 00997 00998 00999 // add more checks here when to become router 01000 // If we are doing attach to new partition, do not upgrade 01001 if(cur->nwk_bootstrap_state != ER_BOOTSRAP_DONE && cur->nwk_bootstrap_state != ER_MLE_ATTACH_READY) { 01002 return; 01003 } 01004 01005 thread_router_bootstrap_timer(cur, ticks); 01006 thread_border_router_seconds_timer(cur->id, ticks); 01007 thread_bbr_seconds_timer(cur->id, ticks); 01008 thread_lowpower_timer(cur, ticks); 01009 thread_nvm_store_seconds_timer(ticks); 01010 01011 if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_ACTIVE) { 01012 nwk_bootsrap_state_update(ARM_NWK_BOOTSTRAP_READY, cur); 01013 } 01014 } 01015 01016 void thread_network_data_request_send(protocol_interface_info_entry_t *cur, uint8_t *requestDstAddress, bool delaydTrig) 01017 { 01018 thread_info_t *thread_info = cur->thread_info; 01019 uint8_t req_tlv = MLE_TYPE_NETWORK_DATA; 01020 01021 if (!cur->thread_info) { 01022 return; 01023 } 01024 01025 tr_debug("Send MLE network data request"); 01026 01027 if(cur->thread_info->networkDataRequested){ 01028 tr_debug("Pending data request found"); 01029 return; 01030 } 01031 01032 cur->thread_info->networkDataRequested = true; 01033 01034 thread_tlv_request(thread_info->interface_id, requestDstAddress,delaydTrig, &req_tlv, 1); 01035 } 01036 01037 void thread_timer(protocol_interface_info_entry_t *cur, uint8_t ticks) 01038 { 01039 thread_info_t *thread_info = cur->thread_info; 01040 if (!thread_info) { 01041 return; 01042 } 01043 01044 if (cur->nwk_bootstrap_state != ER_BOOTSRAP_DONE && cur->nwk_bootstrap_state != ER_MLE_ATTACH_READY) { 01045 /* Own attach is ongoing, do not send advertisements */ 01046 return; 01047 } 01048 01049 if (thread_i_am_router(cur)) { 01050 if (thread_routing_timer(thread_info, ticks)) { 01051 thread_router_bootstrap_mle_advertise(cur); 01052 } 01053 } 01054 } 01055 01056 /* This test is used to indicate that we're following the Thread 1.0 oddities 01057 * arising from not having LL16 addresses on the mesh. For example, LL16 01058 * addresses go through the MAC and only one radio hop, and UL16/GP16 addresses 01059 * have special semantics on the PAN. 01060 */ 01061 bool thread_insist_that_mesh_isnt_a_link(const protocol_interface_info_entry_t *cur) 01062 { 01063 return cur->thread_info && !cur->thread_info->rfc6775; 01064 } 01065 01066 int8_t thread_beacon_create_payload(struct protocol_interface_info_entry *cur) 01067 { 01068 uint8_t *ptr; 01069 uint8_t payload_len; 01070 link_configuration_s *leader_link_setup; 01071 thread_management_server_data_t server_data; 01072 01073 leader_link_setup = thread_joiner_application_get_config(cur->id); 01074 01075 if (!leader_link_setup) { 01076 return -1; 01077 } 01078 01079 if(!(leader_link_setup->securityPolicy & SECURITY_POLICY_BEACON_PAYLOAD_ENABLED)){ 01080 mac_helper_beacon_payload_reallocate(cur, 0); 01081 return mac_helper_beacon_payload_register(cur); 01082 } 01083 if (thread_management_server_commisoner_data_get(cur->id, &server_data) != 0) { 01084 return mac_helper_beacon_payload_register(cur); 01085 } 01086 01087 payload_len = 2/*header*/ + 16/*Network id*/ + 8/*extented PANID*/; 01088 01089 if (cur->thread_info->registered_commissioner.commissioner_valid && cur->thread_info->registered_commissioner.steering_data_len) { 01090 payload_len += cur->thread_info->registered_commissioner.steering_data_len + 2; 01091 } 01092 01093 if (server_data.joiner_router_enabled) { 01094 payload_len += 4/*Joiner UDP port*/; 01095 } 01096 if((leader_link_setup->securityPolicy & SECURITY_POLICY_NATIVE_COMMISSIONING_ALLOWED)){ 01097 payload_len += 4/*Commissioner UDP port*/; 01098 } 01099 01100 ptr = mac_helper_beacon_payload_reallocate(cur, payload_len); 01101 if (!ptr) { 01102 return -1; 01103 } 01104 01105 *ptr++ = THREAD_BEACON_PROTOCOL_ID; 01106 *ptr = THREAD_BEACON_PROTOCOL_VERSION << THREAD_BEACON_VERSION_SHIFT; 01107 01108 if (cur->thread_info->registered_commissioner.commissioner_valid && cur->thread_info->registered_commissioner.steering_data_len > 0) { 01109 *ptr |= THREAD_BEACON_JOINING_PERMITTED_BIT; // permit join bit set on 01110 } 01111 if((leader_link_setup->securityPolicy & SECURITY_POLICY_NATIVE_COMMISSIONING_ALLOWED)){ 01112 *ptr |= THREAD_BEACON_NATIVE_COMMISSIONER_BIT; 01113 } 01114 ptr++; 01115 memcpy(ptr, leader_link_setup->name, 16); 01116 ptr += 16; 01117 memcpy(ptr, leader_link_setup->extented_pan_id, 8); 01118 ptr += 8; 01119 01120 if (server_data.joiner_router_enabled) { 01121 /* MESHCOP_TLV_JOINER_UDP_PORT */ 01122 ptr = thread_joining_port_tlv_write(server_data.joiner_router_port, ptr); 01123 } 01124 if((leader_link_setup->securityPolicy & SECURITY_POLICY_NATIVE_COMMISSIONING_ALLOWED)){ 01125 /* MESHCOP_TLV_COMMISSIONER_UDP_PORT */ 01126 ptr = thread_commissioner_port_tlv_write(server_data.commissioner_port, ptr); 01127 } 01128 01129 01130 if (cur->thread_info->registered_commissioner.commissioner_valid && cur->thread_info->registered_commissioner.steering_data_len > 0){ 01131 ptr = thread_nd_commission_data_write_steering_data(ptr, cur->thread_info->registered_commissioner.steering_data, cur->thread_info->registered_commissioner.steering_data_len); 01132 } 01133 01134 return mac_helper_beacon_payload_register(cur); 01135 } 01136 01137 uint8_t thread_beacon_indication(uint8_t *ptr, uint8_t len, protocol_interface_info_entry_t *cur) 01138 { 01139 (void)ptr; 01140 (void)len; 01141 (void)cur; 01142 return 1; 01143 } 01144 01145 static uint8_t *thread_linkquality_write(int8_t interface_id, uint8_t *buffer) 01146 { 01147 protocol_interface_info_entry_t *interface_ptr = protocol_stack_interface_info_get_by_id(interface_id); 01148 if (!interface_ptr && !interface_ptr->thread_info) { 01149 return buffer; 01150 } 01151 01152 uint8_t lqi1 = 0, lqi2 = 0, lqi3 = 0; 01153 thread_link_quality_e thread_link_quality; 01154 mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(interface_ptr)->neighbour_list; 01155 01156 ns_list_foreach(mac_neighbor_table_entry_t, cur, mac_table_list) { 01157 if (thread_is_router_addr(cur->mac16)) { 01158 // Only count routers to link quality 01159 uint16_t link_margin = thread_neighbor_entry_linkmargin_get(&interface_ptr->thread_info->neighbor_class, cur->index); 01160 thread_link_quality = thread_link_margin_to_quality(link_margin); 01161 switch (thread_link_quality) { 01162 case QUALITY_20dB: 01163 lqi3++; 01164 break; 01165 case QUALITY_10dB: 01166 lqi2++; 01167 break; 01168 case QUALITY_2dB: 01169 lqi1++; 01170 break; 01171 case QUALITY_BAD: 01172 break; 01173 01174 } 01175 } 01176 } 01177 01178 *buffer++ = lqi3; 01179 *buffer++ = lqi2; 01180 *buffer++ = lqi1; 01181 return buffer; 01182 } 01183 01184 uint8_t thread_route_option_size(protocol_interface_info_entry_t *cur) 01185 { 01186 return 2 + MLE_ROUTE_MIN_OPTION_LEN + thread_routing_get_route_data_size(cur); 01187 01188 } 01189 uint8_t *thread_route_option_write(protocol_interface_info_entry_t *cur, uint8_t *ptr) 01190 { 01191 uint8_t *len_ptr; 01192 uint8_t *saved_ptr; 01193 01194 saved_ptr = ptr; 01195 *ptr++ = MLE_TYPE_ROUTE; 01196 len_ptr = ptr++; 01197 /* ptr now points to ID sequence */ 01198 01199 /* Can write the data straight into the buffer */ 01200 if (thread_routing_get_route_data(cur, 01201 ptr, /* ptr to ID sequence (1 byte) */ 01202 ptr + 1, /* ptr to ID mask (MLE_ROUTE_ID_MASK_SIZE bytes) */ 01203 ptr + MLE_ROUTE_MIN_OPTION_LEN, /* ptr to router table data */ 01204 len_ptr) != 0) /* ptr to length */ { /* 0 -> SUCCESS */ 01205 /* Point to beginning of buffer again */ 01206 ptr = saved_ptr; 01207 } else { 01208 /* Function sets length to router table length - adjust for ID sequence and ID mask length */ 01209 *len_ptr += MLE_ROUTE_MIN_OPTION_LEN; 01210 /* Advance buffer pointer past value field */ 01211 ptr += *len_ptr; 01212 } 01213 01214 return ptr; 01215 } 01216 01217 uint8_t *thread_connectivity_tlv_write(uint8_t *ptr, protocol_interface_info_entry_t *cur, uint8_t mode) 01218 { 01219 thread_info_t *thread = thread_info(cur); 01220 //Set Connectivity 01221 *ptr++ = MLE_TYPE_CONNECTIVITY; 01222 *ptr++ = 10; 01223 01224 // determine parent priority 01225 if ((mode & MLE_DEV_MASK) == MLE_RFD_DEV && (3*mle_class_rfd_entry_count_get(cur) > 2*THREAD_MAX_MTD_CHILDREN)) { 01226 *ptr++ = CONNECTIVITY_PP_LOW; 01227 } else if (!(mode & MLE_RX_ON_IDLE) && (3*mle_class_sleepy_entry_count_get(cur) > 2*THREAD_MAX_SED_CHILDREN)) { 01228 *ptr++ = CONNECTIVITY_PP_LOW; 01229 } else if (3*thread_router_bootstrap_child_count_get(cur) > 2*thread->maxChildCount) { 01230 // 1/3 of the child capacity remaining, PP=low 01231 *ptr++ = CONNECTIVITY_PP_LOW; 01232 } else if (mle_class_free_entry_count_get(cur) < THREAD_FREE_MLE_ENTRY_THRESHOLD) { 01233 // If only few entries available in the MLE table, change priority to low 01234 *ptr++ = CONNECTIVITY_PP_LOW; 01235 } else { 01236 *ptr++ = CONNECTIVITY_PP_MEDIUM; 01237 } 01238 01239 ptr = thread_linkquality_write(cur->id, ptr); 01240 01241 // Route Cost To leader 01242 if (thread->thread_attached_state == THREAD_STATE_CONNECTED_ROUTER){ 01243 // Leader cost 01244 *ptr++ = thread_routing_cost_get_by_router_id(&thread->routing, thread->thread_leader_data->leaderRouterId); 01245 //Router ID sequence 01246 *ptr++ = thread->routing.router_id_sequence; 01247 } else { 01248 // Leader cost when attached as child (REED,FED,SED,MED) 01249 *ptr++ = thread->thread_endnode_parent->pathCostToLeader; 01250 //Router ID sequence 01251 if (thread->routing.router_id_sequence_valid) { 01252 *ptr++ = thread->routing.router_id_sequence; 01253 } else {// We dont know the correct value 01254 *ptr++ = 0; 01255 } 01256 } 01257 01258 // active Routers 01259 uint8_t activeRouters = 0; 01260 if (cur->thread_info->leader_private_data) { 01261 activeRouters = thread_routing_count_active_routers_from_mask(cur->thread_info->leader_private_data->master_router_id_mask); 01262 } else if (thread->thread_device_mode == THREAD_DEVICE_MODE_ROUTER ) { 01263 activeRouters = thread_routing_count_active_routers(&thread->routing); 01264 } 01265 *ptr++ = activeRouters; 01266 01267 //Set SED Buffer size and datagram count 01268 ptr = common_write_16_bit(THREAD_SED_BUFFER_SIZE, ptr); 01269 *ptr++ = THREAD_SED_DATAGRAM_COUNT; 01270 01271 return ptr; 01272 } 01273 01274 uint16_t thread_network_data_tlv_length(protocol_interface_info_entry_t *cur, bool fullist) 01275 { 01276 if (fullist) { 01277 return cur->thread_info->networkDataStorage.network_data_len; 01278 } 01279 01280 return thread_network_data_generate_stable_set(cur, NULL); 01281 } 01282 01283 uint16_t thread_network_data_generate_stable_set(protocol_interface_info_entry_t *cur, uint8_t *result_ptr) 01284 { 01285 uint8_t *dptr; 01286 uint16_t network_data_len = 0; 01287 uint8_t length; 01288 uint8_t type; 01289 01290 dptr = cur->thread_info->networkDataStorage.network_data; 01291 uint16_t network_data_length = cur->thread_info->networkDataStorage.network_data_len; 01292 01293 tr_debug("Generating stable set from network data of size %d", 01294 cur->thread_info->networkDataStorage.network_data_len); 01295 01296 while (network_data_length) { 01297 if (network_data_length >= 2) { 01298 type = *dptr++; 01299 length = *dptr++; 01300 01301 if (length == 0) { 01302 // 0 is not valid length for TLV 01303 return 0; 01304 } 01305 01306 if (!(type & THREAD_NWK_STABLE_DATA)) { 01307 // Skip this TLV altogether... 01308 network_data_length -= 2 + length; 01309 dptr += length; 01310 continue; 01311 } 01312 01313 type &= THREAD_NWK_DATA_TYPE_MASK; 01314 network_data_length -= 2; 01315 01316 if (network_data_length < length) { 01317 tr_error("Length error"); 01318 return 0; 01319 } 01320 01321 // Set length ready for next check 01322 network_data_length -= length; 01323 01324 if (type == THREAD_NWK_DATA_TYPE_PREFIX) { 01325 uint8_t *length_ptr = NULL; 01326 length -= 2; 01327 01328 uint8_t prefix_bytes_len = prefixBits_to_bytes(*(dptr+1)); 01329 01330 if (prefix_bytes_len > length) { 01331 return 0; 01332 } 01333 01334 length -= prefix_bytes_len; 01335 01336 if (result_ptr) { 01337 *result_ptr++ = type | THREAD_NWK_STABLE_DATA; 01338 length_ptr = result_ptr; 01339 result_ptr++; 01340 memcpy(result_ptr, dptr, 2 + prefix_bytes_len); 01341 result_ptr += 2 + prefix_bytes_len; 01342 } 01343 dptr += 2 + prefix_bytes_len; 01344 01345 network_data_len += 2 + 2 + prefix_bytes_len; 01346 uint16_t total_tlv_length = 2 + prefix_bytes_len; 01347 01348 uint8_t context_id = thread_border_router_prefix_context_id(dptr, length); 01349 tr_debug("Resolved Context ID: %d", context_id); 01350 01351 while (length > 2) { 01352 type = *dptr++; 01353 uint8_t subLength = *dptr++; 01354 thread_border_router_tlv_entry_t genericService; 01355 01356 if (!(type & THREAD_NWK_STABLE_DATA)) { 01357 // Skip this sub-TLV altogether... 01358 dptr += subLength; 01359 length -= 2 + subLength; 01360 continue; 01361 } 01362 01363 type &= THREAD_NWK_DATA_TYPE_MASK; 01364 length -= 2; 01365 01366 tr_debug("SubType: %02x, %s", type, trace_array(dptr, subLength)); 01367 total_tlv_length += 2 + subLength; 01368 network_data_len += 2 + subLength; 01369 tr_debug("Total TLV length: %d", total_tlv_length); 01370 if (subLength <= length) { 01371 length -= subLength; 01372 if (type == THREAD_NWK_DATA_TYPE_BORDER_ROUTER) { 01373 if (result_ptr) { 01374 *result_ptr++ = type | THREAD_NWK_STABLE_DATA; 01375 *result_ptr++ = subLength; 01376 } 01377 while (subLength) { 01378 dptr += 2; 01379 uint16_t flags = common_read_16_bit(dptr); 01380 dptr += 2; 01381 subLength -= THREAD_BORDER_ROUTER_TLV_LENGTH; 01382 genericService.P_dhcp = ((flags >> THREAD_P_DHCP_BIT_MOVE) & 1); 01383 if (result_ptr) { 01384 if (genericService.P_dhcp) { 01385 result_ptr = common_write_16_bit(0xfc00 | context_id, result_ptr); 01386 } else { 01387 result_ptr = common_write_16_bit(0xfffe, result_ptr); 01388 } 01389 result_ptr = common_write_16_bit(flags, result_ptr); 01390 } 01391 } 01392 } else if (type == THREAD_NWK_DATA_TYPE_ROUTE) { 01393 if (result_ptr) { 01394 *result_ptr++ = type | THREAD_NWK_STABLE_DATA; 01395 *result_ptr++ = subLength; 01396 } 01397 while (subLength) { 01398 dptr += 2; 01399 uint8_t preference = *dptr++; 01400 subLength -= THREAD_HAS_ROUTE_TLV_LENGTH; 01401 if (result_ptr) { 01402 result_ptr = common_write_16_bit(0xfffe, result_ptr); 01403 *result_ptr++ = preference; 01404 } 01405 } 01406 } else { 01407 if (result_ptr) { 01408 *result_ptr++ = type | THREAD_NWK_STABLE_DATA; 01409 *result_ptr++ = subLength; 01410 memcpy(result_ptr, dptr, subLength); 01411 result_ptr += subLength; 01412 } 01413 01414 dptr += subLength; 01415 } 01416 01417 } else { 01418 tr_error("Length fail"); 01419 return 0; 01420 } 01421 } 01422 01423 if (result_ptr) { 01424 *length_ptr = total_tlv_length; 01425 } 01426 01427 } else if (type == THREAD_NWK_DATA_TYPE_SERVICE_DATA) { 01428 uint8_t * length_ptr = NULL; 01429 uint16_t total_tlv_length = 0; 01430 uint16_t copy_length = 1; 01431 uint8_t T = (*dptr) >> 7; 01432 uint8_t S_id = *dptr & 0x0f; 01433 01434 if (!T) { 01435 network_data_len += 4; 01436 total_tlv_length += 4; 01437 copy_length += 4; 01438 length -= 4; 01439 } 01440 01441 uint16_t service_data_length = *(dptr+copy_length); 01442 01443 if (result_ptr) { 01444 *result_ptr++ = type | THREAD_NWK_STABLE_DATA; 01445 length_ptr = result_ptr; 01446 result_ptr++; 01447 memcpy(result_ptr, dptr, 1 + copy_length + service_data_length); 01448 result_ptr += 1 + copy_length + service_data_length; 01449 } 01450 network_data_len += 2 + 2 + service_data_length; 01451 total_tlv_length += 2 + service_data_length; 01452 dptr += 1 + copy_length + service_data_length; 01453 length -= 2 + service_data_length; 01454 01455 while (length > 2) { 01456 type = *dptr++; 01457 uint8_t subLength = *dptr++; 01458 01459 if (!(type & THREAD_NWK_STABLE_DATA)) { 01460 // Skip this sub-TLV altogether... 01461 length -= 2 + subLength; 01462 dptr += subLength; 01463 continue; 01464 } 01465 01466 length -= 2; 01467 type &= THREAD_NWK_DATA_TYPE_MASK; 01468 01469 if (subLength <= length) { 01470 tr_debug("SubType: %02x, length: %d, data: %s", type, length, trace_array(dptr, subLength)); 01471 total_tlv_length += 2 + subLength; 01472 network_data_len += 2 + subLength; 01473 length -= subLength; 01474 if (result_ptr) { 01475 *result_ptr++ = type | THREAD_NWK_STABLE_DATA; 01476 *result_ptr++ = subLength; 01477 uint8_t *rloc_ptr = result_ptr; 01478 // Copy the remaining 01479 memcpy(result_ptr, dptr, subLength); 01480 result_ptr += subLength; 01481 // Copy RLOC but replace with ALOC 01482 common_write_16_bit(0xfc10 | S_id, rloc_ptr); 01483 } 01484 dptr += subLength; 01485 } else { 01486 tr_debug("Server sub-TLV parse fail!"); 01487 return 0; 01488 } 01489 } 01490 01491 if (result_ptr) { 01492 *length_ptr = total_tlv_length; 01493 } 01494 } else { 01495 tr_debug("Unknown TLV: %d, length: %d", type, length); 01496 network_data_len += 2 + length; 01497 if (result_ptr) { 01498 *result_ptr++ = type | THREAD_NWK_STABLE_DATA; 01499 *result_ptr++ = length; 01500 memcpy(result_ptr, dptr, length); 01501 result_ptr += length; 01502 } 01503 dptr += length; 01504 } 01505 } else { 01506 tr_error("Length failure"); 01507 return 0; 01508 } 01509 } 01510 01511 return network_data_len; 01512 } 01513 01514 uint16_t thread_network_data_tlv_size(protocol_interface_info_entry_t *cur, bool fullist) 01515 { 01516 uint16_t length = thread_network_data_tlv_length(cur, fullist); 01517 01518 if (length > 254) { 01519 // 2 extra bytes for extended TLV format 01520 length += 2; 01521 } 01522 01523 return length; 01524 } 01525 01526 uint8_t *thread_network_data_tlv_write(protocol_interface_info_entry_t *cur, uint8_t *ptr, bool fulllist) 01527 { 01528 uint16_t length = thread_network_data_tlv_length(cur, fulllist); 01529 *ptr++ = MLE_TYPE_NETWORK_DATA; 01530 01531 if (length > 254) { 01532 *ptr++ = 0xff; 01533 ptr = common_write_16_bit(length, ptr); 01534 } else { 01535 *ptr++ = length; 01536 } 01537 01538 if (fulllist) { 01539 if (cur->thread_info->networkDataStorage.network_data_len > 0) { 01540 memcpy(ptr, cur->thread_info->networkDataStorage.network_data, 01541 cur->thread_info->networkDataStorage.network_data_len); 01542 ptr += cur->thread_info->networkDataStorage.network_data_len; 01543 } 01544 return ptr; 01545 } 01546 01547 uint16_t size = thread_network_data_generate_stable_set(cur, ptr); 01548 return ptr + size; 01549 } 01550 01551 uint8_t *thread_active_timestamp_write(protocol_interface_info_entry_t *cur, uint8_t *ptr) 01552 { 01553 link_configuration_s *configuration; 01554 01555 configuration = thread_joiner_application_get_config(cur->id); 01556 if (!configuration) { 01557 tr_error("No configuration"); 01558 return ptr; 01559 } 01560 *ptr++ = MLE_TYPE_ACTIVE_TIMESTAMP; 01561 *ptr++ = 8; 01562 ptr = common_write_64_bit(configuration->timestamp, ptr); 01563 return ptr; 01564 } 01565 01566 uint16_t thread_active_operational_dataset_size(protocol_interface_info_entry_t *cur) 01567 { 01568 return 2 + thread_joiner_application_active_config_length(cur->id, NULL, 0, mle_active_configuration_dataset_ignore_tlvs, mle_active_configuration_dataset_ignore_tlvs_size()); 01569 } 01570 01571 uint8_t *thread_active_operational_dataset_write(protocol_interface_info_entry_t *cur, uint8_t *ptr) 01572 { 01573 int length; 01574 length = thread_joiner_application_active_config_length(cur->id, NULL, 0, mle_active_configuration_dataset_ignore_tlvs, mle_active_configuration_dataset_ignore_tlvs_size()); 01575 if (length < 1) { 01576 return ptr; 01577 } 01578 *ptr++ = MLE_TYPE_OPERATIONAL_DATASET; 01579 *ptr++ = length; 01580 ptr = thread_joiner_application_active_config_write(cur->id, ptr, NULL, 0, mle_active_configuration_dataset_ignore_tlvs, mle_active_configuration_dataset_ignore_tlvs_size()); 01581 01582 return ptr; 01583 } 01584 bool thread_active_operational_dataset_process(protocol_interface_info_entry_t *cur, uint8_t *ptr, uint16_t len, uint64_t dataset_timestamp) 01585 { 01586 //make a copy of the incoming timestamp 01587 uint64_t timestamp; 01588 link_configuration_s *link_configuration; 01589 01590 if(!cur || !cur->thread_info || !ptr || !len){ 01591 return false; 01592 } 01593 link_configuration = thread_joiner_application_get_config(cur->id); 01594 if (!link_configuration) { 01595 return false; 01596 } 01597 tr_debug("process Active dataset"); 01598 timestamp = thread_joiner_application_active_timestamp_get(cur->id); 01599 01600 if (timestamp > dataset_timestamp) { 01601 tr_debug("We have newer timestamp"); 01602 thread_joiner_application_next_active_config_save(cur->id); 01603 } 01604 if (timestamp == dataset_timestamp) { 01605 // No changes required 01606 return false; 01607 } 01608 tr_debug("Update Active dataset"); 01609 // New active operational dataset received; 01610 thread_joiner_application_update_configuration(cur->id, ptr, len, false); 01611 thread_joiner_application_active_timestamp_set(cur->id,dataset_timestamp); 01612 thread_configuration_thread_activate(cur,link_configuration); 01613 thread_joiner_application_configuration_nvm_save(cur->id); 01614 return true; 01615 } 01616 01617 uint8_t thread_pending_timestamp_tlv_size(protocol_interface_info_entry_t *cur) 01618 { 01619 if (!thread_joiner_application_pending_config_timestamp_get(cur->id) ) { 01620 return 0; 01621 } 01622 return 2 + 8; 01623 } 01624 01625 uint8_t *thread_pending_timestamp_write(protocol_interface_info_entry_t *cur, uint8_t *ptr) 01626 { 01627 uint64_t pending_timestamp; 01628 01629 pending_timestamp = thread_joiner_application_pending_config_timestamp_get(cur->id); 01630 if (!pending_timestamp ) { 01631 return ptr; 01632 } 01633 *ptr++ = MLE_TYPE_PENDING_TIMESTAMP; 01634 *ptr++ = 8; 01635 ptr = common_write_64_bit(pending_timestamp, ptr); 01636 return ptr; 01637 } 01638 01639 uint16_t thread_pending_operational_dataset_size(protocol_interface_info_entry_t *cur) 01640 { 01641 01642 if (!thread_joiner_application_pending_config_exists(cur->id)) { 01643 return 0; 01644 } 01645 // Pending set always includes delay timer but not pending timestamp 01646 return thread_joiner_application_pending_config_length(cur->id, NULL, 0, mle_pending_configuration_dataset_ignore_tlvs, mle_pending_configuration_dataset_ignore_tlvs_size()); 01647 } 01648 01649 uint8_t *thread_pending_operational_dataset_write(protocol_interface_info_entry_t *cur, uint8_t *ptr) 01650 { 01651 int dataset_length; 01652 if (!thread_joiner_application_pending_config_exists(cur->id)) { 01653 return ptr; 01654 } 01655 01656 dataset_length = thread_joiner_application_pending_config_length(cur->id, NULL, 0, mle_pending_configuration_dataset_ignore_tlvs, mle_pending_configuration_dataset_ignore_tlvs_size()); 01657 if (dataset_length < 1) { 01658 return ptr; 01659 } 01660 *ptr++ = MLE_TYPE_PENDING_OPERATIONAL_DATASET; 01661 *ptr++ = dataset_length; 01662 ptr = thread_joiner_application_pending_config_build(cur->id, ptr, NULL, 0, mle_pending_configuration_dataset_ignore_tlvs, mle_pending_configuration_dataset_ignore_tlvs_size()); 01663 return ptr; 01664 } 01665 01666 bool thread_pending_operational_dataset_process(protocol_interface_info_entry_t *cur, uint64_t mle_pending_timestamp, uint8_t *ptr, uint16_t len) 01667 { 01668 uint32_t delay_timer; 01669 01670 if(!cur || !cur->thread_info ){ 01671 return false; 01672 } 01673 tr_debug("process pending dataset"); 01674 if( !ptr || !len){ 01675 // No pending set received 01676 return false; 01677 } 01678 01679 if (4 > thread_meshcop_tlv_data_get_uint32(ptr, len,MESHCOP_TLV_DELAY_TIMER, &delay_timer)){ 01680 tr_warn("Delay timer not present"); 01681 return false; 01682 } 01683 01684 if (mle_pending_timestamp < thread_joiner_application_pending_config_timestamp_get(cur->id) ) { 01685 // Saving this config for later use first we get the current active 01686 tr_debug("save pending set for future"); 01687 thread_joiner_application_next_pending_config_save(cur->id); 01688 } 01689 01690 if( 0 != thread_joiner_application_pending_config_create(cur->id, ptr, len)){ 01691 tr_error("pending set creation failed"); 01692 return false; 01693 } 01694 tr_debug("updating pending dataset"); 01695 thread_joiner_application_pending_config_timestamp_set(cur->id,mle_pending_timestamp); 01696 thread_joiner_application_pending_config_enable(cur->id,delay_timer); 01697 return true; 01698 } 01699 01700 uint8_t thread_leader_data_tlv_size(protocol_interface_info_entry_t *cur) 01701 { 01702 if (!cur || !cur->thread_info || !cur->thread_info->thread_leader_data) { 01703 return 0; 01704 } 01705 return 9; 01706 } 01707 01708 uint8_t *thread_leader_data_tlv_write(uint8_t *ptr, protocol_interface_info_entry_t *cur) 01709 { 01710 if (!cur || !cur->thread_info || !cur->thread_info->thread_leader_data) { 01711 return ptr; 01712 } 01713 *ptr++ = MLE_TYPE_LEADER_DATA; /* MLE TLV Type */ 01714 *ptr++ = 8; /* MLE TLV Value: NWD:LDR TLV Length (7) */ 01715 ptr = common_write_32_bit(cur->thread_info->thread_leader_data->partitionId, ptr); 01716 *ptr++ = cur->thread_info->thread_leader_data->weighting; 01717 *ptr++ = cur->thread_info->thread_leader_data->dataVersion; 01718 *ptr++ = cur->thread_info->thread_leader_data->stableDataVersion; 01719 *ptr++ = cur->thread_info->thread_leader_data->leaderRouterId; 01720 return ptr; 01721 } 01722 01723 uint8_t *thread_address_registration_tlv_write(uint8_t *ptr, protocol_interface_info_entry_t *cur) 01724 { 01725 uint8_t thread_realm_local_mcast_addr[16]; 01726 lowpan_context_t *ctx; 01727 uint8_t *address_len_ptr; 01728 01729 if (thread_info(cur)->thread_device_mode != THREAD_DEVICE_MODE_SLEEPY_END_DEVICE && 01730 thread_info(cur)->thread_device_mode != THREAD_DEVICE_MODE_END_DEVICE) { 01731 // No address registration for others than MED or SED 01732 return ptr; 01733 } 01734 *ptr++ = MLE_TYPE_ADDRESS_REGISTRATION; 01735 address_len_ptr = ptr++; 01736 01737 *address_len_ptr = 0; 01738 01739 // Register all global addressess 01740 ns_list_foreach(if_address_entry_t, e, &cur->ip_addresses) { 01741 01742 if (*address_len_ptr > 148 ) { 01743 // Maximum length of address registrations 01744 continue; 01745 } 01746 if (addr_ipv6_scope(e->address, cur) == IPV6_SCOPE_GLOBAL || (addr_ipv6_scope(e->address, cur) == IPV6_SCOPE_REALM_LOCAL 01747 && !thread_addr_is_mesh_local_16(e->address, cur))) { 01748 ctx = lowpan_context_get_by_address(&cur->lowpan_contexts, e->address); 01749 if (ctx) { 01750 //Write TLV to list 01751 *ptr++ = (ctx->cid | 0x80); 01752 memcpy(ptr, e->address + 8, 8); 01753 ptr += 8; 01754 *address_len_ptr += 9; 01755 } else { 01756 *ptr++ = 0; 01757 memcpy(ptr, e->address, 16); 01758 ptr += 16; 01759 *address_len_ptr += 17; 01760 } 01761 } 01762 } 01763 01764 /* Registers multicast addresses to the parent */ 01765 thread_bootstrap_all_nodes_address_generate(thread_realm_local_mcast_addr, cur->thread_info->threadPrivatePrefixInfo.ulaPrefix, 3); 01766 01767 ns_list_foreach(if_group_entry_t, entry, &cur->ip_groups) 01768 { 01769 if (*address_len_ptr > 148) { 01770 // Maximum length of address registrations 01771 continue; 01772 } 01773 if (addr_ipv6_multicast_scope(entry->group) < IPV6_SCOPE_REALM_LOCAL) { 01774 /* Skip Link Local multicast address */ 01775 continue; 01776 } 01777 01778 if (addr_ipv6_equal(entry->group, thread_realm_local_mcast_addr)) { 01779 /* Skip well-known realm-local all Thread nodes multicast address */ 01780 continue; 01781 } 01782 if (addr_ipv6_equal(entry->group, ADDR_ALL_MPL_FORWARDERS)) { 01783 /* Skip All MPL Forwarders address */ 01784 continue; 01785 } 01786 if (addr_ipv6_equal(entry->group, ADDR_REALM_LOCAL_ALL_NODES)) { 01787 /* Skip Mesh local all nodes */ 01788 continue; 01789 } 01790 if (addr_ipv6_equal(entry->group, ADDR_REALM_LOCAL_ALL_ROUTERS)) { 01791 /* Skip Mesh local all routers */ 01792 continue; 01793 } 01794 01795 *ptr++ = 0; 01796 memcpy(ptr, entry->group, 16); 01797 ptr += 16; 01798 *address_len_ptr += 17; 01799 } 01800 if (*address_len_ptr == 0) { 01801 // No address added remove type and length 01802 ptr -= 2; 01803 } 01804 return ptr; 01805 01806 } 01807 01808 int thread_link_reject_send(protocol_interface_info_entry_t *interface, const uint8_t *ll64) 01809 { 01810 uint16_t buf_id; 01811 uint32_t keySequence; 01812 uint8_t *ptr; 01813 mle_message_timeout_params_t timeout; 01814 01815 buf_id = mle_service_msg_allocate(interface->id, 32, false, MLE_COMMAND_REJECT); 01816 if (buf_id == 0) { 01817 return -1; 01818 } 01819 01820 thread_management_get_current_keysequence(interface->id, &keySequence); 01821 mle_service_msg_update_security_params(buf_id, 5, 2, keySequence); 01822 01823 mle_service_set_msg_destination_address(buf_id, ll64); 01824 01825 ptr = mle_service_get_data_pointer(buf_id); 01826 01827 // write status TLV 01828 *ptr++ = MLE_TYPE_STATUS; 01829 *ptr++ = 1; 01830 *ptr++ = MLE_STATUS_ERROR; 01831 01832 if (mle_service_update_length_by_ptr(buf_id,ptr)!= 0) { 01833 tr_debug("Buffer overflow at message write"); 01834 } 01835 01836 timeout.retrans_max = 0; 01837 timeout.timeout_init = 0; 01838 timeout.timeout_max = 0; 01839 timeout.delay = MLE_NO_DELAY; 01840 01841 mle_service_set_msg_timeout_parameters(buf_id, &timeout); 01842 01843 return mle_service_send_message(buf_id); 01844 01845 } 01846 01847 static uint8_t * thread_joining_port_tlv_write(uint16_t port, uint8_t *ptr) 01848 { 01849 *ptr++ = MESHCOP_TLV_JOINER_UDP_PORT; 01850 *ptr++ = 2; 01851 return common_write_16_bit(port, ptr); 01852 } 01853 01854 static uint8_t * thread_commissioner_port_tlv_write(uint16_t port, uint8_t *ptr) 01855 { 01856 *ptr++ = MESHCOP_TLV_COMMISSIONER_UDP_PORT; 01857 *ptr++ = 2; 01858 return common_write_16_bit(port, ptr); 01859 } 01860 01861 static void thread_tx_failure_handler(int8_t nwk_id, uint8_t accumulated_failures, uint8_t attribute_index) 01862 { 01863 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(nwk_id); 01864 01865 tr_debug("In Thread TX_FAIL handler, accumulated_failures=%d", accumulated_failures); 01866 01867 if (!cur || !cur->thread_info) { 01868 return; 01869 } 01870 01871 mac_neighbor_table_entry_t *neighbor = mac_neighbor_table_attribute_discover(mac_neighbor_info(cur), attribute_index); 01872 if (!neighbor) { 01873 return; 01874 } 01875 01876 if (accumulated_failures >= THREAD_MAC_TRANSMISSIONS*THREAD_FAILED_CHILD_TRANSMISSIONS) { 01877 mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), neighbor); 01878 } 01879 } 01880 01881 /* Called when MLE link to neighbour lost, or ETX callback says link is bad */ 01882 void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, mac_neighbor_table_entry_t *neighbour) 01883 { 01884 thread_parent_info_t *thread_endnode_parent = thread_info(cur)->thread_endnode_parent; 01885 01886 if (!thread_i_am_router(cur) && thread_endnode_parent && thread_endnode_parent->shortAddress == neighbour->mac16 ) { 01887 if(cur->nwk_bootstrap_state != ER_CHILD_ID_REQ) { 01888 tr_warn("End device lost parent, reset!\n"); 01889 thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL); 01890 } 01891 } 01892 01893 thread_routing_remove_link(cur, neighbour->mac16 ); 01894 thread_router_bootstrap_reset_child_info(cur, neighbour); 01895 protocol_6lowpan_release_long_link_address_from_neighcache(cur, neighbour->mac64 ); 01896 mac_helper_devicetable_remove(cur->mac_api, neighbour->index ); 01897 thread_neighbor_class_entry_remove(&cur->thread_info->neighbor_class, neighbour->index ); 01898 } 01899 01900 uint8_t thread_get_router_count_from_route_tlv(mle_tlv_info_t *routeTlv) 01901 { 01902 if (!routeTlv) 01903 return 0; 01904 01905 if (routeTlv->tlvLen < (MLE_ROUTE_ID_MASK_SIZE + 1)) 01906 return 0; 01907 01908 if (!routeTlv->dataPtr) 01909 return 0; 01910 01911 return routeTlv->tlvLen - MLE_ROUTE_ID_MASK_SIZE - 1; 01912 } 01913 01914 static void thread_address_notification_cb(struct protocol_interface_info_entry *interface, const struct if_address_entry *addr, if_address_callback_t reason) 01915 { 01916 if (thread_attach_ready(interface) != 0) { 01917 return; 01918 } 01919 01920 if (reason != ADDR_CALLBACK_DAD_COMPLETE && reason != ADDR_CALLBACK_DELETED) { 01921 return; 01922 } 01923 01924 if (addr_ipv6_scope(addr->address, interface) > IPV6_SCOPE_REALM_LOCAL) { 01925 tr_debug("Global address changed: %s", trace_ipv6(addr->address)); 01926 01927 if (thread_bootstrap_should_register_address(interface)) { 01928 interface->thread_info->childUpdateReqTimer = 1; 01929 } else { 01930 if (reason == ADDR_CALLBACK_DAD_COMPLETE) { 01931 /* Send address notification (our parent doesn't do that for us) */ 01932 thread_extension_address_registration(interface, addr->address, NULL, false, false); 01933 } 01934 } 01935 } 01936 } 01937 01938 void thread_mcast_group_change(struct protocol_interface_info_entry *interface, if_group_entry_t *group, bool addr_added) 01939 { 01940 01941 if (thread_attach_ready(interface) != 0) { 01942 return; 01943 } 01944 01945 tr_debug("Thread multicast address changed: %s", trace_ipv6(group->group)); 01946 01947 if (thread_bootstrap_should_register_address(interface)) { 01948 /* Trigger Child Update Request only if MTD child's multicast address change */ 01949 if (addr_ipv6_multicast_scope(group->group) > IPV6_SCOPE_LINK_LOCAL) { 01950 interface->thread_info->childUpdateReqTimer = 1; 01951 } 01952 } else { 01953 if (addr_added) { 01954 thread_address_registration_timer_set(interface, 0, 1); 01955 } 01956 } 01957 } 01958 01959 void thread_partition_data_purge(protocol_interface_info_entry_t *cur) 01960 { 01961 /* Partition has been changed. Wipe out data related to old partition */ 01962 thread_management_client_pending_coap_request_kill(cur->id); 01963 01964 /* Reset previous routing information */ 01965 thread_routing_reset(&cur->thread_info->routing); 01966 01967 /* Flush address cache */ 01968 ipv6_neighbour_cache_flush(&cur->ipv6_neighbour_cache); 01969 01970 } 01971 01972 bool thread_partition_match(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData) 01973 { 01974 if (thread_info(cur)->thread_leader_data) { 01975 if ((thread_info(cur)->thread_leader_data->partitionId == leaderData->partitionId) && 01976 (thread_info(cur)->thread_leader_data->weighting == leaderData->weighting)) { 01977 return true; 01978 } 01979 } 01980 return false; 01981 } 01982 01983 void thread_partition_info_update(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData) 01984 { 01985 /* Force network data update later when processing network data TLV */ 01986 thread_info(cur)->thread_leader_data->dataVersion = leaderData->dataVersion - 1; 01987 thread_info(cur)->thread_leader_data->stableDataVersion = leaderData->stableDataVersion - 1; 01988 thread_info(cur)->thread_leader_data->leaderRouterId = leaderData->leaderRouterId; 01989 thread_info(cur)->thread_leader_data->partitionId = leaderData->partitionId; 01990 thread_info(cur)->thread_leader_data->weighting = leaderData->weighting; 01991 /* New network data learned, get rid of old partition data */ 01992 thread_partition_data_purge(cur); 01993 } 01994 01995 void thread_neighbor_communication_update(protocol_interface_info_entry_t *cur, uint8_t neighbor_attribute_index) 01996 { 01997 thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, neighbor_attribute_index); 01998 } 01999 02000 #endif 02001
Generated on Tue Aug 9 2022 00:37:22 by
1.7.2