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_network_synch.c Source File

thread_network_synch.c

00001 /*
00002  * Copyright (c) 2015-2018, Arm Limited and affiliates.
00003  * SPDX-License-Identifier: BSD-3-Clause
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holder nor the
00014  *    names of its contributors may be used to endorse or promote products
00015  *    derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 /*
00031  * \file thread_network_synch.c
00032  *
00033  */
00034 #include "nsconfig.h"
00035 #ifdef HAVE_THREAD
00036 #include <string.h>
00037 #include <ns_types.h>
00038 #include <nsdynmemLIB.h>
00039 #include "eventOS_event.h"
00040 #include "eventOS_event_timer.h"
00041 #include "randLIB.h"
00042 #include "common_functions.h"
00043 #include "NWK_INTERFACE/Include/protocol.h"
00044 #include "net_thread_test.h"
00045 #include "libDHCPv6/libDHCPv6.h"
00046 #include "libDHCPv6/libDHCPv6_server.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_host_bootstrap.h"
00054 #include "6LoWPAN/Thread/thread_router_bootstrap.h"
00055 #include "6LoWPAN/Thread/thread_management_internal.h"
00056 #include "6LoWPAN/Thread/thread_joiner_application.h"
00057 #include "6LoWPAN/Thread/thread_management_client.h"
00058 #include "6LoWPAN/Thread/thread_network_synch.h"
00059 #include "6LoWPAN/Thread/thread_neighbor_class.h"
00060 #include "thread_management_if.h"
00061 #include "thread_config.h"
00062 #include "Common_Protocols/ipv6.h"
00063 #include "Common_Protocols/icmpv6.h"
00064 #include "Common_Protocols/icmpv6_radv.h"
00065 #include "MLE/mle.h"
00066 #include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
00067 #include "6LoWPAN/MAC/mac_helper.h"
00068 
00069 #define TRACE_GROUP "tsyn"
00070 
00071 typedef struct thread_sync_child_info {
00072     uint32_t mle_frame_counter;
00073     uint32_t mac_frame_counter;
00074     uint8_t long_addr[8];
00075     uint16_t short_addr;
00076     uint8_t mode;
00077 } thread_sync_child_info_t;
00078 
00079 typedef struct thread_network_dynamic_data_store {
00080     thread_leader_info_t *leader_private_data;
00081     thread_parent_info_t *thread_endnode_parent;
00082     thread_attach_state_e thread_attached_state;
00083     uint16_t shortAddress;
00084     thread_sync_child_info_t children[THREAD_MAX_CHILD_COUNT];
00085 } thread_network_dynamic_data_store_t;
00086 
00087 
00088 typedef struct thread_network_dynamic_data_entry {
00089     int8_t interfaceId;
00090     ns_list_link_t link; /*!< List link entry */
00091     thread_network_dynamic_data_store_t networ_dynamic_data_parameters;
00092 } thread_network_dynamic_data_entry_t;
00093 
00094 static thread_sync_child_info_t *thread_dynamic_storage_free_child_find(int8_t interface_id);
00095 static thread_sync_child_info_t *thread_dynamic_storage_child_info_find(int8_t interface_id, mac_neighbor_table_entry_t *child);
00096 static NS_LIST_DEFINE(thread_network_dynamic_data_info, thread_network_dynamic_data_entry_t, link);
00097 
00098 thread_network_dynamic_data_entry_t *thread_network_synch_create(int8_t interfaceId)
00099 {
00100     thread_network_dynamic_data_entry_t *newEntry = ns_dyn_mem_alloc(sizeof(thread_network_dynamic_data_entry_t));
00101     if (newEntry) {
00102         tr_debug("Allocate New Store");
00103         newEntry->interfaceId = interfaceId;
00104         newEntry->networ_dynamic_data_parameters.thread_attached_state = THREAD_STATE_NETWORK_DISCOVER;
00105         newEntry->networ_dynamic_data_parameters.shortAddress = 0xfffe;
00106         newEntry->networ_dynamic_data_parameters.leader_private_data = NULL;
00107         newEntry->networ_dynamic_data_parameters.thread_endnode_parent = NULL;
00108         for (int i = 0; i < THREAD_MAX_CHILD_COUNT; ++i) {
00109             memset(&newEntry->networ_dynamic_data_parameters.children[i], 0, sizeof(thread_sync_child_info_t));
00110         }
00111         ns_list_add_to_end(&thread_network_dynamic_data_info, newEntry);
00112     }
00113     return newEntry;
00114 }
00115 
00116 thread_network_dynamic_data_entry_t *thread_network_synch_find(int8_t interfaceId)
00117 {
00118     //Check current  List
00119     ns_list_foreach(thread_network_dynamic_data_entry_t, cur, &thread_network_dynamic_data_info) {
00120         if (interfaceId == cur->interfaceId) {
00121             return cur;
00122         }
00123     }
00124     return NULL;
00125 }
00126 
00127 int thread_network_synch_delete(int8_t interfaceId)
00128 {
00129     thread_network_dynamic_data_entry_t *newEntry = thread_network_synch_find(interfaceId);
00130     if (newEntry) {
00131         //Free
00132         if (newEntry->networ_dynamic_data_parameters.leader_private_data) {
00133             ns_dyn_mem_free(newEntry->networ_dynamic_data_parameters.leader_private_data);
00134         }
00135 
00136         if (newEntry->networ_dynamic_data_parameters.thread_endnode_parent) {
00137             ns_dyn_mem_free(newEntry->networ_dynamic_data_parameters.thread_endnode_parent);
00138         }
00139 
00140         newEntry->networ_dynamic_data_parameters.thread_attached_state = THREAD_STATE_NETWORK_DISCOVER;
00141         newEntry->networ_dynamic_data_parameters.shortAddress = 0xfffe;
00142         newEntry->networ_dynamic_data_parameters.leader_private_data = NULL;
00143         newEntry->networ_dynamic_data_parameters.thread_endnode_parent = NULL;
00144 
00145         return 0;
00146     }
00147     return -1;
00148 }
00149 
00150 //Call This when clean synched networkdata
00151 int thread_network_synch_data_free(int8_t interface_id)
00152 {
00153     return thread_network_synch_delete(interface_id);
00154 }
00155 
00156 /*
00157  * Dynamic network data storage.
00158  */
00159 
00160 void thread_dynamic_storage_child_info_store(protocol_interface_info_entry_t *cur_interface, mac_neighbor_table_entry_t *child)
00161 {
00162     thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(cur_interface->id);
00163 
00164     if (!storeEntry) {
00165         storeEntry = thread_network_synch_create(cur_interface->id);
00166     }
00167 
00168     if (!storeEntry) {
00169         return;
00170     }
00171 
00172     uint32_t mle_frame_counter = mle_service_neighbor_frame_counter_get(cur_interface->id, child->index );
00173 
00174     thread_sync_child_info_t *child_info = thread_dynamic_storage_child_info_find(cur_interface->id, child);
00175     if (!child_info) {
00176         child_info = thread_dynamic_storage_free_child_find(cur_interface->id);
00177     }
00178 
00179     if (child_info) {
00180         uint8_t mode = mle_mode_write_from_mac_entry(child);
00181         mode |= thread_neighbor_class_mode_write_from_entry(&cur_interface->thread_info->neighbor_class, child->index );
00182 
00183         child_info->mode = mode;
00184         child_info->short_addr = child->mac16 ;
00185         child_info->mle_frame_counter = mle_frame_counter;
00186         child_info->mac_frame_counter = 0;
00187         memcpy(child_info->long_addr, child->mac64 , 8);
00188         return;
00189     }
00190     return;
00191 }
00192 
00193 void thread_dynamic_storage_child_info_clear(int8_t interface_id, struct mac_neighbor_table_entry *child)
00194 {
00195     thread_sync_child_info_t *child_info = thread_dynamic_storage_child_info_find(interface_id, child);
00196 
00197     if (child_info) {
00198         // Clear child information
00199         memset(child_info, 0, sizeof(thread_sync_child_info_t));
00200         tr_debug("Dynamic storage: cleared child; mac16=%04x", child->mac16 );
00201         return;
00202     }
00203     return;
00204 }
00205 
00206 static thread_sync_child_info_t *thread_dynamic_storage_child_info_find(int8_t interface_id, mac_neighbor_table_entry_t *child)
00207 {
00208     thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id);
00209 
00210     if (!storeEntry) {
00211         return NULL;
00212     }
00213 
00214     for (uint16_t i = 0; i < THREAD_MAX_CHILD_COUNT; ++i) {
00215         uint8_t *mac64 = storeEntry->networ_dynamic_data_parameters.children[i].long_addr;
00216         if (memcmp(mac64, child->mac64 , 8) == 0) {
00217             return &storeEntry->networ_dynamic_data_parameters.children[i];
00218         }
00219     }
00220     return NULL;
00221 }
00222 
00223 static thread_sync_child_info_t *thread_dynamic_storage_free_child_find(int8_t interface_id)
00224 {
00225     thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id);
00226     if (!storeEntry) {
00227         return NULL;
00228     }
00229     for (int i = 0; i < THREAD_MAX_CHILD_COUNT; ++i) {
00230         if (storeEntry->networ_dynamic_data_parameters.children[i].short_addr == 0) {
00231             return &storeEntry->networ_dynamic_data_parameters.children[i];
00232         }
00233     }
00234     return NULL;
00235 }
00236 
00237 void thread_dynamic_storage_build_mle_table(int8_t interface_id)
00238 {
00239     tr_debug("Dynamic storage: building MLE table.");
00240     protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
00241     if (!cur || !cur->mac_parameters) {
00242         return;
00243     }
00244 
00245     thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id);
00246     bool new_entry_created;
00247 
00248     if (!storeEntry) {
00249         storeEntry = thread_network_synch_create(interface_id);
00250     }
00251 
00252     if (!storeEntry) {
00253         return;
00254     }
00255 
00256     mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
00257 
00258     if (!mac_table_list) {
00259         return;
00260     }
00261 
00262     int i;
00263     for (i = 0; i < THREAD_MAX_CHILD_COUNT; ++i) {
00264         if (storeEntry->networ_dynamic_data_parameters.children[i].short_addr == 0) {
00265             // Skip empty child entry
00266             continue;
00267         }
00268         uint8_t *mac64 = storeEntry->networ_dynamic_data_parameters.children[i].long_addr;
00269         tr_debug("Child: %04x, %s", storeEntry->networ_dynamic_data_parameters.children[i].short_addr, trace_array(mac64, 8));
00270 
00271         mac_neighbor_table_entry_t *mac_entry = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(cur), mac64, true, &new_entry_created);
00272         if (mac_entry) {
00273 
00274             mac_entry->mac16  = storeEntry->networ_dynamic_data_parameters.children[i].short_addr;
00275             mle_service_frame_counter_entry_add(interface_id, mac_entry->index , storeEntry->networ_dynamic_data_parameters.children[i].mle_frame_counter);
00276             mle_mode_parse_to_mac_entry(mac_entry, storeEntry->networ_dynamic_data_parameters.children[i].mode);
00277 
00278             // Set MAC layer frame counter for the child
00279             mlme_device_descriptor_t device_desc;
00280             thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, mac_entry->index , 64, new_entry_created);
00281             thread_neighbor_class_mode_parse_to_entry(&cur->thread_info->neighbor_class, mac_entry->index , storeEntry->networ_dynamic_data_parameters.children[i].mode);
00282             thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, mac_entry->index );
00283             mac_helper_device_description_write(cur, &device_desc, mac_entry->mac64 , mac_entry->mac16 , storeEntry->networ_dynamic_data_parameters.children[i].mac_frame_counter, false);
00284             mac_helper_devicetable_set(&device_desc, cur, mac_entry->index , cur->mac_parameters->mac_default_key_index, new_entry_created);
00285         }
00286     }
00287 }
00288 #endif