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