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