Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more
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 void *pending_configuration; 00082 uint64_t pending_timestamp; 00083 uint32_t mle_frame_counter; 00084 uint32_t mac_frame_counter; 00085 uint32_t network_sequence_counter; 00086 uint8_t mleid[8]; 00087 uint8_t mac[8]; 00088 uint16_t shortAddress; 00089 thread_sync_child_info_t children[THREAD_MAX_CHILD_COUNT]; 00090 } thread_network_dynamic_data_store_t; 00091 00092 00093 typedef struct thread_network_dynamic_data_entry { 00094 int8_t interfaceId; 00095 ns_list_link_t link; /*!< List link entry */ 00096 thread_network_dynamic_data_store_t networ_dynamic_data_parameters; 00097 } thread_network_dynamic_data_entry_t; 00098 00099 static thread_sync_child_info_t *thread_dynamic_storage_free_child_find(int8_t interface_id); 00100 static thread_sync_child_info_t *thread_dynamic_storage_child_info_find(int8_t interface_id, mle_neigh_table_entry_t *child); 00101 static NS_LIST_DEFINE(thread_network_dynamic_data_info, thread_network_dynamic_data_entry_t, link); 00102 00103 thread_network_dynamic_data_entry_t *thread_network_synch_create(int8_t interfaceId) 00104 { 00105 thread_network_dynamic_data_entry_t *newEntry = ns_dyn_mem_alloc(sizeof(thread_network_dynamic_data_entry_t)); 00106 if (newEntry) { 00107 tr_debug("Allocate New Store"); 00108 newEntry->interfaceId = interfaceId; 00109 newEntry->networ_dynamic_data_parameters.thread_attached_state = THREAD_STATE_NETWORK_DISCOVER; 00110 newEntry->networ_dynamic_data_parameters.shortAddress = 0xfffe; 00111 newEntry->networ_dynamic_data_parameters.leader_private_data = NULL; 00112 newEntry->networ_dynamic_data_parameters.thread_endnode_parent = NULL; 00113 newEntry->networ_dynamic_data_parameters.pending_configuration = NULL; 00114 newEntry->networ_dynamic_data_parameters.pending_timestamp = 0; 00115 newEntry->networ_dynamic_data_parameters.mac_frame_counter = 0; 00116 newEntry->networ_dynamic_data_parameters.mle_frame_counter = 0; 00117 newEntry->networ_dynamic_data_parameters.network_sequence_counter = 0; 00118 for (int i = 0; i < THREAD_MAX_CHILD_COUNT; ++i) { 00119 memset(&newEntry->networ_dynamic_data_parameters.children[i], 0, sizeof(thread_sync_child_info_t)); 00120 } 00121 ns_list_add_to_end(&thread_network_dynamic_data_info, newEntry); 00122 } 00123 return newEntry; 00124 } 00125 00126 thread_network_dynamic_data_entry_t *thread_network_synch_find(int8_t interfaceId) 00127 { 00128 //Check current List 00129 ns_list_foreach(thread_network_dynamic_data_entry_t, cur, &thread_network_dynamic_data_info) { 00130 if (interfaceId == cur->interfaceId) { 00131 return cur; 00132 } 00133 } 00134 return NULL; 00135 } 00136 00137 int thread_network_synch_delete(int8_t interfaceId) 00138 { 00139 thread_network_dynamic_data_entry_t *newEntry = thread_network_synch_find(interfaceId); 00140 if (newEntry) { 00141 //Free 00142 if (newEntry->networ_dynamic_data_parameters.leader_private_data) { 00143 ns_dyn_mem_free(newEntry->networ_dynamic_data_parameters.leader_private_data); 00144 } 00145 00146 if (newEntry->networ_dynamic_data_parameters.thread_endnode_parent) { 00147 ns_dyn_mem_free(newEntry->networ_dynamic_data_parameters.thread_endnode_parent); 00148 } 00149 00150 newEntry->networ_dynamic_data_parameters.thread_attached_state = THREAD_STATE_NETWORK_DISCOVER; 00151 newEntry->networ_dynamic_data_parameters.shortAddress = 0xfffe; 00152 newEntry->networ_dynamic_data_parameters.leader_private_data = NULL; 00153 newEntry->networ_dynamic_data_parameters.thread_endnode_parent = NULL; 00154 00155 return 0; 00156 } 00157 return -1; 00158 } 00159 00160 //Call This when clean synched networkdata 00161 int thread_network_synch_data_free(int8_t interface_id) 00162 { 00163 return thread_network_synch_delete(interface_id); 00164 } 00165 /* 00166 * Dynamic network data storage. 00167 */ 00168 00169 void thread_dynamic_storage_child_info_store(int8_t interface_id, mle_neigh_table_entry_t *child) 00170 { 00171 thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id); 00172 00173 if (!storeEntry) { 00174 storeEntry = thread_network_synch_create(interface_id); 00175 } 00176 00177 if (!storeEntry) { 00178 return; 00179 } 00180 00181 thread_sync_child_info_t *child_info = thread_dynamic_storage_child_info_find(interface_id, child); 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 return; 00189 } 00190 00191 child_info = thread_dynamic_storage_free_child_find(interface_id); 00192 00193 if (child_info) { 00194 child_info->mode = child->mode; 00195 child_info->short_addr = child->short_adr; 00196 child_info->mle_frame_counter = child->mle_frame_counter; 00197 child_info->mac_frame_counter = 0; 00198 memcpy(child_info->long_addr, child->mac64, 8); 00199 } 00200 return; 00201 } 00202 00203 void thread_dynamic_storage_child_info_clear(int8_t interface_id, mle_neigh_table_entry_t *child) 00204 { 00205 thread_sync_child_info_t *child_info = thread_dynamic_storage_child_info_find(interface_id, child); 00206 00207 if (child_info){ 00208 // Clear child information 00209 memset (child_info,0,sizeof(thread_sync_child_info_t)); 00210 tr_debug("Dynamic storage: cleared child; mac16=%04x", child->short_adr); 00211 return; 00212 } 00213 return; 00214 } 00215 00216 static thread_sync_child_info_t *thread_dynamic_storage_child_info_find(int8_t interface_id, mle_neigh_table_entry_t *child) 00217 { 00218 thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id); 00219 00220 if (!storeEntry) { 00221 return NULL; 00222 } 00223 00224 for (uint16_t i = 0; i < THREAD_MAX_CHILD_COUNT; ++i) { 00225 uint8_t *mac64 = storeEntry->networ_dynamic_data_parameters.children[i].long_addr; 00226 if (memcmp(mac64, child->mac64, 8) == 0) { 00227 return &storeEntry->networ_dynamic_data_parameters.children[i]; 00228 } 00229 } 00230 return NULL; 00231 } 00232 00233 static thread_sync_child_info_t *thread_dynamic_storage_free_child_find(int8_t interface_id) 00234 { 00235 thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id); 00236 if (!storeEntry) { 00237 return NULL; 00238 } 00239 for (int i = 0; i < THREAD_MAX_CHILD_COUNT; ++i) { 00240 if (storeEntry->networ_dynamic_data_parameters.children[i].short_addr == 0) { 00241 return &storeEntry->networ_dynamic_data_parameters.children[i]; 00242 } 00243 } 00244 return NULL; 00245 } 00246 00247 void thread_dynamic_storage_build_mle_table(int8_t interface_id) 00248 { 00249 tr_debug("Dynamic storage: building MLE table."); 00250 00251 thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id); 00252 00253 if (!storeEntry) { 00254 storeEntry = thread_network_synch_create(interface_id); 00255 } 00256 00257 if (!storeEntry) { 00258 return; 00259 } 00260 00261 mle_neigh_table_list_t *neig_list = mle_class_active_list_get(interface_id); 00262 00263 if (!neig_list) { 00264 return; 00265 } 00266 00267 int i; 00268 for (i = 0; i < THREAD_MAX_CHILD_COUNT; ++i) { 00269 if (storeEntry->networ_dynamic_data_parameters.children[i].short_addr == 0) { 00270 // Skip empty child entry 00271 continue; 00272 } 00273 uint8_t *mac64 = storeEntry->networ_dynamic_data_parameters.children[i].long_addr; 00274 tr_debug("Child: %04x, %s", storeEntry->networ_dynamic_data_parameters.children[i].short_addr, trace_array(mac64, 8)); 00275 mle_neigh_table_entry_t *entry = mle_class_get_entry_by_mac64(interface_id, 64, mac64, true); 00276 if (entry) { 00277 entry->short_adr = storeEntry->networ_dynamic_data_parameters.children[i].short_addr; 00278 entry->mle_frame_counter = storeEntry->networ_dynamic_data_parameters.children[i].mle_frame_counter; 00279 entry->mode = storeEntry->networ_dynamic_data_parameters.children[i].mode; 00280 entry->threadNeighbor = true; 00281 00282 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00283 00284 if (cur && cur->mac_parameters) { 00285 // Set MAC layer frame counter for the child 00286 mac_helper_devicetable_set(entry, cur, storeEntry->networ_dynamic_data_parameters.children[i].mac_frame_counter, cur->mac_parameters->mac_default_key_index); 00287 } 00288 } 00289 } 00290 } 00291 00292 00293 00294 /*Pending configuration storage*/ 00295 void thread_dynamic_storage_pending_configuration_store(int8_t interface_id, void *data, uint16_t size) 00296 { 00297 thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id); 00298 if (!storeEntry) { 00299 storeEntry = thread_network_synch_create(interface_id); 00300 } 00301 if (!storeEntry) { 00302 return; 00303 } 00304 00305 tr_info("saved pending configuration to store"); 00306 ns_dyn_mem_free(storeEntry->networ_dynamic_data_parameters.pending_configuration); 00307 storeEntry->networ_dynamic_data_parameters.pending_configuration = NULL; 00308 if (!data || !size) { 00309 return; 00310 } 00311 00312 storeEntry->networ_dynamic_data_parameters.pending_configuration = ns_dyn_mem_alloc(size); 00313 if (!storeEntry->networ_dynamic_data_parameters.pending_configuration) { 00314 return; 00315 } 00316 memcpy(storeEntry->networ_dynamic_data_parameters.pending_configuration, data,size); 00317 00318 } 00319 00320 bool thread_dynamic_storage_pending_configuration_exists(int8_t interface_id) 00321 { 00322 thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id); 00323 if (!storeEntry || !storeEntry->networ_dynamic_data_parameters.pending_configuration) { 00324 tr_debug("no pending config found in store"); 00325 return false; 00326 } 00327 return true; 00328 } 00329 void thread_dynamic_storage_pending_configuration_read(int8_t interface_id, void *data, uint16_t size) 00330 { 00331 thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id); 00332 if (!storeEntry || !storeEntry->networ_dynamic_data_parameters.pending_configuration) { 00333 tr_debug("no pending config found in store"); 00334 return; 00335 } 00336 memcpy(data,storeEntry->networ_dynamic_data_parameters.pending_configuration, size); 00337 return; 00338 } 00339 00340 int thread_pending_data_delete(int8_t interfaceId) 00341 { 00342 thread_network_dynamic_data_entry_t *newEntry = thread_network_synch_find(interfaceId); 00343 if (newEntry) { 00344 //Free 00345 newEntry->networ_dynamic_data_parameters.pending_configuration = NULL; 00346 newEntry->networ_dynamic_data_parameters.pending_timestamp = 0; 00347 return 0; 00348 } 00349 return -1; 00350 } 00351 00352 void thread_dynamic_storage_device_configuration_read(int8_t interface_id, uint8_t *mac_ptr, uint8_t *mleid_ptr) 00353 { 00354 thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id); 00355 if (!storeEntry) { 00356 tr_error("no device configuration in store"); 00357 return; 00358 } 00359 memcpy(mac_ptr,storeEntry->networ_dynamic_data_parameters.mac, 8); 00360 memcpy(mleid_ptr,storeEntry->networ_dynamic_data_parameters.mleid, 8); 00361 return; 00362 } 00363 00364 void thread_dynamic_storage_device_configuration_store(int8_t interface_id, uint8_t *mac_ptr, uint8_t *mleid_ptr) 00365 { 00366 thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id); 00367 if (!storeEntry) { 00368 storeEntry = thread_network_synch_create(interface_id); 00369 } 00370 if (!storeEntry) { 00371 return; 00372 } 00373 tr_debug("store device configuration"); 00374 memcpy(storeEntry->networ_dynamic_data_parameters.mac, mac_ptr, 8); 00375 memcpy(storeEntry->networ_dynamic_data_parameters.mleid,mleid_ptr, 8); 00376 return; 00377 } 00378 00379 static uint8_t loaded = false; 00380 static uint8_t mac[8] = {0}; 00381 static uint16_t short_addr = 0xffff; 00382 00383 void thread_nvm_store_link_info_file_read() 00384 { 00385 if (!memcmp(mac,ADDR_UNSPECIFIED,8) && short_addr == 0xffff) { 00386 return; 00387 } 00388 // File exists at bootup 00389 loaded = true; 00390 } 00391 bool thread_nvm_store_link_info_get(uint8_t *parent_mac64, uint16_t *my_short_address) 00392 { 00393 if (!memcmp(mac,ADDR_UNSPECIFIED,8) && short_addr == 0xffff) { 00394 return false; 00395 } 00396 if (!loaded) { 00397 return false; 00398 } 00399 if (parent_mac64) { 00400 memcpy(parent_mac64,mac,8); 00401 } 00402 if (my_short_address) { 00403 *my_short_address = short_addr; 00404 } 00405 00406 // File was found and values read 00407 return true; 00408 } 00409 00410 void thread_nvm_store_link_info_clear() 00411 { 00412 memset(mac,0,8); 00413 short_addr = 0xffff; 00414 loaded = false; 00415 // synchronised settings were used and now are deleted 00416 // it is only allowed to use synch settings during the first boot 00417 } 00418 00419 void thread_nvm_store_link_info_file_write(protocol_interface_info_entry_t *cur) 00420 { 00421 if(cur->thread_info->thread_endnode_parent) { 00422 memcpy(mac,cur->thread_info->thread_endnode_parent->mac64,8); 00423 } else { 00424 memset(mac,0,8); 00425 } 00426 short_addr = mac_helper_mac16_address_get(cur); 00427 // Settings are changed, but values should not be saved yet only after certain 00428 // grace period. But the values are not returned in get. 00429 } 00430 #endif
Generated on Tue Jul 12 2022 13:03:21 by
