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