BA
/
BaBoRo1
Embed:
(wiki syntax)
Show/hide line numbers
thread_nvm_store.c
00001 /* 00002 * Copyright (c) 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 * \file thread_nvm_store.c 00031 * 00032 */ 00033 00034 #include "nsconfig.h" 00035 00036 #include <string.h> 00037 #include <stdio.h> 00038 #include "Core/include/address.h" 00039 #include "ns_file_system.h" 00040 #include "thread_config.h" 00041 #include "thread_common.h" 00042 #include "thread_nvm_store.h" 00043 #include "ns_trace.h" 00044 00045 #define TRACE_GROUP "tnvm" 00046 const char *FAST_DATA_FILE = "f_d"; 00047 #define FAST_DATA_VERSION 1 00048 #define LINK_INFO_WRITE_DELAY 2 00049 #define LINK_INFO_SHORT_ADDR_NOT_SET 0xffff 00050 #define LINK_INFO_WRITE_DONE 0xffff 00051 00052 const char *LINK_INFO_FILE = "l_i"; 00053 #define LINK_INFO_DATA_VERSION 1 00054 00055 typedef struct { 00056 uint8_t mac[8]; 00057 uint16_t short_addr; 00058 } nvm_link_info_t; 00059 00060 typedef struct { 00061 nvm_link_info_t nvm_link_info; 00062 uint16_t write_delay; 00063 bool loaded; 00064 } thread_nvm_store_link_info_t; 00065 00066 const char *THREAD_NVM_ACTIVE_CONF_FILE = "a_c"; 00067 #define ACTIVE_CONF_DATA_VERSION 1 00068 00069 const char *DEVICE_CONF_FILE = "s_d"; 00070 #define DEVICE_CONF_VERSION 1 00071 00072 const char *THREAD_NVM_PENDING_CONF_FILE = "p_c"; 00073 #define PENDING_CONF_DATA_VERSION 1 00074 00075 static const char* thread_nvm_store_get_root_path(void); 00076 static int root_path_valid(void); 00077 static int thread_nvm_store_read(const char *file_name, void *data, uint32_t data_size, uint32_t *version); 00078 static int thread_nvm_store_write(const char *file_name, void *data, uint32_t data_size, uint32_t version); 00079 static void thread_nvm_store_create_path(char* fast_data_path, const char* file_name); 00080 static int thread_nvm_store_fast_data_save(thread_nvm_fast_data_t* fast_data_to_set); 00081 static int thread_nvm_store_all_counters_store(uint32_t mac_frame_counter, uint32_t mle_frame_counter, uint32_t seq_counter); 00082 static void thread_nvm_store_link_info_delayed_write(uint32_t seconds); 00083 00084 #define MAX_ROOT_PATH_LEN 150 00085 00086 #define FAST_DATA_STRING_LEN (strlen(FAST_DATA_FILE)+strlen(thread_nvm_store_get_root_path())+1) 00087 #define ACTIVE_CONF_STRING_LEN (strlen(THREAD_NVM_ACTIVE_CONF_FILE)+strlen(thread_nvm_store_get_root_path())+1) 00088 #define DEVICE_CONF_STRING_LEN (strlen(DEVICE_CONF_FILE)+strlen(thread_nvm_store_get_root_path())+1) 00089 #define PENDING_CONF_STRING_LEN (strlen(THREAD_NVM_PENDING_CONF_FILE)+strlen(thread_nvm_store_get_root_path())+1) 00090 #define LINK_INFO_STRING_LEN (strlen(LINK_INFO_FILE)+strlen(thread_nvm_store_get_root_path())+1) 00091 00092 00093 thread_nvm_fast_data_t cached_fast_data; 00094 thread_nvm_store_link_info_t cached_link_info = { 00095 .nvm_link_info.short_addr = LINK_INFO_SHORT_ADDR_NOT_SET, 00096 .nvm_link_info.mac = {0,0,0,0,0,0,0,0}, 00097 .write_delay = LINK_INFO_WRITE_DELAY, 00098 .loaded = false 00099 }; 00100 00101 static const char* thread_nvm_store_get_root_path(void) 00102 { 00103 char* path = ns_file_system_get_root_path(); 00104 if (NULL==path) { 00105 return ""; 00106 } 00107 return path; 00108 } 00109 00110 static int root_path_valid(void) 00111 { 00112 if (NULL==ns_file_system_get_root_path()) 00113 return 0; 00114 int path_len = strlen(thread_nvm_store_get_root_path()); 00115 if(path_len==0 || path_len>MAX_ROOT_PATH_LEN) { 00116 return 0; 00117 } 00118 return 1; 00119 } 00120 int thread_nvm_store_device_configuration_write(uint8_t *mac_ptr, uint8_t *mleid_ptr) 00121 { 00122 thread_nvm_device_conf_t d_c; 00123 if (!root_path_valid()) { 00124 return THREAD_NVM_FILE_ROOT_PATH_INVALID; 00125 } 00126 memcpy(d_c.mac, mac_ptr, sizeof(d_c.mac)); 00127 memcpy(d_c.mle_id, mleid_ptr, sizeof(d_c.mle_id)); 00128 char device_conf_path[DEVICE_CONF_STRING_LEN]; 00129 thread_nvm_store_create_path(device_conf_path, DEVICE_CONF_FILE); 00130 return thread_nvm_store_write(device_conf_path, &d_c, sizeof(thread_nvm_device_conf_t), DEVICE_CONF_VERSION); 00131 } 00132 00133 int thread_nvm_store_device_configuration_read(uint8_t *mac_ptr, uint8_t *mleid_ptr) 00134 { 00135 int ret = THREAD_NVM_FILE_READ_ERROR; 00136 if (!root_path_valid()) { 00137 return THREAD_NVM_FILE_ROOT_PATH_INVALID; 00138 } 00139 char device_conf_path[DEVICE_CONF_STRING_LEN]; 00140 thread_nvm_store_create_path(device_conf_path, DEVICE_CONF_FILE); 00141 uint32_t version; 00142 thread_nvm_device_conf_t d_c; 00143 00144 ret = thread_nvm_store_read(device_conf_path, &d_c, sizeof(thread_nvm_device_conf_t), &version); 00145 if(THREAD_NVM_FILE_SUCCESS==ret) { 00146 if (THREAD_NVM_FILE_SUCCESS==ret && DEVICE_CONF_VERSION!=version) { 00147 tr_info("fast data version mismatch %"PRIu32, version); 00148 ret = THREAD_NVM_FILE_VERSION_WRONG; 00149 } 00150 else { 00151 memcpy(mac_ptr, d_c.mac, sizeof(d_c.mac)); 00152 memcpy(mleid_ptr, d_c.mle_id, sizeof(d_c.mle_id)); 00153 } 00154 } 00155 return ret; 00156 } 00157 00158 int thread_nvm_store_pending_configuration_write(void *data, uint16_t size) 00159 { 00160 char pc_data_path[PENDING_CONF_STRING_LEN]; 00161 if (NULL==data) { 00162 return THREAD_NVM_FILE_PARAMETER_INVALID; 00163 } 00164 if (!root_path_valid()) { 00165 return THREAD_NVM_FILE_ROOT_PATH_INVALID; 00166 } 00167 thread_nvm_store_create_path(pc_data_path, THREAD_NVM_PENDING_CONF_FILE); 00168 return thread_nvm_store_write(pc_data_path, data, size, PENDING_CONF_DATA_VERSION); 00169 } 00170 00171 int thread_nvm_store_pending_configuration_read(void *data, uint16_t size) 00172 { 00173 char pc_data_path[PENDING_CONF_STRING_LEN]; 00174 uint32_t version; 00175 if (NULL==data) { 00176 return THREAD_NVM_FILE_PARAMETER_INVALID; 00177 } 00178 if (!root_path_valid()) { 00179 return THREAD_NVM_FILE_ROOT_PATH_INVALID; 00180 } 00181 thread_nvm_store_create_path(pc_data_path, THREAD_NVM_PENDING_CONF_FILE); 00182 00183 int ret = thread_nvm_store_read(pc_data_path, data, size, &version); 00184 if (THREAD_NVM_FILE_SUCCESS==ret && PENDING_CONF_DATA_VERSION!=version) { 00185 tr_info("Pending configuration version mismatch %"PRIu32, version); 00186 return THREAD_NVM_FILE_VERSION_WRONG; 00187 } 00188 return ret; 00189 } 00190 00191 int thread_nvm_store_active_configuration_write(void *data, uint16_t data_size) 00192 { 00193 char ac_data_path[ACTIVE_CONF_STRING_LEN]; 00194 if (NULL==data) { 00195 return THREAD_NVM_FILE_PARAMETER_INVALID; 00196 } 00197 if (!root_path_valid()) { 00198 return THREAD_NVM_FILE_ROOT_PATH_INVALID; 00199 } 00200 00201 thread_nvm_store_create_path(ac_data_path, THREAD_NVM_ACTIVE_CONF_FILE); 00202 return thread_nvm_store_write(ac_data_path, data, data_size, ACTIVE_CONF_DATA_VERSION); 00203 } 00204 00205 int thread_nvm_store_active_configuration_read(void *data, uint16_t data_size) 00206 { 00207 char ac_data_path[ACTIVE_CONF_STRING_LEN]; 00208 uint32_t version; 00209 if (NULL==data) { 00210 return THREAD_NVM_FILE_PARAMETER_INVALID; 00211 } 00212 if (!root_path_valid()) { 00213 return THREAD_NVM_FILE_ROOT_PATH_INVALID; 00214 } 00215 thread_nvm_store_create_path(ac_data_path, THREAD_NVM_ACTIVE_CONF_FILE); 00216 00217 int ret = thread_nvm_store_read(ac_data_path, data, data_size, &version); 00218 if (THREAD_NVM_FILE_SUCCESS==ret && ACTIVE_CONF_DATA_VERSION!=version) { 00219 tr_info("active configuration version mismatch %"PRIu32, version); 00220 return THREAD_NVM_FILE_VERSION_WRONG; 00221 } 00222 return ret; 00223 } 00224 00225 int thread_nvm_store_active_configuration_remove(void) 00226 { 00227 if (!root_path_valid()) { 00228 return THREAD_NVM_FILE_ROOT_PATH_INVALID; 00229 } 00230 char ac_data_path[ACTIVE_CONF_STRING_LEN]; 00231 thread_nvm_store_create_path(ac_data_path, THREAD_NVM_ACTIVE_CONF_FILE); 00232 return remove(ac_data_path); 00233 } 00234 00235 int thread_nvm_store_pending_configuration_remove(void) 00236 { 00237 if (!root_path_valid()) { 00238 return THREAD_NVM_FILE_ROOT_PATH_INVALID; 00239 } 00240 char ac_data_path[PENDING_CONF_STRING_LEN]; 00241 thread_nvm_store_create_path(ac_data_path, THREAD_NVM_PENDING_CONF_FILE); 00242 return remove(ac_data_path); 00243 } 00244 00245 00246 int thread_nvm_store_seq_counter_write(uint32_t network_seq_counter) 00247 { 00248 int ret = THREAD_NVM_FILE_SUCCESS; 00249 if (cached_fast_data.seq_counter!=network_seq_counter) { 00250 ret = thread_nvm_store_all_counters_store(cached_fast_data.mac_frame_counter, cached_fast_data.mle_frame_counter, network_seq_counter); 00251 cached_fast_data.seq_counter=network_seq_counter; 00252 } 00253 return ret; 00254 } 00255 00256 int thread_nvm_store_fast_data_check_and_write(uint32_t mac_frame_counter, uint32_t mle_frame_counter, uint32_t network_seq_counter) 00257 { 00258 int ret = THREAD_NVM_FILE_SUCCESS; 00259 if( ((int)(mac_frame_counter - cached_fast_data.mac_frame_counter) > MAC_FRAME_COUNTER_LIMIT) || 00260 ((int)(mle_frame_counter - cached_fast_data.mle_frame_counter) > MLE_FRAME_COUNTER_LIMIT) || 00261 cached_fast_data.seq_counter!=network_seq_counter) { 00262 ret = thread_nvm_store_all_counters_store(mac_frame_counter, mle_frame_counter, network_seq_counter); 00263 cached_fast_data.mac_frame_counter = mac_frame_counter; 00264 cached_fast_data.mle_frame_counter = mle_frame_counter; 00265 cached_fast_data.seq_counter=network_seq_counter; 00266 } 00267 return ret; 00268 } 00269 00270 00271 int thread_nvm_store_frame_counters_check_and_write(uint32_t mac_frame_counter, uint32_t mle_frame_counter) 00272 { 00273 int ret = THREAD_NVM_FILE_SUCCESS; 00274 if( ((int)(mac_frame_counter - cached_fast_data.mac_frame_counter) > MAC_FRAME_COUNTER_LIMIT) || 00275 ((int)(mle_frame_counter - cached_fast_data.mle_frame_counter) > MLE_FRAME_COUNTER_LIMIT)) { 00276 ret = thread_nvm_store_all_counters_store(mac_frame_counter, mle_frame_counter, cached_fast_data.seq_counter); 00277 cached_fast_data.mac_frame_counter = mac_frame_counter; 00278 cached_fast_data.mle_frame_counter = mle_frame_counter; 00279 } 00280 return ret; 00281 } 00282 00283 static int thread_nvm_store_all_counters_store(uint32_t mac_frame_counter, uint32_t mle_frame_counter, uint32_t network_seq_counter) 00284 { 00285 thread_nvm_fast_data_t fast_data; 00286 fast_data.mac_frame_counter = mac_frame_counter; 00287 fast_data.mle_frame_counter = mle_frame_counter; 00288 fast_data.seq_counter = network_seq_counter; 00289 if (root_path_valid()) { 00290 return thread_nvm_store_fast_data_save(&fast_data); 00291 } 00292 else{ 00293 return THREAD_NVM_FILE_ROOT_PATH_INVALID; 00294 } 00295 } 00296 00297 int thread_nvm_store_fast_data_write(thread_nvm_fast_data_t* fast_data) 00298 { 00299 cached_fast_data.mac_frame_counter = fast_data->mac_frame_counter; 00300 cached_fast_data.mle_frame_counter = fast_data->mle_frame_counter; 00301 cached_fast_data.seq_counter = fast_data->seq_counter; 00302 00303 if (root_path_valid()) { 00304 return thread_nvm_store_fast_data_save(fast_data); 00305 } 00306 else { 00307 return THREAD_NVM_FILE_ROOT_PATH_INVALID; 00308 } 00309 } 00310 00311 static void thread_nvm_store_create_path(char* fast_data_path, const char* file_name) 00312 { 00313 strcpy(fast_data_path, thread_nvm_store_get_root_path()); 00314 strcat(fast_data_path, file_name); 00315 } 00316 00317 int thread_nvm_store_fast_data_read(thread_nvm_fast_data_t* fast_data) 00318 { 00319 int ret = THREAD_NVM_FILE_SUCCESS; 00320 00321 if (root_path_valid()) { 00322 char fast_data_path[FAST_DATA_STRING_LEN]; 00323 thread_nvm_store_create_path(fast_data_path, FAST_DATA_FILE); 00324 uint32_t version; 00325 ret = thread_nvm_store_read(fast_data_path, fast_data, sizeof(thread_nvm_fast_data_t), &version); 00326 if (THREAD_NVM_FILE_SUCCESS==ret && FAST_DATA_VERSION!=version) { 00327 tr_info("fast data version mismatch %"PRIu32, version); 00328 return THREAD_NVM_FILE_VERSION_WRONG; 00329 } 00330 } 00331 else { 00332 fast_data->mac_frame_counter = cached_fast_data.mac_frame_counter; 00333 fast_data->mle_frame_counter = cached_fast_data.mle_frame_counter; 00334 fast_data->seq_counter = cached_fast_data.seq_counter; 00335 } 00336 return ret; 00337 } 00338 00339 static int thread_nvm_store_fast_data_save(thread_nvm_fast_data_t* fast_data_to_set) 00340 { 00341 char fast_data_path[FAST_DATA_STRING_LEN]; 00342 thread_nvm_store_create_path(fast_data_path, FAST_DATA_FILE); 00343 return thread_nvm_store_write(fast_data_path, fast_data_to_set, sizeof(thread_nvm_fast_data_t), FAST_DATA_VERSION); 00344 } 00345 00346 static int thread_nvm_store_write(const char *file_name, void *data, uint32_t data_size, uint32_t version) 00347 { 00348 FILE *fp = fopen(file_name, "w"); 00349 if(fp == NULL) { 00350 tr_error("NVM open error: %s", file_name); 00351 return THREAD_NVM_FILE_CANNOT_OPEN; 00352 } 00353 00354 size_t n_bytes = fwrite(&version, 1, sizeof(uint32_t), fp); 00355 if (n_bytes!=sizeof(uint32_t)) { 00356 tr_warning("NVM version write error"); 00357 fclose(fp); 00358 return THREAD_NVM_FILE_WRITE_ERROR; 00359 } 00360 00361 n_bytes = fwrite(data, 1, data_size, fp); 00362 fclose(fp); 00363 if (n_bytes!=data_size) { 00364 tr_error("NVM write error %s", file_name); 00365 return THREAD_NVM_FILE_WRITE_ERROR; 00366 } 00367 else { 00368 return THREAD_NVM_FILE_SUCCESS; 00369 } 00370 } 00371 00372 // returns 0 when ok 00373 static int thread_nvm_store_read(const char *file_name, void *data, uint32_t data_size, uint32_t *version) 00374 { 00375 FILE *fp = fopen(file_name, "r"); 00376 if(fp == NULL) { 00377 tr_warning("File not found: %s", file_name); 00378 return THREAD_NVM_FILE_CANNOT_OPEN; 00379 } 00380 00381 size_t n_bytes = fread(version, 1, sizeof(uint32_t), fp); 00382 if (n_bytes!=sizeof(uint32_t)) { 00383 tr_warning("NVM version read error %s", file_name); 00384 fclose(fp); 00385 return THREAD_NVM_FILE_READ_ERROR; 00386 } 00387 00388 n_bytes = fread(data, 1, data_size, fp); 00389 fclose(fp); 00390 if (n_bytes!=data_size) { 00391 tr_error("NVM read error %s", file_name); 00392 return THREAD_NVM_FILE_READ_ERROR; 00393 } 00394 else { 00395 return THREAD_NVM_FILE_SUCCESS; // return how many bytes was written. 00396 } 00397 } 00398 00399 int thread_nvm_store_link_info_read(void) 00400 { 00401 nvm_link_info_t nvm_link_info_tmp; 00402 int status; 00403 00404 if (!ns_file_system_get_root_path()) { 00405 if (!memcmp(cached_link_info.nvm_link_info.mac, ADDR_UNSPECIFIED, 8) && 00406 cached_link_info.nvm_link_info.short_addr == LINK_INFO_SHORT_ADDR_NOT_SET) { 00407 tr_info("link info not cached"); 00408 return THREAD_NVM_FILE_READ_ERROR; 00409 } 00410 } 00411 cached_link_info.loaded = true; 00412 char link_info_path[LINK_INFO_STRING_LEN]; 00413 strcpy(link_info_path, thread_nvm_store_get_root_path()); 00414 strcat(link_info_path, LINK_INFO_FILE); 00415 00416 uint32_t version=0; 00417 status = thread_nvm_store_read(link_info_path, &nvm_link_info_tmp, sizeof(nvm_link_info_t), &version); 00418 00419 if (status != THREAD_NVM_FILE_SUCCESS) { 00420 if (!memcmp(cached_link_info.nvm_link_info.mac, ADDR_UNSPECIFIED, 8) && 00421 cached_link_info.nvm_link_info.short_addr == LINK_INFO_SHORT_ADDR_NOT_SET) { 00422 tr_info("link info not cached and read error %d", status); 00423 cached_link_info.loaded = false; 00424 return THREAD_NVM_FILE_READ_ERROR; 00425 } 00426 return status; 00427 } 00428 else if (ACTIVE_CONF_DATA_VERSION != version) { 00429 tr_info("link info version mismatch %"PRIu32, version); 00430 return THREAD_NVM_FILE_VERSION_WRONG; 00431 } 00432 memcpy(cached_link_info.nvm_link_info.mac, nvm_link_info_tmp.mac, 8); 00433 cached_link_info.nvm_link_info.short_addr = nvm_link_info_tmp.short_addr; 00434 tr_info("info read: %s parent short addr: %"PRIu16, trace_array(cached_link_info.nvm_link_info.mac, 8), cached_link_info.nvm_link_info.short_addr); 00435 return THREAD_NVM_FILE_SUCCESS; 00436 } 00437 00438 int thread_nvm_store_link_info_get(uint8_t *parent_mac64, uint16_t *my_short_address) 00439 { 00440 if (!memcmp(cached_link_info.nvm_link_info.mac, ADDR_UNSPECIFIED, 8) && 00441 cached_link_info.nvm_link_info.short_addr == LINK_INFO_SHORT_ADDR_NOT_SET) { 00442 tr_info("thread_nvm_store_link_info_get addr zeros"); 00443 return THREAD_NVM_FILE_READ_ERROR; 00444 } 00445 00446 if (!cached_link_info.loaded) { 00447 return THREAD_NVM_FILE_READ_ERROR; 00448 } 00449 // read data from cache if cached data is available 00450 if (parent_mac64) { 00451 memcpy(parent_mac64, cached_link_info.nvm_link_info.mac, 8); 00452 } 00453 if (my_short_address) { 00454 *my_short_address = cached_link_info.nvm_link_info.short_addr; 00455 } 00456 return THREAD_NVM_FILE_SUCCESS; 00457 } 00458 00459 int thread_nvm_store_link_info_clear(void) 00460 { 00461 int status; 00462 tr_info("thread_nvm_store_link_info_clear"); 00463 memset(cached_link_info.nvm_link_info.mac, 0, 8); 00464 cached_link_info.nvm_link_info.short_addr = LINK_INFO_SHORT_ADDR_NOT_SET; 00465 00466 cached_link_info.loaded = false; 00467 00468 if (!ns_file_system_get_root_path()) { 00469 return THREAD_NVM_FILE_ROOT_PATH_INVALID; 00470 } 00471 00472 char link_info_path[LINK_INFO_STRING_LEN]; 00473 strcpy(link_info_path, thread_nvm_store_get_root_path()); 00474 strcat(link_info_path, LINK_INFO_FILE); 00475 00476 status = remove(link_info_path); 00477 00478 if (status != 0) { 00479 return THREAD_NVM_FILE_REMOVE_ERROR; 00480 } 00481 00482 return THREAD_NVM_FILE_SUCCESS; 00483 } 00484 00485 int thread_nvm_store_link_info_write(uint8_t *parent_mac, uint16_t short_addr) 00486 { 00487 //tr_info("write mac: %s parent short addr: %"PRIu16, trace_array(parent_mac, 8), short_addr); 00488 if (parent_mac) { 00489 memcpy(cached_link_info.nvm_link_info.mac, parent_mac, 8); 00490 } else { 00491 memset(cached_link_info.nvm_link_info.mac, 0, 8); 00492 tr_info("setting to zero"); 00493 } 00494 // when router parent is zeros, but my short address is the actual routing address. 00495 cached_link_info.nvm_link_info.short_addr = short_addr; 00496 00497 if (cached_link_info.write_delay == LINK_INFO_WRITE_DONE) { 00498 cached_link_info.write_delay = LINK_INFO_WRITE_DELAY; // delay writing some seconds 00499 } 00500 00501 if (!ns_file_system_get_root_path()) { 00502 return THREAD_NVM_FILE_ROOT_PATH_INVALID; 00503 } 00504 00505 return THREAD_NVM_FILE_SUCCESS; 00506 } 00507 00508 static void thread_nvm_store_link_info_delayed_write(uint32_t seconds) 00509 { 00510 if (cached_link_info.write_delay == LINK_INFO_WRITE_DONE) { 00511 return; 00512 } 00513 else if (cached_link_info.write_delay > seconds) { 00514 cached_link_info.write_delay -= seconds; 00515 return; 00516 } 00517 cached_link_info.write_delay = LINK_INFO_WRITE_DONE; 00518 00519 if (!ns_file_system_get_root_path()) { 00520 return; 00521 } 00522 00523 char link_info_path[LINK_INFO_STRING_LEN]; 00524 strcpy(link_info_path, thread_nvm_store_get_root_path()); 00525 strcat(link_info_path, LINK_INFO_FILE); 00526 tr_info("link info write parent mac: %s parent short addr: %"PRIu16, trace_array(cached_link_info.nvm_link_info.mac, 8), cached_link_info.nvm_link_info.short_addr); 00527 thread_nvm_store_write(link_info_path, &cached_link_info.nvm_link_info, sizeof(nvm_link_info_t), LINK_INFO_DATA_VERSION); 00528 } 00529 00530 void thread_nvm_store_seconds_timer(uint32_t seconds) 00531 { 00532 thread_nvm_store_link_info_delayed_write(seconds); 00533 }
Generated on Tue Jul 12 2022 12:22:26 by
