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