EL4121 Embedded System / mbed-os

Dependents:   cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers thread_router_bootstrap.c Source File

thread_router_bootstrap.c

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