Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers thread_leader_service.c Source File

thread_leader_service.c

00001 /*
00002  * Copyright (c) 2016-2018, Arm Limited and affiliates.
00003  * SPDX-License-Identifier: BSD-3-Clause
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holder nor the
00014  *    names of its contributors may be used to endorse or promote products
00015  *    derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 #include "nsconfig.h"
00031 
00032 #include <string.h>
00033 #include "ns_types.h"
00034 #include <nsdynmemLIB.h>
00035 #include <ns_list.h>
00036 #include "randLIB.h"
00037 #include "ns_trace.h"
00038 #include "common_functions.h"
00039 #include "thread_management_if.h"
00040 #include "thread_border_router_api.h"
00041 #include "6LoWPAN/Thread/thread_config.h"
00042 #include "6LoWPAN/Thread/thread_common.h"
00043 #include "6LoWPAN/Thread/thread_bootstrap.h"
00044 #include "DHCPv6_client/dhcpv6_client_api.h"
00045 #include "6LoWPAN/Thread/thread_discovery.h"
00046 #include "6LoWPAN/Thread/thread_joiner_application.h"
00047 #include "6LoWPAN/Thread/thread_network_data_lib.h"
00048 #include "6LoWPAN/Thread/thread_nd.h"
00049 #include "6LoWPAN/Thread/thread_tmfcop_lib.h"
00050 #include "6LoWPAN/Thread/thread_management_internal.h"
00051 #include "6LoWPAN/Thread/thread_management_server.h"
00052 #include "6LoWPAN/Thread/thread_commissioning_if.h"
00053 #include "6LoWPAN/Thread/thread_leader_service.h"
00054 #include "6LoWPAN/Thread/thread_router_bootstrap.h"
00055 #include "6LoWPAN/Thread/thread_network_synch.h"
00056 #include "6LoWPAN/Thread/thread_nvm_store.h"
00057 #include "Service_Libs/mle_service/mle_service_api.h"
00058 #include "6LoWPAN/Thread/thread_host_bootstrap.h"
00059 #include "6LoWPAN/Thread/thread_border_router_api_internal.h"
00060 #include "MPL/mpl.h"
00061 #include "MLE/mle.h"
00062 #include "6LoWPAN/MAC/mac_helper.h"
00063 #include "mac_api.h"
00064 #include "6LoWPAN/MAC/mac_data_poll.h"
00065 #include "coap_service_api.h"
00066 
00067 #define TRACE_GROUP "tLdr"
00068 
00069 #ifdef HAVE_THREAD_LEADER_SERVICE
00070 
00071 /*
00072  * Leader instance data.
00073  */
00074 typedef struct thread_leader_service {
00075     int8_t interface_id;
00076     int8_t coap_service_id;
00077     bool leader_enabled: 1;
00078     ns_list_link_t link;
00079 } thread_leader_service_t;
00080 
00081 /*
00082  * Helper structure for router_id handling
00083  */
00084 typedef struct {
00085     uint8_t     routerID[8];
00086     uint32_t    validLifeTime;
00087     uint32_t    preferredLifeTime;
00088     uint16_t    shortAddress;
00089     uint8_t     dataSeq;
00090 } thread_leader_service_router_id_resp_t;
00091 
00092 static NS_LIST_DEFINE(leader_service_instance_list, thread_leader_service_t, link);
00093 
00094 static void thread_leader_service_commissioner_timeout_cb(void *arg);
00095 
00096 /* Private functions */
00097 static thread_leader_service_t *thread_leader_service_find_by_interface(int8_t interface_id)
00098 {
00099     thread_leader_service_t *this = NULL;
00100     ns_list_foreach(thread_leader_service_t, cur_br, &leader_service_instance_list) {
00101         if (cur_br->interface_id == interface_id) {
00102             this = cur_br;
00103             break;
00104         }
00105     }
00106     return this;
00107 }
00108 
00109 static thread_leader_service_t *thread_leader_service_find_by_service(int8_t service_id)
00110 {
00111     thread_leader_service_t *this = NULL;
00112     ns_list_foreach(thread_leader_service_t, cur_br, &leader_service_instance_list) {
00113         if (cur_br->coap_service_id == service_id) {
00114             this = cur_br;
00115             break;
00116         }
00117     }
00118     return this;
00119 }
00120 
00121 static char *thread_commissioning_if_commissioner_id_get(int8_t interface_id)
00122 {
00123     protocol_interface_info_entry_t *cur;
00124 
00125     cur = protocol_stack_interface_info_get_by_id(interface_id);
00126     if (!cur || !cur->thread_info || !cur->thread_info->registered_commissioner.commissioner_valid) {
00127         return NULL;
00128     }
00129 
00130     return cur->thread_info->registered_commissioner.commissioner_id_ptr;
00131 }
00132 
00133 
00134 static bool thread_leader_service_commissioner_address_changed(int8_t interface_id, uint8_t border_router_address[static 16])
00135 {
00136     protocol_interface_info_entry_t *cur;
00137 
00138     cur = protocol_stack_interface_info_get_by_id(interface_id);
00139     if (!cur || !cur->thread_info || !cur->thread_info->registered_commissioner.commissioner_valid) {
00140         return false;
00141     }
00142 
00143     if (!memcmp(cur->thread_info->registered_commissioner.border_router_address, border_router_address, 16)) {
00144         // Border router address is same
00145         return false;
00146     }
00147     if (common_read_16_bit(&border_router_address[14]) >= 0xfc00) {
00148         // Address is not valid RLOC we dont change address to this.
00149         return false;
00150     }
00151     memcpy(cur->thread_info->registered_commissioner.border_router_address, border_router_address, 16);
00152     thread_leader_service_network_data_changed(cur, false, true);
00153     // This will trigger advertisement either from following commands or from leader tick
00154     return true;
00155 }
00156 static int thread_leader_service_steering_data_set(int8_t interface_id, uint8_t *buf_ptr, uint16_t length)
00157 {
00158     protocol_interface_info_entry_t *cur;
00159     link_configuration_s *linkConfiguration;
00160 
00161     linkConfiguration = thread_joiner_application_get_config(interface_id);
00162     if (!linkConfiguration) {
00163         return -1;
00164     }
00165 
00166     cur = protocol_stack_interface_info_get_by_id(interface_id);
00167     if (!cur || !cur->thread_info || !cur->thread_info->leader_private_data || !cur->thread_info->registered_commissioner.commissioner_valid) {
00168         return -1;
00169     }
00170     if (length > 16) {
00171         return -2;
00172     }
00173 
00174     tr_debug("Save new steering data %s", trace_array(buf_ptr, length));
00175 
00176     cur->thread_info->registered_commissioner.steering_data_len = 0;
00177 
00178     if (buf_ptr && length > 0) {
00179         memcpy(cur->thread_info->registered_commissioner.steering_data, buf_ptr, length);
00180         cur->thread_info->registered_commissioner.steering_data_len = length;
00181     }
00182 
00183     thread_leader_service_network_data_changed(cur, false, true);
00184 
00185     return 0;
00186 }
00187 
00188 static bool thread_leader_service_commissioner_unregister(int8_t interface_id, uint16_t session_id)
00189 {
00190     protocol_interface_info_entry_t *cur;
00191     link_configuration_s *linkConfiguration;
00192 
00193     linkConfiguration = thread_joiner_application_get_config(interface_id);
00194     if (!linkConfiguration) {
00195         return false;
00196     }
00197 
00198     cur = protocol_stack_interface_info_get_by_id(interface_id);
00199     if (!cur || !cur->thread_info || !cur->thread_info->leader_private_data) {
00200         return false;
00201     }
00202 
00203     if (cur->thread_info->registered_commissioner.session_id != session_id) {
00204         tr_debug("Commissioner session id not valid - unregister failed");
00205         return false;
00206     }
00207     // Removing commissioner we need to increase the session id
00208     cur->thread_info->registered_commissioner.session_id++;
00209 
00210     if (cur->thread_info->registered_commissioner.commissioner_id_ptr) {
00211         ns_dyn_mem_free(cur->thread_info->registered_commissioner.commissioner_id_ptr);
00212         cur->thread_info->registered_commissioner.commissioner_id_ptr = NULL;
00213     }
00214 
00215     cur->thread_info->registered_commissioner.commissioner_valid = false;
00216     cur->thread_info->registered_commissioner.steering_data_len = 0;
00217 
00218     /* Send unregistration without delay */
00219     thread_leader_service_network_data_changed(cur, false, true);
00220 
00221     eventOS_timeout_cancel(cur->thread_info->registered_commissioner.commissioner_timeout);
00222     cur->thread_info->registered_commissioner.commissioner_timeout = NULL;
00223     cur->thread_info->registered_commissioner.commissioner_registration = THREAD_COMMISSIONER_NOT_REGISTERED;
00224 
00225     return true;
00226 }
00227 
00228 static bool thread_leader_service_commissioner_session_refresh(int8_t interface_id, uint16_t session_id)
00229 {
00230     protocol_interface_info_entry_t *cur;
00231 
00232     // Check pointers
00233     cur = protocol_stack_interface_info_get_by_id(interface_id);
00234     if (!cur || !cur->thread_info || !cur->thread_info->leader_private_data || !cur->thread_info->registered_commissioner.commissioner_valid) {
00235         return false;
00236     }
00237 
00238     if (cur->thread_info->registered_commissioner.commissioner_registration == THREAD_COMMISSIONER_NOT_REGISTERED) {
00239         tr_debug("Commissioner not registered - refresh failed");
00240         return false;
00241     }
00242 
00243     if (cur->thread_info->registered_commissioner.session_id != session_id) {
00244         tr_debug("Commissioner session id not valid - refresh failed");
00245         return false;
00246     }
00247 
00248     cur->thread_info->registered_commissioner.commissioner_registration = THREAD_COMMISSIONER_REGISTERED;
00249 
00250     eventOS_timeout_cancel(cur->thread_info->registered_commissioner.commissioner_timeout);
00251     cur->thread_info->registered_commissioner.commissioner_timeout = eventOS_timeout_ms(thread_leader_service_commissioner_timeout_cb, COMMISSIONER_OBSOLETE_TIMEOUT, cur->thread_info);
00252 
00253     return true;
00254 }
00255 
00256 static void thread_leader_service_commissioner_timeout_cb(void *arg)
00257 {
00258     thread_info_t *thread_ptr = arg;
00259 
00260     thread_ptr->registered_commissioner.commissioner_timeout = NULL;
00261 
00262     if (!thread_ptr->registered_commissioner.commissioner_valid) {
00263         return;
00264     }
00265 
00266     if (!thread_ptr->leader_private_data) {
00267         return;
00268     }
00269 
00270     switch (thread_ptr->registered_commissioner.commissioner_registration) {
00271         case THREAD_COMMISSIONER_REGISTRATION_OBSOLETE:
00272             thread_ptr->registered_commissioner.commissioner_registration = THREAD_COMMISSIONER_NOT_REGISTERED;
00273             if (false == thread_leader_service_commissioner_unregister(thread_ptr->interface_id, thread_ptr->registered_commissioner.session_id)) {
00274                 tr_debug("Commissioner registration remove failed");
00275             } else {
00276                 tr_debug("Commissioner registration removed");
00277             }
00278             break;
00279         case THREAD_COMMISSIONER_REGISTERED:
00280             tr_debug("Commissioner registration obsoleted");
00281             thread_ptr->registered_commissioner.commissioner_registration = THREAD_COMMISSIONER_REGISTRATION_OBSOLETE;
00282             thread_ptr->registered_commissioner.commissioner_timeout = eventOS_timeout_ms(thread_leader_service_commissioner_timeout_cb, COMMISSIONER_REMOVE_TIMEOUT, thread_ptr);
00283             break;
00284         case THREAD_COMMISSIONER_NOT_REGISTERED:
00285         default:
00286             break;
00287     }
00288 }
00289 
00290 
00291 static int thread_leader_service_commissioner_register(int8_t interface_id, uint8_t border_router_address[static 16],
00292                                                        uint8_t *commissioner_id_ptr, uint16_t commissioner_id_len,
00293                                                        uint16_t *session_id)
00294 {
00295     /* Save commissioner data to new commissioner structure and start advertise it
00296     Commissioner session id
00297     commissioner timestamp
00298     commissioner credentials -> static configuration
00299     security policy -> static configuration
00300     network name -> static configuration
00301     border router locator
00302     steering data
00303     */
00304     protocol_interface_info_entry_t *cur;
00305     link_configuration_s *linkConfiguration;
00306 
00307 
00308     linkConfiguration = thread_joiner_application_get_config(interface_id);
00309     if (!linkConfiguration) {
00310         return -1;
00311     }
00312 
00313     cur = protocol_stack_interface_info_get_by_id(interface_id);
00314     if (!cur || !cur->thread_info || !cur->thread_info->leader_private_data) {
00315         return -1;
00316     }
00317 
00318     /* If commissioner already registered */
00319     if (cur->thread_info->registered_commissioner.commissioner_valid &&
00320             cur->thread_info->registered_commissioner.commissioner_registration == THREAD_COMMISSIONER_REGISTERED) {
00321         return -2;
00322     }
00323 
00324     ns_dyn_mem_free(cur->thread_info->registered_commissioner.commissioner_id_ptr);
00325     cur->thread_info->registered_commissioner.commissioner_id_ptr = ns_dyn_mem_alloc(commissioner_id_len + 1);
00326     if (!cur->thread_info->registered_commissioner.commissioner_id_ptr) {
00327         return -1;
00328     }
00329     memcpy(cur->thread_info->registered_commissioner.commissioner_id_ptr, commissioner_id_ptr, commissioner_id_len);
00330     cur->thread_info->registered_commissioner.commissioner_id_ptr[commissioner_id_len] = 0;
00331 
00332     // Initialise values
00333     cur->thread_info->registered_commissioner.session_id++;
00334     if (cur->thread_info->registered_commissioner.session_id == 0) {
00335         cur->thread_info->registered_commissioner.session_id++;
00336     }
00337 
00338     if (session_id) {
00339         *session_id = cur->thread_info->registered_commissioner.session_id;
00340     }
00341 
00342     if (memcmp(border_router_address, linkConfiguration->mesh_local_ula_prefix, 8) == 0 &&
00343             memcmp(border_router_address + 8, ADDR_SHORT_ADR_SUFFIC, 6) == 0 &&
00344             border_router_address[14] == 0xfc) {
00345         // source address is ALOC
00346         common_write_16_bit(cur->thread_info->routerShortAddress, &border_router_address[14]);
00347     }
00348     tr_debug("Register interface %d commissioner: %s", interface_id, trace_ipv6(border_router_address));
00349     //SET Border Router Locator
00350     memcpy(cur->thread_info->registered_commissioner.border_router_address, border_router_address, 16);
00351     cur->thread_info->registered_commissioner.commissioner_valid = true;
00352 
00353     cur->thread_info->registered_commissioner.commissioner_registration = THREAD_COMMISSIONER_REGISTERED;
00354 
00355     eventOS_timeout_cancel(cur->thread_info->registered_commissioner.commissioner_timeout);
00356     cur->thread_info->registered_commissioner.commissioner_timeout = eventOS_timeout_ms(thread_leader_service_commissioner_timeout_cb, COMMISSIONER_OBSOLETE_TIMEOUT, cur->thread_info);
00357 
00358     /* Delay network data propagation, perhaps we receive more data */
00359     thread_leader_service_network_data_changed(cur, false, true);
00360 
00361     return 0;
00362 }
00363 
00364 
00365 
00366 static int thread_leader_service_active_set_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr)
00367 {
00368     thread_leader_service_t *this = thread_leader_service_find_by_service(service_id);
00369     link_configuration_s *linkConfiguration;
00370     sn_coap_msg_code_e response_code = COAP_MSG_CODE_RESPONSE_CHANGED;
00371     uint16_t session_id;
00372     uint8_t payload[5]; // 4 + 1
00373     uint8_t *ptr;
00374     uint8_t *response_ptr;
00375     uint64_t timestamp;
00376     bool msg_from_commissioner = false;
00377     bool changing_connectivity = false;
00378     (void) source_address;
00379     (void) source_port;
00380     int ret = 0;
00381 
00382     if (!this) {
00383         return -1;
00384     }
00385     protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(this->interface_id);
00386     linkConfiguration = thread_joiner_application_get_config(this->interface_id);
00387     if (!cur || !cur->thread_info || !linkConfiguration || !cur->thread_info->leader_private_data) {
00388         return -1;
00389     }
00390 
00391     tr_info("thread management Active set");
00392 
00393     response_ptr = payload;
00394 
00395     if (3 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_CHANNEL, &ptr) &&
00396             (linkConfiguration->rfChannel != common_read_16_bit(&ptr[1]) || linkConfiguration->channel_page != *ptr)) {
00397         tr_debug("Channel changed");
00398         changing_connectivity = true;
00399         // validity check for channel page
00400         if (*ptr != 0 || common_read_16_bit(&ptr[1]) < 11 || common_read_16_bit(&ptr[1]) > 26) {
00401             tr_warn("invalid channel");
00402             ret = -1;
00403             goto send_response;
00404         }
00405     }
00406     if (2 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_PANID, &ptr) &&
00407             linkConfiguration->panId != common_read_16_bit(ptr)) {
00408         tr_debug("PANID changed");
00409         changing_connectivity = true;
00410         if (common_read_16_bit(ptr) > 0xfffe) {
00411             tr_warn("invalid panid");
00412             ret = -1;
00413             goto send_response;
00414         }
00415     }
00416     if (3 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_SECURITY_POLICY, &ptr)) {
00417         if (common_read_16_bit(ptr) < 1) {
00418             tr_warn("invalid security policy");
00419             ret = -1;
00420             goto send_response;
00421         }
00422     }
00423 
00424     if (8 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_NETWORK_MESH_LOCAL_ULA, &ptr) &&
00425             memcmp(linkConfiguration->mesh_local_ula_prefix, ptr, 8) != 0) {
00426         tr_debug("ML prefix changed");
00427         changing_connectivity = true;
00428     }
00429     if (16 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_NETWORK_MASTER_KEY, &ptr) &&
00430             memcmp(linkConfiguration->master_key, ptr, 16) != 0) {
00431         tr_debug("Master key changed");
00432         changing_connectivity = true;
00433     }
00434 
00435     if (2 <= thread_meshcop_tlv_data_get_uint16(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_COMMISSIONER_SESSION_ID, &session_id)) {
00436         // Session id present must be valid
00437         tr_info("message from commissioner");
00438         msg_from_commissioner = true;
00439         if (cur->thread_info->registered_commissioner.session_id != session_id) {
00440             tr_warn("Invalid commissioner session id");
00441             ret = -1;
00442             goto send_response;
00443         }
00444         thread_leader_service_commissioner_address_changed(this->interface_id, source_address);
00445         // Check if address changed
00446         if (changing_connectivity == true) {
00447             tr_warn("Changes affecting connectivity rejected");
00448             ret = -1;
00449             goto send_response;
00450         }
00451     }
00452 
00453     if (8 > thread_meshcop_tlv_data_get_uint64(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_ACTIVE_TIME_STAMP, &timestamp)) {
00454         tr_warn("no timestamp");
00455         ret = -1;
00456         goto send_response;
00457     }
00458     if (timestamp < linkConfiguration->timestamp) {
00459         tr_warn("older timestamp");
00460         ret = -1;
00461         goto send_response;
00462     }
00463     if (timestamp == linkConfiguration->timestamp) {
00464         tr_warn("same timestamp");
00465         ret = -1;
00466         goto send_response;
00467     }
00468     if (!msg_from_commissioner) {
00469         tr_debug("message from end device");
00470         if (cur->thread_info->registered_commissioner.commissioner_registration != THREAD_COMMISSIONER_NOT_REGISTERED) {
00471             // Node changed settings and Registered commissioner send changed_notify to commissioner
00472             tr_info("Notify commissioner that settings are changed");
00473             coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, cur->thread_info->registered_commissioner.border_router_address,
00474                                       THREAD_MANAGEMENT_PORT, COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_DATASET_CHANGED,
00475                                       COAP_CT_OCTET_STREAM, NULL, 0, NULL);
00476         }
00477     }
00478     if (changing_connectivity) {
00479 
00480         tr_info("creating pending configuration");
00481 
00482         if (thread_joiner_application_pending_config_exists(this->interface_id) &&
00483                 thread_joiner_application_pending_config_timestamp_get(this->interface_id) >= timestamp) {
00484             tr_info("Pending config is newer we reject");
00485             ret = -1;
00486             goto send_response;
00487         }
00488         if (thread_joiner_application_pending_config_create(this->interface_id, request_ptr->payload_ptr, request_ptr->payload_len) != 0) {
00489             tr_error("Could not create pending config");
00490             response_code = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR;
00491             goto send_error_response;
00492         }
00493 
00494         // Start distributing pending configuration
00495         thread_joiner_application_pending_config_add_missing_fields(this->interface_id);
00496         thread_joiner_application_pending_config_timestamp_set(this->interface_id, timestamp);
00497         thread_joiner_application_pending_config_enable(this->interface_id, thread_delay_timer_default * 1000);
00498 
00499     } else {
00500         tr_info("updating active configuration");
00501         ret = thread_joiner_application_update_configuration(cur->id, request_ptr->payload_ptr, request_ptr->payload_len, true);
00502         // link configuration is changed, read configuration again
00503         linkConfiguration = thread_joiner_application_get_config(cur->id);
00504         if (!linkConfiguration) {
00505             tr_error("Could not find current config");
00506             response_code = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR;
00507             goto send_error_response;
00508         }
00509         // Activate new configuration.
00510         thread_configuration_thread_activate(cur, linkConfiguration);
00511     }
00512     thread_joiner_application_configuration_nvm_save(this->interface_id);
00513 
00514     // Start timer to propagate new data
00515     thread_leader_service_network_data_changed(cur, true, true);
00516 
00517 send_response:
00518     // build response
00519     response_ptr = thread_meshcop_tlv_data_write_uint8(response_ptr, MESHCOP_TLV_STATE, ret == 0 ? 1 : 0xff);
00520 
00521 send_error_response:
00522     coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, response_code, COAP_CT_OCTET_STREAM, payload, response_ptr - payload);
00523     return 0;
00524 }
00525 
00526 static int thread_leader_service_pending_set_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr)
00527 {
00528     thread_leader_service_t *this = thread_leader_service_find_by_service(service_id);
00529     link_configuration_s *linkConfiguration;
00530     uint8_t *ptr;
00531     sn_coap_msg_code_e response_code = COAP_MSG_CODE_RESPONSE_CHANGED;
00532     uint16_t session_id;
00533     uint8_t payload[5]; // 4 + 1
00534     uint8_t *secret_ptr;
00535     uint64_t active_timestamp;
00536     uint64_t pending_timestamp;
00537     uint32_t delay_timer;
00538     (void) source_address;
00539     (void) source_port;
00540     int ret = 0;
00541     bool msg_from_commissioner = false;
00542     bool master_key_changed = false;
00543 
00544     ptr = payload;
00545     if (!this) {
00546         return -1;
00547     }
00548     protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(this->interface_id);
00549     linkConfiguration = thread_joiner_application_get_config(this->interface_id);
00550     if (!cur || !cur->thread_info || !linkConfiguration || !cur->thread_info->leader_private_data) {
00551         return -1;
00552     }
00553 
00554     tr_info("thread management Pending set");
00555 
00556     if (2 <= thread_meshcop_tlv_data_get_uint16(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_COMMISSIONER_SESSION_ID, &session_id)) {
00557         // Session id present must be valid
00558         if (cur->thread_info->registered_commissioner.session_id != session_id) {
00559             tr_warn("Invalid commissioner session id");
00560             ret = -1;
00561             goto send_response;
00562         }
00563         thread_leader_service_commissioner_address_changed(this->interface_id, source_address);
00564         msg_from_commissioner = true;
00565     }
00566     if (16 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_NETWORK_MASTER_KEY, &secret_ptr) &&
00567             memcmp(linkConfiguration->master_key, secret_ptr, 16) != 0) {
00568         tr_debug("Master key changed");
00569         master_key_changed = true;
00570     }
00571 
00572     if (8 > thread_meshcop_tlv_data_get_uint64(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_PENDING_TIMESTAMP, &pending_timestamp)) {
00573         tr_warn("no timestamp");
00574         ret = -1;
00575         goto send_response;
00576     }
00577     if (4 > thread_meshcop_tlv_data_get_uint32(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_DELAY_TIMER, &delay_timer)) {
00578         tr_warn("no delay timer");
00579         ret = -1;
00580         goto send_response;
00581     }
00582     if (8 > thread_meshcop_tlv_data_get_uint64(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_ACTIVE_TIME_STAMP, &active_timestamp)) {
00583         tr_warn("no active timestamp");
00584         ret = -1;
00585         goto send_response;
00586     }
00587     if (active_timestamp <= linkConfiguration->timestamp && !master_key_changed) {
00588         tr_warn("Timestamp is lower or same, without Master key change");
00589         ret = -1;
00590         goto send_response;
00591     }
00592 
00593     if (thread_joiner_application_pending_config_exists(this->interface_id) &&
00594             pending_timestamp <= thread_joiner_application_pending_config_timestamp_get(this->interface_id)) {
00595         tr_warn("Older or same pending timestamp");
00596         ret = -1;
00597         goto send_response;
00598     }
00599 
00600     if (delay_timer > THREAD_MAX_DELAY_TIMER_SECONDS * 1000) {
00601         delay_timer = THREAD_MAX_DELAY_TIMER_SECONDS * 1000;
00602     }
00603 
00604     if (master_key_changed &&
00605             delay_timer < thread_delay_timer_default * 1000) {
00606         //If message Changes the master key default value is used
00607         delay_timer = thread_delay_timer_default * 1000;
00608     }
00609     if (delay_timer < THREAD_DELAY_TIMER_MINIMAL_SECONDS * 1000) {
00610         // Absolute minimum value allowed
00611         delay_timer = THREAD_DELAY_TIMER_MINIMAL_SECONDS * 1000;
00612     }
00613 
00614     if (thread_joiner_application_pending_config_create(this->interface_id, request_ptr->payload_ptr, request_ptr->payload_len) != 0) {
00615         tr_error("Could not create pending config");
00616         response_code = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR;
00617         goto send_error_response;
00618     }
00619 
00620     if (!msg_from_commissioner) {
00621         tr_debug("pending set from end device");
00622         if (cur->thread_info->registered_commissioner.commissioner_registration != THREAD_COMMISSIONER_NOT_REGISTERED) {
00623             // Node changed settings and Registered commissioner send changed_notify to commissioner
00624             tr_info("Notify commissioner that settings are changed");
00625             coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, cur->thread_info->registered_commissioner.border_router_address,
00626                                       THREAD_MANAGEMENT_PORT, COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_DATASET_CHANGED,
00627                                       COAP_CT_OCTET_STREAM, NULL, 0, NULL);
00628         }
00629     }
00630 
00631     tr_info("creating new pending set delay: %"PRIu32, delay_timer);
00632     // Activate pending configuration
00633     thread_joiner_application_pending_config_add_missing_fields(this->interface_id);
00634     thread_joiner_application_pending_config_timestamp_set(this->interface_id, pending_timestamp);
00635     thread_joiner_application_pending_config_enable(this->interface_id, delay_timer);
00636 
00637     // Start timer to propagate new data
00638     thread_leader_service_network_data_changed(cur, true, true);
00639 
00640 send_response:
00641     // build response
00642     ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, ret == 0 ? 1 : 0xff);
00643 
00644 send_error_response:
00645     coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, response_code, COAP_CT_OCTET_STREAM, payload, ptr - payload);
00646     return 0;
00647 }
00648 
00649 static int thread_leader_service_commissioner_set_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr)
00650 {
00651     thread_leader_service_t *this = thread_leader_service_find_by_service(service_id);
00652     uint16_t session_id;
00653     uint16_t br_locator;
00654     uint8_t payload[5]; // 4 + 1
00655     uint8_t *ptr;
00656     uint8_t *steering_data_ptr;
00657     uint16_t steering_data_len;
00658     (void) source_address;
00659     (void) source_port;
00660     int ret = -2;
00661 
00662     ptr = payload;
00663     if (!this) {
00664         return -1;
00665     }
00666     protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(this->interface_id);
00667     if (!cur || !cur->thread_info || !cur->thread_info->leader_private_data) {
00668         return -1;
00669     }
00670 
00671     tr_info("thread management commissioner set");
00672 
00673     //Check if the CoAp payload is greater than maximum commissioner data size and reject
00674     if (request_ptr->payload_len > THREAD_MAX_COMMISSIONER_DATA_SIZE) {
00675         tr_error("Payload length greater than maximum commissioner data size");
00676         ret = -1;
00677         goto send_response;
00678     }
00679     //TODO must be checked against a list of all non permissible TLVs
00680     if (2 <= thread_meshcop_tlv_data_get_uint16(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_BORDER_ROUTER_LOCATOR, &br_locator)) {
00681         tr_error("BORDER ROUTER TLV should not be present");
00682         ret = -1;
00683         goto send_response;
00684     }
00685 
00686     // TODO must be checked against commissioner address but there is no way to get it.
00687     if (2 != thread_meshcop_tlv_data_get_uint16(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_COMMISSIONER_SESSION_ID, &session_id)) {
00688         // Session id not present must be valid
00689         tr_warn("Commissioner session id not present");
00690         ret = -1;
00691         goto send_response;
00692     }
00693     if (cur->thread_info->registered_commissioner.session_id != session_id) {
00694         tr_warn("Invalid commissioner session id");
00695         ret = -1;
00696         goto send_response;
00697     }
00698 
00699     /* Set border router address */
00700     thread_leader_service_commissioner_address_changed(this->interface_id, source_address);
00701 
00702     /* Set steering data */
00703     if (thread_meshcop_tlv_exist(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_STEERING_DATA)) {
00704         steering_data_len = thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_STEERING_DATA, &steering_data_ptr);
00705         ret = thread_leader_service_steering_data_set(this->interface_id, steering_data_ptr, steering_data_len);
00706         tr_info("steering data set : %s, ret %d", trace_array(steering_data_ptr, steering_data_len), ret);
00707     }
00708 
00709 send_response:
00710     // build response
00711     ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, ret == 0 ? 1 : 0xff);
00712     coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_OCTET_STREAM, payload, ptr - payload);
00713     return 0;
00714 }
00715 
00716 static void thread_leader_allocate_router_id_by_allocated_id(thread_leader_info_t *info, uint8_t router_id, const uint8_t *eui64)
00717 {
00718     memcpy(info->thread_router_id_list[router_id].eui64, eui64, 8);
00719     bit_set(info->master_router_id_mask, router_id);
00720     info->thread_router_id_list[router_id].validLifeTime = 0xffffffff;
00721     info->thread_router_id_list[router_id].reUsePossible = false;
00722 }
00723 
00724 void thread_leader_mleid_rloc_map_populate(thread_nvm_mleid_rloc_map *mleid_rloc_map, thread_leader_info_t *leader_private_info)
00725 {
00726     for (uint8_t i = 0; i < 64; i++) {
00727         if (bit_test(leader_private_info->master_router_id_mask, i)) {
00728             memcpy(mleid_rloc_map->mleid_rloc_map[i].mle_id, leader_private_info->thread_router_id_list[i].eui64, 8);
00729         }
00730     }
00731 }
00732 
00733 int thread_leader_mleid_rloc_map_to_nvm_write(protocol_interface_info_entry_t *cur)
00734 {
00735     if (!cur->thread_info->leader_private_data) {
00736         return -1;
00737     }
00738 
00739     thread_nvm_mleid_rloc_map *mleid_rloc_map = ns_dyn_mem_temporary_alloc(sizeof(thread_nvm_mleid_rloc_map));
00740     if (!mleid_rloc_map) {
00741         return -2;
00742     }
00743     memset(mleid_rloc_map, 0, sizeof(thread_nvm_mleid_rloc_map));
00744     thread_leader_mleid_rloc_map_populate(mleid_rloc_map, cur->thread_info->leader_private_data);
00745     thread_nvm_store_mleid_rloc_map_write(mleid_rloc_map);
00746     ns_dyn_mem_free(mleid_rloc_map);
00747     return 0;
00748 }
00749 
00750 static int thread_leader_service_router_id_allocate(const uint8_t *eui64, protocol_interface_info_entry_t *cur, thread_leader_service_router_id_resp_t *reponse)
00751 {
00752     int ret_val = -1;
00753     uint8_t allocated_id = 64;
00754     uint8_t i;
00755     uint8_t compareId;
00756     thread_leader_info_t *leader_private_ptr = 0;
00757     thread_info_t *thread_info = cur->thread_info;
00758     uint8_t activeRouterCount;
00759 
00760     if (!thread_info || !thread_info->leader_private_data) {
00761         return -1;
00762     }
00763 
00764     leader_private_ptr = thread_info->leader_private_data;
00765     //Check if we have already allocated router address for this MAC address
00766     for (i = 0; i < 64; i++) {
00767         if (bit_test(leader_private_ptr->master_router_id_mask, i)) {
00768             //Active ID
00769             if (memcmp(eui64, leader_private_ptr->thread_router_id_list[i].eui64, 8) == 0) {
00770                 allocated_id = i;
00771                 break;
00772             }
00773         }
00774     }
00775 
00776     if (allocated_id  < 64) {
00777         goto alloc_ready;
00778     }
00779     activeRouterCount = thread_routing_count_active_routers_from_mask(leader_private_ptr->master_router_id_mask);
00780     if (activeRouterCount >= cur->thread_info->testMaxActiveRouterIdLimit) {
00781         // Only 32 router id allowed for one Thread partition
00782         goto alloc_ready;
00783     }
00784 
00785 
00786     //Try to allocate the same router ID that was previously used
00787     if (thread_is_router_addr(reponse->shortAddress)) {
00788         compareId = thread_router_id_from_addr(reponse->shortAddress);
00789         tr_debug("HInt: %02x", compareId);
00790         if (!bit_test(leader_private_ptr->master_router_id_mask, compareId)) {
00791             //Take Free entry By Hint if valid lifetime is zero
00792             if (leader_private_ptr->thread_router_id_list[compareId].reUsePossible) {
00793                 allocated_id = compareId;
00794             }
00795         }
00796     }
00797 
00798     if (allocated_id  < 64) {
00799         goto alloc_new;
00800     }
00801 
00802     //We need to allocate new Router ID
00803     uint16_t random_base = randLIB_get_random_in_range(0, 64);
00804     // New addresses are assigned randomly
00805     for (i = 0; i < 64; i++) {
00806         uint16_t id = (random_base + i) % (MAX_ROUTER_ID + 1);
00807         if (!bit_test(leader_private_ptr->master_router_id_mask, id)) {
00808             if (leader_private_ptr->thread_router_id_list[id].reUsePossible) {
00809                 allocated_id = id;
00810                 // new id allocated save to nvm after delay
00811                 leader_private_ptr->leader_nvm_sync_timer = LEADER_NVM_SYNC_DELAY;
00812                 break;
00813             }
00814         }
00815     }
00816 
00817 alloc_new:
00818     if (allocated_id < 64) {
00819         //Update Route MASK and push NEW Route Info
00820         thread_leader_allocate_router_id_by_allocated_id(leader_private_ptr, allocated_id, eui64);
00821 
00822         //Increment Route TLV data sequency
00823         thread_leader_service_update_id_set(cur);
00824     }
00825 
00826 alloc_ready:
00827 
00828     if (allocated_id < 64) {
00829         thread_leader_allocate_router_id_by_allocated_id(leader_private_ptr, allocated_id, eui64);
00830         reponse->shortAddress = (allocated_id << 10);
00831         memcpy(reponse->routerID, leader_private_ptr->master_router_id_mask, 8);
00832         reponse->dataSeq = leader_private_ptr->maskSeq;
00833         reponse->preferredLifeTime = 0xffffffff;
00834         reponse->validLifeTime = 0xffffffff;
00835         ret_val = 0;
00836     }
00837     return ret_val;
00838 }
00839 
00840 static int thread_leader_service_leader_data_allocate(protocol_interface_info_entry_t *cur)
00841 {
00842     thread_leader_info_t *leader_info = 0;
00843     leader_info = thread_allocate_and_init_leader_private_data();
00844     if (leader_info == NULL) {
00845         return -1;
00846     }
00847     cur->thread_info->leader_private_data = leader_info;
00848     cur->thread_info->thread_device_mode = THREAD_DEVICE_MODE_ROUTER;
00849     cur->thread_info->thread_attached_state = THREAD_STATE_CONNECTED_ROUTER;
00850     return 0;
00851 }
00852 
00853 static int thread_leader_service_router_id_deallocate(const uint8_t *eui64, protocol_interface_info_entry_t *cur)
00854 {
00855     uint8_t i;
00856     thread_leader_info_t *leader_private_ptr = 0;
00857     thread_info_t *thread_info = cur->thread_info;
00858     if (thread_info && thread_info->leader_private_data) {
00859         leader_private_ptr = thread_info->leader_private_data;
00860         //Check by MAC address
00861         for (i = 0; i < 64; i++) {
00862             if (bit_test(leader_private_ptr->master_router_id_mask, i)) {
00863                 //Active ID
00864                 if (memcmp(eui64, leader_private_ptr->thread_router_id_list[i].eui64, 8) == 0) {
00865                     tr_debug("Release Router Id %d", i);
00866                     leader_private_ptr->leader_nvm_sync_timer = LEADER_NVM_SYNC_DELAY;
00867                     thread_leader_service_route_mask_bit_clear(leader_private_ptr, i);
00868                     leader_private_ptr->thread_router_id_list[i].reUsePossible = true;
00869                     leader_private_ptr->thread_router_id_list[i].validLifeTime = 0;
00870                     //Increment Route TLV data sequency
00871                     thread_leader_service_update_id_set(cur);
00872                     thread_routing_activate(&cur->thread_info->routing);
00873                     return 0;
00874                 }
00875             }
00876         }
00877     }
00878 
00879     return -1;
00880 }
00881 
00882 static int thread_leader_service_routerid_assign(protocol_interface_info_entry_t *cur, const uint8_t mac[8], uint8_t router_id_mask_out[9], uint16_t *router_id)
00883 {
00884     thread_leader_service_router_id_resp_t router_id_response;
00885     tr_debug("RId Server assign");
00886     router_id_response.shortAddress = *router_id; // Set Hint
00887 
00888     if (thread_leader_service_router_id_allocate(mac, cur, &router_id_response) != 0) {
00889         tr_debug("Assign Fail");
00890         return -1;
00891     }
00892     *router_id = router_id_response.shortAddress;
00893     router_id_mask_out[0] = router_id_response.dataSeq;
00894     memcpy(&router_id_mask_out[1], router_id_response.routerID, 8);
00895     return 0;
00896 }
00897 
00898 static int thread_leader_service_routerid_release(int8_t interface_id, uint8_t mac[8], uint16_t router_id)
00899 {
00900     (void) router_id;
00901     protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
00902     if (!cur) {
00903         tr_error("No Interface");
00904         return -1;
00905     }
00906 
00907     if (!cur->thread_info) {
00908         tr_error("Not Thread Interface");
00909         return -1;
00910     }
00911 
00912     if (!cur->thread_info->leader_private_data) {
00913         tr_error("Not Leader");
00914         return -1;
00915     }
00916 
00917     return thread_leader_service_router_id_deallocate(mac, cur);
00918 }
00919 
00920 /**
00921  * Router id assignment callback for leader
00922  * uri = tn/d/as
00923  */
00924 static int thread_leader_service_assign_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr)
00925 {
00926     thread_leader_service_t *this = thread_leader_service_find_by_service(service_id);
00927     uint8_t payload[24]; //!< response payload 4 + 9, 4 + 2, 4 + 1
00928     uint8_t *mac_ptr = NULL;
00929     uint8_t router_id_mask[9] = {0};
00930     uint16_t router_id = 0xfffe;
00931     uint8_t *ptr;
00932     uint8_t *status;
00933     (void) source_address;
00934     (void) source_port;
00935 
00936     if (!this) {
00937         return -1;
00938     }
00939 
00940     tr_debug("Thread router id assign request");
00941     protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(this->interface_id);
00942 
00943     if (!cur || !cur->thread_info) {
00944         return -1;
00945     }
00946 
00947     // LOCATOR is optional others are mandatory
00948     (void)thread_meshcop_tlv_data_get_uint16(request_ptr->payload_ptr, request_ptr->payload_len, TMFCOP_TLV_RLOC16, &router_id);
00949 
00950     if (8 > thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, TMFCOP_TLV_MAC_ADDRESS, &mac_ptr)) {
00951         // Failure in message
00952         return -1;
00953     }
00954 
00955     // Failure in message
00956     if (1 > thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, TMFCOP_TLV_STATUS, &status)) {
00957         return -1;
00958     }
00959 
00960     int ret = -1;
00961     if (*status == THREAD_COAP_STATUS_TLV_TOO_FEW_ROUTERS) {
00962         uint8_t activeRouterCount = 0;
00963         if (cur->thread_info->leader_private_data) {
00964             activeRouterCount = thread_routing_count_active_routers_from_mask(cur->thread_info->leader_private_data->master_router_id_mask);
00965         }
00966 
00967         if (activeRouterCount < cur->thread_info->routerSelectParameters.routerUpgradeThresHold) {
00968             ret = thread_leader_service_routerid_assign(cur, mac_ptr, router_id_mask, &router_id);
00969         } else {
00970             tr_info("Router ID not assigned, routers %d >= %d(upgrade threshold)", activeRouterCount, cur->thread_info->routerSelectParameters.routerUpgradeThresHold);
00971         }
00972     } else {
00973         ret = thread_leader_service_routerid_assign(cur, mac_ptr, router_id_mask, &router_id);
00974     }
00975 
00976     ptr = payload;
00977     if (ret == 0) {
00978         tr_debug("Thread router id mac %s, mask %s, locator %x", trace_array(mac_ptr, 8), trace_array(router_id_mask, 9), router_id);
00979         ptr = thread_tmfcop_tlv_data_write_uint8(ptr, TMFCOP_TLV_STATUS, THREAD_COAP_STATUS_TLV_SUCCESS);
00980         ptr = thread_tmfcop_tlv_data_write_uint16(ptr, TMFCOP_TLV_RLOC16, router_id);
00981         ptr = thread_tmfcop_tlv_data_write(ptr, TMFCOP_TLV_ROUTER_MASK, 9, router_id_mask);
00982     } else {
00983         ptr = thread_tmfcop_tlv_data_write_uint8(ptr, TMFCOP_TLV_STATUS, THREAD_COAP_STATUS_TLV_NO_ADDRESS_AVAILABLE);
00984     }
00985 
00986     coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_OCTET_STREAM, payload, ptr - payload);
00987     return 0;
00988 }
00989 
00990 /**
00991  * Router id assignment callback for leader
00992  * uri = tn/d/ar
00993  */
00994 static int thread_leader_service_release_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr)
00995 {
00996     thread_leader_service_t *this = thread_leader_service_find_by_service(service_id);
00997     uint8_t payload[5]; //!< response payload 4 + 1
00998     uint8_t *mac_ptr;
00999     uint16_t router_id;
01000     uint8_t *ptr;
01001     (void) source_address;
01002     (void) source_port;
01003 
01004     if (!this) {
01005         return -1;
01006     }
01007 
01008     tr_debug("Thread router id release request");
01009     if (2 > thread_meshcop_tlv_data_get_uint16(request_ptr->payload_ptr, request_ptr->payload_len, TMFCOP_TLV_RLOC16, &router_id)) {
01010         return -1;
01011     }
01012 
01013     if (8 > thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, TMFCOP_TLV_MAC_ADDRESS, &mac_ptr)) {
01014         // Failure in message
01015         return -1;
01016     }
01017     tr_debug("Thread router release id mac %s, locator %x", trace_array(mac_ptr, 8), router_id);
01018 
01019     thread_leader_service_routerid_release(this->interface_id, mac_ptr, router_id);
01020 
01021     ptr = payload;
01022     ptr = thread_tmfcop_tlv_data_write_uint8(ptr, TMFCOP_TLV_STATUS, 0);
01023     coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_OCTET_STREAM, payload, ptr - payload);
01024 
01025     return 0;
01026 }
01027 
01028 /**
01029  * Thread commissioning petition handler
01030  * uri = tn/mc/lp
01031  */
01032 static int thread_leader_service_petition_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr)
01033 {
01034     thread_leader_service_t *this = thread_leader_service_find_by_service(service_id);
01035     uint8_t payload[79];// max length for commissioner id is 64 + 4 byte header + 4 + 1 + 4 + 2
01036     uint8_t *ptr;
01037     uint16_t session_id = 0;
01038     uint8_t *tlv_data_ptr = NULL;
01039     uint16_t tlv_length;
01040     char *commissioner_id_ptr = NULL;
01041 
01042     (void) source_port;
01043 
01044     ptr = payload;
01045     if (!this) {
01046         return -1;
01047     }
01048 
01049     tr_debug("Thread management commissioner petition");
01050 
01051     // save values from message
01052     tlv_length = thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_COMMISSIONER_ID, &tlv_data_ptr);
01053 
01054     // register to thread interface
01055     int ret = thread_leader_service_commissioner_register(this->interface_id, source_address, tlv_data_ptr, tlv_length, &session_id);
01056 
01057     // Build response
01058     if (ret == 0) {
01059         // Register OK
01060         ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, 1);
01061         ptr = thread_meshcop_tlv_data_write(ptr, MESHCOP_TLV_COMMISSIONER_ID, tlv_length, tlv_data_ptr);
01062         ptr = thread_meshcop_tlv_data_write_uint16(ptr, MESHCOP_TLV_COMMISSIONER_SESSION_ID, session_id);
01063     } else if (ret == -2) {
01064         // Commissioner already registered - reject and send commissioner ID
01065         ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, 0xff);
01066         commissioner_id_ptr = thread_commissioning_if_commissioner_id_get(this->interface_id);
01067         if (commissioner_id_ptr) {
01068             ptr = thread_meshcop_tlv_data_write(ptr, MESHCOP_TLV_COMMISSIONER_ID, strlen(commissioner_id_ptr), (uint8_t *)commissioner_id_ptr);
01069         }
01070     } else {
01071         // Reject, anyhow, no commissioner registered - no commissioner ID
01072         ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, 0xff);
01073     }
01074 
01075     tr_debug("Petition req recv id %s, RESP session id: %d ret %d", commissioner_id_ptr ? commissioner_id_ptr : "(none)", session_id, ret);
01076 
01077     coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_OCTET_STREAM, payload, ptr - payload);
01078     return 0;
01079 }
01080 
01081 /**
01082  * Thread commissioning keep alive handler
01083  * uri = tn/mc/la
01084  */
01085 static int thread_leader_service_petition_ka_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr)
01086 {
01087     thread_leader_service_t *this = thread_leader_service_find_by_service(service_id);
01088     uint8_t payload[5]; //status 4 + 1
01089     uint8_t *ptr;
01090     uint16_t session_id = 0;
01091     bool state = false;
01092 
01093     (void) source_address;
01094     (void) source_port;
01095 
01096     if (!this) {
01097         return -1;
01098     }
01099 
01100     tr_debug("Thread management commissioner keep alive");
01101 
01102     if (2 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_COMMISSIONER_SESSION_ID, &ptr)) {
01103         session_id = common_read_16_bit(ptr);
01104     }
01105     if (1 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_STATE, &ptr)) {
01106         if (*ptr == 0x01) {
01107             state = thread_leader_service_commissioner_session_refresh(this->interface_id, session_id);
01108         } else if (*ptr == 0xff) {
01109             thread_leader_service_commissioner_unregister(this->interface_id, session_id);
01110             state = false;
01111         }
01112     }
01113     if (state == true) {
01114         thread_leader_service_commissioner_address_changed(this->interface_id, source_address);
01115     }
01116     tr_info("Commissioner keep alive req recv, interface: %d session id %d state %d", this->interface_id, session_id, state);
01117     ptr = payload;
01118     ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, state == true ? 1 : 0xff);
01119 
01120     coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_OCTET_STREAM, payload, ptr - payload);
01121     return 0;
01122 }
01123 
01124 static int thread_leader_service_network_data_register(protocol_interface_info_entry_t *cur, uint8_t *network_data_ptr, uint16_t network_data_length, uint16_t routerId)
01125 {
01126     tr_debug("Register network data for %x", routerId);
01127     // Mark all data to be cleared
01128     thread_network_data_router_id_mark_delete(&cur->thread_info->networkDataStorage, routerId, true);
01129 
01130     // update data from this device
01131     int retVal = thread_bootstrap_network_data_process(cur, network_data_ptr, network_data_length);
01132 
01133     if (retVal < 0) {
01134         tr_warn("network data update failed: %s", trace_array(network_data_ptr, network_data_length));
01135         return retVal;
01136     }
01137     thread_network_data_router_id_free(&cur->thread_info->networkDataStorage, true, cur);
01138 
01139     thread_leader_service_network_data_changed(cur, false, false);
01140     return 0;
01141 }
01142 
01143 /**
01144  * Thread network data registration handler
01145  * uri = tn/sd
01146  */
01147 static int thread_leader_service_register_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr)
01148 {
01149     thread_leader_service_t *this = thread_leader_service_find_by_service(service_id);
01150     uint16_t payload_len;
01151     uint8_t *payload_ptr;
01152     uint16_t network_data_len;
01153     uint8_t *network_data_ptr;
01154     protocol_interface_info_entry_t *cur;
01155     sn_coap_msg_code_e response_code = COAP_MSG_CODE_RESPONSE_CHANGED;
01156     int8_t ret = -3;
01157     uint16_t routerId;
01158     uint16_t old_rloc;
01159     (void) source_port;
01160     tr_debug("register network data");
01161 
01162     if (!this) {
01163         return -1;
01164     }
01165 
01166     cur = protocol_stack_interface_info_get_by_id(this->interface_id);
01167     if (!cur || !cur->thread_info) {
01168         return -1;
01169     }
01170 
01171     //send data to leader api.
01172     routerId = common_read_16_bit(&source_address[14]);
01173     payload_len = request_ptr->payload_len;
01174     payload_ptr = request_ptr->payload_ptr;
01175     request_ptr->payload_ptr = NULL;
01176 
01177 
01178     if (2 <= thread_tmfcop_tlv_data_get_uint16(payload_ptr, payload_len, TMFCOP_TLV_RLOC16, &old_rloc)) {
01179         // This will delete everything from old rloc
01180         tr_warn("Remove network data from: %x", old_rloc);
01181         ret = thread_leader_service_network_data_register(cur, NULL, 0, old_rloc);
01182     }
01183 
01184     if (!thread_tmfcop_tlv_exist(payload_ptr, payload_len, TMFCOP_TLV_NETWORK_DATA)) {
01185         goto send_response;
01186     }
01187     network_data_len = thread_tmfcop_tlv_find(payload_ptr, payload_len, TMFCOP_TLV_NETWORK_DATA, &network_data_ptr);
01188 
01189     /* Check that network data does NOT produce Network Data TLV bigger than MAX_NETWORK_DATA_SIZE */
01190     int32_t len = thread_network_data_resulting_tlv_size(&cur->thread_info->networkDataStorage, network_data_ptr, network_data_len, routerId);
01191 
01192     if (len <= 0 || len > THREAD_MAX_NETWORK_DATA_SIZE) {
01193         tr_warn("Network data would produce Network Data TLV size %"PRId32, len);
01194         response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
01195         goto send_response;
01196     }
01197 
01198     if (network_data_len < 256) {
01199         ret = thread_leader_service_network_data_register(cur, network_data_ptr, network_data_len, routerId);
01200     }
01201     if (ret != 0) {
01202         /* error happened*/
01203         response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; // corruption is the default or not enough room
01204         if (ret == -2) {
01205             response_code = COAP_MSG_CODE_RESPONSE_FORBIDDEN;    // Not leader
01206         }
01207     }
01208 
01209 send_response:
01210     coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, response_code, COAP_CT_OCTET_STREAM, NULL, 0);
01211     return 0;
01212 }
01213 
01214 static int thread_leader_service_leader_start(protocol_interface_info_entry_t *cur)
01215 {
01216     link_configuration_s *linkConfiguration;
01217     linkConfiguration = thread_joiner_application_get_config(cur->id);
01218     if (!linkConfiguration) {
01219         return -1;
01220     }
01221 
01222     //Allocate Setup
01223     if (thread_leader_service_leader_data_allocate(cur) != 0) {
01224         return -1;
01225     }
01226 
01227     if (thread_leader_service_start(cur->id)) {
01228         thread_nd_service_delete(cur->id);
01229         return -1;
01230     }
01231     if (thread_beacon_create_payload(cur) != 0) {
01232         thread_nd_service_delete(cur->id);
01233         return -1;
01234     }
01235     cur->thread_info->rfc6775 = false;
01236     cur->thread_info->leader_private_data->leader_id_seq_timer = ID_SEQUENCE_PERIOD;
01237 
01238     cur->lowpan_info &= ~INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION;
01239     cur->lowpan_info |= INTERFACE_NWK_ROUTER_DEVICE;
01240     cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE;
01241     mac_helper_default_security_level_set(cur, SEC_ENC_MIC32);
01242     mac_helper_default_security_key_id_mode_set(cur, MAC_KEY_ID_MODE_IDX);
01243     thread_discovery_responser_enable(cur->id, true);
01244     if (cur->mac_api) {
01245         mlme_start_t start_req;
01246         memset(&start_req, 0, sizeof(mlme_start_t));
01247         start_req.BeaconOrder = 15;
01248         start_req.SuperframeOrder = 15;
01249         start_req.PANCoordinator = true;
01250         start_req.LogicalChannel = cur->mac_parameters->mac_channel;
01251         start_req.PANId = cur->mac_parameters->pan_id;
01252         cur->mac_api->mlme_req(cur->mac_api, MLME_START, &start_req);
01253     }
01254     return 0;
01255 }
01256 
01257 static int thread_leader_service_leader_init(protocol_interface_info_entry_t *cur)
01258 {
01259     //Clean All allocated stuff's
01260     thread_info_t *thread_info = cur->thread_info;
01261     // mark and delete previous leader network data information
01262     thread_network_data_router_id_mark_delete(&thread_info->networkDataStorage, thread_router_addr_from_id(cur->thread_info->thread_leader_data->leaderRouterId), true);
01263     thread_network_data_router_id_free(&thread_info->networkDataStorage, false, cur);
01264     thread_leader_service_leader_data_free(thread_info);
01265 
01266     thread_info->rfc6775 = false;
01267     thread_routing_free(&thread_info->routing);
01268     ipv6_route_table_remove_info(cur->id, ROUTE_THREAD, NULL);
01269     ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_BORDER_ROUTER, NULL);
01270     dhcp_client_delete(cur->id);
01271     thread_nd_service_delete(cur->id);
01272     mpl_clear_realm_scope_seeds(cur);
01273     ipv6_neighbour_cache_flush(&cur->ipv6_neighbour_cache);
01274     thread_neighbor_list_clean(cur);
01275     cur->mesh_callbacks = NULL;
01276     cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE;
01277 
01278     return thread_leader_service_leader_start(cur);
01279 }
01280 
01281 static void thread_leader_service_leader_data_initialize(protocol_interface_info_entry_t *cur, uint8_t routerId)
01282 {
01283     thread_leader_data_t *leader_data = cur->thread_info->thread_leader_data;
01284 
01285     if (cur->thread_info->thread_leader_data) {
01286         leader_data->partitionId = randLIB_get_32bit(); //Generate Random Instance
01287         leader_data->leaderRouterId = routerId; //Set leader data to zero by Default
01288         leader_data->dataVersion = randLIB_get_8bit();
01289         leader_data->stableDataVersion = randLIB_get_8bit();
01290         leader_data->weighting = cur->thread_info->partition_weighting;
01291     }
01292 }
01293 
01294 static void thread_leader_service_private_routemask_init(thread_leader_info_t *leader_info)
01295 {
01296     memset(leader_info, 0, sizeof(thread_leader_info_t));
01297     leader_info->maskSeq = randLIB_get_8bit();
01298     uint8_t i;
01299     for (i = 0; i < 64; i++) {
01300         leader_info->thread_router_id_list[i].reUsePossible = true;
01301         leader_info->thread_router_id_list[i].validLifeTime = 0xffffffff;
01302     }
01303 }
01304 
01305 static void thread_leader_service_interface_setup_activate(protocol_interface_info_entry_t *cur)
01306 {
01307     uint8_t routerId;
01308     thread_leader_info_t *private = cur->thread_info->leader_private_data;
01309 
01310     routerId = thread_router_id_from_addr(cur->thread_info->routerShortAddress);
01311 
01312     thread_leader_service_leader_data_initialize(cur, routerId);
01313     // Test code
01314     if (cur->thread_info->testRandomPartitionId != 0) {
01315         cur->thread_info->thread_leader_data->partitionId = cur->thread_info->testRandomPartitionId;
01316         cur->thread_info->testRandomPartitionId = 0;
01317     }
01318     thread_leader_service_private_routemask_init(private);
01319     //SET Router ID
01320     thread_leader_allocate_router_id_by_allocated_id(private, routerId, cur->mac);
01321     thread_partition_data_purge(cur);
01322     // remove any existing rloc mapping in nvm
01323     thread_nvm_store_mleid_rloc_map_remove();
01324     cur->lowpan_address_mode = NET_6LOWPAN_GP16_ADDRESS;
01325     thread_bootstrap_update_ml16_address(cur, cur->thread_info->routerShortAddress);
01326     thread_generate_ml64_address(cur);
01327     thread_bootstrap_routing_activate(cur);
01328     thread_routing_update_id_set(cur, private->maskSeq, private->master_router_id_mask);
01329     thread_routing_activate(&cur->thread_info->routing);
01330     cur->thread_info->leader_private_data->leader_id_seq_timer = ID_SEQUENCE_PERIOD;
01331 }
01332 
01333 /*
01334  * Function to clear network data from router children.
01335  * When router is removed, network data from router child must be removed as well.
01336  */
01337 static void thread_leader_router_child_network_data_clear(protocol_interface_info_entry_t *cur, uint16_t router_short_addr)
01338 {
01339     uint16_t child_short_addr;
01340 
01341     child_short_addr = thread_leader_service_child_id_from_networkdata_get(cur->thread_info, router_short_addr);
01342     while (child_short_addr != 0) {
01343         tr_debug("Removing Network data from child %04x", child_short_addr);
01344         thread_leader_service_network_data_register(cur, NULL, 0, child_short_addr);
01345         child_short_addr = thread_leader_service_child_id_from_networkdata_get(cur->thread_info, router_short_addr);
01346     }
01347 }
01348 
01349 
01350 /* Public functions */
01351 
01352 int thread_leader_service_init(int8_t interface_id, uint8_t coap_service_id)
01353 {
01354     thread_leader_service_t *this = thread_leader_service_find_by_interface(interface_id);
01355 
01356     if (this) {
01357         return 0;
01358     }
01359 
01360     this = ns_dyn_mem_alloc(sizeof(thread_leader_service_t));
01361     if (!this) {
01362         return -2;
01363     }
01364 
01365     this->interface_id = interface_id;
01366     this->coap_service_id = coap_service_id;
01367     this->leader_enabled = false;
01368 
01369     ns_list_add_to_start(&leader_service_instance_list, this);
01370 
01371     return 0;
01372 }
01373 
01374 void thread_leader_service_delete(int8_t interface_id)
01375 {
01376     thread_leader_service_t *this = thread_leader_service_find_by_interface(interface_id);
01377     if (!this) {
01378         return;
01379     }
01380 
01381     if (this->leader_enabled) {
01382         thread_leader_service_stop(interface_id);
01383     }
01384 
01385     ns_list_remove(&leader_service_instance_list, this);
01386     ns_dyn_mem_free(this);
01387 }
01388 
01389 int thread_leader_service_start(int8_t interface_id)
01390 {
01391     thread_leader_service_t *this = thread_leader_service_find_by_interface(interface_id);
01392 
01393     if (!this) {
01394         return -1;
01395     }
01396 
01397     this->leader_enabled = true;
01398     /**
01399      * Router id uri register
01400      */
01401     coap_service_register_uri(this->coap_service_id, THREAD_URI_ROUTER_ID_ASSIGNMENT, COAP_SERVICE_ACCESS_GET_ALLOWED, thread_leader_service_assign_cb);
01402     coap_service_register_uri(this->coap_service_id, THREAD_URI_ROUTER_ID_RELEASE, COAP_SERVICE_ACCESS_GET_ALLOWED, thread_leader_service_release_cb);
01403     /**
01404      * Thread commission registration uri handling
01405      */
01406     coap_service_register_uri(this->coap_service_id, THREAD_URI_LEADER_PETITION, COAP_SERVICE_ACCESS_GET_ALLOWED, thread_leader_service_petition_cb);
01407     coap_service_register_uri(this->coap_service_id, THREAD_URI_LEADER_KEEP_ALIVE, COAP_SERVICE_ACCESS_GET_ALLOWED, thread_leader_service_petition_ka_cb);
01408     /**
01409      * Thread network data management handler
01410      */
01411     coap_service_register_uri(this->coap_service_id, THREAD_URI_NETWORK_DATA, COAP_SERVICE_ACCESS_GET_ALLOWED, thread_leader_service_register_cb);
01412     coap_service_register_uri(this->coap_service_id, THREAD_URI_ACTIVE_SET, COAP_SERVICE_ACCESS_GET_ALLOWED, thread_leader_service_active_set_cb);
01413     coap_service_register_uri(this->coap_service_id, THREAD_URI_PENDING_SET, COAP_SERVICE_ACCESS_GET_ALLOWED, thread_leader_service_pending_set_cb);
01414     coap_service_register_uri(this->coap_service_id, THREAD_URI_COMMISSIONER_SET, COAP_SERVICE_ACCESS_GET_ALLOWED, thread_leader_service_commissioner_set_cb);
01415 
01416     return 0;
01417 }
01418 
01419 void thread_leader_service_stop(int8_t interface_id)
01420 {
01421     thread_leader_service_t *this = thread_leader_service_find_by_interface(interface_id);
01422 
01423     if (!this) {
01424         return;
01425     }
01426 
01427     this->leader_enabled = false;
01428     coap_service_unregister_uri(this->coap_service_id, THREAD_URI_ROUTER_ID_ASSIGNMENT);
01429     coap_service_unregister_uri(this->coap_service_id, THREAD_URI_ROUTER_ID_RELEASE);
01430     coap_service_unregister_uri(this->coap_service_id, THREAD_URI_LEADER_PETITION);
01431     coap_service_unregister_uri(this->coap_service_id, THREAD_URI_LEADER_KEEP_ALIVE);
01432     coap_service_unregister_uri(this->coap_service_id, THREAD_URI_NETWORK_DATA);
01433     coap_service_unregister_uri(this->coap_service_id, THREAD_URI_ACTIVE_SET);
01434     coap_service_unregister_uri(this->coap_service_id, THREAD_URI_PENDING_SET);
01435     coap_service_unregister_uri(this->coap_service_id, THREAD_URI_COMMISSIONER_SET);
01436     return;
01437 }
01438 void thread_leader_service_network_data_changed(protocol_interface_info_entry_t *cur, bool force_stable_update, bool force_unstable_update)
01439 {
01440     if (!cur->thread_info) {
01441         return;
01442     }
01443 
01444     if (force_stable_update) {
01445         cur->thread_info->networkDataStorage.stableUpdatePushed = true;
01446     }
01447     if (force_unstable_update) {
01448         cur->thread_info->networkDataStorage.temporaryUpdatePushed = true;
01449     }
01450     // Generate network data from network data structures
01451     if (cur->thread_info->networkDataStorage.stableUpdatePushed) {
01452         tr_debug("Temporary Network Data Update");
01453         cur->thread_info->thread_leader_data->stableDataVersion++;
01454         cur->thread_info->thread_leader_data->dataVersion++;
01455     } else if (cur->thread_info->networkDataStorage.temporaryUpdatePushed) {
01456         tr_debug("Stable Network Data Update");
01457         cur->thread_info->thread_leader_data->dataVersion++;
01458     } else {
01459         // No changes in network data detected
01460         return;
01461     }
01462     tr_debug("network data changed stable:%d, unstable:%d", cur->thread_info->networkDataStorage.stableUpdatePushed, cur->thread_info->networkDataStorage.temporaryUpdatePushed);
01463     thread_leader_service_generate_network_data(cur);
01464 
01465     /* set timer to update new network data */
01466     if (0 == thread_info(cur)->networkDataStorage.network_data_update_delay) {
01467         thread_info(cur)->networkDataStorage.network_data_update_delay = THREAD_COMMISSION_DATA_UPDATE_DELAY;
01468     }
01469 }
01470 
01471 void thread_leader_service_timer(protocol_interface_info_entry_t *cur, uint32_t ticks)
01472 {
01473     if (!cur->thread_info->leader_private_data) {
01474         // I am not a leader
01475         return;
01476     }
01477 
01478     // check for network data update
01479     if (thread_info(cur)->networkDataStorage.network_data_update_delay) {
01480         if (thread_info(cur)->networkDataStorage.network_data_update_delay > ticks) {
01481             thread_info(cur)->networkDataStorage.network_data_update_delay -= ticks;
01482         } else {
01483             // Send New network data.
01484             thread_info(cur)->networkDataStorage.network_data_update_delay = 0;
01485             thread_bootstrap_network_data_update(cur);
01486         }
01487     }
01488 
01489     if (cur->thread_info->leader_private_data->leader_id_seq_timer) {
01490         if (cur->thread_info->leader_private_data->leader_id_seq_timer > ticks) {
01491             cur->thread_info->leader_private_data->leader_id_seq_timer -= ticks;
01492         } else {
01493             cur->thread_info->leader_private_data->leader_id_seq_timer = 0;
01494         }
01495     } else  {
01496         // Leader id sequence number updated
01497         cur->thread_info->leader_private_data->leader_id_seq_timer = ID_SEQUENCE_PERIOD;
01498 
01499         thread_leader_service_update_id_set(cur);
01500         thread_network_data_context_re_use_timer_update(cur->id, &cur->thread_info->networkDataStorage, 10, &cur->lowpan_contexts);
01501         // Send update to network data if needed
01502         thread_leader_service_network_data_changed(cur, false, false);
01503     }
01504 
01505     if (cur->thread_info->leader_private_data->leader_nvm_sync_timer) {
01506         if ((cur->thread_info->leader_private_data->leader_nvm_sync_timer) > ticks) {
01507             cur->thread_info->leader_private_data->leader_nvm_sync_timer -= ticks;
01508         } else {
01509             cur->thread_info->leader_private_data->leader_nvm_sync_timer = 0;
01510             thread_leader_mleid_rloc_map_to_nvm_write(cur);
01511         }
01512     }
01513 
01514     thread_leader_service_router_id_valid_lifetime_update(cur, ticks);
01515 
01516 }
01517 
01518 void thread_leader_service_leader_data_free(thread_info_t *thread_info)
01519 {
01520     if (thread_info && thread_info->thread_leader_data) {
01521         ns_dyn_mem_free(thread_info->leader_private_data);
01522         thread_info->leader_private_data = NULL;
01523     }
01524 }
01525 
01526 void thread_leader_service_thread_partitition_generate(int8_t interface_id, bool newPartition)
01527 {
01528     protocol_interface_info_entry_t *cur;
01529     link_configuration_s *linkConfiguration = thread_joiner_application_get_config(interface_id);
01530     uint8_t *parent_mac_addr = NULL;
01531     uint16_t leaderRloc;
01532 
01533     cur = protocol_stack_interface_info_get_by_id(interface_id);
01534     if (!cur || !cur->thread_info) {
01535         return;
01536     }
01537 
01538     if (!linkConfiguration) {
01539         goto failure_exit;
01540     }
01541 
01542     mle_service_interface_tx_queue_clean(interface_id);
01543 
01544     if (!newPartition) {
01545         if (cur->nwk_bootstrap_state == ER_ACTIVE_SCAN && cur->nwk_nd_re_scan_count < THREAD_NETWORK_ACTIVE_SCAN_COUNTER) {
01546             tr_debug("RE trig Active Scan");
01547             cur->bootsrap_state_machine_cnt = randLIB_get_random_in_range(1, 6);
01548             return;
01549         }
01550     }
01551 
01552     if (cur->thread_info->thread_device_mode != THREAD_DEVICE_MODE_ROUTER) {
01553         tr_debug("End device did not find networks");
01554         goto failure_exit;
01555     }
01556     leaderRloc = cur->thread_info->routerShortAddress;
01557 
01558     //Set For Destination cache clean purpose
01559     cur->mac_parameters->pan_id = linkConfiguration->panId;
01560 
01561     if (thread_leader_service_leader_init(cur) != 0) {
01562         tr_debug("Leader allocate Fail");
01563         goto failure_exit;
01564     }
01565 
01566     /* Delete old parent info */
01567     if (cur->thread_info->thread_endnode_parent) {
01568         ns_dyn_mem_free(cur->thread_info->thread_endnode_parent);
01569         cur->thread_info->thread_endnode_parent = NULL;
01570     }
01571 
01572     tr_debug("Leader Link generated & Started");
01573 
01574     //Run Nomal Init
01575     thread_interface_init(cur);
01576 
01577     // Init clears the address
01578     cur->thread_info->routerShortAddress = leaderRloc;
01579 
01580     if (cur->thread_info->routerShortAddress == 0xfffe ||
01581             !thread_is_router_addr(cur->thread_info->routerShortAddress)) {
01582         //If we were REED do not use reed address
01583         cur->thread_info->routerShortAddress = thread_router_addr_from_id(randLIB_get_random_in_range(0, MAX_ROUTER_ID));
01584     }
01585 
01586     // clean network data
01587     thread_network_data_free_and_clean(&cur->thread_info->networkDataStorage);
01588     thread_network_data_base_init(&cur->thread_info->networkDataStorage);
01589     thread_leader_service_interface_setup_activate(cur);
01590 
01591     //memset(cur->thread_info->lastValidRouteMask, 0, (N_THREAD_ROUTERS+7)/8);
01592     //SET SHort Address & PAN-ID
01593     cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE;
01594     mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true);
01595     cur->interface_mode = INTERFACE_UP;
01596     cur->nwk_mode = ARM_NWK_GP_IP_MODE;
01597     thread_bootstrap_ready(cur);
01598     thread_configuration_mle_activate(cur);
01599     if (cur->thread_info->thread_endnode_parent) {
01600         parent_mac_addr = cur->thread_info->thread_endnode_parent->mac64;
01601     }
01602     thread_nvm_store_link_info_write(parent_mac_addr, mac_helper_mac16_address_get(cur));
01603 
01604     if (thread_nd_own_service_list_data_size(&cur->thread_info->localServerDataBase)) {
01605         // We publish our services if we have some BUG leader cannot remove old ones
01606         thread_border_router_publish(cur->id);
01607     }
01608     return;
01609 
01610 failure_exit:
01611     nwk_bootsrap_state_update(ARM_NWK_NWK_SCAN_FAIL, cur);
01612 }
01613 
01614 int thread_leader_service_thread_partitition_restart(int8_t interface_id, mle_tlv_info_t *routing)
01615 {
01616     protocol_interface_info_entry_t *cur;
01617     cur = protocol_stack_interface_info_get_by_id(interface_id);
01618     if (!cur || !cur->thread_info) {
01619         return -1;
01620     }
01621     if (!thread_info(cur)->leader_private_data) {
01622         thread_info(cur)->leader_private_data = thread_allocate_and_init_leader_private_data();
01623     }
01624     if (!thread_info(cur)->leader_private_data) {
01625         return -1;
01626     }
01627     if (thread_leader_service_start(cur->id)) {
01628         return -1;
01629     }
01630     //Learn network data, we remove own data from here it should be re given by application
01631     //thread_management_network_data_register(cur->id, networkData.dataPtr, networkData.tlvLen, address16 );
01632     thread_nvm_mleid_rloc_map *mleid_rloc_map = ns_dyn_mem_temporary_alloc(sizeof(thread_nvm_mleid_rloc_map));
01633     if (!mleid_rloc_map) {
01634         return -1;
01635     }
01636     if (thread_nvm_store_mleid_rloc_map_read(mleid_rloc_map) != THREAD_NVM_FILE_SUCCESS) {
01637         memset(mleid_rloc_map, 0, sizeof(thread_nvm_mleid_rloc_map));
01638     }
01639     // initialize private data
01640     thread_info(cur)->leader_private_data->maskSeq = *routing->dataPtr;
01641     memcpy(thread_info(cur)->leader_private_data->master_router_id_mask, routing->dataPtr + 1, 8);
01642     for (int i = 0; i < 64; i++) {
01643         if (bit_test(thread_info(cur)->leader_private_data->master_router_id_mask, i)) {
01644             //Active ID
01645             thread_info(cur)->leader_private_data->thread_router_id_list[i].reUsePossible = false;
01646             memcpy(thread_info(cur)->leader_private_data->thread_router_id_list[i].eui64, mleid_rloc_map->mleid_rloc_map[i].mle_id, 8);
01647         } else {
01648             // Free id
01649             thread_info(cur)->leader_private_data->thread_router_id_list[i].reUsePossible = true;
01650             // clear the mleid in both local router id list and nvm
01651             memset(thread_info(cur)->leader_private_data->thread_router_id_list[i].eui64, 0, 8);
01652             memset(mleid_rloc_map->mleid_rloc_map[i].mle_id, 0, 8);
01653         }
01654         thread_info(cur)->leader_private_data->thread_router_id_list[i].validLifeTime = 0xffffffff;
01655     }
01656     // write back updated map to store
01657     thread_nvm_store_mleid_rloc_map_write(mleid_rloc_map);
01658     ns_dyn_mem_free(mleid_rloc_map);
01659     // Clear network data (if exists) and propagate new empty network data
01660     thread_network_data_free_and_clean(&cur->thread_info->networkDataStorage);
01661     thread_network_data_base_init(&cur->thread_info->networkDataStorage);
01662     // Update router sequence id to prevent network fragmentation in case of Leader was temporarily down
01663     // and routers were not able to get new sequence id for NETWORK_ID_TIMEOUT duration.
01664     thread_leader_service_update_id_set(cur);
01665     return 0;
01666 }
01667 
01668 void thread_leader_service_update_id_set(protocol_interface_info_entry_t *cur)
01669 {
01670     thread_leader_info_t *leader_private_ptr = cur->thread_info->leader_private_data;
01671 
01672     leader_private_ptr->maskSeq++;
01673     thread_routing_update_id_set(cur, leader_private_ptr->maskSeq, leader_private_ptr->master_router_id_mask);
01674 }
01675 
01676 void thread_leader_service_router_id_valid_lifetime_update(protocol_interface_info_entry_t *cur, uint32_t tickUpdate)
01677 {
01678     uint8_t i;
01679     bool update_routeTable = false;
01680     thread_info_t *thread_info = cur->thread_info;
01681     thread_leader_info_t *leader_private_ptr = 0;
01682     if (thread_info && thread_info->leader_private_data) {
01683         leader_private_ptr = thread_info->leader_private_data;
01684 
01685         for (i = 0; i < 64; i++) {
01686             if (bit_test(leader_private_ptr->master_router_id_mask, i)) {
01687                 if (i != thread_info->thread_leader_data->leaderRouterId) {
01688                     //Active ID
01689                     if (leader_private_ptr->thread_router_id_list[i].validLifeTime != 0xffffffff) {
01690                         if (leader_private_ptr->thread_router_id_list[i].validLifeTime > tickUpdate) {
01691                             //Increment Time
01692                             leader_private_ptr->thread_router_id_list[i].validLifeTime -= tickUpdate;
01693                         } else {
01694                             //RElease
01695                             tr_debug("Router ID bit Release: %x start re assign delay", i);
01696                             leader_private_ptr->thread_router_id_list[i].validLifeTime = ROUTER_ID_REUSE_DELAY;
01697                             leader_private_ptr->thread_router_id_list[i].reUsePossible = false;
01698                             thread_leader_service_route_mask_bit_clear(leader_private_ptr, i);
01699                             thread_leader_service_network_data_register(cur, NULL, 0, thread_router_addr_from_id(i));
01700                             thread_leader_router_child_network_data_clear(cur, thread_router_addr_from_id(i));
01701                             thread_routing_activate(&thread_info->routing);
01702                             update_routeTable = true;
01703                         }
01704                     }
01705                 }
01706             } else {
01707                 if (leader_private_ptr->thread_router_id_list[i].validLifeTime != 0xffffffff) {
01708                     if (leader_private_ptr->thread_router_id_list[i].validLifeTime > tickUpdate) {
01709                         //Increment Time
01710                         leader_private_ptr->thread_router_id_list[i].validLifeTime -= tickUpdate;
01711                     } else {
01712                         //RElease
01713                         tr_debug("Router ID available again: %x", i);
01714                         leader_private_ptr->thread_router_id_list[i].validLifeTime = 0xffffffff;
01715                         leader_private_ptr->thread_router_id_list[i].reUsePossible = true;
01716                     }
01717                 }
01718 
01719             }
01720         }
01721         if (update_routeTable) {
01722             thread_leader_service_update_id_set(cur);
01723         }
01724     }
01725 }
01726 
01727 bool thread_leader_service_route_mask_bit_clear(thread_leader_info_t *info, uint8_t router_id)
01728 {
01729     if (bit_test(info->master_router_id_mask, router_id)) {
01730         bit_clear(info->master_router_id_mask, router_id);
01731         return true;
01732     }
01733     return false;
01734 }
01735 
01736 static uint8_t thread_unstable_commission_data_length(protocol_interface_info_entry_t *cur)
01737 {
01738     uint8_t localDataLength = 0;
01739 
01740     localDataLength += 4; // Commissioner session ID
01741 
01742     if (cur->thread_info->registered_commissioner.commissioner_valid) {
01743         localDataLength += 4; // Border router address
01744         if (cur->thread_info->registered_commissioner.steering_data_len) {
01745             localDataLength += cur->thread_info->registered_commissioner.steering_data_len;
01746             localDataLength += 2;
01747         }
01748     }
01749     return localDataLength;
01750 }
01751 
01752 static uint8_t *thread_unstable_commission_data_write(protocol_interface_info_entry_t *cur, uint8_t *ptr)
01753 {
01754 
01755     uint8_t length = thread_unstable_commission_data_length(cur);
01756     if (!length) {
01757         // No unstable TLV in thread 1.0 or if TLV is empty we skip it
01758         return ptr;
01759     }
01760     *ptr++ = THREAD_NWK_DATA_TYPE_COMMISSION_DATA ;
01761     *ptr++ = length;
01762     ptr = thread_meshcop_tlv_data_write_uint16(ptr, MESHCOP_TLV_COMMISSIONER_SESSION_ID, cur->thread_info->registered_commissioner.session_id);
01763     if (cur->thread_info->registered_commissioner.commissioner_valid) {
01764         //SET Commision TLV
01765         ptr = thread_meshcop_tlv_data_write(ptr, MESHCOP_TLV_BORDER_ROUTER_LOCATOR, 2, &cur->thread_info->registered_commissioner.border_router_address[14]);
01766         if (cur->thread_info->registered_commissioner.steering_data_len) {
01767             ptr = thread_meshcop_tlv_data_write(ptr, MESHCOP_TLV_STEERING_DATA, cur->thread_info->registered_commissioner.steering_data_len, cur->thread_info->registered_commissioner.steering_data);
01768         }
01769     }
01770     return ptr;
01771 }
01772 
01773 static uint16_t thread_leader_service_network_data_length(protocol_interface_info_entry_t *cur, bool fullist)
01774 {
01775     uint16_t networkDataLength = 0;
01776     uint16_t prefixDataLength = 0;
01777     uint16_t commissionDataLength = 0;
01778 
01779     prefixDataLength = thread_network_data_prefix_set_size(&cur->thread_info->networkDataStorage, fullist);
01780     if (prefixDataLength) {
01781         networkDataLength += prefixDataLength;
01782     }
01783     prefixDataLength = thread_network_data_service_set_size(&cur->thread_info->networkDataStorage, fullist);
01784     if (prefixDataLength) {
01785         networkDataLength += prefixDataLength;
01786     }
01787     commissionDataLength = thread_unstable_commission_data_length(cur);
01788     if (fullist && commissionDataLength) {
01789         networkDataLength += 2 + commissionDataLength;
01790     }
01791 
01792     return networkDataLength;
01793 }
01794 
01795 static uint8_t *thread_leader_service_network_data_tlv_write(protocol_interface_info_entry_t *cur, uint8_t *ptr)
01796 {
01797     ptr = thread_network_data_prefix_set_write(&cur->thread_info->networkDataStorage, ptr);
01798     ptr = thread_network_data_service_set_write(&cur->thread_info->networkDataStorage, ptr);
01799     ptr = thread_unstable_commission_data_write(cur, ptr);
01800 
01801     return ptr;
01802 }
01803 
01804 void thread_leader_service_generate_network_data(protocol_interface_info_entry_t *cur)
01805 {
01806     int16_t size = thread_leader_service_network_data_length(cur, true);
01807 
01808     if (size > 0) {
01809         tr_debug("Leader network data size %d", size);
01810         thread_leader_service_network_data_tlv_write(cur, cur->thread_info->networkDataStorage.network_data);
01811         cur->thread_info->networkDataStorage.network_data_len = size;
01812     }
01813 }
01814 
01815 uint16_t thread_leader_service_child_id_from_networkdata_get(thread_info_t *thread_info, uint16_t router_short_addr)
01816 {
01817     return thread_network_data_service_child_id_from_networkdata_get(&thread_info->networkDataStorage, router_short_addr);
01818 }
01819 
01820 void thread_leader_service_router_state_changed(thread_info_t *thread_info, uint8_t router_id, bool available, int8_t interface_id)
01821 {
01822     thread_leader_info_t *info = thread_info->leader_private_data;
01823     (void)interface_id;
01824 
01825     if (!info) {
01826         return;
01827     }
01828     if (available) {
01829         /* Stop the timer */
01830         info->thread_router_id_list[router_id].validLifeTime = 0xffffffff;
01831     } else {
01832         /* Reset the timer to ROUTER_ID_REUSE_DELAY, if it's not already running. */
01833         if (info->thread_router_id_list[router_id].validLifeTime == 0xffffffff) {
01834             tr_debug("Router ID: %d cost infinite", router_id);
01835 
01836             info->thread_router_id_list[router_id].validLifeTime = ROUTER_ID_INFINITY_DELAY;
01837             info->thread_router_id_list[router_id].reUsePossible = false;
01838         }
01839     }
01840 }
01841 
01842 #endif // HAVE_THREAD_LEADER_SERVICE */