Skip to content

Commit 231daf7

Browse files
author
Juha Heiskanen
committed
Wi-sun NUD State Machine update
Added support to detect timeout for NA after trgiggered NS. NUD will use 2 retry with timeout 5 seconds. Probe and NUD gen random time is 1 - 900ms.
1 parent e7d551c commit 231daf7

File tree

4 files changed

+156
-16
lines changed

4 files changed

+156
-16
lines changed

source/6LoWPAN/ws/ws_bootstrap.c

Lines changed: 132 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,128 @@ static int8_t ws_bootsrap_event_trig(ws_bootsrap_event_type_e event_type, int8_t
176176
return eventOS_event_send(&event);
177177
}
178178

179+
static void ws_nud_table_reset(protocol_interface_info_entry_t *cur)
180+
{
181+
//Empty active list
182+
ns_list_foreach_safe(ws_nud_table_entry_t, entry, &cur->ws_info->active_nud_process) {
183+
ns_list_remove(&cur->ws_info->active_nud_process, entry);
184+
}
185+
186+
//Empty free list
187+
ns_list_foreach_safe(ws_nud_table_entry_t, entry, &cur->ws_info->free_nud_entries) {
188+
ns_list_remove(&cur->ws_info->free_nud_entries, entry);
189+
}
190+
//Add to free list to full
191+
for (int i=0; i< ACTIVE_NUD_PROCESS_MAX; i++) {
192+
ns_list_add_to_end(&cur->ws_info->free_nud_entries, &cur->ws_info->nud_table_entrys[i]);
193+
}
194+
}
195+
196+
static ws_nud_table_entry_t *ws_nud_entry_get_free(protocol_interface_info_entry_t *cur)
197+
{
198+
ws_nud_table_entry_t *entry = ns_list_get_first(&cur->ws_info->free_nud_entries);
199+
if (entry) {
200+
entry->wait_response = false;
201+
entry->retry_count = 0;
202+
entry->nud_process = false;
203+
entry->timer = randLIB_get_random_in_range(1, 900);
204+
entry->neighbor_info = NULL;
205+
ns_list_remove(&cur->ws_info->free_nud_entries, entry);
206+
ns_list_add_to_end(&cur->ws_info->active_nud_process, entry);
207+
}
208+
return entry;
209+
}
210+
211+
212+
void ws_nud_entry_remove_active(protocol_interface_info_entry_t *cur, void *neighbor)
213+
{
214+
ns_list_foreach(ws_nud_table_entry_t, entry, &cur->ws_info->active_nud_process) {
215+
if (entry->neighbor_info == neighbor) {
216+
mac_neighbor_table_entry_t *mac_neighbor = neighbor;
217+
ns_list_remove(&cur->ws_info->active_nud_process, entry);
218+
ns_list_add_to_end(&cur->ws_info->free_nud_entries, entry);
219+
if (mac_neighbor->nud_active) {
220+
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), mac_neighbor, mac_neighbor->link_lifetime);
221+
}
222+
223+
mac_neighbor_table_neighbor_connected(mac_neighbor_info(cur), mac_neighbor);
224+
return;
225+
}
226+
}
227+
}
228+
229+
static void ws_nud_state_clean(protocol_interface_info_entry_t *cur, ws_nud_table_entry_t *entry)
230+
{
231+
mac_neighbor_table_entry_t *neighbor = entry->neighbor_info;
232+
ns_list_remove(&cur->ws_info->active_nud_process, entry);
233+
ns_list_add_to_end(&cur->ws_info->free_nud_entries, entry);
234+
if (neighbor->nud_active) {
235+
neighbor->nud_active = false;
236+
mac_neighbor_info(cur)->active_nud_process--;
237+
}
238+
}
239+
240+
static bool ws_nud_message_build(protocol_interface_info_entry_t *cur, mac_neighbor_table_entry_t *neighbor)
241+
{
242+
//Send NS
243+
uint8_t ll_target[16];
244+
memcpy(ll_target, ADDR_LINK_LOCAL_PREFIX, 8);
245+
memcpy(ll_target + 8, neighbor->mac64, 8);
246+
ll_target[8] ^= 2;
247+
tr_debug("NUD generate NS %u", neighbor->index);
248+
buffer_t * buffer = icmpv6_build_ns(cur, ll_target, NULL, true, false, NULL);
249+
if (buffer) {
250+
protocol_push(buffer);
251+
return true;
252+
}
253+
return false;
254+
}
255+
256+
void ws_nud_active_timer(protocol_interface_info_entry_t *cur, uint16_t time_in_ms)
257+
{
258+
259+
ns_list_foreach_safe(ws_nud_table_entry_t, entry, &cur->ws_info->active_nud_process) {
260+
if (entry->timer <= time_in_ms) {
261+
//TX Process or timeout
262+
if (entry->wait_response) {
263+
//Timeout for NUD or Probe
264+
if (entry->nud_process) {
265+
tr_debug("NUD NA timeout");
266+
if (entry->retry_count < 2) {
267+
entry->timer = randLIB_get_random_in_range(1, 900);
268+
entry->wait_response = false;
269+
} else {
270+
//Clear entry from active list
271+
ws_nud_state_clean(cur, entry);
272+
//Remove whole entry
273+
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry->neighbor_info);
274+
}
275+
} else {
276+
ws_nud_state_clean(cur, entry);
277+
}
278+
279+
} else {
280+
//Random TX wait period is over
281+
entry->wait_response = ws_nud_message_build(cur, entry->neighbor_info);
282+
if (!entry->wait_response) {
283+
if (entry->nud_process && entry->retry_count < 2) {
284+
entry->timer = randLIB_get_random_in_range(1, 900);
285+
} else {
286+
//Clear entry from active list
287+
//Remove and try again later on
288+
ws_nud_state_clean(cur, entry);
289+
}
290+
} else {
291+
entry->retry_count++;
292+
entry->timer = 5001;
293+
}
294+
}
295+
} else {
296+
entry->timer -= time_in_ms;
297+
}
298+
}
299+
}
300+
179301
static fhss_ws_neighbor_timing_info_t *ws_get_neighbor_info(const fhss_api_t *api, uint8_t eui64[8])
180302
{
181303
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_fhss_api(api);
@@ -436,6 +558,8 @@ static int8_t ws_bootstrap_up(protocol_interface_info_entry_t *cur)
436558
/* Disable NUD Probes */
437559
cur->ipv6_neighbour_cache.send_nud_probes = false;
438560

561+
ws_nud_table_reset(cur);
562+
439563
ws_bootstrap_event_discovery_start(cur);
440564

441565
return 0;
@@ -455,6 +579,7 @@ static int8_t ws_bootstrap_down(protocol_interface_info_entry_t *cur)
455579
// ws_common_reset(cur)
456580
ws_llc_reset(cur);
457581
nd_proxy_downstream_interface_unregister(cur->id);
582+
ws_nud_table_reset(cur);
458583

459584
return nwk_6lowpan_down(cur);
460585
}
@@ -1037,17 +1162,15 @@ static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr,
10371162
return false;
10381163
}
10391164

1040-
1041-
uint8_t ll_target[16];
1042-
memcpy(ll_target, ADDR_LINK_LOCAL_PREFIX, 8);
1043-
memcpy(ll_target + 8, entry_ptr->mac64, 8);
1044-
ll_target[8] ^= 2;
1045-
tr_debug("NUD generate NS %u", entry_ptr->index);
1046-
buffer_t * buffer = icmpv6_build_ns(cur, ll_target, NULL, true, false, NULL);
1047-
if (!buffer) {
1165+
ws_nud_table_entry_t *entry = ws_nud_entry_get_free(cur);
1166+
if (!entry) {
10481167
return false;
10491168
}
1050-
protocol_push(buffer);
1169+
entry->neighbor_info = entry_ptr;
1170+
1171+
if (etx_entry->etx_samples >= WS_NEIGBOR_ETX_SAMPLE_MAX) {
1172+
entry->nud_process = true;
1173+
}
10511174
return true;
10521175
}
10531176

source/6LoWPAN/ws/ws_bootstrap.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ void ws_bootstrap_trickle_timer(protocol_interface_info_entry_t *cur, uint16_t t
5656

5757
void ws_primary_parent_update(protocol_interface_info_entry_t *interface, mac_neighbor_table_entry_t *neighbor);
5858

59+
void ws_nud_entry_remove_active(protocol_interface_info_entry_t *cur, void *neighbor);
60+
61+
void ws_nud_active_timer(protocol_interface_info_entry_t *cur, uint16_t time_in_ms);
62+
5963
#else
6064

6165
#define ws_bootstrap_init(interface_id, bootstrap_mode) (-1)

source/6LoWPAN/ws/ws_common.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ int8_t ws_common_allocate_and_init(protocol_interface_info_entry_t *cur)
140140
}
141141

142142
memset(cur->ws_info,0, sizeof(ws_info_t));
143+
ns_list_init(&cur->ws_info->active_nud_process);
144+
ns_list_init(&cur->ws_info->free_nud_entries);
143145

144146
cur->ws_info->pan_information.use_parent_bs = true;
145147
cur->ws_info->pan_information.rpl_routing_method = true;
@@ -172,6 +174,7 @@ void ws_common_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seco
172174
void ws_common_fast_timer(protocol_interface_info_entry_t *cur, uint16_t ticks)
173175
{
174176
ws_bootstrap_trickle_timer(cur, ticks);
177+
ws_nud_active_timer(cur, 100);
175178
}
176179

177180

@@ -180,12 +183,7 @@ void ws_common_neighbor_update(protocol_interface_info_entry_t *cur, const uint8
180183
//Neighbor connectected update
181184
mac_neighbor_table_entry_t *mac_neighbor = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), ll_address, false, NULL);
182185
if (mac_neighbor) {
183-
if (mac_neighbor->nud_active) {
184-
tr_debug("NUD Response %u", mac_neighbor->index);
185-
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), mac_neighbor, mac_neighbor->link_lifetime);
186-
}
187-
188-
mac_neighbor_table_neighbor_connected(mac_neighbor_info(cur), mac_neighbor);
186+
ws_nud_entry_remove_active(cur, mac_neighbor);
189187
}
190188
}
191189

source/6LoWPAN/ws/ws_common.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@
2020

2121

2222
#include "ns_types.h"
23+
#include "ns_list.h"
2324
#include "fhss_api.h"
2425
#include "fhss_config.h"
2526
#include "net_fhss.h"
2627
#include "6LoWPAN/ws/ws_common_defines.h"
2728
#include "6LoWPAN/ws/ws_neighbor_class.h"
29+
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
2830

2931
struct ws_pan_information_s;
3032
struct ws_neighbor_class_s;
@@ -40,6 +42,17 @@ typedef struct parent_info_s {
4042
uint32_t timestamp; /**< Timestamp when packet was received */
4143
}parent_info_t;
4244

45+
typedef struct ws_nud_table_entry {
46+
void *neighbor_info;
47+
uint16_t timer; /*!< Timer which resolution is 100ms*/
48+
unsigned retry_count:2;
49+
bool wait_response:1; /*!< True when NS is sended and wait NA, False when random timer is active*/
50+
bool nud_process;
51+
ns_list_link_t link;
52+
} ws_nud_table_entry_t;
53+
54+
typedef NS_LIST_HEAD(ws_nud_table_entry_t, link) ws_nud_table_list_t;
55+
4356
typedef struct ws_info_s {
4457
char network_name[33]; // Network name max 32 octets + terminating 0.
4558
uint16_t network_pan_id;
@@ -68,7 +81,9 @@ typedef struct ws_info_s {
6881
uint8_t fhss_uc_fixed_channel;
6982
uint8_t fhss_bc_fixed_channel;
7083
uint32_t fhss_channel_mask[8];
71-
84+
ws_nud_table_entry_t nud_table_entrys[ACTIVE_NUD_PROCESS_MAX];
85+
ws_nud_table_list_t active_nud_process;
86+
ws_nud_table_list_t free_nud_entries;
7287
struct ws_pan_information_s pan_information;
7388
ws_hopping_schedule_t hopping_schdule;
7489
struct ws_neighbor_class_s neighbor_storage;

0 commit comments

Comments
 (0)