Skip to content

Commit 9c6b876

Browse files
added nvm support for leader router id allocation. (#1626)
nvm support for MLE-ID to router id mapping maintained by the leader. This enables the leader to reallocate router ids even after restart.
1 parent 4f5e97d commit 9c6b876

File tree

6 files changed

+130
-4
lines changed

6 files changed

+130
-4
lines changed

source/6LoWPAN/Thread/thread_common.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,7 @@ thread_leader_info_t *thread_allocate_and_init_leader_private_data(void)
524524
thread_leader_info_t *leader_info = ns_dyn_mem_alloc(sizeof(thread_leader_info_t));
525525
if (leader_info) {
526526
leader_info->leader_id_seq_timer = ID_SEQUENCE_PERIOD;
527+
leader_info->leader_nvm_sync_timer = 0;
527528
}
528529
return leader_info;
529530
}

source/6LoWPAN/Thread/thread_common.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
*/
4949
#define ROUTER_ID_REUSE_DELAY 100 //Seconds
5050

51+
#define LEADER_NVM_SYNC_DELAY 30 // Leader router ids write delay to NVM
52+
5153
#define ROUTER_ID_INFINITY_DELAY 90 //Seconds
5254

5355
#define NETWORK_ID_TIMEOUT 120 //seconds
@@ -145,6 +147,7 @@ typedef struct thread_leader_info_s {
145147
uint8_t leader_id_seq_timer;
146148
uint8_t master_router_id_mask[8];
147149
uint8_t maskSeq;
150+
uint8_t leader_nvm_sync_timer;
148151
} thread_leader_info_t;
149152

150153
typedef struct thread_leader_data_s {

source/6LoWPAN/Thread/thread_leader_service.c

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,28 @@ static void thread_leader_allocate_router_id_by_allocated_id(thread_leader_info_
733733
info->thread_router_id_list[router_id].reUsePossible = false;
734734
}
735735

736+
void thread_leader_mleid_rloc_map_populate(thread_nvm_mleid_rloc_map *mleid_rloc_map, thread_leader_info_t *leader_private_info)
737+
{
738+
for (uint8_t i = 0; i < 64; i++) {
739+
if (bit_test(leader_private_info->master_router_id_mask, i)) {
740+
memcpy(mleid_rloc_map->mleid_rloc_map[i].mle_id, leader_private_info->thread_router_id_list[i].eui64, 8);
741+
}
742+
}
743+
}
744+
745+
static int thread_leader_update_mleid_rloc_map_in_nvm(protocol_interface_info_entry_t *cur)
746+
{
747+
thread_nvm_mleid_rloc_map *mleid_rloc_map = ns_dyn_mem_temporary_alloc(sizeof(thread_nvm_mleid_rloc_map));
748+
if (!mleid_rloc_map) {
749+
return -1;
750+
}
751+
memset(mleid_rloc_map, 0, sizeof(thread_nvm_mleid_rloc_map));
752+
thread_leader_mleid_rloc_map_populate(mleid_rloc_map, cur->thread_info->leader_private_data);
753+
thread_nvm_store_mleid_rloc_map_write(mleid_rloc_map);
754+
ns_dyn_mem_free(mleid_rloc_map);
755+
return 0;
756+
}
757+
736758
static int thread_leader_service_router_id_allocate(const uint8_t *eui64, protocol_interface_info_entry_t *cur, thread_leader_service_router_id_resp_t *reponse)
737759
{
738760
int ret_val = -1;
@@ -793,6 +815,8 @@ static int thread_leader_service_router_id_allocate(const uint8_t *eui64, protoc
793815
if (!bit_test(leader_private_ptr->master_router_id_mask, id)) {
794816
if (leader_private_ptr->thread_router_id_list[id].reUsePossible) {
795817
allocated_id = id;
818+
// new id allocated save to nvm after delay
819+
leader_private_ptr->leader_nvm_sync_timer = LEADER_NVM_SYNC_DELAY;
796820
break;
797821
}
798822
}
@@ -847,6 +871,7 @@ static int thread_leader_service_router_id_deallocate(const uint8_t *eui64, prot
847871
//Active ID
848872
if (memcmp(eui64, leader_private_ptr->thread_router_id_list[i].eui64, 8) == 0) {
849873
tr_debug("Release Router Id %d", i);
874+
leader_private_ptr->leader_nvm_sync_timer = LEADER_NVM_SYNC_DELAY;
850875
thread_leader_service_route_mask_bit_clear(leader_private_ptr, i);
851876
leader_private_ptr->thread_router_id_list[i].reUsePossible = true;
852877
leader_private_ptr->thread_router_id_list[i].validLifeTime = 0;
@@ -1318,6 +1343,8 @@ static void thread_leader_service_interface_setup_activate(protocol_interface_in
13181343
//SET Router ID
13191344
thread_leader_allocate_router_id_by_allocated_id(private, routerId, cur->mac);
13201345
thread_old_partition_data_purge(cur);
1346+
// remove any existing rloc mapping in nvm
1347+
thread_nvm_store_mleid_rloc_map_remove();
13211348
cur->lowpan_address_mode = NET_6LOWPAN_GP16_ADDRESS;
13221349
thread_bootstrap_update_ml16_address(cur, cur->thread_info->routerShortAddress);
13231350
thread_generate_ml64_address(cur);
@@ -1500,6 +1527,16 @@ void thread_leader_service_timer(protocol_interface_info_entry_t *cur, uint32_t
15001527
thread_leader_service_network_data_changed(cur, false, false);
15011528
}
15021529

1530+
if (cur->thread_info->leader_private_data->leader_nvm_sync_timer) {
1531+
if ((cur->thread_info->leader_private_data->leader_nvm_sync_timer) > ticks) {
1532+
cur->thread_info->leader_private_data->leader_nvm_sync_timer -= ticks;
1533+
}
1534+
else {
1535+
cur->thread_info->leader_private_data->leader_nvm_sync_timer = 0;
1536+
thread_leader_update_mleid_rloc_map_in_nvm(cur);
1537+
}
1538+
}
1539+
15031540
thread_leader_service_router_id_valid_lifetime_update(cur, ticks);
15041541

15051542
}
@@ -1619,22 +1656,33 @@ int thread_leader_service_thread_partitition_restart(int8_t interface_id, mle_tl
16191656
}
16201657
//Learn network data, we remove own data from here it should be re given by application
16211658
//thread_management_network_data_register(cur->id, networkData.dataPtr, networkData.tlvLen, address16 );
1622-
1659+
thread_nvm_mleid_rloc_map *mleid_rloc_map = ns_dyn_mem_temporary_alloc(sizeof(thread_nvm_mleid_rloc_map));
1660+
if (!mleid_rloc_map) {
1661+
return -1;
1662+
}
1663+
if (thread_nvm_store_mleid_rloc_map_read(mleid_rloc_map) != THREAD_NVM_FILE_SUCCESS) {
1664+
memset(mleid_rloc_map, 0, sizeof(thread_nvm_mleid_rloc_map));
1665+
}
16231666
// initialize private data
16241667
thread_info(cur)->leader_private_data->maskSeq = *routing->dataPtr;
1625-
memcpy(thread_info(cur)->leader_private_data->master_router_id_mask,routing->dataPtr + 1,8);
1668+
memcpy(thread_info(cur)->leader_private_data->master_router_id_mask,routing->dataPtr + 1, 8);
16261669
for (int i = 0; i < 64; i++) {
1627-
memset(thread_info(cur)->leader_private_data->thread_router_id_list[i].eui64,0,8);
16281670
if (bit_test(thread_info(cur)->leader_private_data->master_router_id_mask, i)) {
16291671
//Active ID
16301672
thread_info(cur)->leader_private_data->thread_router_id_list[i].reUsePossible = false;
1631-
1673+
memcpy(thread_info(cur)->leader_private_data->thread_router_id_list[i].eui64, mleid_rloc_map->mleid_rloc_map[i].mle_id, 8);
16321674
} else {
16331675
// Free id
16341676
thread_info(cur)->leader_private_data->thread_router_id_list[i].reUsePossible = true;
1677+
// clear the mleid in both local router id list and nvm
1678+
memset(thread_info(cur)->leader_private_data->thread_router_id_list[i].eui64, 0, 8);
1679+
memset(mleid_rloc_map->mleid_rloc_map[i].mle_id, 0, 8);
16351680
}
16361681
thread_info(cur)->leader_private_data->thread_router_id_list[i].validLifeTime = 0xffffffff;
16371682
}
1683+
// write back updated map to store
1684+
thread_nvm_store_mleid_rloc_map_write(mleid_rloc_map);
1685+
ns_dyn_mem_free(mleid_rloc_map);
16381686
// Clear network data (if exists) and propagate new empty network data
16391687
thread_network_data_free_and_clean(&cur->thread_info->networkDataStorage);
16401688
thread_network_data_base_init(&cur->thread_info->networkDataStorage);

source/6LoWPAN/Thread/thread_nvm_store.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ const char *FAST_DATA_FILE = "f_d";
5252
const char *LINK_INFO_FILE = "l_i";
5353
#define LINK_INFO_DATA_VERSION 1
5454

55+
const char *LEADER_INFO_FILE = "ld_i";
56+
#define LEADER_INFO_DATA_VERSION 1
57+
5558
typedef struct {
5659
uint8_t mac[8];
5760
uint16_t short_addr;
@@ -88,6 +91,7 @@ static void thread_nvm_store_link_info_delayed_write(uint32_t seconds);
8891
#define DEVICE_CONF_STRING_LEN (strlen(DEVICE_CONF_FILE)+strlen(thread_nvm_store_get_root_path())+1)
8992
#define PENDING_CONF_STRING_LEN (strlen(THREAD_NVM_PENDING_CONF_FILE)+strlen(thread_nvm_store_get_root_path())+1)
9093
#define LINK_INFO_STRING_LEN (strlen(LINK_INFO_FILE)+strlen(thread_nvm_store_get_root_path())+1)
94+
#define LEADER_INFO_STRING_LEN (strlen(LEADER_INFO_FILE)+strlen(thread_nvm_store_get_root_path())+1)
9195

9296

9397
thread_nvm_fast_data_t cached_fast_data;
@@ -117,6 +121,62 @@ static int root_path_valid(void)
117121
}
118122
return 1;
119123
}
124+
125+
int thread_nvm_store_mleid_rloc_map_write(thread_nvm_mleid_rloc_map *mleid_rloc_map)
126+
{
127+
char lc_data_path[LEADER_INFO_STRING_LEN];
128+
if (!root_path_valid()) {
129+
return THREAD_NVM_FILE_ROOT_PATH_INVALID;
130+
}
131+
thread_nvm_store_create_path(lc_data_path, LEADER_INFO_FILE);
132+
tr_debug("writing to store rloc mapping info");
133+
return thread_nvm_store_write(lc_data_path, mleid_rloc_map, sizeof(thread_nvm_mleid_rloc_map), LEADER_INFO_DATA_VERSION);
134+
}
135+
136+
int thread_nvm_store_mleid_rloc_map_read(thread_nvm_mleid_rloc_map *mleid_rloc_map)
137+
{
138+
char lc_data_path[LEADER_INFO_STRING_LEN];
139+
uint32_t version;
140+
if (NULL==mleid_rloc_map) {
141+
return THREAD_NVM_FILE_PARAMETER_INVALID;
142+
}
143+
if (!root_path_valid()) {
144+
return THREAD_NVM_FILE_ROOT_PATH_INVALID;
145+
}
146+
thread_nvm_store_create_path(lc_data_path, LEADER_INFO_FILE);
147+
148+
int ret = thread_nvm_store_read(lc_data_path, mleid_rloc_map, sizeof(thread_nvm_mleid_rloc_map), &version);
149+
150+
if (LEADER_INFO_DATA_VERSION!=version) {
151+
tr_info("Leader data map version mismatch %"PRIu32, version);
152+
thread_nvm_store_mleid_rloc_map_remove();
153+
return THREAD_NVM_FILE_VERSION_WRONG;
154+
}
155+
if (THREAD_NVM_FILE_SUCCESS!=ret) {
156+
tr_info("Leader data map read failed");
157+
thread_nvm_store_mleid_rloc_map_remove();
158+
}
159+
return ret;
160+
}
161+
162+
int thread_nvm_store_mleid_rloc_map_remove(void)
163+
{
164+
int status;
165+
tr_info("thread_nvm_store_leader_info_remove");
166+
167+
if (!ns_file_system_get_root_path()) {
168+
return THREAD_NVM_FILE_ROOT_PATH_INVALID;
169+
}
170+
171+
char lc_data_path[LEADER_INFO_STRING_LEN];
172+
thread_nvm_store_create_path(lc_data_path, LEADER_INFO_FILE);
173+
status = remove(lc_data_path);
174+
if (status != 0) {
175+
return THREAD_NVM_FILE_REMOVE_ERROR;
176+
}
177+
return THREAD_NVM_FILE_SUCCESS;
178+
}
179+
120180
int thread_nvm_store_device_configuration_write(uint8_t *mac_ptr, uint8_t *mleid_ptr)
121181
{
122182
thread_nvm_device_conf_t d_c;

source/6LoWPAN/Thread/thread_nvm_store.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,15 @@ typedef struct {
6767
uint8_t mle_id[8];
6868
} thread_nvm_device_conf_t;
6969

70+
typedef struct {
71+
uint8_t mle_id[8];
72+
} thread_nvm_rloc_map_entry_t;
73+
74+
typedef struct {
75+
// mapping is in order from 0 to 63
76+
thread_nvm_rloc_map_entry_t mleid_rloc_map[64];
77+
} thread_nvm_mleid_rloc_map;
78+
7079
/* reads all fast data from nvm, if the return values is THREAD_NVM_FILE_ROOT_PATH_INVALID, the cached values are returned. */
7180
int thread_nvm_store_fast_data_read(thread_nvm_fast_data_t* fast_data);
7281
/* stores all fast data to nvm */
@@ -87,6 +96,9 @@ int thread_nvm_store_active_configuration_remove(void);
8796

8897
int thread_nvm_store_device_configuration_write(uint8_t *mac_ptr, uint8_t *mleid_ptr);
8998
int thread_nvm_store_device_configuration_read(uint8_t *mac_ptr, uint8_t *mleid_ptr);
99+
int thread_nvm_store_mleid_rloc_map_write(thread_nvm_mleid_rloc_map *mleid_rloc_map);
100+
int thread_nvm_store_mleid_rloc_map_read(thread_nvm_mleid_rloc_map *mleid_rloc_map);
101+
int thread_nvm_store_mleid_rloc_map_remove(void);
90102
int thread_nvm_store_pending_configuration_write(void *data, uint16_t size);
91103
int thread_nvm_store_pending_configuration_read(void *data, uint16_t size);
92104
int thread_nvm_store_pending_configuration_remove(void);

source/6LoWPAN/Thread/thread_router_bootstrap.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,8 @@ static void thread_router_synch_receive_cb(int8_t interface_id, mle_message_t *m
410410
cur->thread_info->thread_leader_data->dataVersion--;
411411
cur->thread_info->thread_leader_data->stableDataVersion--;
412412
thread_network_data_request_send(cur, mle_msg->packet_src_address, true);
413+
// remove any existing rloc mapping in nvm
414+
thread_nvm_store_mleid_rloc_map_remove();
413415
tr_info("Router synch OK as Router");
414416
}
415417

0 commit comments

Comments
 (0)