@@ -176,6 +176,128 @@ static int8_t ws_bootsrap_event_trig(ws_bootsrap_event_type_e event_type, int8_t
176
176
return eventOS_event_send (& event );
177
177
}
178
178
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
+
179
301
static fhss_ws_neighbor_timing_info_t * ws_get_neighbor_info (const fhss_api_t * api , uint8_t eui64 [8 ])
180
302
{
181
303
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)
436
558
/* Disable NUD Probes */
437
559
cur -> ipv6_neighbour_cache .send_nud_probes = false;
438
560
561
+ ws_nud_table_reset (cur );
562
+
439
563
ws_bootstrap_event_discovery_start (cur );
440
564
441
565
return 0 ;
@@ -455,6 +579,7 @@ static int8_t ws_bootstrap_down(protocol_interface_info_entry_t *cur)
455
579
// ws_common_reset(cur)
456
580
ws_llc_reset (cur );
457
581
nd_proxy_downstream_interface_unregister (cur -> id );
582
+ ws_nud_table_reset (cur );
458
583
459
584
return nwk_6lowpan_down (cur );
460
585
}
@@ -1037,17 +1162,15 @@ static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr,
1037
1162
return false;
1038
1163
}
1039
1164
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 ) {
1048
1167
return false;
1049
1168
}
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
+ }
1051
1174
return true;
1052
1175
}
1053
1176
0 commit comments