@@ -73,6 +73,7 @@ fhss_structure_t *fhss_ws_enable(fhss_api_t *fhss_api, const fhss_ws_configurati
73
73
74
74
fhss_struct -> ws -> fhss_configuration = * fhss_configuration ;
75
75
fhss_struct -> number_of_channels = channel_count ;
76
+ ns_list_init (& fhss_struct -> fhss_failed_tx_list );
76
77
return fhss_struct ;
77
78
}
78
79
@@ -112,8 +113,6 @@ static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
112
113
fhss_start_timer (fhss_structure , fhss_structure -> ws -> fhss_configuration .fhss_bc_dwell_interval * 1000 , fhss_broadcast_handler );
113
114
fhss_structure -> ws -> is_on_bc_channel = true;
114
115
next_channel = fhss_ws_calc_bc_channel (fhss_structure );
115
- // TODO: Randomize polling TX queue when on broadcast channel
116
- fhss_structure -> callbacks .tx_poll (fhss_structure -> fhss_api );
117
116
} else {
118
117
uint32_t timeout = (fhss_structure -> ws -> fhss_configuration .fhss_broadcast_interval - fhss_structure -> ws -> fhss_configuration .fhss_bc_dwell_interval ) * 1000 ;
119
118
fhss_start_timer (fhss_structure , timeout , fhss_broadcast_handler );
@@ -125,6 +124,10 @@ static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
125
124
#endif /*FHSS_CHANNEL_DEBUG*/
126
125
}
127
126
fhss_structure -> callbacks .change_channel (fhss_structure -> fhss_api , next_channel );
127
+ if (fhss_structure -> callbacks .read_tx_queue_size (fhss_structure -> fhss_api , true)) {
128
+ // TODO: Randomize polling TX queue when on broadcast channel
129
+ fhss_structure -> callbacks .tx_poll (fhss_structure -> fhss_api );
130
+ }
128
131
}
129
132
130
133
static int own_floor (float value )
@@ -289,6 +292,21 @@ static int fhss_ws_tx_handle_callback(const fhss_api_t *api, bool is_broadcast_a
289
292
return 0 ;
290
293
}
291
294
295
+ static bool fhss_check_bad_channel (fhss_structure_t * fhss_structure , uint8_t handle )
296
+ {
297
+ if (!fhss_structure ) {
298
+ return false;
299
+ }
300
+ fhss_failed_tx_t * failed_tx = fhss_failed_handle_find (fhss_structure , handle );
301
+ if (!failed_tx ) {
302
+ return true;
303
+ }
304
+ if (failed_tx -> bad_channel == fhss_structure -> rx_channel ) {
305
+ return false;
306
+ }
307
+ return true;
308
+ }
309
+
292
310
static bool fhss_ws_check_tx_conditions_callback (const fhss_api_t * api , bool is_broadcast_addr , uint8_t handle , int frame_type , uint16_t frame_length , uint8_t phy_header_length , uint8_t phy_tail_length )
293
311
{
294
312
(void ) handle ;
@@ -303,10 +321,18 @@ static bool fhss_ws_check_tx_conditions_callback(const fhss_api_t *api, bool is_
303
321
if (fhss_structure -> ws -> fhss_configuration .ws_channel_function == WS_FIXED_CHANNEL ) {
304
322
return true;
305
323
}
324
+ // This condition will check that message is not sent on bad channel
325
+ if (fhss_check_bad_channel (fhss_structure , handle ) == false) {
326
+ return false;
327
+ }
306
328
// Do not allow broadcast destination on unicast channel
307
329
if (is_broadcast_addr && (fhss_structure -> ws -> is_on_bc_channel == false)) {
308
330
return false;
309
331
}
332
+ // Do not allow unicast destination on broadcast channel
333
+ if (!is_broadcast_addr && (fhss_structure -> ws -> is_on_bc_channel == true)) {
334
+ return false;
335
+ }
310
336
return true;
311
337
}
312
338
@@ -372,10 +398,34 @@ static void fhss_ws_data_tx_done_callback(const fhss_api_t *api, bool waiting_ac
372
398
373
399
static bool fhss_ws_data_tx_fail_callback (const fhss_api_t * api , uint8_t handle , int frame_type )
374
400
{
375
- (void ) api ;
376
- (void ) handle ;
377
- (void ) frame_type ;
378
- return false;
401
+ fhss_structure_t * fhss_structure = fhss_get_object_with_api (api );
402
+ if (!fhss_structure ) {
403
+ return false;
404
+ }
405
+ // Only use channel retries when device is synchronized
406
+ if (fhss_structure -> fhss_state == FHSS_UNSYNCHRONIZED ) {
407
+ return false;
408
+ }
409
+
410
+ // Use channel retries only for data frames
411
+ if (FHSS_DATA_FRAME != frame_type ) {
412
+ return false;
413
+ }
414
+
415
+ fhss_failed_tx_t * fhss_failed_tx = fhss_failed_handle_find (fhss_structure , handle );
416
+ if (fhss_failed_tx ) {
417
+ fhss_failed_tx -> retries_done ++ ;
418
+ if (fhss_failed_tx -> retries_done >= WS_NUMBER_OF_CHANNEL_RETRIES ) {
419
+ // No more retries. Return false to stop retransmitting.
420
+ fhss_failed_handle_remove (fhss_structure , handle );
421
+ return false;
422
+ }
423
+ fhss_failed_tx -> bad_channel = fhss_structure -> rx_channel ;
424
+ } else {
425
+ // Create new failure handle and return true to retransmit
426
+ fhss_failed_handle_add (fhss_structure , handle , fhss_structure -> rx_channel );
427
+ }
428
+ return true;
379
429
}
380
430
381
431
static void fhss_ws_receive_frame_callback (const fhss_api_t * api , uint16_t pan_id , uint8_t * source_address , uint32_t timestamp , uint8_t * synch_info , int frame_type )
@@ -407,6 +457,9 @@ static void fhss_unicast_handler(const fhss_api_t *fhss_api, uint16_t delay)
407
457
timeout = fhss_ws_get_sf_timeout_callback (fhss_structure );
408
458
fhss_start_timer (fhss_structure , timeout - (delay * fhss_structure -> platform_functions .fhss_resolution_divider ), fhss_unicast_handler );
409
459
fhss_ws_update_uc_channel_callback (fhss_structure );
460
+ if (fhss_structure -> callbacks .read_tx_queue_size (fhss_structure -> fhss_api , false)) {
461
+ fhss_structure -> callbacks .tx_poll (fhss_structure -> fhss_api );
462
+ }
410
463
}
411
464
412
465
int fhss_ws_set_callbacks (fhss_structure_t * fhss_structure )
0 commit comments