Skip to content

Commit b9e3ee0

Browse files
author
Jarkko Paso
committed
FHSS WS: Implemented fhss retry logic
1 parent fe4073b commit b9e3ee0

File tree

8 files changed

+157
-7
lines changed

8 files changed

+157
-7
lines changed

nanostack/fhss_api.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,13 +143,13 @@ typedef int16_t fhss_synch_state_set(const fhss_api_t *api, fhss_states fhss_sta
143143
typedef uint32_t fhss_read_timestamp(const fhss_api_t *api);
144144

145145
/**
146-
* @brief Get retransmission period. FHSS uses different retry periods for different destinations.
146+
* @brief Get additional retransmission period. FHSS uses different retry periods depending on destination or channel availability.
147147
* @param api FHSS instance.
148148
* @param destination_address Destination MAC address.
149149
* @param phy_mtu PHY MTU size.
150-
* @return Retransmission period.
150+
* @return Retransmission period in microsecond which should be added to normal backoff period.
151151
*/
152-
typedef uint16_t fhss_get_retry_period(const fhss_api_t *api, uint8_t *destination_address, uint16_t phy_mtu);
152+
typedef uint32_t fhss_get_retry_period(const fhss_api_t *api, uint8_t *destination_address, uint16_t phy_mtu);
153153

154154
/**
155155
* @brief Write synchronization info to given pointer.

source/MAC/IEEE802_15_4/mac_pd_sap.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ uint32_t mac_csma_backoff_get(protocol_interface_rf_mac_setup_s *rf_mac_setup)
105105
if (backoff_in_us < (uint32_t)(rf_mac_setup->multi_cca_interval * (rf_mac_setup->number_of_csma_ca_periods - 1))) {
106106
backoff_in_us += ((rf_mac_setup->multi_cca_interval * (rf_mac_setup->number_of_csma_ca_periods - 1)) - backoff_in_us);
107107
}
108+
if (rf_mac_setup->mac_tx_retry) {
109+
backoff_in_us += rf_mac_setup->fhss_api->get_retry_period(rf_mac_setup->fhss_api, rf_mac_setup->active_pd_data_request->DstAddr, rf_mac_setup->dev_driver->phy_driver->phy_MTU);
110+
}
108111
}
109112
return backoff_in_us;
110113
}

source/Service_Libs/fhss/fhss.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1191,7 +1191,7 @@ static void fhss_receive_frame_callback(const fhss_api_t *api, uint16_t pan_id,
11911191
}
11921192
}
11931193

1194-
static uint16_t fhss_get_retry_period_callback(const fhss_api_t *api, uint8_t *destination_address, uint16_t phy_mtu)
1194+
static uint32_t fhss_get_retry_period_callback(const fhss_api_t *api, uint8_t *destination_address, uint16_t phy_mtu)
11951195
{
11961196
uint16_t retry_period = 0;
11971197
uint16_t random_number = randLIB_get_16bit();

source/Service_Libs/fhss/fhss_ws.c

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
242242
uint16_t bc_max_random = (bc_dwell_us / 10) / 50;
243243
eventOS_callback_timer_start(fhss_structure->fhss_event_timer, randLIB_get_random_in_range(bc_min_random, bc_max_random));
244244
} else {
245+
fhss_structure->ws->unicast_start_time_us = fhss_structure->callbacks.read_timestamp(fhss_structure->fhss_api);
245246
uint32_t timeout = MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_broadcast_interval - fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval);
246247
fhss_ws_start_timer(fhss_structure, timeout - (delay * fhss_structure->platform_functions.fhss_resolution_divider), fhss_broadcast_handler);
247248
fhss_structure->ws->is_on_bc_channel = false;
@@ -250,7 +251,7 @@ static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
250251
/* Start timer with random timeout to trigger unicast TX queue poll event.
251252
* For hops 0,1,4,5,8,9,...
252253
* Min random is 1/100 of the TX slot length.
253-
* Max random is 1/10 of the TX slot length.
254+
* Max random is 1/5 of the TX slot length.
254255
*
255256
* For hops 2,3,6,7,10,11,...
256257
* Min random is 1/100 of the TX slot length plus 0.5*TX slot length.
@@ -261,7 +262,7 @@ static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
261262
uint8_t own_tx_trig_slot = calc_own_tx_trig_slot(fhss_structure->own_hop);
262263
uint32_t txrx_slot_length_us = MS_TO_US(fhss_structure->ws->txrx_slot_length_ms);
263264
uint16_t uc_min_random = (((txrx_slot_length_us / 2) * own_tx_trig_slot) / 50) + ((txrx_slot_length_us / 100) / 50);
264-
uint16_t uc_max_random = (((txrx_slot_length_us / 2) * own_tx_trig_slot) / 50) + ((txrx_slot_length_us / 10) / 50);
265+
uint16_t uc_max_random = (((txrx_slot_length_us / 2) * own_tx_trig_slot) / 50) + ((txrx_slot_length_us / 5) / 50);
265266
bool tx_allowed = fhss_ws_check_tx_allowed(fhss_structure);
266267
if (!tx_allowed) {
267268
uc_min_random += (txrx_slot_length_us) / 50;
@@ -719,6 +720,45 @@ static bool fhss_ws_use_broadcast_queue_cb(const fhss_api_t *api, bool is_broadc
719720
return is_broadcast_addr;
720721
}
721722

723+
static uint32_t fhss_ws_get_retry_period_callback(const fhss_api_t *api, uint8_t *destination_address, uint16_t phy_mtu)
724+
{
725+
(void) destination_address;
726+
(void) phy_mtu;
727+
uint32_t return_value = 0;
728+
fhss_structure_t *fhss_structure = fhss_get_object_with_api(api);
729+
if (!fhss_structure) {
730+
return return_value;
731+
}
732+
if (fhss_structure->own_hop == 0xff) {
733+
return return_value;
734+
}
735+
if (fhss_structure->ws->is_on_bc_channel == true) {
736+
return return_value;
737+
}
738+
739+
uint32_t txrx_slot_length_us = MS_TO_US(fhss_structure->ws->txrx_slot_length_ms);
740+
uint32_t unicast_start_us = fhss_structure->ws->unicast_start_time_us;
741+
uint32_t cur_time_us = fhss_structure->callbacks.read_timestamp(fhss_structure->fhss_api);
742+
uint32_t tx_trig_offset_us = (txrx_slot_length_us / 2) * calc_own_tx_trig_slot(fhss_structure->own_hop);
743+
744+
uint32_t next_tx_trig_slot_start_us = unicast_start_us + (txrx_slot_length_us * !fhss_ws_check_tx_allowed(fhss_structure)) + tx_trig_offset_us;
745+
uint32_t next_tx_trig_slot_end_us = next_tx_trig_slot_start_us + (txrx_slot_length_us / 2);
746+
while ((next_tx_trig_slot_start_us < cur_time_us) || ((next_tx_trig_slot_start_us - cur_time_us) > (uint32_t) MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_broadcast_interval))) {
747+
if (cur_time_us < next_tx_trig_slot_end_us) {
748+
return 0;
749+
}
750+
next_tx_trig_slot_start_us += (txrx_slot_length_us * 2);
751+
next_tx_trig_slot_end_us = next_tx_trig_slot_start_us + (txrx_slot_length_us / 2);
752+
}
753+
return_value = next_tx_trig_slot_start_us - cur_time_us;
754+
uint32_t time_to_bc_channel = get_remaining_slots_us(fhss_structure, fhss_broadcast_handler, MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_broadcast_interval));
755+
if (time_to_bc_channel <= return_value) {
756+
return_value += MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval);
757+
}
758+
759+
return return_value;
760+
}
761+
722762
static void fhss_unicast_handler(const fhss_api_t *fhss_api, uint16_t delay)
723763
{
724764
uint32_t timeout = 0;
@@ -755,7 +795,7 @@ int fhss_ws_set_callbacks(fhss_structure_t *fhss_structure)
755795
fhss_structure->fhss_api->data_tx_fail = &fhss_ws_data_tx_fail_callback;
756796
fhss_structure->fhss_api->synch_state_set = &fhss_ws_synch_state_set_callback;
757797
fhss_structure->fhss_api->read_timestamp = NULL;
758-
fhss_structure->fhss_api->get_retry_period = NULL;
798+
fhss_structure->fhss_api->get_retry_period = &fhss_ws_get_retry_period_callback;
759799
fhss_structure->fhss_api->write_synch_info = &fhss_ws_write_synch_info_callback;
760800
fhss_structure->fhss_api->init_callbacks = &fhss_init_callbacks_cb;
761801
return 0;

source/Service_Libs/fhss/fhss_ws.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ struct fhss_ws {
3636
uint16_t min_synch_interval;
3737
uint32_t txrx_slot_length_ms;
3838
uint32_t synchronization_time;
39+
uint32_t unicast_start_time_us;
3940
int32_t drift_per_millisecond_ns;
4041
int16_t *tr51_channel_table;
4142
uint8_t *tr51_output_table;

test/nanostack/unittest/service_libs/fhss_ws/fhsswstest.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ TEST(fhssws, test_fhss_broadcast_handler)
7878
CHECK(test_fhss_broadcast_handler());
7979
}
8080

81+
TEST(fhssws, test_fhss_ws_get_retry_period_callback)
82+
{
83+
CHECK(test_fhss_ws_get_retry_period_callback());
84+
}
85+
8186
TEST(fhssws, test_fhss_ws_update_uc_channel_callback)
8287
{
8388
CHECK(test_fhss_ws_update_uc_channel_callback());

test/nanostack/unittest/service_libs/fhss_ws/test_fhss_ws.c

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,106 @@ bool test_fhss_broadcast_handler()
548548
return true;
549549
}
550550

551+
bool test_fhss_ws_get_retry_period_callback()
552+
{
553+
fhss_api_t *api = test_generate_fhss_api();
554+
enable_fhss_struct();
555+
// Test when own hop not set
556+
fhss_common_stub.fhss_struct.ws->is_on_bc_channel = false;
557+
fhss_common_stub.fhss_struct.own_hop = 0xff;
558+
if (fhss_common_stub.fhss_struct.fhss_api->get_retry_period(api, NULL, 0) != 0) {
559+
return false;
560+
}
561+
// Test when on broadcast channel
562+
fhss_common_stub.fhss_struct.ws->is_on_bc_channel = true;
563+
fhss_common_stub.fhss_struct.own_hop = 1;
564+
if (fhss_common_stub.fhss_struct.fhss_api->get_retry_period(api, NULL, 0) != 0) {
565+
return false;
566+
}
567+
// Test when not on TX trig slot
568+
fhss_common_stub.fhss_struct.ws->is_on_bc_channel = false;
569+
fhss_common_stub.fhss_struct.own_hop = 0;
570+
fhss_common_stub.fhss_struct.ws->txrx_slot_length_ms = 127;
571+
fhss_common_stub.fhss_struct.ws->unicast_start_time_us = 1000000;
572+
fhss_platform_stub.remaining_slots_value = 700000;
573+
fhss_callbacks_stub.uint32_value = 1065000;
574+
if (fhss_common_stub.fhss_struct.fhss_api->get_retry_period(api, NULL, 0) != 189000) {
575+
return false;
576+
}
577+
// Test when not on TX trig slot
578+
fhss_common_stub.fhss_struct.ws->is_on_bc_channel = false;
579+
fhss_common_stub.fhss_struct.own_hop = 0;
580+
fhss_common_stub.fhss_struct.ws->txrx_slot_length_ms = 127;
581+
fhss_common_stub.fhss_struct.ws->unicast_start_time_us = 1000000;
582+
fhss_platform_stub.remaining_slots_value = 436000;
583+
fhss_callbacks_stub.uint32_value = 1329000;
584+
if (fhss_common_stub.fhss_struct.fhss_api->get_retry_period(api, NULL, 0) != 179000) {
585+
return false;
586+
}
587+
// Test when not on TX trig slot
588+
fhss_common_stub.fhss_struct.ws->is_on_bc_channel = false;
589+
fhss_common_stub.fhss_struct.own_hop = 0;
590+
fhss_common_stub.fhss_struct.ws->txrx_slot_length_ms = 127;
591+
fhss_common_stub.fhss_struct.ws->unicast_start_time_us = 1000000;
592+
fhss_platform_stub.remaining_slots_value = 182000;
593+
fhss_callbacks_stub.uint32_value = 1583000;
594+
if (fhss_common_stub.fhss_struct.fhss_api->get_retry_period(api, NULL, 0) != 179000) {
595+
return false;
596+
}
597+
// Test when on TX trig slot
598+
fhss_common_stub.fhss_struct.ws->is_on_bc_channel = false;
599+
fhss_common_stub.fhss_struct.own_hop = 2;
600+
fhss_common_stub.fhss_struct.ws->txrx_slot_length_ms = 127;
601+
fhss_common_stub.fhss_struct.ws->unicast_start_time_us = 1000000;
602+
fhss_platform_stub.remaining_slots_value = 700000;
603+
fhss_callbacks_stub.uint32_value = 1065000;
604+
if (fhss_common_stub.fhss_struct.fhss_api->get_retry_period(api, NULL, 0) != 0) {
605+
return false;
606+
}
607+
// Test when on TX trig slot
608+
fhss_common_stub.fhss_struct.ws->is_on_bc_channel = false;
609+
fhss_common_stub.fhss_struct.own_hop = 2;
610+
fhss_common_stub.fhss_struct.ws->txrx_slot_length_ms = 127;
611+
fhss_common_stub.fhss_struct.ws->unicast_start_time_us = 1000000;
612+
fhss_platform_stub.remaining_slots_value = 486000;
613+
fhss_callbacks_stub.uint32_value = 1279000;
614+
if (fhss_common_stub.fhss_struct.fhss_api->get_retry_period(api, NULL, 0) != 38500) {
615+
return false;
616+
}
617+
// Test when timestamp overflows
618+
fhss_common_stub.fhss_struct.ws->is_on_bc_channel = false;
619+
fhss_common_stub.fhss_struct.own_hop = 0;
620+
fhss_common_stub.fhss_struct.ws->txrx_slot_length_ms = 127;
621+
fhss_common_stub.fhss_struct.ws->unicast_start_time_us = 4294967285;
622+
fhss_platform_stub.remaining_slots_value = 700000;
623+
fhss_callbacks_stub.uint32_value = 64989;
624+
if (fhss_common_stub.fhss_struct.fhss_api->get_retry_period(api, NULL, 0) != 189000) {
625+
return false;
626+
}
627+
// Test when on RX slot
628+
fhss_common_stub.fhss_struct.ws->is_on_bc_channel = false;
629+
fhss_common_stub.fhss_struct.own_hop = 1;
630+
fhss_common_stub.fhss_struct.ws->txrx_slot_length_ms = 127;
631+
fhss_common_stub.fhss_struct.ws->unicast_start_time_us = 1000000;
632+
fhss_platform_stub.remaining_slots_value = 700000;
633+
fhss_callbacks_stub.uint32_value = 1065000;
634+
if (fhss_common_stub.fhss_struct.fhss_api->get_retry_period(api, NULL, 0) != 62000) {
635+
return false;
636+
}
637+
// Test when going to BC channel
638+
fhss_common_stub.fhss_struct.ws->fhss_configuration.fhss_bc_dwell_interval = 255;
639+
fhss_common_stub.fhss_struct.ws->is_on_bc_channel = false;
640+
fhss_common_stub.fhss_struct.own_hop = 0;
641+
fhss_common_stub.fhss_struct.ws->txrx_slot_length_ms = 100;
642+
fhss_common_stub.fhss_struct.ws->unicast_start_time_us = 1000000;
643+
fhss_platform_stub.remaining_slots_value = 130000;
644+
fhss_callbacks_stub.uint32_value = 1670000;
645+
if (fhss_common_stub.fhss_struct.fhss_api->get_retry_period(api, NULL, 0) != 385000) {
646+
return false;
647+
}
648+
return true;
649+
}
650+
551651
bool test_fhss_ws_update_uc_channel_callback()
552652
{
553653
fhss_api_t *api = test_generate_fhss_api();

test/nanostack/unittest/service_libs/fhss_ws/test_fhss_ws.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ bool test_fhss_ws_data_tx_fail_callback();
3434
bool test_fhss_ws_synch_state_set_callback();
3535
bool test_fhss_ws_write_synch_info_callback();
3636
bool test_fhss_broadcast_handler();
37+
bool test_fhss_ws_get_retry_period_callback();
3738
bool test_fhss_ws_update_uc_channel_callback();
3839
bool test_fhss_unicast_handler();
3940
bool test_fhss_ws_set_parent();

0 commit comments

Comments
 (0)