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