Skip to content

Commit d6086d0

Browse files
author
Juha Heiskanen
authored
Merge pull request ARMmbed#1818 from ARMmbed/nud_statemachine
Nud statemachine Update and some fix's
2 parents e7d551c + a2b8491 commit d6086d0

11 files changed

+242
-40
lines changed

source/6LoWPAN/adaptation_interface.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,8 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff
914914
if (indirect) {
915915
ns_dyn_mem_free(tx_ptr->fragmenter_buf);
916916
ns_dyn_mem_free(tx_ptr);
917+
} else {
918+
tx_ptr->buf = NULL;
917919
}
918920
goto tx_error_handler;
919921
}

source/6LoWPAN/ws/ws_bbr_api.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,8 @@ void ws_bbr_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds
207207
// We update the RPL version in same time to allow nodes to reselect parent
208208
// As configuration is made so that devices cant move downward in dodag this allows it
209209
// TODO think the correct rate for this
210-
if (cur->ws_info->pan_information.pan_version % 3 == 0) {
211-
// Third the rate of configuration version change at default 12 minutes
210+
if ( cur->ws_info->pan_information.pan_version && cur->ws_info->pan_information.pan_version % RPL_VERSION_LIFETIME / PAN_VERSION_LIFETIME == 0) {
211+
// Third the rate of configuration version change at default 5 hours
212212
rpl_control_increment_dodag_version(protocol_6lowpan_rpl_root_dodag);
213213
}
214214
}

source/6LoWPAN/ws/ws_bootstrap.c

Lines changed: 194 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,134 @@ 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_info("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 ticks)
257+
{
258+
//Convert TICKS to real milliseconds
259+
if (ticks > 0xffff / 100) {
260+
ticks = 0xffff;
261+
} else {
262+
ticks *= 100;
263+
}
264+
265+
ns_list_foreach_safe(ws_nud_table_entry_t, entry, &cur->ws_info->active_nud_process) {
266+
if (entry->timer <= ticks) {
267+
//TX Process or timeout
268+
if (entry->wait_response) {
269+
//Timeout for NUD or Probe
270+
if (entry->nud_process) {
271+
tr_debug("NUD NA timeout");
272+
if (entry->retry_count < 2) {
273+
entry->timer = randLIB_get_random_in_range(1, 900);
274+
entry->wait_response = false;
275+
} else {
276+
//Clear entry from active list
277+
ws_nud_state_clean(cur, entry);
278+
//Remove whole entry
279+
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry->neighbor_info);
280+
}
281+
} else {
282+
ws_nud_state_clean(cur, entry);
283+
}
284+
285+
} else {
286+
//Random TX wait period is over
287+
entry->wait_response = ws_nud_message_build(cur, entry->neighbor_info);
288+
if (!entry->wait_response) {
289+
if (entry->nud_process && entry->retry_count < 2) {
290+
entry->timer = randLIB_get_random_in_range(1, 900);
291+
} else {
292+
//Clear entry from active list
293+
//Remove and try again later on
294+
ws_nud_state_clean(cur, entry);
295+
}
296+
} else {
297+
entry->retry_count++;
298+
entry->timer = 5001;
299+
}
300+
}
301+
} else {
302+
entry->timer -= ticks;
303+
}
304+
}
305+
}
306+
179307
static fhss_ws_neighbor_timing_info_t *ws_get_neighbor_info(const fhss_api_t *api, uint8_t eui64[8])
180308
{
181309
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_fhss_api(api);
@@ -331,26 +459,32 @@ static void ws_bootstrap_primary_parent_set(struct protocol_interface_info_entry
331459
{
332460

333461
fhss_ws_configuration_t fhss_configuration;
462+
if (!neighbor_info->ws_neighbor->broadcast_timing_info_stored) {
463+
tr_error("No BC timing info for set new parent");
464+
return;
465+
}
466+
334467
memcpy(&fhss_configuration, ns_fhss_ws_configuration_get(cur->ws_info->fhss_api), sizeof(fhss_ws_configuration_t));
335468

336469
ws_fhss_set_defaults(cur, &fhss_configuration);
337470

338471
// Learning broadcast network configuration
339-
fhss_configuration.ws_bc_channel_function = neighbor_info->ws_neighbor->fhss_data.bc_timing_info.broadcast_channel_function;
340-
if (fhss_configuration.ws_bc_channel_function == WS_FIXED_CHANNEL) {
341-
cur->ws_info->hopping_schdule.bc_fixed_channel = neighbor_info->ws_neighbor->fhss_data.bc_timing_info.fixed_channel;
472+
if (neighbor_info->ws_neighbor->broadcast_shedule_info_stored) {
473+
fhss_configuration.ws_bc_channel_function = neighbor_info->ws_neighbor->fhss_data.bc_timing_info.broadcast_channel_function;
474+
if (fhss_configuration.ws_bc_channel_function == WS_FIXED_CHANNEL) {
475+
cur->ws_info->hopping_schdule.bc_fixed_channel = neighbor_info->ws_neighbor->fhss_data.bc_timing_info.fixed_channel;
476+
}
477+
fhss_configuration.bsi = neighbor_info->ws_neighbor->fhss_data.bc_timing_info.broadcast_schedule_id;
478+
fhss_configuration.fhss_bc_dwell_interval = neighbor_info->ws_neighbor->fhss_data.bc_timing_info.broadcast_dwell_interval;
479+
fhss_configuration.fhss_broadcast_interval = neighbor_info->ws_neighbor->fhss_data.bc_timing_info.broadcast_interval;
480+
fhss_configuration.broadcast_fixed_channel = cur->ws_info->fhss_bc_fixed_channel;
481+
342482
}
343-
fhss_configuration.bsi = neighbor_info->ws_neighbor->fhss_data.bc_timing_info.broadcast_schedule_id;
344-
fhss_configuration.fhss_bc_dwell_interval = neighbor_info->ws_neighbor->fhss_data.bc_timing_info.broadcast_dwell_interval;
345-
fhss_configuration.fhss_broadcast_interval = neighbor_info->ws_neighbor->fhss_data.bc_timing_info.broadcast_interval;
346483
fhss_configuration.unicast_fixed_channel = cur->ws_info->fhss_uc_fixed_channel;
347-
fhss_configuration.broadcast_fixed_channel = cur->ws_info->fhss_bc_fixed_channel;
348484
ns_fhss_ws_configuration_set(cur->ws_info->fhss_api, &fhss_configuration);
349485

350-
if (fhss_configuration.fhss_bc_dwell_interval && fhss_configuration.fhss_broadcast_interval) {
351-
// We have broadcast schedule set up set the broadcast parent schedule
352-
ns_fhss_ws_set_parent(cur->ws_info->fhss_api, neighbor_info->neighbor->mac64, &neighbor_info->ws_neighbor->fhss_data.bc_timing_info);
353-
}
486+
// We have broadcast schedule set up set the broadcast parent schedule
487+
ns_fhss_ws_set_parent(cur->ws_info->fhss_api, neighbor_info->neighbor->mac64, &neighbor_info->ws_neighbor->fhss_data.bc_timing_info);
354488

355489
// Update LLC to follow updated fhss settings
356490
ws_bootstrap_llc_hopping_update(cur,&fhss_configuration);
@@ -380,11 +514,34 @@ uint16_t ws_etx_read(protocol_interface_info_entry_t *interface, addrtype_t addr
380514
ws_neighbor_class_entry_t *ws_neighbour = ws_neighbor_class_entry_get(&interface->ws_info->neighbor_storage, attribute_index);
381515
etx_storage_t *etx_entry = etx_storage_entry_get(interface->id, attribute_index);
382516

383-
if (!ws_neighbour || !etx_entry || etx_entry->etx_samples < 1 ||
384-
!ws_neighbour->candidate_parent) {
385-
// if RSL value is not good enough candidate parent flag is removed and device not accepted as parent
386-
//tr_debug("ws_etx_read not valid parent");
387-
return 0xffff;
517+
if (interface->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
518+
if (!ws_neighbour || !etx_entry) {
519+
return 0xffff;
520+
}
521+
} else {
522+
523+
if (!ws_neighbour || !etx_entry || etx_entry->etx_samples < 1 ||
524+
!ws_neighbour->candidate_parent) {
525+
// if RSL value is not good enough candidate parent flag is removed and device not accepted as parent
526+
//tr_debug("ws_etx_read not valid parent");
527+
return 0xffff;
528+
}
529+
530+
#if 0
531+
//If we are not following gbobal Broadcast synch
532+
if (!interface->ws_info->pan_information.use_parent_bs) {
533+
//We must know both information's here
534+
if (!ws_neighbour->broadcast_shedule_info_stored ||
535+
!ws_neighbour->broadcast_timing_info_stored) {
536+
return 0xffff;
537+
}
538+
} else {
539+
if (!ws_neighbour->broadcast_timing_info_stored) {
540+
//Global shedule is stored already
541+
return 0xffff;
542+
}
543+
}
544+
#endif
388545
}
389546

390547
etx = etx_local_etx_read(interface->id,attribute_index);
@@ -436,6 +593,8 @@ static int8_t ws_bootstrap_up(protocol_interface_info_entry_t *cur)
436593
/* Disable NUD Probes */
437594
cur->ipv6_neighbour_cache.send_nud_probes = false;
438595

596+
ws_nud_table_reset(cur);
597+
439598
ws_bootstrap_event_discovery_start(cur);
440599

441600
return 0;
@@ -455,6 +614,7 @@ static int8_t ws_bootstrap_down(protocol_interface_info_entry_t *cur)
455614
// ws_common_reset(cur)
456615
ws_llc_reset(cur);
457616
nd_proxy_downstream_interface_unregister(cur->id);
617+
ws_nud_table_reset(cur);
458618

459619
return nwk_6lowpan_down(cur);
460620
}
@@ -746,12 +906,21 @@ static void ws_bootstrap_pan_config_analyse(struct protocol_interface_info_entry
746906
return;
747907
}
748908
}
909+
910+
749911
}
750912

751913
if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
752914
//Border router does not learn network information
753915
return;
754916
}
917+
918+
//Update synch to primary parent allways to update broadcast shedule and timing
919+
if (neighbor_info.neighbor->link_role == PRIORITY_PARENT_NEIGHBOUR) {
920+
// RPL priority parent configuration we must update FHSS data
921+
ws_bootstrap_primary_parent_set(cur, &neighbor_info);
922+
}
923+
755924
if (cur->ws_info->configuration_learned &&
756925
cur->ws_info->pan_information.pan_version == pan_version) {
757926
// No new information
@@ -778,8 +947,8 @@ static void ws_bootstrap_pan_config_analyse(struct protocol_interface_info_entry
778947
// set neighbor as priority parent clear if there is others
779948
protocol_6lowpan_neighbor_priority_clear_all(cur->id, PRIORITY_1ST);
780949
neighbor_info.neighbor->link_role = PRIORITY_PARENT_NEIGHBOUR;
781-
} else if (neighbor_info.neighbor->link_role == PRIORITY_PARENT_NEIGHBOUR) {
782-
// RPL priority parent configuration we must update FHSS data
950+
} else if (neighbor_info.neighbor->link_role != PRIORITY_PARENT_NEIGHBOUR) {
951+
//This cuold affect serious problem if BC parameters are changed
783952
ws_bootstrap_primary_parent_set(cur, &neighbor_info);
784953
}
785954
}
@@ -1037,17 +1206,15 @@ static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr,
10371206
return false;
10381207
}
10391208

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) {
1209+
ws_nud_table_entry_t *entry = ws_nud_entry_get_free(cur);
1210+
if (!entry) {
10481211
return false;
10491212
}
1050-
protocol_push(buffer);
1213+
entry->neighbor_info = entry_ptr;
1214+
1215+
if (etx_entry->etx_samples >= WS_NEIGBOR_ETX_SAMPLE_MAX) {
1216+
entry->nud_process = true;
1217+
}
10511218
return true;
10521219
}
10531220

@@ -1717,7 +1884,6 @@ void ws_bootstrap_network_scan_process(protocol_interface_info_entry_t *cur)
17171884
return;
17181885
}
17191886

1720-
ws_bootstrap_primary_parent_set(cur, &neighbor_info);
17211887
ws_bootstrap_network_information_learn(cur);
17221888
ws_bootstrap_fhss_activate(cur);
17231889
ws_bootstrap_event_authentication_start(cur);

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 ticks);
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, ticks);
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

0 commit comments

Comments
 (0)