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