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_router_bootstrap.c
00001 /* 00002 * Copyright (c) 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 00030 /* 00031 * \file thread_router_bootstrap.c 00032 * \brief Add short description about this file!!! 00033 * 00034 */ 00035 #include "nsconfig.h" 00036 #include <string.h> 00037 #include <ns_types.h> 00038 #include <ns_list.h> 00039 #include <nsdynmemLIB.h> 00040 #include "eventOS_event.h" 00041 #include "eventOS_event_timer.h" 00042 #include "randLIB.h" 00043 #include "shalib.h" 00044 #include "common_functions.h" 00045 #include "NWK_INTERFACE/Include/protocol.h" 00046 #include "net_thread_test.h" 00047 #include "ns_trace.h" 00048 #include "6LoWPAN/Bootstraps/protocol_6lowpan.h" 00049 #include "6LoWPAN/Thread/thread_common.h" 00050 #include "6LoWPAN/Thread/thread_routing.h" 00051 #include "6LoWPAN/Thread/thread_nd.h" 00052 #include "6LoWPAN/Thread/thread_bootstrap.h" 00053 #include "6LoWPAN/Thread/thread_router_bootstrap.h" 00054 #include "6LoWPAN/Thread/thread_host_bootstrap.h" 00055 #include "6LoWPAN/Thread/thread_management_internal.h" 00056 #include "6LoWPAN/Thread/thread_network_synch.h" 00057 #include "6LoWPAN/Thread/thread_discovery.h" 00058 #include "6LoWPAN/Thread/thread_joiner_application.h" 00059 #include "6LoWPAN/Thread/thread_address_registration_client.h" 00060 #include "6LoWPAN/Thread/thread_management_client.h" 00061 #include "6LoWPAN/Thread/thread_management_server.h" 00062 #include "6LoWPAN/Thread/thread_extension.h" 00063 #include "6LoWPAN/Thread/thread_leader_service.h" 00064 #include "6LoWPAN/Thread/thread_beacon.h" 00065 #include "6LoWPAN/Thread/thread_network_data_lib.h" 00066 #include "6LoWPAN/Thread/thread_lowpower_private_api.h" 00067 #include "6LoWPAN/Thread/thread_tmfcop_lib.h" 00068 #include "6LoWPAN/Thread/thread_nvm_store.h" 00069 #include "thread_management_if.h" 00070 #include "Common_Protocols/ipv6.h" 00071 #include "Common_Protocols/icmpv6.h" 00072 #include "Common_Protocols/icmpv6_radv.h" 00073 #include "MLE/mle.h" 00074 #include "MLE/mle_tlv.h" 00075 #include "thread_config.h" 00076 #include "multicast_api.h" 00077 #include "Service_Libs/nd_proxy/nd_proxy.h" 00078 #include "Service_Libs/mle_service/mle_service_api.h" 00079 #include "Service_Libs/blacklist/blacklist.h" 00080 #include "thread_dhcpv6_client.h" 00081 #include "6LoWPAN/MAC/mac_helper.h" 00082 #include "mac_api.h" 00083 #include "6LoWPAN/MAC/mac_data_poll.h" 00084 #include "thread_border_router_api.h" 00085 #include "Core/include/address.h" 00086 00087 #ifdef HAVE_THREAD_ROUTER 00088 00089 #define TRACE_GROUP "trbs" 00090 00091 static bool thread_rfd_device(uint8_t mode); 00092 static uint8_t *thread_tlv_add(protocol_interface_info_entry_t *cur, uint8_t *ptr, uint8_t tlv_type, uint8_t mode); 00093 00094 static void mle_multicast_push_to_sleep_child(protocol_interface_info_entry_t *cur, buffer_t *buf); 00095 00096 static void thread_bootstrap_client_router_id_cb(int8_t interface_id, int8_t status, uint16_t router_rloc, const uint8_t router_mask_ptr[9]); 00097 static void thread_router_synch_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers); 00098 static void thread_bootstrap_client_router_id_release_cb(int8_t interface_id, int8_t status, uint16_t router_rloc, const uint8_t router_mask_ptr[9]); 00099 00100 static int thread_router_synch_accept_request_build(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, uint16_t shortAddress, uint8_t *challenge, uint8_t chalLen, uint8_t *tlvReq, uint8_t tlvReqLen); 00101 static int thread_router_accept_to_endevice(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, uint8_t *challenge, uint8_t chalLen); 00102 static int thread_router_accept_request_build(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, uint16_t shortAddress, uint8_t *challenge, uint8_t chalLen, uint8_t type, bool rssi_tlv, uint8_t rssi); 00103 static int thread_child_update_response(protocol_interface_info_entry_t *cur, uint8_t *dst_address, uint8_t mode, uint16_t short_address, uint32_t timeout, mle_tlv_info_t *addressRegisterTlv,mle_tlv_info_t *tlvReq, mle_tlv_info_t *challengeTlv); 00104 static int mle_build_and_send_data_response_msg(protocol_interface_info_entry_t *cur, uint8_t *dst_address, uint8_t *data_ptr, uint16_t data_len, mle_tlv_info_t *request_tlv, uint8_t mode); 00105 static int thread_attach_parent_response_build(protocol_interface_info_entry_t *cur, uint8_t *dstAddress, uint8_t *challenge, uint16_t chalLen, uint8_t linkMargin, uint8_t scanMask, uint8_t mode); 00106 static int mle_attach_child_id_response_build(protocol_interface_info_entry_t *cur, uint8_t *dstAddress,thread_pending_child_id_req_t *child_req,mle_neigh_table_entry_t *neigh_info); 00107 00108 static int8_t thread_router_bootstrap_synch_request_send(protocol_interface_info_entry_t *cur); 00109 static bool thread_child_id_request(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *entry_temp); 00110 00111 static bool thread_rfd_device(uint8_t mode) 00112 { 00113 if ((mode & MLE_DEV_MASK) != MLE_RFD_DEV) { 00114 return false; 00115 } 00116 return true; 00117 } 00118 00119 static bool thread_router_parent_address_check(protocol_interface_info_entry_t *cur, uint8_t *source_addr) 00120 { 00121 if (thread_info(cur)->thread_endnode_parent && 00122 addr_iid_matches_eui64(source_addr + 8, thread_info(cur)->thread_endnode_parent->mac64)) { 00123 return true; 00124 } 00125 00126 return false; 00127 } 00128 00129 static void thread_send_proactive_an(protocol_interface_info_entry_t *cur) 00130 { 00131 ns_list_foreach(if_address_entry_t, e, &cur->ip_addresses) { 00132 if (e->source == ADDR_SOURCE_DHCP || e->source == ADDR_SOURCE_SLAAC) { 00133 uint8_t br_ml_addr[16]; 00134 ns_list_foreach(thread_network_data_prefix_cache_entry_t, prefix, &cur->thread_info->networkDataStorage.localPrefixList) { 00135 uint8_t prefixBytesLen = prefixBits_to_bytes(prefix->servicesPrefixLen); 00136 00137 if (memcmp(e->address, prefix->servicesPrefix, prefixBytesLen) != 0) { 00138 continue; 00139 } 00140 00141 ns_list_foreach(thread_network_server_data_entry_t, br, &prefix->borderRouterList) { 00142 if (br->routerID == 0xfffe) { 00143 continue; 00144 } 00145 00146 uint16_t rloc16 = mac_helper_mac16_address_get(cur); 00147 00148 thread_addr_write_mesh_local_16(br_ml_addr, br->routerID, cur->thread_info); 00149 tr_debug("Sending proactive AN to border router: %s", trace_ipv6(br_ml_addr)); 00150 thread_management_client_proactive_an(cur->id, e->address , rloc16, cur->iid_slaac, br_ml_addr); 00151 } 00152 } 00153 } 00154 } 00155 } 00156 00157 int thread_router_bootstrap_mle_advertise(protocol_interface_info_entry_t *cur) 00158 { 00159 /* How was this 40 calculated? Seems to be more than enough, at least. 00160 * MODE = 2+1, SRC_ADDR = 2+2, LINK = 2+1+4*neighbours, ROUTE = 2+MLE_ROUTE_MIN_OPTION_LEN+routers 00161 * Total = 10 + neighbours * 4 00162 */ 00163 uint16_t neig_cache_size = 40 + 3; 00164 uint8_t *ptr; 00165 00166 if (!cur) { 00167 return -1; 00168 } 00169 00170 if (!thread_is_connected(cur)) { 00171 return -1; 00172 } 00173 00174 if (thread_i_am_router(cur)) { 00175 neig_cache_size += thread_route_option_size(cur); 00176 neig_cache_size += thread_leader_data_tlv_size(cur); 00177 } 00178 00179 uint16_t buf_id = mle_service_msg_allocate(cur->id, neig_cache_size, false, MLE_COMMAND_ADVERTISEMENT); 00180 if (buf_id == 0) { 00181 return -1; 00182 } 00183 00184 uint32_t keySequence; 00185 if (thread_management_get_current_keysequence(cur->id, &keySequence) == 0) { 00186 mle_service_msg_update_security_params(buf_id, 5, 2, keySequence); 00187 } 00188 00189 //SET Destination address 00190 mle_service_set_msg_destination_address(buf_id, ADDR_LINK_LOCAL_ALL_NODES); 00191 00192 ptr = mle_service_get_data_pointer(buf_id); 00193 ptr = mle_general_write_source_address(ptr, cur); 00194 if (thread_i_am_router(cur)) { 00195 ptr = thread_route_option_write(cur, ptr); 00196 } else { 00197 *ptr++ = MLE_TYPE_ROUTE; 00198 *ptr++ = 0; 00199 } 00200 00201 ptr = thread_leader_data_tlv_write(ptr, cur); 00202 00203 if (mle_service_update_length_by_ptr(buf_id,ptr)!= 0) { 00204 tr_debug("Buffer overflow at message write"); 00205 } 00206 00207 tr_debug("Send MLE Secured Advertisement"); 00208 return mle_service_send_message(buf_id); 00209 00210 } 00211 00212 static void clone_multicast_to_unicast(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *mle_entry, buffer_t *buf) 00213 { 00214 link_configuration_s *linkConfiguration = thread_joiner_application_get_config(cur->id); 00215 if (!linkConfiguration) { 00216 return; 00217 } 00218 00219 buffer_t *new_buf = buffer_clone(buf); 00220 if ((new_buf->info & B_DIR_MASK) == B_DIR_UP) { 00221 buffer_data_pointer(new_buf)[IPV6_HDROFF_HOP_LIMIT] = --new_buf->options .hop_limit ; 00222 } 00223 00224 new_buf->info = (buffer_info_t) (B_DIR_DOWN | B_TO_IPV6_TXRX | B_FROM_IPV6_FWD); 00225 uint8_t next_hop[16]; 00226 memcpy(next_hop, ADDR_LINK_LOCAL_PREFIX, 8); 00227 memcpy(&next_hop[8], mle_entry->mac64, 8); 00228 next_hop[8] ^= 2; 00229 00230 ipv6_buffer_route_to(new_buf, next_hop, cur); 00231 protocol_push(new_buf); 00232 tr_debug("Cloned %s to %s", tr_ipv6(buf->dst_sa .address ), tr_ipv6(next_hop)); 00233 } 00234 00235 static void mle_multicast_push_to_sleep_child(protocol_interface_info_entry_t *cur, buffer_t *buf) 00236 { 00237 mle_neigh_table_list_t *mle_neigh_list = mle_class_active_list_get(cur->id); 00238 if (!mle_neigh_list) { 00239 return; 00240 } 00241 ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_neigh_list) { 00242 if (cur_entry->threadNeighbor) { 00243 if (!(cur_entry->mode & MLE_RX_ON_IDLE)) { 00244 clone_multicast_to_unicast(cur, cur_entry, buf); 00245 } 00246 } 00247 } 00248 } 00249 00250 static void thread_multicast_forward_to_child(protocol_interface_info_entry_t *cur, buffer_t *buffer) 00251 { 00252 mle_multicast_push_to_sleep_child(cur, buffer); 00253 } 00254 00255 static void thread_registered_mcast_forward_to_child(protocol_interface_info_entry_t *cur, buffer_t *buffer) 00256 { 00257 thread_registered_mcast_addr_t *addr = thread_registered_mcast_addr_entry_find(cur, buffer->dst_sa .address ); 00258 00259 if (addr) { 00260 tr_debug("Forwarding to registered multicast address: %s", trace_ipv6(addr->address)); 00261 00262 ns_list_foreach(thread_mcast_child_t, child, &addr->children) { 00263 mle_neigh_table_entry_t *mle_entry = mle_class_get_by_link_address(cur->id, child->mac64, ADDR_802_15_4_LONG ); 00264 if (mle_entry && mle_entry->threadNeighbor && !(mle_entry->mode & MLE_RX_ON_IDLE)) { 00265 clone_multicast_to_unicast(cur, mle_entry, buffer); 00266 } 00267 } 00268 } 00269 } 00270 00271 void thread_router_bootstrap_multicast_forwarder_enable(protocol_interface_info_entry_t *cur, buffer_t *buf) 00272 { 00273 //tr_debug("Considering forward %s (%s)", tr_ipv6(buf->dst_sa.address), (buf->info & B_DIR_MASK) == B_DIR_UP ? "up" : "down"); 00274 if (addr_ipv6_multicast_scope(buf->dst_sa .address ) <= IPV6_SCOPE_INTERFACE_LOCAL) { 00275 return; 00276 } 00277 00278 // Safe guard: do NOT forward received link-local 00279 // multicast packets to our sleepy children 00280 if ((buf->info & B_DIR_MASK) == B_DIR_UP && 00281 addr_ipv6_multicast_scope(buf->dst_sa .address ) <= IPV6_SCOPE_LINK_LOCAL) { 00282 tr_debug("Received link-local multicast; return..."); 00283 return; 00284 } 00285 00286 uint8_t addr[16]; 00287 thread_bootstrap_all_nodes_address_generate(addr, cur->thread_info->threadPrivatePrefixInfo.ulaPrefix, IPV6_SCOPE_LINK_LOCAL); 00288 if (addr_ipv6_equal(buf->dst_sa .address , addr)) { 00289 thread_multicast_forward_to_child(cur, buf); 00290 return; 00291 } 00292 thread_bootstrap_all_nodes_address_generate(addr, cur->thread_info->threadPrivatePrefixInfo.ulaPrefix, IPV6_SCOPE_REALM_LOCAL); 00293 if (addr_ipv6_equal(buf->dst_sa .address , addr)) { 00294 thread_multicast_forward_to_child(cur, buf); 00295 return; 00296 } 00297 thread_registered_mcast_forward_to_child(cur, buf); 00298 } 00299 00300 static void thread_router_synch_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers) 00301 { 00302 thread_leader_data_t leaderData; 00303 uint8_t linkMarginfronNeigh; 00304 uint16_t version, shortAddress, address16; 00305 uint32_t llFrameCounter; 00306 mle_tlv_info_t routing; 00307 mle_neigh_table_entry_t *entry_temp; 00308 tr_debug("Thread MLE message router sync"); 00309 //State machine What packet shuold accept in this case 00310 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00311 if (!cur) { 00312 return; 00313 } 00314 00315 /* Check that message is from link-local scope */ 00316 if(!addr_is_ipv6_link_local(mle_msg->packet_src_address)) { 00317 return; 00318 } 00319 00320 if (!thread_leader_data_parse(mle_msg->data_ptr, mle_msg->data_length, &leaderData)) { 00321 return; 00322 } 00323 00324 //Validate ready TLV for router Synch 00325 if ((!mle_tlv_read_16_bit_tlv(MLE_TYPE_VERSION, mle_msg->data_ptr, mle_msg->data_length, &version)) || 00326 (!mle_tlv_read_16_bit_tlv(MLE_TYPE_ADDRESS16, mle_msg->data_ptr, mle_msg->data_length, &address16)) || 00327 (!mle_tlv_read_32_bit_tlv(MLE_TYPE_LL_FRAME_COUNTER, mle_msg->data_ptr, mle_msg->data_length, &llFrameCounter)) || 00328 (!mle_tlv_read_tlv(MLE_TYPE_ROUTE, mle_msg->data_ptr, mle_msg->data_length, &routing)) || 00329 (!mle_tlv_read_16_bit_tlv(MLE_TYPE_SRC_ADDRESS, mle_msg->data_ptr, mle_msg->data_length, &shortAddress))) { 00330 return ; 00331 } 00332 00333 uint8_t linkMargin = thread_compute_link_margin(mle_msg->dbm); 00334 00335 switch (mle_msg->message_type) { 00336 case MLE_COMMAND_ACCEPT: { 00337 tr_info("Accept (ROUTER handler)"); 00338 uint32_t mleFrameCounter; 00339 uint16_t messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length); 00340 00341 if (messageId == 0) { 00342 tr_debug("Not for me"); 00343 return; 00344 } 00345 /*Link accept command has an optional MLE Frame counter TLV, if this is not present use link layer frame counter TLV 00346 * as MLE frame counter TLV*/ 00347 if(!mle_tlv_read_32_bit_tlv(MLE_TYPE_MLE_FRAME_COUNTER, mle_msg->data_ptr, mle_msg->data_length, &mleFrameCounter)) { 00348 mleFrameCounter = llFrameCounter; 00349 } 00350 00351 if (!thread_is_router_addr(address16)){ 00352 return; 00353 } 00354 //Allocate neighbor entry 00355 00356 entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, true); 00357 if (!entry_temp) { 00358 return; 00359 } 00360 00361 //Free Response 00362 mle_service_msg_free(messageId); 00363 entry_temp->threadNeighbor = true; 00364 mac_helper_devicetable_set(entry_temp, cur, llFrameCounter, security_headers->KeyIndex); 00365 entry_temp->short_adr = shortAddress; 00366 //when allocating neighbour entry, use MLE Frame counter if present to validate further advertisements from the neighbour 00367 entry_temp->mle_frame_counter = mleFrameCounter; 00368 if (entry_temp->timeout_rx) { 00369 mle_entry_timeout_refresh(entry_temp); 00370 } else { 00371 mle_tlv_info_t mle_tlv_info; 00372 uint32_t timeout_tlv; 00373 if (mle_tlv_option_discover(mle_msg->data_ptr, mle_msg->data_length, MLE_TYPE_TIMEOUT, &mle_tlv_info) > 0) { 00374 timeout_tlv = common_read_32_bit(mle_tlv_info.dataPtr); 00375 mle_entry_timeout_update(entry_temp, timeout_tlv); 00376 } else { 00377 mle_entry_timeout_update(entry_temp, THREAD_DEFAULT_LINK_LIFETIME); 00378 } 00379 } 00380 00381 if (thread_is_router_addr(shortAddress)) { 00382 entry_temp->handshakeReady = 1; 00383 } 00384 00385 entry_temp->mode |= MLE_THREAD_REQ_FULL_DATA_SET; 00386 00387 if (mle_tlv_read_8_bit_tlv(MLE_TYPE_RSSI, mle_msg->data_ptr, mle_msg->data_length, &linkMarginfronNeigh)) { 00388 thread_routing_update_link_margin(cur, entry_temp->short_adr, linkMargin, linkMarginfronNeigh); 00389 } 00390 00391 mac_helper_devicetable_set(entry_temp, cur, llFrameCounter, security_headers->KeyIndex); 00392 00393 //Copy Leader Data 00394 *cur->thread_info->thread_leader_data = leaderData; 00395 thread_bootstrap_update_ml16_address(cur, address16); 00396 thread_info(cur)->routerShortAddress = address16; 00397 thread_info(cur)->thread_attached_state = THREAD_STATE_CONNECTED_ROUTER; 00398 if (cur->thread_info->thread_leader_data->leaderRouterId == thread_router_id_from_addr(address16)) { 00399 if (thread_leader_service_thread_partitition_restart(interface_id, &routing)) { 00400 return; 00401 } 00402 tr_info("Router synch success as Leader of network"); 00403 } else { 00404 // Remove possibly registered network data from leader 00405 thread_management_client_network_data_unregister(cur->id, address16); 00406 00407 // Decrement data version and request network data to be updated 00408 cur->thread_info->thread_leader_data->dataVersion--; 00409 cur->thread_info->thread_leader_data->stableDataVersion--; 00410 thread_network_data_request_send(cur, mle_msg->packet_src_address, true); 00411 tr_info("Router synch success as Router"); 00412 } 00413 00414 thread_router_bootstrap_route_tlv_push(cur, routing.dataPtr, routing.tlvLen , linkMargin, entry_temp); 00415 thread_bootstrap_attached_ready(cur); 00416 00417 } 00418 00419 break; 00420 default: 00421 00422 break; 00423 } 00424 } 00425 00426 static int thread_router_synch_accept_request_build(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, uint16_t shortAddress, uint8_t *challenge, uint8_t chalLen, uint8_t *tlvReq, uint8_t tlvReqLen) 00427 { 00428 uint16_t length = 127; 00429 uint8_t i, tlvType; 00430 mle_message_timeout_params_t timeout; 00431 struct link_configuration *linkConfiguration; 00432 linkConfiguration = thread_joiner_application_get_config(cur->id); 00433 if (!linkConfiguration) { 00434 return -1; 00435 } 00436 00437 tr_debug("MLE Router Link Synh response"); 00438 00439 for (i = 0; i < tlvReqLen; i++) { 00440 tlvType = tlvReq[i]; 00441 if (tlvType == MLE_TYPE_NETWORK_DATA) { 00442 length += 2 + thread_network_data_tlv_size(cur, true); 00443 break; 00444 } 00445 } 00446 00447 uint16_t bufId = mle_service_msg_allocate(cur->id, length, false, MLE_COMMAND_ACCEPT); 00448 if (bufId == 0) { 00449 return -1; 00450 } 00451 00452 uint8_t *ptr = mle_service_get_data_pointer(bufId); 00453 00454 ptr = thread_leader_data_tlv_write(ptr, cur); 00455 ptr = mle_tlv_write_version(ptr, cur->thread_info->version); 00456 ptr = mle_general_write_link_layer_framecounter(ptr, cur); 00457 //SET MLE Frame Counter 00458 ptr = mle_tlv_write_framecounter(ptr, mle_service_security_get_frame_counter(cur->id)); 00459 00460 ptr = mle_tlv_write_response(ptr, challenge, chalLen); 00461 ptr = mle_general_write_source_address(ptr, cur); 00462 00463 for (i = 0; i < tlvReqLen; i++) { 00464 tlvType = tlvReq[i]; 00465 if (tlvType == MLE_TYPE_NETWORK_DATA) { 00466 ptr = thread_network_data_tlv_write(cur, ptr, true); 00467 } else if (tlvType == MLE_TYPE_ROUTE) { 00468 ptr = thread_route_option_write(cur, ptr); 00469 } else if (tlvType == MLE_TYPE_ADDRESS16) { 00470 ptr = mle_tlv_write_short_address(ptr, shortAddress); 00471 } else if (tlvType == MLE_TYPE_RSSI) { 00472 00473 } 00474 } 00475 00476 timeout.retrans_max = 0; 00477 timeout.timeout_init = 0; 00478 timeout.timeout_max = 0; 00479 timeout.delay = MLE_STANDARD_RESPONSE_DELAY; 00480 if (mle_service_update_length_by_ptr(bufId,ptr)!= 0) { 00481 tr_debug("Buffer overflow at message write"); 00482 } 00483 //SET Destination address 00484 mle_service_set_msg_destination_address(bufId, mle_msg->packet_src_address); 00485 mle_service_set_msg_timeout_parameters(bufId, &timeout); 00486 uint32_t keySequence; 00487 thread_management_get_current_keysequence(cur->id, &keySequence); 00488 mle_service_msg_update_security_params(bufId, 5, 2, keySequence); 00489 00490 mle_service_send_message(bufId); 00491 return 0; 00492 } 00493 00494 static int thread_router_accept_to_endevice(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, uint8_t *challenge, uint8_t chalLen) 00495 { 00496 mle_message_timeout_params_t timeout; 00497 uint16_t bufId = mle_service_msg_allocate(cur->id, 64, false, MLE_COMMAND_ACCEPT); 00498 if (bufId == 0) { 00499 return -1; 00500 } 00501 00502 if (addr_is_ipv6_multicast(mle_msg->packet_src_address)) { 00503 timeout.delay = MLE_STANDARD_RESPONSE_DELAY; 00504 } else { 00505 timeout.delay = MLE_NO_DELAY; 00506 } 00507 tr_debug("MLE Router Link Request response to REED or ED"); 00508 00509 uint8_t *ptr = mle_service_get_data_pointer(bufId); 00510 00511 timeout.retrans_max = 0; 00512 timeout.timeout_init = 0; 00513 timeout.timeout_max = 0; 00514 00515 ptr = mle_tlv_write_version(ptr, cur->thread_info->version); 00516 ptr = mle_general_write_link_layer_framecounter(ptr, cur); 00517 //SET MLE Frame Counter 00518 ptr = mle_tlv_write_framecounter(ptr, mle_service_security_get_frame_counter(cur->id)); 00519 ptr = mle_tlv_write_response(ptr, challenge, chalLen); 00520 ptr = thread_leader_data_tlv_write(ptr, cur); 00521 ptr = mle_general_write_source_address(ptr, cur); 00522 00523 if (mle_service_update_length_by_ptr(bufId,ptr)!= 0) { 00524 tr_debug("Buffer overflow at message write"); 00525 } 00526 //SET Destination address 00527 mle_service_set_msg_destination_address(bufId, mle_msg->packet_src_address); 00528 mle_service_set_msg_timeout_parameters(bufId, &timeout); 00529 uint32_t keySequence; 00530 thread_management_get_current_keysequence(cur->id, &keySequence); 00531 mle_service_msg_update_security_params(bufId, 5, 2, keySequence); 00532 mle_service_send_message(bufId); 00533 return 0; 00534 00535 } 00536 00537 static int thread_router_accept_request_build(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, uint16_t shortAddress, uint8_t *challenge, uint8_t chalLen, uint8_t type, bool rssi_tlv, uint8_t rssi) 00538 { 00539 mle_message_timeout_params_t timeout; 00540 uint16_t bufId; 00541 (void)shortAddress; 00542 uint32_t keySequence; 00543 if (type == MLE_COMMAND_ACCEPT) { 00544 timeout.retrans_max = 0; 00545 timeout.timeout_init = 0; 00546 timeout.timeout_max = 0; 00547 bufId = mle_service_msg_allocate(cur->id, 128, false, type); 00548 } else { 00549 timeout.retrans_max = 1; 00550 timeout.timeout_init = 2; 00551 timeout.timeout_max = 3; 00552 bufId = mle_service_msg_allocate(cur->id, 128, true, type); 00553 } 00554 if (bufId == 0) { 00555 return -1; 00556 } 00557 00558 if (addr_is_ipv6_multicast(mle_msg->packet_dst_address)) { 00559 timeout.delay = MLE_HALF_SECOND_MAX_DELAY; 00560 } else { 00561 timeout.delay = MLE_NO_DELAY; 00562 } 00563 00564 tr_debug("MLE Router Link Request response"); 00565 00566 thread_management_get_current_keysequence(cur->id, &keySequence); 00567 mle_service_msg_update_security_params(bufId, 5, 2, keySequence); 00568 00569 uint8_t *ptr = mle_service_get_data_pointer(bufId); 00570 00571 ptr = thread_leader_data_tlv_write(ptr, cur); 00572 if (rssi_tlv) { 00573 ptr = mle_tlv_write_version(ptr, cur->thread_info->version); 00574 ptr = mle_tlv_rssi_tlv(ptr, rssi); 00575 if (type != MLE_COMMAND_ACCEPT) { 00576 uint8_t req_tlv = MLE_TYPE_RSSI; 00577 ptr = mle_tlv_req_tlv(ptr, &req_tlv, 1); 00578 00579 } 00580 } 00581 00582 if (challenge && chalLen) { 00583 ptr = mle_general_write_link_layer_framecounter(ptr, cur); 00584 //SET MLE Frame Counter 00585 ptr = mle_tlv_write_framecounter(ptr, mle_service_security_get_frame_counter(cur->id)); 00586 ptr = mle_tlv_write_response(ptr, challenge, chalLen); 00587 } 00588 00589 ptr = mle_general_write_source_address(ptr, cur); 00590 00591 if (mle_service_update_length_by_ptr(bufId,ptr)!= 0) { 00592 tr_debug("Buffer overflow at message write"); 00593 } 00594 mle_service_set_msg_destination_address(bufId, mle_msg->packet_src_address); 00595 mle_service_set_msg_timeout_parameters(bufId, &timeout); 00596 mle_service_send_message(bufId); 00597 return 0; 00598 00599 } 00600 00601 static uint16_t thread_tlv_len(protocol_interface_info_entry_t *cur, uint8_t *tlv_ptr, uint16_t tlv_len, uint8_t mode) 00602 {// Calculates the extra length for bigger TLVs it is assumed that smaller ones fit in extra reserved space 00603 uint16_t len = 0; 00604 for (uint16_t i = 0; i < tlv_len; i++) { 00605 if (*tlv_ptr == MLE_TYPE_ROUTE) { 00606 len += thread_route_option_size(cur); 00607 } else if (*tlv_ptr == MLE_TYPE_NETWORK_DATA) { 00608 len += 2 + thread_network_data_tlv_size(cur, mode & MLE_THREAD_REQ_FULL_DATA_SET); 00609 } else if (*tlv_ptr == MLE_TYPE_ADDRESS16) { 00610 //Short Address 00611 len += 4; 00612 } 00613 tlv_ptr++; 00614 } 00615 return len; 00616 } 00617 00618 static uint8_t *thread_tlv_add(protocol_interface_info_entry_t *cur, uint8_t *ptr, uint8_t tlv_type, uint8_t mode) 00619 { 00620 struct link_configuration *linkConfiguration; 00621 linkConfiguration = thread_joiner_application_get_config(cur->id); 00622 if (!linkConfiguration) { 00623 return ptr; 00624 } 00625 00626 switch (tlv_type) { 00627 case MLE_TYPE_SRC_ADDRESS: 00628 /* Add a MLE Source Address TLV */ 00629 ptr = mle_general_write_source_address(ptr, cur); /* TODO cur normally first in param list */ 00630 break; 00631 case MLE_TYPE_MODE: { 00632 /* Add a MLE Mode TLV */ 00633 *ptr++ = MLE_TYPE_MODE; 00634 *ptr++ = 1; 00635 *ptr++ = thread_mode_get_by_interface_ptr(cur); 00636 } 00637 break; 00638 case MLE_TYPE_TIMEOUT: 00639 /* Add a MLE Timeout TLV */ 00640 ptr = mle_tlv_write_timeout(ptr, cur->thread_info->host_link_timeout); 00641 break; 00642 case MLE_TYPE_LL_FRAME_COUNTER: 00643 /* Add a MLE Timeout TLV */ 00644 ptr = mle_general_write_link_layer_framecounter(ptr, cur); 00645 break; 00646 case MLE_TYPE_NWK_PARAM: 00647 /* Add a MLE Network Parameter TLV */ 00648 /* TODO */ 00649 break; 00650 case MLE_TYPE_MLE_FRAME_COUNTER: 00651 /* Add a MLE MLE Frame Counter TLV */ 00652 /* TODO */ 00653 /* Not ostensibly used in Thread */ 00654 break; 00655 case MLE_TYPE_ROUTE: 00656 /* Add a MLE Router Table TLV */ 00657 ptr = thread_route_option_write(cur, ptr); 00658 break; 00659 case MLE_TYPE_ADDRESS16: 00660 /* Add a MLE Short Address TLV */ 00661 /* TODO */ 00662 break; 00663 case MLE_TYPE_LEADER_DATA: 00664 ptr = thread_leader_data_tlv_write(ptr, cur); 00665 break; 00666 case MLE_TYPE_NETWORK_DATA: 00667 ptr = thread_network_data_tlv_write(cur, ptr, mode & MLE_THREAD_REQ_FULL_DATA_SET); 00668 break; 00669 case MLE_TYPE_SCAN_MASK: 00670 break; 00671 case MLE_TYPE_CONNECTIVITY: 00672 break; 00673 case MLE_TYPE_RSSI: 00674 break; 00675 default: 00676 /* No other TLV type can be requested */ 00677 /* LQI possibly - but not for thread */ 00678 break; 00679 } 00680 return ptr; 00681 } 00682 00683 static int thread_child_update_response(protocol_interface_info_entry_t *cur, uint8_t *dst_address, uint8_t mode, uint16_t short_address, uint32_t timeout, mle_tlv_info_t *addressRegisterTlv,mle_tlv_info_t *tlvReq, mle_tlv_info_t *challengeTlv) 00684 { 00685 uint16_t i; 00686 uint16_t len = 64; 00687 uint32_t keySequence; 00688 uint8_t *ptr; 00689 if (!thread_info(cur)) { 00690 return -1; 00691 } 00692 00693 if (tlvReq && tlvReq->tlvLen) { 00694 mle_tlv_ignore(tlvReq->dataPtr, tlvReq->tlvLen, MLE_TYPE_LL_FRAME_COUNTER); 00695 len += thread_tlv_len(cur, tlvReq->dataPtr, tlvReq->tlvLen, mode); 00696 } 00697 if (addressRegisterTlv && addressRegisterTlv->tlvLen){ 00698 len += addressRegisterTlv->tlvLen; 00699 } 00700 00701 uint16_t bufId = mle_service_msg_allocate(cur->id, len, false, MLE_COMMAND_CHILD_UPDATE_RESPONSE); 00702 00703 if (bufId == 0) { 00704 return -1; 00705 } 00706 00707 tr_debug("MLE Child synch response"); 00708 00709 thread_management_get_current_keysequence(cur->id, &keySequence); 00710 mle_service_msg_update_security_params(bufId, 5, 2, keySequence); 00711 00712 ptr = mle_service_get_data_pointer(bufId); 00713 00714 ptr = mle_tlv_write_mode(ptr, mode); //Write Mode Allways 00715 00716 if (addressRegisterTlv && addressRegisterTlv->tlvLen){ 00717 *ptr++ = MLE_TYPE_ADDRESS_REGISTRATION; 00718 *ptr++ = addressRegisterTlv->tlvLen; 00719 memcpy(ptr, addressRegisterTlv->dataPtr, addressRegisterTlv->tlvLen); 00720 ptr += addressRegisterTlv->tlvLen; 00721 } 00722 //Set SRC 00723 ptr = mle_general_write_source_address(ptr, cur); 00724 //SET leader data 00725 ptr = thread_leader_data_tlv_write(ptr, cur); 00726 if (timeout) { 00727 ptr = mle_tlv_write_timeout(ptr, timeout); 00728 } 00729 00730 if (challengeTlv && challengeTlv->tlvLen) { 00731 ptr = mle_tlv_write_response(ptr, challengeTlv->dataPtr, challengeTlv->tlvLen); 00732 ptr = mle_general_write_link_layer_framecounter(ptr, cur); 00733 //SET MLE Frame Counter 00734 ptr = mle_tlv_write_framecounter(ptr, mle_service_security_get_frame_counter(cur->id)); 00735 } 00736 00737 if (tlvReq && tlvReq->tlvLen) { 00738 /* Go through the requested TLV mask */ 00739 for (i = 0; i < tlvReq->tlvLen; i++) { 00740 ptr = thread_tlv_add(cur, ptr, tlvReq->dataPtr[i], mode); 00741 } 00742 if (mle_tlv_requested(tlvReq->dataPtr, tlvReq->tlvLen, MLE_TYPE_ADDRESS16)) { 00743 ptr = mle_tlv_write_short_address(ptr, short_address); 00744 } 00745 } 00746 00747 if (mle_service_update_length_by_ptr(bufId,ptr)!= 0) { 00748 tr_debug("Buffer overflow at message write"); 00749 } 00750 mle_service_set_msg_destination_address(bufId, dst_address); 00751 mle_service_send_message(bufId); 00752 return 0; 00753 00754 } 00755 00756 static int mle_build_and_send_data_response_msg(protocol_interface_info_entry_t *cur, uint8_t *dst_address, uint8_t *data_ptr, uint16_t data_len, mle_tlv_info_t *request_tlv, uint8_t mode) 00757 { 00758 uint16_t length = 64 + 20 + 4; // source address 4 bytes 00759 uint8_t *ptr; 00760 uint_fast16_t i; 00761 uint64_t active_timestamp = 0; 00762 uint64_t pending_timestamp = 0; 00763 bool add_active_configuration = false; 00764 bool add_pending_configuration = false; 00765 bool active_timestamp_present_in_request = false; 00766 bool pending_timestamp_present_in_request = false; 00767 uint64_t own_pending_timestamp = 0; 00768 link_configuration_s *link_configuration; 00769 link_configuration = thread_joiner_application_get_config(cur->id); 00770 00771 if (!link_configuration) { 00772 return 0; 00773 } 00774 00775 active_timestamp_present_in_request = mle_tlv_read_64_bit_tlv(MLE_TYPE_ACTIVE_TIMESTAMP, data_ptr, data_len, &active_timestamp); 00776 pending_timestamp_present_in_request = mle_tlv_read_64_bit_tlv(MLE_TYPE_PENDING_TIMESTAMP, data_ptr, data_len, &pending_timestamp); 00777 00778 length += thread_pending_timestamp_tlv_size(cur); 00779 00780 00781 if (!active_timestamp_present_in_request || active_timestamp != link_configuration->timestamp) { 00782 length += thread_active_operational_dataset_size(cur); 00783 add_active_configuration = true; 00784 } 00785 own_pending_timestamp = thread_joiner_application_pending_config_timestamp_get(cur->id); 00786 if (!pending_timestamp_present_in_request || (own_pending_timestamp && own_pending_timestamp != pending_timestamp)) { 00787 length += thread_pending_operational_dataset_size(cur); 00788 add_pending_configuration = true; 00789 } 00790 00791 // Leader data is added by default 00792 mle_tlv_ignore(request_tlv->dataPtr, request_tlv->tlvLen, MLE_TYPE_LEADER_DATA); 00793 length += thread_tlv_len(cur, request_tlv->dataPtr, request_tlv->tlvLen, mode); 00794 00795 //link metrics info 00796 length += thread_lowpower_link_metrics_length(cur, dst_address); 00797 00798 uint16_t bufId = mle_service_msg_allocate(cur->id, length, false, MLE_COMMAND_DATA_RESPONSE); 00799 00800 if (bufId == 0) { 00801 return -1; 00802 } 00803 00804 tr_debug("Send MLE data response, %s mode=%x", trace_ipv6(dst_address), mode); 00805 ptr = mle_service_get_data_pointer(bufId); 00806 00807 ptr = thread_leader_data_tlv_write(ptr, cur); 00808 /* Go through the requested TLV mask */ 00809 for (i = 0; i < request_tlv->tlvLen; i++) { 00810 ptr = thread_tlv_add(cur, ptr, request_tlv->dataPtr[i], mode); 00811 } 00812 00813 ptr = thread_active_timestamp_write(cur,ptr); 00814 ptr = thread_pending_timestamp_write(cur,ptr); 00815 ptr = mle_general_write_source_address(ptr, cur); 00816 if (add_active_configuration) { 00817 ptr = thread_active_operational_dataset_write(cur, ptr); 00818 } 00819 if (add_pending_configuration) { 00820 ptr = thread_pending_operational_dataset_write(cur, ptr); 00821 } 00822 ptr = thread_lowpower_link_metrics_write(cur, dst_address, ptr); 00823 00824 if (mle_service_update_length_by_ptr(bufId,ptr)!= 0) { 00825 tr_debug("Buffer overflow at message write"); 00826 } 00827 mle_service_set_msg_destination_address(bufId, dst_address); 00828 //Set Security 00829 uint32_t keySequence; 00830 thread_management_get_current_keysequence(cur->id, &keySequence); 00831 mle_service_msg_update_security_params(bufId, 5, 2, keySequence); 00832 00833 mle_service_send_message(bufId); 00834 return 0; 00835 00836 00837 } 00838 00839 //this responds with zeros currently, needs to be updated after results are computed 00840 00841 static int thread_attach_parent_response_build(protocol_interface_info_entry_t *cur, uint8_t *dstAddress, uint8_t *challenge, uint16_t chalLen, uint8_t linkMargin, uint8_t scanMask, uint8_t mode) 00842 { 00843 /** 00844 * This Message need to add Next Items: 00845 * - MLE_TYPE_SRC_ADDRESS 00846 * - MLE_TYPE_LEADER_DATA 00847 * - MLE_TYPE_LL_FRAME_COUNTER 00848 * - MLE_TYPE_MLE FRAME_COUNTER 00849 * - MLE_TYPE_CHALLENGE 00850 * - MLE_TYPE_RESPONSE 00851 * - MLE_TYPE_CONNECTIVITY 00852 * - MLE_TYPE_RSSI 00853 * - MLE_TYPE_VERSION 00854 */ 00855 00856 mle_message_timeout_params_t timeout; 00857 00858 uint16_t bufId = mle_service_msg_allocate(cur->id, 128, true, MLE_COMMAND_PARENT_RESPONSE); 00859 if (bufId == 0) { 00860 return -1; 00861 } 00862 tr_debug("MLE ATTACHED 2. Packet"); 00863 00864 uint32_t keySequence; 00865 uint8_t *ptr = mle_service_get_data_pointer(bufId); 00866 00867 //Set Security 00868 thread_management_get_current_keysequence(cur->id, &keySequence); 00869 mle_service_msg_update_security_params(bufId, 5, 2, keySequence); 00870 00871 //SET Leader Data 00872 ptr = thread_leader_data_tlv_write(ptr, cur); 00873 00874 // SET Connectivity TLV 00875 ptr = thread_connectivity_tlv_write(ptr, cur, mode); 00876 00877 //SET LL Frame Counter 00878 ptr = mle_general_write_link_layer_framecounter(ptr, cur); 00879 //SET MLE Frame Counter 00880 ptr = mle_tlv_write_framecounter(ptr, mle_service_security_get_frame_counter(cur->id)); 00881 //SET Source Address 00882 ptr = mle_general_write_source_address(ptr, cur); 00883 //SET Response 00884 if (challenge != NULL) { 00885 ptr = mle_tlv_write_response(ptr, challenge, chalLen); 00886 } 00887 //RSSI 00888 ptr = mle_tlv_rssi_tlv(ptr, linkMargin); 00889 //Set Version 00890 ptr = mle_tlv_write_version(ptr, cur->thread_info->version); 00891 00892 if (mle_service_update_length_by_ptr(bufId,ptr)!= 0) { 00893 tr_debug("Buffer overflow at message write"); 00894 } 00895 timeout.retrans_max = 1; 00896 timeout.timeout_init = 6; 00897 timeout.timeout_max = 6; 00898 00899 switch (scanMask & 0xc0) { 00900 case 0x80: 00901 timeout.delay = MLE_HALF_SECOND_MAX_DELAY; 00902 break; 00903 default: 00904 timeout.delay = MLE_STANDARD_RESPONSE_DELAY; 00905 break; 00906 } 00907 00908 //SET Destination address 00909 mle_service_set_msg_destination_address(bufId, dstAddress); 00910 mle_service_set_msg_timeout_parameters(bufId, &timeout); 00911 mle_service_send_message(bufId); 00912 return 0; 00913 } 00914 00915 void thread_router_bootstrap_child_information_clear(protocol_interface_info_entry_t *cur) 00916 { 00917 if (!cur->thread_info) { 00918 return; 00919 } 00920 00921 if (cur->thread_info->routerShortAddress == 0xfffe) { 00922 return; 00923 } 00924 00925 // Remove registered entries in IP neighbour cache 00926 ns_list_foreach_safe(ipv6_neighbour_t, neighbour, &cur->ipv6_neighbour_cache.list) { 00927 if (neighbour->type == IP_NEIGHBOUR_REGISTERED) { 00928 ipv6_neighbour_entry_remove(&cur->ipv6_neighbour_cache, neighbour); 00929 } 00930 } 00931 00932 // Remove mle neighbour entries for children in previous partition 00933 mle_neigh_table_list_t *entry_list = mle_class_active_list_get(cur->id); 00934 if (!entry_list) { 00935 return; 00936 } 00937 ns_list_foreach_safe(mle_neigh_table_entry_t, table_entry, entry_list) { 00938 if (!thread_is_router_addr(table_entry->short_adr) && thread_router_addr_from_addr(table_entry->short_adr) == cur->thread_info->routerShortAddress) { 00939 mle_class_remove_entry(cur->id, table_entry); 00940 } 00941 } 00942 00943 } 00944 00945 static void thread_bootstrap_client_router_id_cb(int8_t interface_id, int8_t status, uint16_t router_rloc, const uint8_t router_mask_ptr[9]) 00946 { 00947 uint8_t ml16[16]; 00948 protocol_interface_info_entry_t *cur; 00949 uint8_t parent_router_id = FAST_ROUTE_NO_ROUTE; 00950 00951 cur = protocol_stack_interface_info_get_by_id(interface_id); 00952 tr_debug("RouterID CB"); 00953 if (!cur) { 00954 return; 00955 } 00956 if (!cur->thread_info->routerIdReqCoapID) { 00957 return; 00958 } 00959 cur->thread_info->routerIdReqCoapID = 0; 00960 00961 if (cur->thread_info->thread_device_mode != THREAD_DEVICE_MODE_ROUTER || 00962 cur->thread_info->leader_private_data ) { 00963 // Test api can cause these states or some out of sync operation. 00964 tr_warn("Router address for non-REED"); 00965 return; 00966 } 00967 00968 if (status < 0) { 00969 thread_bootstrap_router_id_get_fail(cur); 00970 return; 00971 } 00972 00973 uint8_t routeId = *router_mask_ptr++; 00974 00975 if(cur->thread_info->thread_endnode_parent) { 00976 parent_router_id = cur->thread_info->thread_endnode_parent->router_id; 00977 } 00978 00979 //ADD New ML16 00980 // This should be used thread_bootstrap_update_ml16_address(cur, router_rloc); 00981 thread_clean_old_16_bit_address_based_addresses(cur); 00982 00983 mac_helper_mac16_address_set(cur, router_rloc); 00984 cur->thread_info->routerShortAddress = router_rloc; 00985 memcpy(ml16, cur->thread_info->threadPrivatePrefixInfo.ulaPrefix, 8); 00986 memcpy(&ml16[8], ADDR_SHORT_ADR_SUFFIC , 6); 00987 common_write_16_bit(router_rloc, &ml16[14]); 00988 00989 cur->global_address_available = true; 00990 //Register UL16 00991 if_address_entry_t *def_address = addr_add(cur, ml16, 64, ADDR_SOURCE_UNKNOWN, 0xffffffff, 0xffffffff, true); 00992 if (!def_address) { 00993 return; 00994 } 00995 00996 tr_info("Thread Short address changed old: %x new: %x", cur->thread_info->routerShortAddress, router_rloc); 00997 /*the default routerShortAddress if nothing is requested is 0xfffe so eliminate this case 00998 Also make sure that the child info (from previous partition if any) 00999 is cleared if the router address requested is not what is got from leader */ 01000 if (cur->thread_info->routerShortAddress != router_rloc) { 01001 thread_router_bootstrap_child_information_clear(cur); 01002 } 01003 // Release network data from old address 01004 cur->thread_info->localServerDataBase.release_old_address = true; 01005 01006 // /* XXX Is short_src_adr ever reset? Is it undefined if info not in msg? */ 01007 tr_debug("Route seq %d Router mask: %s", routeId, trace_array(router_mask_ptr, 8)); 01008 cur->thread_info->routing.router_id_sequence_valid = false; 01009 if (parent_router_id != FAST_ROUTE_NO_ROUTE) { 01010 thread_routing_force_next_hop(cur, routeId, router_mask_ptr, parent_router_id); 01011 } else { 01012 tr_warn("No parent information available, no initial route set."); 01013 thread_routing_update_id_set(cur, routeId, router_mask_ptr); 01014 } 01015 thread_bootstrap_attached_active_router(cur); 01016 01017 } 01018 01019 void thread_router_bootstrap_router_id_request(protocol_interface_info_entry_t *cur, uint8_t status) 01020 { 01021 int router_id_req_status; 01022 tr_debug("Router ID Request"); 01023 if (cur->thread_info->routerIdReqCoapID) { 01024 tr_warn("Router ID already requested"); 01025 return; 01026 } 01027 01028 router_id_req_status = thread_management_client_router_id_get(cur->id, cur->mac, cur->thread_info->routerShortAddress, thread_bootstrap_client_router_id_cb, status); 01029 tr_debug("Coap address req, ID=%d", router_id_req_status); 01030 if (router_id_req_status > 0) { 01031 cur->thread_info->routerIdReqCoapID = (uint16_t)router_id_req_status; 01032 } 01033 } 01034 01035 static int mle_attach_child_id_response_build(protocol_interface_info_entry_t *cur, uint8_t *dstAddress,thread_pending_child_id_req_t *child_req,mle_neigh_table_entry_t *neigh_info) 01036 { 01037 uint16_t len = 12 + 4; //Leader data and short address 01038 uint8_t *ptr; 01039 bool fullList = false; 01040 uint64_t pending_timestamp; 01041 struct link_configuration *linkConfiguration; 01042 linkConfiguration = thread_joiner_application_get_config(cur->id); 01043 if (!linkConfiguration) { 01044 return -1; 01045 } 01046 01047 if (neigh_info->mode & MLE_THREAD_REQ_FULL_DATA_SET) { 01048 fullList = true; 01049 } 01050 01051 if (child_req->shortAddressReq) { 01052 //Short Address 01053 len += 4; 01054 } 01055 01056 if (child_req->networkDataReq) { 01057 len += 2 + thread_network_data_tlv_size(cur, fullList); 01058 } 01059 01060 if (child_req->routeReq) { 01061 len += thread_route_option_size(cur); 01062 } 01063 if (child_req->request_active_config || child_req->active_timestamp != linkConfiguration->timestamp) { 01064 len += thread_active_operational_dataset_size(cur); 01065 } 01066 01067 //always put active timestamp 01068 len += 10; 01069 len += thread_pending_timestamp_tlv_size(cur); 01070 pending_timestamp = thread_joiner_application_pending_config_timestamp_get(cur->id); 01071 if (pending_timestamp && pending_timestamp != child_req->pending_timestamp) { 01072 len += thread_pending_operational_dataset_size(cur); 01073 } 01074 01075 mle_message_timeout_params_t timeout; 01076 uint16_t bufId = mle_service_msg_allocate(cur->id, len , false, MLE_COMMAND_CHILD_ID_RESPONSE); 01077 if (bufId == 0) { 01078 return -1; 01079 } 01080 uint32_t keySequence; 01081 thread_management_get_current_keysequence(cur->id, &keySequence); 01082 mle_service_msg_update_security_params(bufId, 5, 2, keySequence); 01083 01084 tr_debug("Send MLE Child ID response"); 01085 01086 ptr = mle_service_get_data_pointer(bufId); 01087 01088 ptr = thread_leader_data_tlv_write(ptr, cur); 01089 01090 ptr = mle_general_write_source_address(ptr, cur); 01091 01092 if (child_req->shortAddressReq) { 01093 ptr = mle_tlv_write_short_address(ptr, neigh_info->short_adr); 01094 } 01095 01096 if (child_req->routeReq) { 01097 ptr = thread_route_option_write(cur, ptr); 01098 } 01099 01100 if (child_req->networkDataReq) { 01101 ptr = thread_network_data_tlv_write(cur, ptr, fullList); 01102 } 01103 01104 if (child_req->active_timestamp != linkConfiguration->timestamp) { 01105 ptr = thread_active_operational_dataset_write(cur, ptr); 01106 } 01107 01108 //always write active timestamp 01109 ptr = thread_active_timestamp_write(cur,ptr); 01110 if (pending_timestamp > 0 && pending_timestamp != child_req->pending_timestamp) { 01111 ptr = thread_pending_operational_dataset_write(cur, ptr); 01112 } 01113 01114 ptr = thread_pending_timestamp_write(cur,ptr); 01115 01116 01117 if (mle_service_update_length_by_ptr(bufId,ptr)!= 0) { 01118 tr_debug("Buffer overflow at message write"); 01119 } 01120 timeout.retrans_max = 0; 01121 timeout.timeout_init = 0; 01122 timeout.timeout_max = 0; 01123 timeout.delay = MLE_NO_DELAY; 01124 mle_service_set_msg_destination_address(bufId, dstAddress); 01125 mle_service_set_msg_timeout_parameters(bufId, &timeout); 01126 mle_service_send_message(bufId); 01127 return 0; 01128 01129 01130 } 01131 uint16_t thread_router_bootstrap_child_count_get(protocol_interface_info_entry_t *cur) 01132 { 01133 uint16_t child_count = 0; 01134 uint16_t router_address = thread_info(cur)->routerShortAddress; 01135 if (router_address >= 0xfffe) { 01136 router_address = mac_helper_mac16_address_get(cur); 01137 } 01138 if (router_address & THREAD_CHILD_MASK) { 01139 return 0; //I am child 01140 } 01141 if (router_address >= 0xfffe) { 01142 return 0; 01143 } 01144 mle_neigh_table_list_t *mle_table = mle_class_active_list_get(cur->id); 01145 if (!mle_table) { 01146 return -1; 01147 } 01148 ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_table) { 01149 if (thread_router_addr_from_addr(cur_entry->short_adr) == router_address) { 01150 child_count++; 01151 } 01152 } 01153 return child_count; 01154 } 01155 01156 static uint16_t thread_router_bootstrap_child_address_generate(protocol_interface_info_entry_t *cur) 01157 { 01158 mle_neigh_table_list_t *mle_table = mle_class_active_list_get(cur->id); 01159 if (!mle_table) { 01160 return -1; 01161 } 01162 01163 if (thread_router_bootstrap_child_count_get(cur) >= cur->thread_info->maxChildCount) { 01164 tr_info("Maximum count %d reached", cur->thread_info->maxChildCount); 01165 return 0xffff; 01166 } 01167 01168 bool address_allocated = false; 01169 for (uint16_t i = 0; i < cur->thread_info->maxChildCount; i++) { 01170 address_allocated = false; 01171 cur->thread_info->lastAllocatedChildAddress = (cur->thread_info->lastAllocatedChildAddress % THREAD_MAX_CHILD_ID_COUNT) + 1; 01172 ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_table) { 01173 if ( (cur_entry->short_adr & THREAD_CHILD_MASK) == cur->thread_info->lastAllocatedChildAddress) { 01174 address_allocated = true; 01175 break; 01176 } 01177 } 01178 if (!address_allocated){ 01179 break; 01180 } 01181 } 01182 if (address_allocated){ 01183 // all possible addresses already allocated 01184 return 0xffff; 01185 } 01186 return ((mac_helper_mac16_address_get(cur) & THREAD_ROUTER_MASK) | cur->thread_info->lastAllocatedChildAddress); 01187 } 01188 01189 static bool thread_child_id_request(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *entry_temp) 01190 { 01191 //Remove All Short address links from router 01192 if (entry_temp->short_adr != 0xffff) { 01193 protocol_6lowpan_release_short_link_address_from_neighcache(cur, entry_temp->short_adr); 01194 } 01195 01196 //allocate child address if current is router, 0xffff or not our child 01197 if (!thread_addr_is_equal_or_child(mac_helper_mac16_address_get(cur), entry_temp->short_adr)) { 01198 entry_temp->short_adr = thread_router_bootstrap_child_address_generate(cur); 01199 } 01200 01201 if (entry_temp->short_adr == 0xffff) { 01202 return false; 01203 } 01204 01205 // Store this child info to the NVM 01206 thread_dynamic_storage_child_info_store(cur->id, entry_temp); 01207 //} 01208 return true; 01209 } 01210 01211 void thread_router_bootstrap_child_id_handler(protocol_interface_info_entry_t *cur) 01212 { 01213 thread_pending_child_id_req_t *req; 01214 bool new_neigbour = false; 01215 01216 if (cur->thread_info->thread_attached_state == THREAD_STATE_CONNECTED) { 01217 if (!cur->thread_info->routerIdReqCoapID) { 01218 tr_info("Upgrade REED to Router"); 01219 thread_router_bootstrap_router_id_request(cur, THREAD_COAP_STATUS_TLV_HAVE_CHILD_ID_REQUEST); 01220 } 01221 return; 01222 } 01223 req = thread_child_id_request_entry_get_from_the_list(cur); 01224 01225 if (!req) { 01226 tr_debug("Child Id Req pending list empty"); 01227 return; 01228 } 01229 01230 if (cur->thread_info->thread_attached_state != THREAD_STATE_CONNECTED_ROUTER) { 01231 // We are not router can not process 01232 goto free_request; 01233 } 01234 01235 uint8_t ll64[16]; 01236 //set LL64 destination address 01237 memcpy(ll64, ADDR_LINK_LOCAL_PREFIX , 8); 01238 memcpy(&ll64[8], req->euid64 , 8); 01239 ll64[8] ^= 2; 01240 //Allocate entry 01241 mle_neigh_table_entry_t *entry_temp = mle_class_get_entry_by_ll64(cur->id, req->linkMargin, ll64, false); 01242 01243 if (!entry_temp) { 01244 entry_temp = mle_class_get_entry_by_ll64(cur->id, req->linkMargin, ll64, true); 01245 new_neigbour = true; 01246 } 01247 if (!entry_temp) { 01248 //Send link reject 01249 thread_link_reject_send(cur, ll64); 01250 goto free_request; 01251 } 01252 01253 // If mac frame couter is less than previous we need to leave the old one 01254 01255 //Update or set neigh info 01256 entry_temp->holdTime = 90; 01257 01258 mle_entry_timeout_update(entry_temp, req->timeout); 01259 entry_temp->mode = req->mode; 01260 entry_temp->threadNeighbor = true; 01261 entry_temp->handshakeReady = 1; 01262 entry_temp->mle_frame_counter = req->mleFrameCounter; 01263 01264 if (req->shortAddressReq) { 01265 if (!thread_child_id_request(cur, entry_temp)) { 01266 mle_class_remove_entry(cur->id, entry_temp); 01267 thread_link_reject_send(cur, ll64); 01268 goto free_request; 01269 } 01270 } 01271 if (new_neigbour) { 01272 mac_helper_devicetable_set(entry_temp, cur, req->frameCounter, req->keyId); 01273 } else { 01274 // in get response handler this will update the short address from MLE table 01275 mlme_get_t get_req; 01276 get_req.attr = macDeviceTable; 01277 get_req.attr_index = entry_temp->attribute_index; 01278 cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req); 01279 } 01280 01281 //Register MLEID if RRFD device 01282 if ((entry_temp->mode & MLE_DEV_MASK) == MLE_RFD_DEV) { 01283 uint8_t tempIPv6Address[16]; 01284 memcpy(tempIPv6Address, thread_info(cur)->threadPrivatePrefixInfo.ulaPrefix, 8); 01285 memcpy(&tempIPv6Address[8], req->eiid, 8); 01286 memcpy(&entry_temp->mlEid, req->eiid, 8); 01287 01288 tr_debug("Register %s", trace_ipv6(tempIPv6Address)); 01289 //Register GP --> 16 01290 thread_nd_address_registration(cur, tempIPv6Address, entry_temp->short_adr, cur->mac_parameters->pan_id, entry_temp->mac64); 01291 } 01292 01293 tr_debug("Response Child Id Request"); 01294 mle_attach_child_id_response_build(cur,ll64,req, entry_temp); 01295 01296 free_request: 01297 ns_dyn_mem_free(req); 01298 thread_bootstrap_child_id_request(cur); 01299 } 01300 01301 static void thread_address_registration_tlv_parse(uint8_t *ptr, uint16_t data_length, protocol_interface_info_entry_t *cur, uint16_t mac16, uint8_t *mac64) 01302 { 01303 lowpan_context_t *ctx; 01304 uint8_t tempIPv6Address[16]; 01305 uint8_t ctxId; 01306 01307 while (data_length) { 01308 //Read 01309 ctxId = *ptr++; 01310 if (ctxId & 0x80) { 01311 ctxId &= 0x0f; 01312 ctx = lowpan_contex_get_by_id(&cur->lowpan_contexts, ctxId); 01313 if (ctx) { 01314 memcpy(tempIPv6Address, ctx->prefix, 8); 01315 memcpy(&tempIPv6Address[8], ptr, 8); 01316 tr_debug("Register %s", trace_ipv6(tempIPv6Address)); 01317 //Register GP --> 16 01318 thread_nd_address_registration(cur, tempIPv6Address, mac16, cur->mac_parameters->pan_id, mac64); 01319 thread_extension_address_registration(cur, tempIPv6Address, mac64); 01320 } else { 01321 tr_debug("No Context %u", ctxId); 01322 } 01323 ptr += 8; 01324 data_length -= 9; 01325 } else { 01326 tr_debug("Register %s", trace_ipv6(ptr)); 01327 01328 if (addr_is_ipv6_multicast(ptr)) { 01329 // Register multicast address (higher scope than link-local) 01330 if (addr_ipv6_multicast_scope(ptr) > IPV6_SCOPE_LINK_LOCAL) { 01331 addr_add_group(cur, ptr); 01332 if (thread_child_mcast_entry_get(cur, ptr, mac64)) { 01333 tr_debug("Added sleepy multicast registration entry."); 01334 } 01335 } 01336 } else { 01337 //Register GP --> 16 01338 thread_nd_address_registration(cur, ptr, mac16, cur->mac_parameters->pan_id, mac64); 01339 thread_extension_address_registration(cur, ptr, mac64); 01340 } 01341 01342 ptr += 16; 01343 data_length -= 17; 01344 } 01345 } 01346 } 01347 01348 void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers) 01349 { 01350 thread_leader_data_t leaderData; 01351 mle_neigh_table_entry_t *entry_temp; 01352 bool rssiTLV; 01353 bool leaderDataReceived; 01354 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 01355 if (!cur) { 01356 return; 01357 } 01358 01359 //TLV REQUSTED 01360 if (mle_tlv_type_requested(MLE_TYPE_RSSI, mle_msg->data_ptr, mle_msg->data_length)) { 01361 rssiTLV = true; 01362 } else { 01363 rssiTLV = false; 01364 } 01365 01366 if (thread_leader_data_parse(mle_msg->data_ptr, mle_msg->data_length, &leaderData)) { 01367 leaderDataReceived = true; 01368 } else { 01369 leaderDataReceived = false; 01370 } 01371 01372 01373 uint8_t linkMargin = thread_compute_link_margin(mle_msg->dbm); 01374 tr_debug("Thread MLE REED Handler"); 01375 switch (mle_msg->message_type) { 01376 case MLE_COMMAND_PARENT_REQUEST: { 01377 uint8_t scanMask, mode; 01378 uint16_t version; 01379 mle_tlv_info_t challengeTlv; 01380 tr_info("Recv MLE Parent Request"); 01381 01382 if (cur->nwk_bootstrap_state != ER_BOOTSRAP_DONE && cur->nwk_bootstrap_state != ER_MLE_ATTACH_READY) { 01383 // If own attach is ongoing, do not process parent request 01384 return; 01385 } 01386 01387 if (security_headers->KeyIdMode != MAC_KEY_ID_MODE_SRC4_IDX) { 01388 tr_debug("Wrong key mode %u ", security_headers->KeyIdMode); 01389 return; 01390 } 01391 01392 if (!thread_router_bootstrap_routing_allowed(cur)) { 01393 tr_debug("R bit is off in security policy; drop packet"); 01394 return; 01395 } 01396 01397 if (thread_am_reed(cur)) { 01398 // If we are in REED mode and receive PARENT_REQ from our parent, don't send response. 01399 if (thread_router_parent_address_check(cur, mle_msg->packet_src_address)) { 01400 tr_debug("Drop PARENT_REQ from own parent"); 01401 return; 01402 } 01403 } 01404 01405 // parent request received 01406 entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false); 01407 if (entry_temp) { 01408 entry_temp->mode = (MLE_FFD_DEV | MLE_RX_ON_IDLE | MLE_THREAD_REQ_FULL_DATA_SET); 01409 } 01410 if(!entry_temp) { 01411 if (!mle_tlv_read_8_bit_tlv(MLE_TYPE_MODE, mle_msg->data_ptr, mle_msg->data_length, &mode)) { 01412 tr_debug("NO Mode"); 01413 return; 01414 } 01415 01416 // New child trying to attach check if we have room 01417 if (mle_service_interface_tx_queue_size(cur->id) > THREAD_MAX_PARALLEL_MLE_PARENT_REQUEST) { 01418 tr_info("Drop MLE message: too many simultaneous MLE messages"); 01419 return; 01420 } 01421 01422 if (mle_class_free_entry_count_get(cur->id) < 1) { 01423 tr_info("Drop MLE message: no space left in the MLE table"); 01424 return; 01425 } 01426 01427 if ((mode & MLE_DEV_MASK) == MLE_RFD_DEV && mle_class_rfd_entry_count_get(cur->id) >= THREAD_MAX_MTD_CHILDREN) { 01428 tr_info("Drop MLE message: maximum MTD child count reached."); 01429 return; 01430 } 01431 01432 if (!(mode & MLE_RX_ON_IDLE) && mle_class_sleepy_entry_count_get(cur->id) >= THREAD_MAX_SED_CHILDREN) { 01433 tr_info("Drop MLE message: maximum SED child count reached."); 01434 return; 01435 } 01436 01437 if (cur->thread_info->thread_attached_state == THREAD_STATE_CONNECTED_ROUTER && 01438 thread_router_bootstrap_child_count_get(cur) >= cur->thread_info->maxChildCount) { 01439 tr_info("Drop MLE message: maximum Child count reached (%d)", cur->thread_info->maxChildCount); 01440 return; 01441 } 01442 } 01443 01444 if (thread_route_ready_to_leader(cur) != 0) { 01445 tr_debug("Leader Path infinite"); 01446 return; 01447 } 01448 01449 /** 01450 * MLE attached First packet Mandatory TLV:s are validated at this function 01451 * - MLE_TYPE_SCAN_MASK 01452 * - MLE_TYPE_CHALLENGE 01453 * - MLE_TYPE_VERSION 01454 */ 01455 //Validate Mask 01456 if (!mle_tlv_read_8_bit_tlv(MLE_TYPE_SCAN_MASK, mle_msg->data_ptr, mle_msg->data_length, &scanMask)) { 01457 tr_debug("NO Scan mask"); 01458 return; 01459 } 01460 01461 if (!mle_tlv_read_8_bit_tlv(MLE_TYPE_MODE, mle_msg->data_ptr, mle_msg->data_length, &mode)) { 01462 tr_debug("NO Mode"); 01463 return; 01464 } 01465 01466 if (!thread_scan_mask_validation(cur, scanMask)) { 01467 tr_debug("Not my type"); 01468 return; 01469 } 01470 01471 if(cur->thread_info->thread_attached_state == THREAD_STATE_CONNECTED && 01472 31 < thread_routing_count_active_routers(&cur->thread_info->routing)) { 01473 tr_info("No possibility to upgrade to router"); 01474 return; 01475 } 01476 01477 if (!mle_tlv_read_16_bit_tlv(MLE_TYPE_VERSION, mle_msg->data_ptr, mle_msg->data_length, &version)) { 01478 tr_debug("NO version"); 01479 return; 01480 } 01481 01482 //Read Challenge for Build Response 01483 if (!mle_tlv_read_tlv(MLE_TYPE_CHALLENGE, mle_msg->data_ptr, mle_msg->data_length, &challengeTlv)) { 01484 tr_debug("No challenge"); 01485 return; 01486 } 01487 01488 if (thread_attach_parent_response_build(cur, mle_msg->packet_src_address, challengeTlv.dataPtr, challengeTlv.tlvLen, linkMargin, scanMask, mode) == 0) { 01489 tr_debug("Send MLE Parent response"); 01490 } 01491 break; 01492 } 01493 01494 case MLE_COMMAND_CHILD_ID_REQUEST: 01495 tr_info("Recv MLE Child ID Request from %s", trace_ipv6(mle_msg->packet_src_address)); 01496 if (cur->nwk_bootstrap_state != ER_BOOTSRAP_DONE && cur->nwk_bootstrap_state != ER_MLE_ATTACH_READY) { 01497 // If own attach is ongoing, do not process child ID req 01498 return; 01499 } 01500 01501 if (!thread_router_bootstrap_routing_allowed(cur)) { 01502 tr_debug("R bit is off in security policy; drop packet"); 01503 return; 01504 } 01505 01506 // If we are in REED mode and receive child IR request from our parent, call connection error. 01507 if (thread_am_reed(cur)) { 01508 if (thread_router_parent_address_check(cur, mle_msg->packet_src_address)) { 01509 tr_debug("Child ID req from own parent -> connection error"); 01510 thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL); 01511 return; 01512 } 01513 } 01514 01515 if (security_headers->KeyIdMode != MAC_KEY_ID_MODE_SRC4_IDX) { 01516 tr_debug("Wrong key mode %u ", security_headers->KeyIdMode); 01517 return; 01518 } else { 01519 thread_pending_child_id_req_t *id_req; 01520 uint8_t tlvType; 01521 mle_tlv_info_t tlvRequest, addressRegisteredTlv; 01522 uint8_t *t_ptr; 01523 01524 uint16_t messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length); 01525 01526 if (messageId == 0) { 01527 tr_debug("Not for me"); 01528 return; 01529 } 01530 01531 /* Perform key synchronization */ 01532 thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource)); 01533 01534 //Free Response 01535 mle_service_msg_free(messageId); 01536 01537 mle_msg->packet_src_address[8] ^= 2; 01538 id_req = thread_child_id_request_entry_get(cur, (mle_msg->packet_src_address + 8)); 01539 mle_msg->packet_src_address[8] ^= 2; 01540 01541 if (!id_req) { 01542 return; 01543 } 01544 01545 /** 01546 * MLE attached Tree packet Mandatory TLV:s are validated at this function 01547 * - MLE_TYPE_TIMEOUT 01548 * - MLE_TYPE_MODE 01549 * - MLE_TYPE_LL_FRAME_COUNTER 01550 * - MLE_TYPE_TLV_REQUEST 01551 * - MLE_TYPE_VERSION 01552 * Optional: 01553 * - MLE_TYPE_ADDRESS_REGISTRATION 01554 * - MLE_TYPE_MLE_FRAME_COUNTER 01555 */ 01556 01557 if ((!mle_tlv_read_32_bit_tlv(MLE_TYPE_TIMEOUT, mle_msg->data_ptr, mle_msg->data_length, &id_req->timeout)) || 01558 (!mle_tlv_read_8_bit_tlv(MLE_TYPE_MODE, mle_msg->data_ptr, mle_msg->data_length, &id_req->mode)) || 01559 (!mle_tlv_read_16_bit_tlv(MLE_TYPE_VERSION, mle_msg->data_ptr, mle_msg->data_length, &id_req->version)) || 01560 (!mle_tlv_read_32_bit_tlv(MLE_TYPE_LL_FRAME_COUNTER, mle_msg->data_ptr, mle_msg->data_length, &id_req->frameCounter)) || 01561 (!mle_tlv_read_tlv(MLE_TYPE_TLV_REQUEST, mle_msg->data_ptr, mle_msg->data_length, &tlvRequest))) { 01562 thread_child_id_request_entry_remove(cur, id_req); 01563 return; 01564 } 01565 //If MLE MLE_TYPE_MLE_FRAME_COUNTER TLV is present then use it for validating further messages else use link layer frame counter 01566 if (!mle_tlv_read_32_bit_tlv(MLE_TYPE_MLE_FRAME_COUNTER, mle_msg->data_ptr, mle_msg->data_length, &id_req->mleFrameCounter)) { 01567 id_req->mleFrameCounter = id_req->frameCounter; 01568 } 01569 01570 t_ptr = tlvRequest.dataPtr; 01571 01572 for (uint8_t i = 0; i < tlvRequest.tlvLen; i++) { 01573 tlvType = *t_ptr++; 01574 if (tlvType == MLE_TYPE_ADDRESS16) { 01575 id_req->shortAddressReq = true; 01576 } else if (tlvType == MLE_TYPE_NETWORK_DATA) { 01577 id_req->networkDataReq = true; 01578 } else if (tlvType == MLE_TYPE_ROUTE) { 01579 id_req->routeReq = true; 01580 } 01581 } 01582 if (mle_tlv_read_tlv(MLE_TYPE_ADDRESS_REGISTRATION, mle_msg->data_ptr, mle_msg->data_length, &addressRegisteredTlv)) { 01583 uint8_t context; 01584 t_ptr = addressRegisteredTlv.dataPtr; 01585 context = *t_ptr++; 01586 if (context & 0x80) { 01587 context &= 0x0f; 01588 if (addressRegisteredTlv.tlvLen == 9 && (context == 0)) { 01589 memcpy(id_req->eiid, t_ptr, 8); 01590 } 01591 } else { 01592 t_ptr += 8; 01593 memcpy(id_req->eiid, t_ptr, 8); 01594 } 01595 } 01596 01597 01598 id_req->keyId = security_headers->KeyIndex; 01599 id_req->keySeq = common_read_32_bit(security_headers->Keysource); 01600 id_req->linkMargin = linkMargin; 01601 01602 id_req->active_timestamp = 0; 01603 id_req->request_active_config = false; 01604 if (!mle_tlv_read_64_bit_tlv(MLE_TYPE_ACTIVE_TIMESTAMP, mle_msg->data_ptr, mle_msg->data_length, &id_req->active_timestamp)) { 01605 id_req->request_active_config = true; 01606 } 01607 if (!mle_tlv_read_64_bit_tlv(MLE_TYPE_PENDING_TIMESTAMP, mle_msg->data_ptr, mle_msg->data_length, &id_req->pending_timestamp)) { 01608 id_req->pending_timestamp = 0; 01609 } 01610 01611 //Push Event to queue 01612 if (thread_bootstrap_child_id_request(cur) != 0) { 01613 thread_child_id_request_entry_remove(cur, id_req); 01614 } 01615 01616 break; 01617 } 01618 01619 case MLE_COMMAND_REQUEST:{ 01620 uint16_t shortAddress, version; 01621 mle_tlv_info_t addressRegisteredTlv, requestTlv, challengeTlv; 01622 uint8_t response_type = MLE_COMMAND_ACCEPT_AND_REQUEST; 01623 //Router attachment 01624 tr_info("Recv Router Link request"); 01625 01626 if (!thread_attach_active_router(cur)) { 01627 return; //Do respond until we are reed 01628 } 01629 01630 if (!mle_tlv_read_tlv(MLE_TYPE_CHALLENGE, mle_msg->data_ptr, mle_msg->data_length, &challengeTlv)) { 01631 return; 01632 } 01633 if (!mle_tlv_read_16_bit_tlv(MLE_TYPE_VERSION, mle_msg->data_ptr, mle_msg->data_length, &version)) { 01634 return; 01635 } 01636 if (!mle_tlv_read_tlv(MLE_TYPE_TLV_REQUEST, mle_msg->data_ptr, mle_msg->data_length, &requestTlv)) { 01637 /** 01638 * This cuold cause problem if any dummy coder add this to message 01639 * Validate is it REED or End device message link synch Request 01640 * - MLE_TYPE_SRC_ADDRESS 01641 * - MLE_TYPE_VERSION 01642 * - MLE_TYPE_CHALLENGE 01643 */ 01644 if (mle_tlv_read_16_bit_tlv(MLE_TYPE_SRC_ADDRESS, mle_msg->data_ptr, mle_msg->data_length, &shortAddress)) { 01645 //Correct TLV's lets response 01646 if (!thread_is_router_addr(shortAddress)) { 01647 if (leaderDataReceived && thread_info(cur)->thread_leader_data->partitionId == leaderData.partitionId) { 01648 //REED or end device send response 01649 thread_router_accept_to_endevice(cur, mle_msg, challengeTlv.dataPtr, challengeTlv.tlvLen); 01650 } else { 01651 tr_debug("Drop Link Request from REED/ED in a different partition."); 01652 // Do nothing... ignore. 01653 } 01654 } 01655 } 01656 return; 01657 } 01658 01659 entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false); 01660 01661 if (!mle_tlv_read_16_bit_tlv(MLE_TYPE_SRC_ADDRESS, mle_msg->data_ptr, mle_msg->data_length, &shortAddress)) { 01662 01663 /** 01664 * MLE Router Synch mandatory options are 01665 * - MLE_TYPE_VERSION 01666 * - MLE_TYPE_CHALLENGE 01667 * - MLE_TYPE_TLV_REQUEST 01668 * 01669 */ 01670 01671 if (entry_temp && entry_temp->handshakeReady) { 01672 mle_entry_timeout_refresh(entry_temp); 01673 thread_router_synch_accept_request_build(cur, mle_msg, entry_temp->short_adr, challengeTlv.dataPtr, challengeTlv.tlvLen, requestTlv.dataPtr, requestTlv.tlvLen); 01674 } 01675 } 01676 bool update_mac_mib = false; 01677 /** 01678 * MLE attached First packet Mandatory TLV:s are validated at this function 01679 * - MLE_TYPE_SRC_ADDRESS 01680 * - MLE_TYPE_CHALLENGE 01681 * - MLE_TYPE_LEADER_DATA 01682 * - MLE_TYPE_VERSION 01683 * - MLE_TYPE_TLV_REQUEST 01684 */ 01685 01686 //Read Leader Data and verify connectivity 01687 if (!leaderDataReceived) { 01688 return; 01689 } 01690 01691 //validate partition id 01692 if (thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) { 01693 tr_debug("Drop link request from wrong partition"); 01694 return; 01695 } 01696 01697 if (entry_temp) { 01698 /*remove from child list when becoming router*/ 01699 // Was this previously our child? If yes, update. 01700 if ((entry_temp->short_adr & THREAD_CHILD_MASK) && thread_router_addr_from_addr(entry_temp->short_adr) == cur->thread_info->routerShortAddress) { 01701 thread_dynamic_storage_child_info_clear(cur->id, entry_temp); 01702 protocol_6lowpan_release_short_link_address_from_neighcache(cur, entry_temp->short_adr); 01703 } 01704 update_mac_mib = true; 01705 entry_temp->short_adr = shortAddress; // short address refreshed 01706 01707 if (entry_temp->handshakeReady) { 01708 if (mle_tlv_read_tlv(MLE_TYPE_ADDRESS_REGISTRATION, mle_msg->data_ptr, mle_msg->data_length, &addressRegisteredTlv)) { 01709 if (thread_rfd_device(entry_temp->mode)) { 01710 thread_address_registration_tlv_parse(addressRegisteredTlv.dataPtr, addressRegisteredTlv.tlvLen, cur, entry_temp->short_adr, entry_temp->mac64); 01711 } 01712 } 01713 01714 mle_entry_timeout_refresh(entry_temp); 01715 if (!mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex) && update_mac_mib) { 01716 //GET 01717 mlme_get_t get_req; 01718 get_req.attr = macDeviceTable; 01719 get_req.attr_index = entry_temp->attribute_index; 01720 cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req); 01721 } 01722 response_type = MLE_COMMAND_ACCEPT; 01723 } 01724 response_type = MLE_COMMAND_ACCEPT; 01725 } 01726 01727 01728 bool accept_link = false; 01729 if (entry_temp) { 01730 // We know already so we can accept 01731 accept_link = true; 01732 } else if (addr_is_ipv6_multicast(mle_msg->packet_dst_address)) { 01733 if (thread_bootstrap_link_create_check(cur, shortAddress) && 01734 thread_bootstrap_link_create_allowed(cur, shortAddress, mle_msg->packet_src_address)) { 01735 // Multicast and we can respond to message 01736 accept_link = true; 01737 } 01738 } else if ( thread_bootstrap_link_create_check(cur, shortAddress) ) { 01739 // Unicast request and we should make link 01740 accept_link = true; 01741 } 01742 01743 if (accept_link) { 01744 if (!thread_is_router_addr(shortAddress)) { 01745 response_type = MLE_COMMAND_ACCEPT; 01746 } 01747 thread_router_accept_request_build(cur, mle_msg, shortAddress, challengeTlv.dataPtr, challengeTlv.tlvLen, response_type, rssiTLV, linkMargin); 01748 } 01749 01750 break; 01751 } 01752 01753 case MLE_COMMAND_ACCEPT_AND_REQUEST: { 01754 uint8_t linkMarginfronNeigh; 01755 uint16_t version, shortAddress; 01756 uint32_t llFrameCounter; 01757 mle_tlv_info_t requestTlv, challengeTlv; 01758 bool createNew; 01759 tr_info("Recv Router Accept & Request"); 01760 uint16_t messageId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length); 01761 01762 if (messageId == 0) { 01763 tr_debug("Not for me"); 01764 return; 01765 } 01766 01767 if (!addr_is_ipv6_multicast(mle_service_get_msg_destination_address_pointer(messageId))) { 01768 //Free Response only if it is unicast 01769 mle_service_msg_free(messageId); 01770 } 01771 01772 if ((!mle_tlv_read_tlv(MLE_TYPE_CHALLENGE, mle_msg->data_ptr, mle_msg->data_length, &challengeTlv)) || 01773 (!mle_tlv_read_16_bit_tlv(MLE_TYPE_VERSION, mle_msg->data_ptr, mle_msg->data_length, &version)) || 01774 (!mle_tlv_read_tlv(MLE_TYPE_TLV_REQUEST, mle_msg->data_ptr, mle_msg->data_length, &requestTlv)) || 01775 (!mle_tlv_read_8_bit_tlv(MLE_TYPE_RSSI, mle_msg->data_ptr, mle_msg->data_length, &linkMarginfronNeigh)) || 01776 (!mle_tlv_read_32_bit_tlv(MLE_TYPE_LL_FRAME_COUNTER, mle_msg->data_ptr, mle_msg->data_length, &llFrameCounter)) || 01777 (!mle_tlv_read_16_bit_tlv(MLE_TYPE_SRC_ADDRESS, mle_msg->data_ptr, mle_msg->data_length, &shortAddress))) { 01778 thread_link_reject_send(cur, mle_msg->packet_src_address); 01779 return; 01780 } 01781 01782 /* Call to determine whether or not we should create a new link */ 01783 createNew = thread_bootstrap_link_create_check(cur, shortAddress); 01784 01785 //Send Response 01786 entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, createNew); 01787 if (entry_temp) { 01788 01789 if (security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) { 01790 thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource)); 01791 } 01792 01793 entry_temp->threadNeighbor = true; 01794 entry_temp->short_adr = shortAddress; 01795 mac_helper_devicetable_set(entry_temp, cur, llFrameCounter, security_headers->KeyIndex); 01796 if (entry_temp->timeout_rx) { 01797 mle_entry_timeout_refresh(entry_temp); 01798 } else { 01799 mle_entry_timeout_update(entry_temp, THREAD_DEFAULT_LINK_LIFETIME); 01800 } 01801 01802 if (thread_is_router_addr(shortAddress)) { 01803 entry_temp->handshakeReady = 1; 01804 } 01805 01806 entry_temp->mode |= MLE_THREAD_REQ_FULL_DATA_SET; 01807 01808 thread_routing_update_link_margin(cur, entry_temp->short_adr, linkMargin, linkMarginfronNeigh); 01809 //Read Source address and Challenge 01810 mac_data_poll_protocol_poll_mode_decrement(cur); 01811 thread_router_accept_request_build(cur, mle_msg, entry_temp->short_adr, challengeTlv.dataPtr, challengeTlv.tlvLen, MLE_COMMAND_ACCEPT, rssiTLV, linkMargin); 01812 01813 blacklist_update(mle_msg->packet_src_address, true); 01814 } else { 01815 thread_link_reject_send(cur, mle_msg->packet_src_address); 01816 } 01817 01818 break; 01819 } 01820 01821 case MLE_COMMAND_CHILD_UPDATE_REQUEST: 01822 tr_info("Recv Router Child Update request"); 01823 { 01824 uint8_t mode; 01825 uint8_t status; 01826 uint32_t timeout = 0; 01827 mle_tlv_info_t addressRegisterTlv = {0}; 01828 mle_tlv_info_t challengeTlv = {0}; 01829 mle_tlv_info_t tlv_req = {0}; 01830 entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false); 01831 01832 if (mle_tlv_read_8_bit_tlv(MLE_TYPE_STATUS, mle_msg->data_ptr, mle_msg->data_length, &status)) { 01833 if (1 == status && thread_check_is_this_my_parent(cur, entry_temp)) { 01834 tr_debug("parent has removed REED"); 01835 thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL); 01836 } 01837 return; 01838 } 01839 01840 mle_tlv_read_tlv(MLE_TYPE_CHALLENGE, mle_msg->data_ptr, mle_msg->data_length, &challengeTlv); 01841 01842 if (!entry_temp) { 01843 tr_debug("Not Neighbor anymore"); 01844 thread_host_bootstrap_child_update_negative_response(cur, mle_msg->packet_src_address, &challengeTlv); 01845 return; 01846 } 01847 01848 if (!mle_tlv_read_8_bit_tlv(MLE_TYPE_MODE, mle_msg->data_ptr, mle_msg->data_length, &mode)) { 01849 tr_debug("No Mode"); 01850 return; 01851 } 01852 01853 //Keep alive updated 01854 entry_temp->ttl = entry_temp->timeout_rx; 01855 entry_temp->last_contact_time = protocol_core_monotonic_time; 01856 entry_temp->mode = mode; 01857 01858 addressRegisterTlv.tlvType = MLE_TYPE_UNASSIGNED; 01859 mle_tlv_read_tlv(MLE_TYPE_ADDRESS_REGISTRATION, mle_msg->data_ptr, mle_msg->data_length, &addressRegisterTlv); 01860 01861 mle_tlv_read_tlv(MLE_TYPE_TLV_REQUEST, mle_msg->data_ptr, mle_msg->data_length, &tlv_req); 01862 01863 if (addressRegisterTlv.tlvType == MLE_TYPE_ADDRESS_REGISTRATION && 01864 thread_rfd_device(entry_temp->mode)) { 01865 01866 tr_debug("Register child address"); 01867 thread_address_registration_tlv_parse(addressRegisterTlv.dataPtr, addressRegisterTlv.tlvLen, cur, entry_temp->short_adr, entry_temp->mac64); 01868 } 01869 01870 if (mle_tlv_read_32_bit_tlv(MLE_TYPE_TIMEOUT, mle_msg->data_ptr, mle_msg->data_length, &timeout)) { 01871 01872 tr_debug("Setting child timeout, value=%"PRIu32, timeout); 01873 entry_temp->holdTime = 90; 01874 mle_entry_timeout_update(entry_temp, timeout); 01875 } 01876 if (!leaderDataReceived) { 01877 tr_debug("Child synch req"); 01878 } 01879 01880 tr_debug("Keep-Alive -->Respond Child"); 01881 //Response 01882 thread_child_update_response(cur, mle_msg->packet_src_address, mode, entry_temp->short_adr, timeout, &addressRegisterTlv, &tlv_req, &challengeTlv); 01883 01884 } 01885 break; 01886 01887 case MLE_COMMAND_UPDATE: 01888 tr_info("Recv Router Update"); 01889 break; 01890 01891 case MLE_COMMAND_UPDATE_REQUEST: 01892 tr_info("Recv Router update Request"); 01893 break; 01894 01895 case MLE_COMMAND_DATA_REQUEST: { 01896 mle_tlv_info_t requestTlv; 01897 tr_info("Recv Router Data Request"); 01898 entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false); 01899 if (!entry_temp || !mle_tlv_read_tlv(MLE_TYPE_TLV_REQUEST, mle_msg->data_ptr, mle_msg->data_length, &requestTlv)) { 01900 return; 01901 } 01902 mle_build_and_send_data_response_msg(cur, mle_msg->packet_src_address, mle_msg->data_ptr, mle_msg->data_length, &requestTlv, entry_temp->mode); 01903 } 01904 break; 01905 default: 01906 tr_warn("Recv Router UNKNOWN message %d", mle_msg->message_type); 01907 break; 01908 01909 } 01910 } 01911 01912 static int8_t thread_router_bootstrap_synch_request_send(protocol_interface_info_entry_t *cur) 01913 { 01914 uint8_t req_tlv[3]; 01915 mle_message_timeout_params_t timeout; 01916 uint32_t keySequence; 01917 uint16_t buf_id = mle_service_msg_allocate(cur->id, 32, true, MLE_COMMAND_REQUEST); 01918 if (buf_id == 0) { 01919 return -1; 01920 } 01921 thread_management_get_current_keysequence(cur->id, &keySequence); 01922 mle_service_msg_update_security_params(buf_id, 5, 2, keySequence); 01923 mle_service_set_msg_destination_address(buf_id, ADDR_LINK_LOCAL_ALL_ROUTERS); 01924 req_tlv[0] = MLE_TYPE_ADDRESS16; 01925 req_tlv[1] = MLE_TYPE_ROUTE; 01926 uint8_t *ptr = mle_service_get_data_pointer(buf_id); 01927 ptr = mle_tlv_write_version(ptr, cur->thread_info->version); 01928 ptr = mle_tlv_req_tlv(ptr, req_tlv, 2); 01929 if (mle_service_update_length_by_ptr(buf_id,ptr)!= 0) { 01930 tr_debug("Buffer overflow at message write"); 01931 } 01932 01933 timeout.retrans_max = THREAD_REQUEST_MAX_RETRY_CNT; 01934 timeout.timeout_init = 1; 01935 timeout.timeout_max = 3; 01936 timeout.delay = MLE_NO_DELAY; 01937 01938 mle_service_set_packet_callback(buf_id, thread_device_synch_timeout); 01939 mle_service_set_msg_timeout_parameters(buf_id, &timeout); 01940 mle_service_send_message(buf_id); 01941 return 0; 01942 } 01943 01944 static int8_t thread_router_synch_new_router(protocol_interface_info_entry_t *cur, const uint8_t *destAddress) 01945 { 01946 mle_message_timeout_params_t timeout; 01947 uint32_t keySequence; 01948 if (thread_info(cur)) { 01949 if (!thread_info(cur)->thread_leader_data) { 01950 return -1; 01951 } 01952 } 01953 01954 uint16_t bufId = mle_service_msg_allocate(cur->id, 64, true, MLE_COMMAND_REQUEST); 01955 01956 if (bufId == 0) { 01957 return -1; 01958 } 01959 uint8_t req_tlv = MLE_TYPE_RSSI; 01960 01961 thread_management_get_current_keysequence(cur->id, &keySequence); 01962 mle_service_msg_update_security_params(bufId, 5, 2, keySequence); 01963 01964 mle_service_set_msg_destination_address(bufId, destAddress); 01965 01966 01967 uint8_t *ptr = mle_service_get_data_pointer(bufId); 01968 ptr = mle_tlv_write_version(ptr, cur->thread_info->version); 01969 ptr = thread_leader_data_tlv_write(ptr, cur); 01970 ptr = mle_general_write_source_address(ptr, cur); 01971 ptr = mle_tlv_req_tlv(ptr, &req_tlv, 1); 01972 01973 if (!addr_is_ipv6_multicast(destAddress)) { 01974 timeout.retrans_max = 2; 01975 timeout.timeout_init = 2; 01976 timeout.timeout_max = 3; 01977 timeout.delay = MLE_STANDARD_RESPONSE_DELAY; 01978 } else { 01979 // Multicasts need transaction timer 01980 timeout.retrans_max = 1; 01981 timeout.timeout_init = 2; 01982 timeout.timeout_max = 3; 01983 timeout.delay = 0; 01984 } 01985 mle_service_set_packet_callback(bufId, thread_link_request_timeout); 01986 mle_service_set_msg_timeout_parameters(bufId, &timeout); 01987 01988 if (mle_service_update_length_by_ptr(bufId,ptr)!= 0) { 01989 tr_debug("Buffer overflow at message write"); 01990 } 01991 01992 01993 mle_service_send_message(bufId); 01994 return 0; 01995 } 01996 01997 int thread_router_bootstrap_link_synch_start(protocol_interface_info_entry_t *cur) 01998 { 01999 //Send Link Request for 02000 if (thread_router_bootstrap_synch_request_send(cur) == 0) { 02001 //SET Router synch receiver handler 02002 mle_service_interface_receiver_handler_update(cur->id, thread_router_synch_receive_cb); 02003 cur->nwk_bootstrap_state = ER_MLE_SYNCH; 02004 return 0; 02005 } 02006 return -1; 02007 } 02008 02009 bool thread_router_bootstrap_router_downgrade(protocol_interface_info_entry_t *cur) 02010 { 02011 uint8_t activeRouterCount; 02012 uint8_t goodLinks; 02013 02014 if (cur->thread_info->thread_attached_state != THREAD_STATE_CONNECTED_ROUTER) { 02015 return false; 02016 } 02017 02018 // if we are commissioner border router we have registered our address and cant upgrade or downgrade 02019 if (cur->thread_info->registered_commissioner.commissioner_valid && 02020 addr_get_entry(cur,cur->thread_info->registered_commissioner.border_router_address) ) { 02021 return false; 02022 } 02023 02024 // spec: Not be the Leader 02025 if (cur->thread_info->leader_private_data) { 02026 if (!thread_router_bootstrap_routing_allowed(cur)) { 02027 tr_debug("Cannot be leader anymore"); 02028 // Settings have changed, cannot be leader anymore 02029 thread_bootstrap_reset_restart(cur->id); 02030 } 02031 // Leader can not downgrade 02032 return false; 02033 } 02034 02035 if (!thread_router_bootstrap_routing_allowed(cur)) { 02036 return true; 02037 } 02038 02039 //spec: If the number of active Routers on the network exceeds ROUTER_DOWNGRADE_THRESHOLD 02040 activeRouterCount = thread_routing_count_active_routers(&cur->thread_info->routing); 02041 if (activeRouterCount <= cur->thread_info->routerSelectParameters.routerDowngradeThresHold) { 02042 return false; 02043 } 02044 02045 uint_fast8_t asGood; 02046 goodLinks = thread_routing_count_neighbours_for_downgrade(&cur->thread_info->routing, &asGood); 02047 02048 //spec: Have at least MIN_DOWNGRADE_NEIGHBORS neighbors in set M. 02049 if (goodLinks < MIN_DOWNGRADE_NEIGHBORS) { 02050 return false; 02051 } 02052 02053 //spec: Have at least one neighbor that has as good or better quality links to all Routers in M. 02054 if (asGood == 0) { 02055 return false; 02056 } 02057 02058 //spec: Not be the sole Border Router for a particular Provisioning Domain 02059 if (!ns_list_is_empty(&cur->thread_info->localServerDataBase.prefix_list)) { 02060 return false; 02061 } 02062 02063 uint16_t child_count = thread_router_bootstrap_child_count_get(cur); 02064 //Cant downgrade if child count is larger than 3 times exceed routers 02065 if (child_count > (3 * (activeRouterCount - cur->thread_info->routerSelectParameters.routerDowngradeThresHold))) { 02066 return false; 02067 } 02068 tr_info("Reed downgrade:ChildCount %u Active Routers %u good links %u downgrade threshold %u", child_count, activeRouterCount, goodLinks, cur->thread_info->routerSelectParameters.routerDowngradeThresHold); 02069 02070 return true; 02071 } 02072 02073 bool thread_router_bootstrap_reed_upgrade(protocol_interface_info_entry_t *cur) 02074 { 02075 uint8_t activeRouterCount; 02076 02077 if (!thread_router_bootstrap_routing_allowed(cur)) { 02078 return false; 02079 } 02080 02081 if (thread_am_router(cur)) { 02082 return false; 02083 } 02084 02085 // if we are commissioner border router we have registered our address and cant upgrade or downgrade 02086 if (cur->thread_info->registered_commissioner.commissioner_valid && 02087 addr_get_entry(cur,cur->thread_info->registered_commissioner.border_router_address) ) { 02088 return false; 02089 } 02090 02091 if (!cur->thread_info->routing.router_id_sequence_valid) { 02092 // In case routing information is not up-to-date yet... 02093 return false; 02094 } 02095 02096 activeRouterCount = thread_routing_count_active_routers(&cur->thread_info->routing); 02097 02098 if (activeRouterCount >= cur->thread_info->routerSelectParameters.routerUpgradeThresHold) { 02099 return false; 02100 } 02101 tr_info("Reed Upgrade:Active Routers %u upgrade threshold %u", activeRouterCount, cur->thread_info->routerSelectParameters.routerUpgradeThresHold); 02102 02103 return true; 02104 } 02105 02106 void thread_router_bootstrap_child_id_reject(protocol_interface_info_entry_t *cur) 02107 { 02108 thread_pending_child_id_req_t *req; 02109 req = thread_child_id_request_entry_get_from_the_list(cur); 02110 while (req) { 02111 tr_debug("Remove entry from list"); 02112 //Remove entry from list 02113 mle_class_remove_neighbour(cur->id, req->euid64, ADDR_802_15_4_LONG ); 02114 02115 ns_dyn_mem_free(req); 02116 req = thread_child_id_request_entry_get_from_the_list(cur); 02117 } 02118 } 02119 02120 void thread_router_bootstrap_active_router_attach(protocol_interface_info_entry_t *cur) 02121 { 02122 arm_nwk_6lowpan_thread_test_print_routing_database(cur->id); 02123 uint16_t address16 = mac_helper_mac16_address_get(cur); 02124 cur->thread_info->thread_attached_state = THREAD_STATE_CONNECTED_ROUTER; 02125 02126 if (cur->thread_info->thread_leader_data->leaderRouterId == address16 && 02127 !cur->thread_info->leader_private_data ) { 02128 // Error we are set up as leader but no private data 02129 tr_error("Leader setup error"); 02130 } 02131 cur->lowpan_info |= INTERFACE_NWK_ROUTER_DEVICE; 02132 thread_routing_activate(&cur->thread_info->routing); 02133 thread_router_synch_new_router(cur, ADDR_LINK_LOCAL_ALL_ROUTERS); 02134 mle_class_mode_set(cur->id, MLE_CLASS_ROUTER); 02135 thread_bootstrap_ready(cur); 02136 thread_bootstrap_network_prefixes_process(cur); 02137 thread_nd_service_activate(cur->id); 02138 thread_router_bootstrap_mle_advertise(cur); 02139 thread_nvm_store_link_info_file_write(cur); 02140 } 02141 02142 static int thread_validate_own_routeid_from_new_mask(const uint8_t *master_router_id_mask, uint8_t router_id) 02143 { 02144 int ret_val = -1; 02145 if (bit_test(master_router_id_mask, router_id)) { 02146 ret_val = 0; 02147 } 02148 return ret_val; 02149 } 02150 02151 int thread_router_bootstrap_route_tlv_push(protocol_interface_info_entry_t *cur, uint8_t *route_tlv, uint8_t route_len, uint8_t linkMargin, mle_neigh_table_entry_t *entry) 02152 { 02153 (void) route_len; 02154 02155 uint8_t route_id_seq; 02156 const uint8_t *router_id_mask, *route_data; 02157 02158 route_id_seq = *route_tlv++; 02159 router_id_mask = route_tlv; 02160 route_tlv += 8; 02161 route_data = route_tlv; 02162 uint16_t mac16 = mac_helper_mac16_address_get(cur); 02163 02164 if (!thread_is_router_addr(entry->short_adr)) { 02165 // Received route tlv from non router ignore 02166 tr_info("drop route Processing from end device %x", entry->short_adr); 02167 return 0; 02168 } 02169 02170 if (thread_i_am_router(cur)) { 02171 thread_routing_info_t *routing = &cur->thread_info->routing; 02172 if (routing->router_id_sequence_valid && common_serial_number_greater_8(route_id_seq, routing->router_id_sequence)) { 02173 thread_routing_leader_connection_validate(cur->thread_info,routing->networkFragmentationTimer); 02174 routing->networkFragmentationTimer = 0; 02175 if (thread_validate_own_routeid_from_new_mask(router_id_mask, thread_router_id_from_addr(mac16)) != 0) { 02176 02177 tr_debug("RouterID not valid any More"); 02178 thread_bootstrap_connection_error(cur->id, CON_ERROR_NETWORK_KICK, NULL); 02179 return 0; 02180 } 02181 } 02182 } else if (!thread_info(cur)->thread_endnode_parent || 02183 thread_info(cur)->thread_endnode_parent->shortAddress != entry->short_adr ) { 02184 return 0; 02185 } 02186 02187 /* XXX Is short_src_adr ever reset? Is it undefined if info not in msg? */ 02188 /* Don't add routing link if MLE link is NOT bi-directional (i.e. we can only hear) */ 02189 if (entry->handshakeReady) { 02190 thread_routing_add_link(cur, entry->short_adr, linkMargin, route_id_seq, router_id_mask, route_data, false); 02191 } 02192 02193 return 0; 02194 } 02195 02196 02197 static void thread_bootstrap_client_router_id_release_cb(int8_t interface_id, int8_t status, uint16_t router_rloc, const uint8_t router_mask_ptr[9]) 02198 { 02199 protocol_interface_info_entry_t *cur; 02200 (void) status; 02201 (void)router_mask_ptr; 02202 (void)router_rloc; 02203 cur = protocol_stack_interface_info_get_by_id(interface_id); 02204 tr_debug("RouterID ReleaseCB"); 02205 if (!cur) { 02206 return; 02207 } 02208 02209 if (!cur->thread_info->releaseRouterId) { 02210 return; 02211 } 02212 cur->thread_info->releaseRouterId = false; 02213 02214 thread_bootstrap_router_id_release_ready(cur); 02215 return; 02216 02217 } 02218 static uint32_t thread_reed_timeout_calculate(thread_router_select_t *routerSelect) 02219 { 02220 return randLIB_get_random_in_range(routerSelect->reedAdvertisementInterval,(routerSelect->reedAdvertisementInterval)+(routerSelect->reedAdvertisementJitterInterval)); 02221 } 02222 02223 02224 static int thread_reed_advertise (protocol_interface_info_entry_t *cur) 02225 { 02226 uint32_t keySequence; 02227 tr_debug("MLE REED ADVERTISEMENT STARTED"); 02228 struct link_configuration *linkConfiguration; 02229 linkConfiguration = thread_joiner_application_get_config(cur->id); 02230 if (!linkConfiguration) { 02231 return -1; 02232 } 02233 02234 if (!thread_info(cur)) { 02235 return -1; 02236 } 02237 02238 uint16_t bufId = mle_service_msg_allocate(cur->id, 16, false, MLE_COMMAND_ADVERTISEMENT); 02239 if (bufId == 0) { 02240 return -1; 02241 } 02242 02243 thread_management_get_current_keysequence(cur->id, &keySequence); 02244 mle_service_msg_update_security_params(bufId, 5, 2, keySequence); 02245 02246 uint8_t *ptr = mle_service_get_data_pointer(bufId); 02247 02248 /*Add Leader Data & Source Address TLVs */ 02249 ptr = thread_leader_data_tlv_write(ptr, cur); 02250 ptr = mle_general_write_source_address(ptr, cur); 02251 if (mle_service_update_length_by_ptr(bufId,ptr)!= 0) { 02252 tr_debug("Buffer overflow at message write"); 02253 } 02254 02255 mle_service_set_msg_destination_address(bufId, ADDR_LINK_LOCAL_ALL_NODES); 02256 mle_service_send_message(bufId); 02257 return 0; 02258 } 02259 02260 static void thread_reed_advertisements_cb(void* arg) 02261 { 02262 if(!arg) 02263 return; 02264 protocol_interface_info_entry_t *cur = arg; 02265 02266 cur->thread_info->routerSelectParameters.reedAdvertisementTimeout = NULL; 02267 if (cur->thread_info->thread_attached_state == THREAD_STATE_CONNECTED && 02268 cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_ROUTER){ 02269 thread_reed_advertise(cur); 02270 cur->thread_info->routerSelectParameters.reedAdvertisementTimeout = eventOS_timeout_ms(thread_reed_advertisements_cb, thread_reed_timeout_calculate(&cur->thread_info->routerSelectParameters) * 1000, cur); 02271 } 02272 } 02273 02274 void thread_router_bootstrap_reed_advertisements_start(protocol_interface_info_entry_t *cur) 02275 { 02276 uint32_t timeout = THREAD_REED_ADVERTISEMENT_DELAY; 02277 if(!cur) 02278 return; 02279 eventOS_timeout_cancel(cur->thread_info->routerSelectParameters.reedAdvertisementTimeout); 02280 cur->thread_info->routerSelectParameters.reedAdvertisementTimeout = NULL; 02281 02282 cur->thread_info->reedJitterTimer = thread_router_bootstrap_random_upgrade_jitter(); 02283 02284 if (!thread_is_connected(cur)){ 02285 return; 02286 } 02287 if (cur->thread_info->releaseRouterId || 02288 thread_router_bootstrap_child_count_get(cur) == 0) { 02289 // If we dont have any children or are are downgrading send REED advertisement immediately 02290 timeout = 1; 02291 } 02292 cur->thread_info->routerSelectParameters.reedAdvertisementTimeout = eventOS_timeout_ms(thread_reed_advertisements_cb,timeout, cur); 02293 } 02294 02295 void thread_router_bootstrap_router_id_release(protocol_interface_info_entry_t *cur) 02296 { 02297 tr_debug("Router ID Release"); 02298 if (thread_management_client_router_id_release(cur->id, cur->mac, cur->thread_info->routerShortAddress, thread_bootstrap_client_router_id_release_cb) == 0) { 02299 // Release message sent succesfully 02300 cur->thread_info->routerShortAddress = 0xfffe; 02301 cur->thread_info->releaseRouterId = true; 02302 } 02303 } 02304 02305 uint32_t thread_router_bootstrap_random_upgrade_jitter() 02306 { 02307 if (thread_router_selection_jitter <= 2) { 02308 return 1; 02309 } 02310 return randLIB_get_random_in_range(2,thread_router_selection_jitter); 02311 } 02312 02313 void thread_router_bootstrap_timer(protocol_interface_info_entry_t *cur, uint32_t ticks) 02314 { 02315 thread_info_t *thread_info = cur->thread_info; 02316 02317 if (thread_am_host(cur)) { 02318 return; 02319 } 02320 02321 //Do we have a childs and we are REED state 02322 if (cur->thread_info->thread_attached_state == THREAD_STATE_CONNECTED && thread_router_bootstrap_child_count_get(cur)) { 02323 tr_debug("Trig quick router ID request"); 02324 thread_bootstrap_attched_upgrade_reed(cur); 02325 return; 02326 } 02327 02328 if (thread_info->reedJitterTimer > ticks) { 02329 // Reed status is checked every random jitter values 02330 thread_info->reedJitterTimer -= ticks; 02331 } else { 02332 thread_info->reedJitterTimer = thread_router_bootstrap_random_upgrade_jitter(); 02333 if (thread_router_bootstrap_reed_upgrade(cur)) { 02334 //Check UpGrade possibility 02335 tr_debug("REED Upgrade to router"); 02336 thread_bootstrap_attched_upgrade_reed(cur); 02337 } 02338 if (thread_router_bootstrap_router_downgrade(cur)) { 02339 tr_debug("Router downgrade to REED"); 02340 thread_bootstrap_attached_downgrade_router(cur); 02341 } 02342 } 02343 02344 if (!thread_info->leader_private_data && thread_info->thread_attached_state == THREAD_STATE_CONNECTED_ROUTER) { 02345 // Non leader router checks 02346 if (thread_info->routing.activated) { 02347 if (thread_info->routing.networkFragmentationTimer++ >= thread_info->routing.networkIdTimeout) { 02348 tr_debug("Leader Connection Lost"); 02349 thread_bootstrap_connection_error(cur->id, CON_ERROR_NETWORK_REATTACH, NULL); 02350 } 02351 } else { 02352 tr_debug("Routing Disabled?"); 02353 } 02354 } 02355 02356 if (thread_info->proactive_an_timer) { 02357 if (thread_info->proactive_an_timer > ticks) { 02358 thread_info->proactive_an_timer -= ticks; 02359 } else { 02360 thread_send_proactive_an(cur); 02361 thread_info->proactive_an_timer = 0; 02362 } 02363 } 02364 02365 thread_leader_service_timer(cur,ticks); 02366 return; 02367 } 02368 02369 void thread_router_bootstrap_advertiment_analyze(protocol_interface_info_entry_t *cur, uint8_t *src_address, mle_neigh_table_entry_t *entry_temp, uint16_t shortAddress) 02370 { 02371 if (entry_temp) { 02372 entry_temp->threadNeighbor = true; 02373 02374 if (entry_temp->timeout_rx == 0 || thread_is_router_addr(shortAddress)) { 02375 entry_temp->timeout_rx = THREAD_DEFAULT_LINK_LIFETIME / MLE_TIMER_TICKS_SECONDS; 02376 entry_temp->timeout_rx++; 02377 } 02378 02379 if (thread_is_router_addr(shortAddress)) { 02380 //Update MAC Security PIB table by get & set Operation 02381 mlme_get_t get_req; 02382 get_req.attr = macDeviceTable; 02383 get_req.attr_index = entry_temp->attribute_index; 02384 cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req); 02385 entry_temp->ttl = entry_temp->timeout_rx; 02386 } 02387 } else { 02388 // 02389 if (!thread_attach_active_router(cur)) { 02390 // We are not router 02391 return; 02392 } 02393 if (!thread_is_router_addr(shortAddress)) { 02394 // Reed advertisement 02395 return; 02396 } 02397 if (thread_bootstrap_link_create_check(cur, shortAddress) && 02398 thread_bootstrap_link_create_allowed(cur, shortAddress, src_address)) { 02399 //Challenge new router neighbor 02400 tr_debug("Synch new neighbor"); 02401 thread_router_synch_new_router(cur, src_address); 02402 } 02403 } 02404 } 02405 static void thread_router_bootstrap_dhcp_server_any_cast_address_update(protocol_interface_info_entry_t *cur, uint16_t anycastAddress) 02406 { 02407 uint8_t ipv6_address[16]; 02408 02409 thread_addr_write_mesh_local_16(ipv6_address, anycastAddress, cur->thread_info); 02410 tr_debug("generate DHCP anycast address %s", trace_ipv6(ipv6_address)); 02411 addr_add(cur, ipv6_address, 124, ADDR_SOURCE_THREAD_ALOC, 0xffffffff, 0, true); 02412 } 02413 02414 static void thread_bootstrap_dhcp_anycast_address_generate(protocol_interface_info_entry_t *cur) 02415 { 02416 uint8_t ipv6_address[16]; 02417 thread_addr_write_mesh_local_16(ipv6_address, 0xfc00, cur->thread_info); 02418 addr_delete_matching(cur,ipv6_address,124,ADDR_SOURCE_THREAD_ALOC); 02419 02420 ns_list_foreach(thread_network_data_prefix_cache_entry_t, curPrefix, &cur->thread_info->networkDataStorage.localPrefixList) { 02421 // Go through all prefixes 02422 ns_list_foreach(thread_network_server_data_entry_t, curBorderRouter, &curPrefix->borderRouterList) { 02423 if (curBorderRouter->P_dhcp && 02424 curBorderRouter->routerID == cur->mac_parameters->mac_short_address) { 02425 // We host this dhcp service we must add anycast address 02426 ns_list_foreach(thread_network_data_context_entry_t, curRoute, &curPrefix->contextList) { 02427 // Search what is the context id for this prefix 02428 uint16_t anycastAddress = 0xfc00; 02429 anycastAddress |= curRoute->cid; 02430 thread_router_bootstrap_dhcp_server_any_cast_address_update(cur, anycastAddress); 02431 } 02432 } 02433 } 02434 } 02435 } 02436 02437 static void thread_bootstrap_service_anycast_address_generate(protocol_interface_info_entry_t *cur) 02438 { 02439 uint8_t ipv6_address[16]; 02440 02441 // Delete old address 02442 thread_addr_write_mesh_local_16(ipv6_address, 0xfc10, cur->thread_info); 02443 addr_delete_matching(cur,ipv6_address,124,ADDR_SOURCE_THREAD_ALOC); 02444 02445 ns_list_foreach(thread_network_data_service_cache_entry_t, curService, &cur->thread_info->networkDataStorage.service_list) { 02446 // Go through all prefixes 02447 ns_list_foreach(thread_network_data_service_server_entry_t, curServiceServer, &curService->server_list) { 02448 if (curServiceServer->router_id == cur->mac_parameters->mac_short_address) { 02449 // We host this service we must add anycast address 02450 // Search what is the context id for this prefix 02451 thread_addr_write_mesh_local_16(ipv6_address, 0xfc10 | curService->S_id, cur->thread_info); 02452 tr_debug("generate Service anycast address %s", trace_ipv6(ipv6_address)); 02453 addr_add(cur, ipv6_address, 124, ADDR_SOURCE_THREAD_ALOC/*?*/, 0xffffffff, 0, true); 02454 } 02455 } 02456 } 02457 } 02458 02459 02460 static void thread_router_bootstrap_commissioner_aloc_generate(protocol_interface_info_entry_t *cur) 02461 { 02462 uint8_t commissioner_anycast[16]; 02463 02464 // Delete old address 02465 thread_addr_write_mesh_local_16(commissioner_anycast, 0xfc30 + (cur->thread_info->registered_commissioner.session_id % 8), cur->thread_info); 02466 addr_delete_matching(cur,commissioner_anycast,125,ADDR_SOURCE_THREAD_ALOC); 02467 02468 if (!cur->thread_info->registered_commissioner.commissioner_valid) { 02469 // No commissioner available 02470 return; 02471 } 02472 02473 if (!addr_get_entry(cur,cur->thread_info->registered_commissioner.border_router_address) ) { 02474 // Not our address 02475 return; 02476 } 02477 // Add commissioning border router address 02478 tr_debug("generate commissioner anycast address %s", trace_ipv6(commissioner_anycast)); 02479 addr_add(cur,commissioner_anycast,64,ADDR_SOURCE_THREAD_ALOC,0xffffffff,0,true); 02480 } 02481 02482 void thread_router_bootstrap_anycast_address_register(protocol_interface_info_entry_t *cur) 02483 { 02484 uint8_t leader_anycast_address[16]; 02485 02486 tr_debug("Register anycast address:"); 02487 02488 // Generate leader ALOC address 02489 thread_addr_write_mesh_local_16(leader_anycast_address, 0xfc00, cur->thread_info); 02490 02491 if (cur->thread_info->leader_private_data) { 02492 tr_debug("Register leader anycast address: %s", trace_ipv6(leader_anycast_address)); 02493 addr_add(cur, leader_anycast_address, 128, ADDR_SOURCE_UNKNOWN, 0xffffffff, 0, true); 02494 } else { 02495 // Delete Leader ALOC if ml prefix was changed address Source is the defining rule 02496 addr_delete_matching(cur,leader_anycast_address,128,ADDR_SOURCE_UNKNOWN); 02497 02498 } 02499 thread_bootstrap_dhcp_anycast_address_generate(cur); 02500 thread_bootstrap_service_anycast_address_generate(cur); 02501 thread_router_bootstrap_commissioner_aloc_generate(cur); 02502 thread_extension_aloc_generate(cur); 02503 } 02504 02505 static int thread_router_bootstrap_network_data_propagation(protocol_interface_info_entry_t *cur, uint8_t *childUnicastAddress, bool fullList) 02506 { 02507 uint8_t *payload_ptr; 02508 uint16_t payload_size = 16 + 4 + 20 + 4; //Version 4 bytes and Source address 4 bytes 02509 struct link_configuration *linkConfiguration; 02510 linkConfiguration = thread_joiner_application_get_config(cur->id); 02511 if (!linkConfiguration) { 02512 return -1; 02513 } 02514 02515 if (!thread_info(cur)) { 02516 return -1; 02517 } 02518 02519 payload_size += 2 + thread_network_data_tlv_size(cur, fullList); 02520 payload_size += thread_pending_timestamp_tlv_size(cur); 02521 02522 mle_message_timeout_params_t timeout; 02523 uint16_t buf_id = mle_service_msg_allocate(cur->id, payload_size, false, MLE_COMMAND_DATA_RESPONSE); 02524 if (buf_id == 0) { 02525 return -1; 02526 } 02527 02528 tr_debug("Send MLE data response network data changed"); 02529 payload_ptr = mle_service_get_data_pointer(buf_id); 02530 uint8_t *address_ptr = mle_service_get_msg_destination_address_pointer(buf_id); 02531 02532 /* Send to ULA16 of DATA_REQUEST originator. */ 02533 /* Current_gp_prefix should have ULA prefix in */ 02534 if (childUnicastAddress) { 02535 memcpy(address_ptr, childUnicastAddress, 16); 02536 } else { 02537 memcpy(address_ptr, ADDR_LINK_LOCAL_ALL_NODES, 16); 02538 } 02539 02540 /*Add Leader Data & Network Data */ 02541 payload_ptr = thread_leader_data_tlv_write(payload_ptr, cur); 02542 payload_ptr = thread_network_data_tlv_write(cur, payload_ptr, fullList); 02543 02544 payload_ptr = thread_active_timestamp_write(cur, payload_ptr); 02545 payload_ptr = thread_pending_timestamp_write(cur, payload_ptr); 02546 payload_ptr = mle_general_write_source_address(payload_ptr, cur); 02547 02548 if (mle_service_update_length_by_ptr(buf_id,payload_ptr)!= 0) { 02549 tr_debug("Buffer overflow at message write"); 02550 } 02551 timeout.retrans_max = 0; 02552 timeout.timeout_init = 0; 02553 timeout.timeout_max = 0; 02554 timeout.delay = MLE_HALF_SECOND_MAX_DELAY; 02555 mle_service_set_msg_timeout_parameters(buf_id, &timeout); 02556 //Set Security 02557 uint32_t keySequence; 02558 thread_management_get_current_keysequence(cur->id, &keySequence); 02559 mle_service_msg_update_security_params(buf_id, 5, 2, keySequence); 02560 02561 mle_service_send_message(buf_id); 02562 return 0; 02563 02564 } 02565 02566 static void thread_router_bootstrap_network_data_push_to_sleep_child(protocol_interface_info_entry_t *cur, bool stableDataUpdate) 02567 { 02568 uint8_t childLinkLocalAddress[16]; 02569 mle_neigh_table_list_t *mle_table = mle_class_active_list_get(cur->id); 02570 memcpy(childLinkLocalAddress, ADDR_LINK_LOCAL_PREFIX, 8); 02571 ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_table) { 02572 if (cur_entry->threadNeighbor) { 02573 if (!(cur_entry->mode & MLE_RX_ON_IDLE)) { 02574 memcpy(&childLinkLocalAddress[8], cur_entry->mac64, 8); 02575 childLinkLocalAddress[8] ^= 2; 02576 if (cur_entry->mode & MLE_THREAD_REQ_FULL_DATA_SET) { 02577 thread_router_bootstrap_network_data_propagation(cur, childLinkLocalAddress, true); 02578 } else { 02579 if (stableDataUpdate) { 02580 thread_router_bootstrap_network_data_propagation(cur, childLinkLocalAddress, false); 02581 } 02582 } 02583 } 02584 } 02585 } 02586 } 02587 02588 void thread_router_bootstrap_network_data_distribute(protocol_interface_info_entry_t *cur) 02589 { 02590 if (!thread_i_am_router(cur)) { 02591 return; 02592 } 02593 tr_debug("Propagate New Network Data"); 02594 thread_router_bootstrap_network_data_propagation(cur, NULL, true); 02595 thread_router_bootstrap_network_data_push_to_sleep_child(cur, cur->thread_info->networkDataStorage.stableUpdatePushed); 02596 } 02597 02598 bool thread_router_bootstrap_routing_allowed(struct protocol_interface_info_entry *cur) 02599 { 02600 link_configuration_s *link_conf_ptr = thread_management_configuration_get(cur->id); 02601 02602 if (!link_conf_ptr) { 02603 return true; 02604 } 02605 02606 return !(!thread_extension_version_check(cur->thread_info->version) && !(link_conf_ptr->securityPolicy & SECURITY_POLICY_ALL_ROUTERS_JOIN_ALLOWED)); 02607 } 02608 02609 void thread_router_bootstrap_address_change_notify_send(protocol_interface_info_entry_t *cur) 02610 { 02611 thread_info(cur)->proactive_an_timer = THREAD_PROACTIVE_AN_SEND_DELAY; 02612 } 02613 02614 #endif /* HAVE_THREAD_ROUTER */
Generated on Tue Jul 12 2022 13:03:21 by
