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