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