Gleb Klochkov / Mbed OS Climatcontroll_Main

Dependencies:   esp8266-driver

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