Skip to content

Commit

Permalink
Wi-sun NUD State Machine update
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Juha Heiskanen committed Sep 19, 2018
1 parent e7d551c commit 231daf7
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 16 deletions.
141 changes: 132 additions & 9 deletions source/6LoWPAN/ws/ws_bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,128 @@ static int8_t ws_bootsrap_event_trig(ws_bootsrap_event_type_e event_type, int8_t
return eventOS_event_send(&event);
}

static void ws_nud_table_reset(protocol_interface_info_entry_t *cur)
{
//Empty active list
ns_list_foreach_safe(ws_nud_table_entry_t, entry, &cur->ws_info->active_nud_process) {
ns_list_remove(&cur->ws_info->active_nud_process, entry);
}

//Empty free list
ns_list_foreach_safe(ws_nud_table_entry_t, entry, &cur->ws_info->free_nud_entries) {
ns_list_remove(&cur->ws_info->free_nud_entries, entry);
}
//Add to free list to full
for (int i=0; i< ACTIVE_NUD_PROCESS_MAX; i++) {
ns_list_add_to_end(&cur->ws_info->free_nud_entries, &cur->ws_info->nud_table_entrys[i]);
}
}

static ws_nud_table_entry_t *ws_nud_entry_get_free(protocol_interface_info_entry_t *cur)
{
ws_nud_table_entry_t *entry = ns_list_get_first(&cur->ws_info->free_nud_entries);
if (entry) {
entry->wait_response = false;
entry->retry_count = 0;
entry->nud_process = false;
entry->timer = randLIB_get_random_in_range(1, 900);
entry->neighbor_info = NULL;
ns_list_remove(&cur->ws_info->free_nud_entries, entry);
ns_list_add_to_end(&cur->ws_info->active_nud_process, entry);
}
return entry;
}


void ws_nud_entry_remove_active(protocol_interface_info_entry_t *cur, void *neighbor)
{
ns_list_foreach(ws_nud_table_entry_t, entry, &cur->ws_info->active_nud_process) {
if (entry->neighbor_info == neighbor) {
mac_neighbor_table_entry_t *mac_neighbor = neighbor;
ns_list_remove(&cur->ws_info->active_nud_process, entry);
ns_list_add_to_end(&cur->ws_info->free_nud_entries, entry);
if (mac_neighbor->nud_active) {
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), mac_neighbor, mac_neighbor->link_lifetime);
}

mac_neighbor_table_neighbor_connected(mac_neighbor_info(cur), mac_neighbor);
return;
}
}
}

static void ws_nud_state_clean(protocol_interface_info_entry_t *cur, ws_nud_table_entry_t *entry)
{
mac_neighbor_table_entry_t *neighbor = entry->neighbor_info;
ns_list_remove(&cur->ws_info->active_nud_process, entry);
ns_list_add_to_end(&cur->ws_info->free_nud_entries, entry);
if (neighbor->nud_active) {
neighbor->nud_active = false;
mac_neighbor_info(cur)->active_nud_process--;
}
}

static bool ws_nud_message_build(protocol_interface_info_entry_t *cur, mac_neighbor_table_entry_t *neighbor)
{
//Send NS
uint8_t ll_target[16];
memcpy(ll_target, ADDR_LINK_LOCAL_PREFIX, 8);
memcpy(ll_target + 8, neighbor->mac64, 8);
ll_target[8] ^= 2;
tr_debug("NUD generate NS %u", neighbor->index);
buffer_t * buffer = icmpv6_build_ns(cur, ll_target, NULL, true, false, NULL);
if (buffer) {
protocol_push(buffer);
return true;
}
return false;
}

void ws_nud_active_timer(protocol_interface_info_entry_t *cur, uint16_t time_in_ms)
{

ns_list_foreach_safe(ws_nud_table_entry_t, entry, &cur->ws_info->active_nud_process) {
if (entry->timer <= time_in_ms) {
//TX Process or timeout
if (entry->wait_response) {
//Timeout for NUD or Probe
if (entry->nud_process) {
tr_debug("NUD NA timeout");
if (entry->retry_count < 2) {
entry->timer = randLIB_get_random_in_range(1, 900);
entry->wait_response = false;
} else {
//Clear entry from active list
ws_nud_state_clean(cur, entry);
//Remove whole entry
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry->neighbor_info);
}
} else {
ws_nud_state_clean(cur, entry);
}

} else {
//Random TX wait period is over
entry->wait_response = ws_nud_message_build(cur, entry->neighbor_info);
if (!entry->wait_response) {
if (entry->nud_process && entry->retry_count < 2) {
entry->timer = randLIB_get_random_in_range(1, 900);
} else {
//Clear entry from active list
//Remove and try again later on
ws_nud_state_clean(cur, entry);
}
} else {
entry->retry_count++;
entry->timer = 5001;
}
}
} else {
entry->timer -= time_in_ms;
}
}
}

static fhss_ws_neighbor_timing_info_t *ws_get_neighbor_info(const fhss_api_t *api, uint8_t eui64[8])
{
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_fhss_api(api);
Expand Down Expand Up @@ -436,6 +558,8 @@ static int8_t ws_bootstrap_up(protocol_interface_info_entry_t *cur)
/* Disable NUD Probes */
cur->ipv6_neighbour_cache.send_nud_probes = false;

ws_nud_table_reset(cur);

ws_bootstrap_event_discovery_start(cur);

return 0;
Expand All @@ -455,6 +579,7 @@ static int8_t ws_bootstrap_down(protocol_interface_info_entry_t *cur)
// ws_common_reset(cur)
ws_llc_reset(cur);
nd_proxy_downstream_interface_unregister(cur->id);
ws_nud_table_reset(cur);

return nwk_6lowpan_down(cur);
}
Expand Down Expand Up @@ -1037,17 +1162,15 @@ static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr,
return false;
}


uint8_t ll_target[16];
memcpy(ll_target, ADDR_LINK_LOCAL_PREFIX, 8);
memcpy(ll_target + 8, entry_ptr->mac64, 8);
ll_target[8] ^= 2;
tr_debug("NUD generate NS %u", entry_ptr->index);
buffer_t * buffer = icmpv6_build_ns(cur, ll_target, NULL, true, false, NULL);
if (!buffer) {
ws_nud_table_entry_t *entry = ws_nud_entry_get_free(cur);
if (!entry) {
return false;
}
protocol_push(buffer);
entry->neighbor_info = entry_ptr;

if (etx_entry->etx_samples >= WS_NEIGBOR_ETX_SAMPLE_MAX) {
entry->nud_process = true;
}
return true;
}

Expand Down
4 changes: 4 additions & 0 deletions source/6LoWPAN/ws/ws_bootstrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ void ws_bootstrap_trickle_timer(protocol_interface_info_entry_t *cur, uint16_t t

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

void ws_nud_entry_remove_active(protocol_interface_info_entry_t *cur, void *neighbor);

void ws_nud_active_timer(protocol_interface_info_entry_t *cur, uint16_t time_in_ms);

#else

#define ws_bootstrap_init(interface_id, bootstrap_mode) (-1)
Expand Down
10 changes: 4 additions & 6 deletions source/6LoWPAN/ws/ws_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ int8_t ws_common_allocate_and_init(protocol_interface_info_entry_t *cur)
}

memset(cur->ws_info,0, sizeof(ws_info_t));
ns_list_init(&cur->ws_info->active_nud_process);
ns_list_init(&cur->ws_info->free_nud_entries);

cur->ws_info->pan_information.use_parent_bs = true;
cur->ws_info->pan_information.rpl_routing_method = true;
Expand Down Expand Up @@ -172,6 +174,7 @@ void ws_common_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seco
void ws_common_fast_timer(protocol_interface_info_entry_t *cur, uint16_t ticks)
{
ws_bootstrap_trickle_timer(cur, ticks);
ws_nud_active_timer(cur, 100);
}


Expand All @@ -180,12 +183,7 @@ void ws_common_neighbor_update(protocol_interface_info_entry_t *cur, const uint8
//Neighbor connectected update
mac_neighbor_table_entry_t *mac_neighbor = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), ll_address, false, NULL);
if (mac_neighbor) {
if (mac_neighbor->nud_active) {
tr_debug("NUD Response %u", mac_neighbor->index);
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), mac_neighbor, mac_neighbor->link_lifetime);
}

mac_neighbor_table_neighbor_connected(mac_neighbor_info(cur), mac_neighbor);
ws_nud_entry_remove_active(cur, mac_neighbor);
}
}

Expand Down
17 changes: 16 additions & 1 deletion source/6LoWPAN/ws/ws_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@


#include "ns_types.h"
#include "ns_list.h"
#include "fhss_api.h"
#include "fhss_config.h"
#include "net_fhss.h"
#include "6LoWPAN/ws/ws_common_defines.h"
#include "6LoWPAN/ws/ws_neighbor_class.h"
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"

struct ws_pan_information_s;
struct ws_neighbor_class_s;
Expand All @@ -40,6 +42,17 @@ typedef struct parent_info_s {
uint32_t timestamp; /**< Timestamp when packet was received */
}parent_info_t;

typedef struct ws_nud_table_entry {
void *neighbor_info;
uint16_t timer; /*!< Timer which resolution is 100ms*/
unsigned retry_count:2;
bool wait_response:1; /*!< True when NS is sended and wait NA, False when random timer is active*/
bool nud_process;
ns_list_link_t link;
} ws_nud_table_entry_t;

typedef NS_LIST_HEAD(ws_nud_table_entry_t, link) ws_nud_table_list_t;

typedef struct ws_info_s {
char network_name[33]; // Network name max 32 octets + terminating 0.
uint16_t network_pan_id;
Expand Down Expand Up @@ -68,7 +81,9 @@ typedef struct ws_info_s {
uint8_t fhss_uc_fixed_channel;
uint8_t fhss_bc_fixed_channel;
uint32_t fhss_channel_mask[8];

ws_nud_table_entry_t nud_table_entrys[ACTIVE_NUD_PROCESS_MAX];
ws_nud_table_list_t active_nud_process;
ws_nud_table_list_t free_nud_entries;
struct ws_pan_information_s pan_information;
ws_hopping_schedule_t hopping_schdule;
struct ws_neighbor_class_s neighbor_storage;
Expand Down

0 comments on commit 231daf7

Please sign in to comment.