@@ -73,6 +73,7 @@ fhss_structure_t *fhss_ws_enable(fhss_api_t *fhss_api, const fhss_ws_configurati
7373
7474 fhss_struct -> ws -> fhss_configuration = * fhss_configuration ;
7575 fhss_struct -> number_of_channels = channel_count ;
76+ ns_list_init (& fhss_struct -> fhss_failed_tx_list );
7677 return fhss_struct ;
7778}
7879
@@ -112,8 +113,6 @@ static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
112113 fhss_start_timer (fhss_structure , fhss_structure -> ws -> fhss_configuration .fhss_bc_dwell_interval * 1000 , fhss_broadcast_handler );
113114 fhss_structure -> ws -> is_on_bc_channel = true;
114115 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 );
117116 } else {
118117 uint32_t timeout = (fhss_structure -> ws -> fhss_configuration .fhss_broadcast_interval - fhss_structure -> ws -> fhss_configuration .fhss_bc_dwell_interval ) * 1000 ;
119118 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)
125124#endif /*FHSS_CHANNEL_DEBUG*/
126125 }
127126 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+ }
128131}
129132
130133static 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
289292 return 0 ;
290293}
291294
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+
292310static 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 )
293311{
294312 (void ) handle ;
@@ -303,10 +321,18 @@ static bool fhss_ws_check_tx_conditions_callback(const fhss_api_t *api, bool is_
303321 if (fhss_structure -> ws -> fhss_configuration .ws_channel_function == WS_FIXED_CHANNEL ) {
304322 return true;
305323 }
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+ }
306328 // Do not allow broadcast destination on unicast channel
307329 if (is_broadcast_addr && (fhss_structure -> ws -> is_on_bc_channel == false)) {
308330 return false;
309331 }
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+ }
310336 return true;
311337}
312338
@@ -372,10 +398,34 @@ static void fhss_ws_data_tx_done_callback(const fhss_api_t *api, bool waiting_ac
372398
373399static bool fhss_ws_data_tx_fail_callback (const fhss_api_t * api , uint8_t handle , int frame_type )
374400{
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;
379429}
380430
381431static 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)
407457 timeout = fhss_ws_get_sf_timeout_callback (fhss_structure );
408458 fhss_start_timer (fhss_structure , timeout - (delay * fhss_structure -> platform_functions .fhss_resolution_divider ), fhss_unicast_handler );
409459 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+ }
410463}
411464
412465int fhss_ws_set_callbacks (fhss_structure_t * fhss_structure )
0 commit comments