Skip to content

Commit

Permalink
Merge pull request ARMmbed#1704 from ARMmbed/IOTTHD-2484
Browse files Browse the repository at this point in the history
FHSS: Implemented checking TX time
  • Loading branch information
Jarkko Paso committed May 14, 2018
2 parents 0ba4b9a + 2e15944 commit 1f9162d
Show file tree
Hide file tree
Showing 14 changed files with 54 additions and 76 deletions.
3 changes: 1 addition & 2 deletions source/6LoWPAN/ws/ws_bootstrap.c
Expand Up @@ -229,7 +229,6 @@ static int8_t ws_bootstrap_up(protocol_interface_info_entry_t *cur)
tr_debug("Interface not yet fully configured");
return -5;
}
ws_enable_fhss(cur);

addr_interface_set_ll64(cur, NULL);
cur->nwk_nd_re_scan_count = 0;
Expand Down Expand Up @@ -913,7 +912,7 @@ static void ws_bootstrap_mac_activate(protocol_interface_info_entry_t *cur, uint
static void ws_bootstrap_fhss_activate(protocol_interface_info_entry_t *cur)
{
tr_debug("FHSS activate");

ws_enable_fhss(cur);
ws_llc_hopping_schedule_config(cur, &cur->ws_info->hopping_schdule);
// Only supporting fixed channel

Expand Down
7 changes: 6 additions & 1 deletion source/MAC/IEEE802_15_4/mac_fhss_callbacks.c
Expand Up @@ -57,7 +57,12 @@ uint32_t mac_read_phy_datarate(const fhss_api_t *fhss_api)
if (!mac_setup) {
return 0;
}
return dev_get_phy_datarate(mac_setup->dev_driver->phy_driver, mac_setup->mac_channel_list.channel_page);
uint32_t datarate = dev_get_phy_datarate(mac_setup->dev_driver->phy_driver, mac_setup->mac_channel_list.channel_page);
// If datarate is not set, use default 250kbit/s.
if (!datarate) {
datarate = 250000;
}
return datarate;
}

int mac_set_channel(const fhss_api_t *fhss_api, uint8_t channel_number)
Expand Down
26 changes: 14 additions & 12 deletions source/MAC/IEEE802_15_4/mac_pd_sap.c
Expand Up @@ -340,21 +340,23 @@ static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *r
uint8_t *synch_info = tx_buf->buf + rf_ptr->dev_driver->phy_driver->phy_header_length + tx_buf->len - FHSS_SYNCH_INFO_LENGTH;
rf_ptr->fhss_api->write_synch_info(rf_ptr->fhss_api, synch_info, 0, FHSS_SYNCH_FRAME, 0);
}
// Change to destination channel and write synchronization info to Beacon frames here
int tx_handle_retval = rf_ptr->fhss_api->tx_handle(rf_ptr->fhss_api, !mac_is_ack_request_set(active_buf),
if (active_buf->asynch_request == false) {
// Change to destination channel and write synchronization info to Beacon frames here
int tx_handle_retval = rf_ptr->fhss_api->tx_handle(rf_ptr->fhss_api, !mac_is_ack_request_set(active_buf),
active_buf->DstAddr, mac_convert_frame_type_to_fhss(active_buf->fcf_dsn.frametype),
active_buf->mac_payload_length, rf_ptr->dev_driver->phy_driver->phy_header_length,
rf_ptr->dev_driver->phy_driver->phy_tail_length, active_buf->tx_time);
// When FHSS TX handle returns -1, transmission of the packet is currently not allowed -> restart CCA timer
if (tx_handle_retval == -1) {
mac_sap_cca_fail_cb(rf_ptr);
return -2;
}
// When FHSS TX handle returns -3, we are trying to transmit broadcast packet on unicast channel -> push back
// to queue by using CCA fail event
if (tx_handle_retval == -3) {
mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL);
return -3;
// When FHSS TX handle returns -1, transmission of the packet is currently not allowed -> restart CCA timer
if (tx_handle_retval == -1) {
mac_sap_cca_fail_cb(rf_ptr);
return -2;
}
// When FHSS TX handle returns -3, we are trying to transmit broadcast packet on unicast channel -> push back
// to queue by using CCA fail event
if (tx_handle_retval == -3) {
mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL);
return -3;
}
}
}
return 0;
Expand Down
9 changes: 1 addition & 8 deletions source/Service_Libs/fhss/fhss.c
Expand Up @@ -474,11 +474,6 @@ static uint32_t fhss_get_remaining_tx_time(fhss_structure_t *fhss_structure)
return remaining_tx_time;
}

uint32_t fhss_get_tx_time(fhss_structure_t *fhss_structure, uint16_t bytes_to_send, uint8_t phy_header_length, uint8_t phy_tail_length)
{
return ((1000000 / (fhss_structure->datarate / 8)) * (bytes_to_send + phy_header_length + phy_tail_length));
}

// CCA adds extra 2ms with FHSS
#define CCA_FHSS_PERIOD 2000
// Ack frame length
Expand Down Expand Up @@ -721,8 +716,6 @@ static void fhss_synch_state_set_callback(const fhss_api_t *api, fhss_states fhs
}
fhss_generate_scramble_table(fhss_structure);

uint32_t datarate = fhss_structure->callbacks.read_datarate(fhss_structure->fhss_api);
fhss_set_datarate(fhss_structure, datarate);
uint8_t mac_address[8];
fhss_structure->callbacks.read_mac_address(fhss_structure->fhss_api, mac_address);
fhss_structure->bs->uc_channel_index = fhss_get_offset(fhss_structure, mac_address);
Expand Down Expand Up @@ -1197,7 +1190,7 @@ static uint16_t fhss_get_retry_period_callback(const fhss_api_t *api, uint8_t *d

fhss_structure_t *fhss_structure = fhss_get_object_with_api(api);
if (fhss_structure) {
uint32_t datarate = fhss_structure->datarate;
uint32_t datarate = fhss_structure->callbacks.read_datarate(fhss_structure->fhss_api);
uint16_t max_tx_length;

if (datarate && phy_mtu) {
Expand Down
1 change: 0 additions & 1 deletion source/Service_Libs/fhss/fhss.h
Expand Up @@ -111,7 +111,6 @@ struct fhss_bs

fhss_structure_t *fhss_enable(fhss_api_t *fhss_api, const fhss_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer, fhss_statistics_t *fhss_statistics);
bool fhss_is_synch_root(fhss_structure_t *fhss_structure);
uint32_t fhss_get_tx_time(fhss_structure_t *fhss_structure, uint16_t bytes_to_send, uint8_t phy_header_length, uint8_t phy_tail_length);
/**
* Calculate time in microseconds to start of next superframe.
*
Expand Down
18 changes: 5 additions & 13 deletions source/Service_Libs/fhss/fhss_common.c
Expand Up @@ -89,19 +89,6 @@ static fhss_structure_t *fhss_get_object_with_timer_id(const int8_t timer_id)
return NULL;
}

int8_t fhss_set_datarate(fhss_structure_t *fhss_structure, uint32_t datarate)
{
if (!fhss_structure) {
return -1;
}
// If datarate is not set, use default 250kbit/s. Datarate is used as divider later.
if (!datarate) {
datarate = 250000;
}
fhss_structure->datarate = datarate;
return 0;
}

fhss_structure_t *fhss_get_object_with_api(const fhss_api_t *fhss_api)
{
if (!fhss_api || !fhss_struct) {
Expand Down Expand Up @@ -299,3 +286,8 @@ void fhss_failed_list_free(fhss_structure_t *fhss_structure)
fhss_failed_handle_remove(fhss_structure, i);
}
}

uint32_t fhss_get_tx_time(fhss_structure_t *fhss_structure, uint16_t bytes_to_send, uint8_t phy_header_length, uint8_t phy_tail_length)
{
return ((1000000 / (fhss_structure->callbacks.read_datarate(fhss_structure->fhss_api) / 8)) * (bytes_to_send + phy_header_length + phy_tail_length));
}
2 changes: 1 addition & 1 deletion source/Service_Libs/fhss/fhss_common.h
Expand Up @@ -43,7 +43,6 @@ struct fhss_structure
uint8_t active_fhss_events;
uint16_t number_of_channels;
fhss_states fhss_state;
uint32_t datarate;
uint32_t fhss_timeout;
uint32_t fhss_timer;
struct fhss_api *fhss_api;
Expand Down Expand Up @@ -74,4 +73,5 @@ int fhss_failed_handle_remove(fhss_structure_t *fhss_structure, uint8_t handle);
int fhss_failed_handle_add(fhss_structure_t *fhss_structure, uint8_t handle, uint8_t bad_channel);
fhss_failed_tx_t *fhss_failed_handle_find(fhss_structure_t *fhss_structure, uint8_t handle);
void fhss_failed_list_free(fhss_structure_t *fhss_structure);
uint32_t fhss_get_tx_time(fhss_structure_t *fhss_structure, uint16_t bytes_to_send, uint8_t phy_header_length, uint8_t phy_tail_length);
#endif /*FHSS_COMMON_H_*/
29 changes: 21 additions & 8 deletions source/Service_Libs/fhss/fhss_ws.c
Expand Up @@ -339,24 +339,29 @@ static bool fhss_ws_check_tx_allowed(fhss_structure_t *fhss_structure)
return false;
}

static bool fhss_ws_check_tx_time(fhss_structure_t *fhss_structure, uint16_t tx_length, uint8_t phy_header_length, uint8_t phy_tail_length)
{
if (!fhss_structure->ws->fhss_configuration.fhss_broadcast_interval || !fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) {
return true;
}
uint32_t tx_time = fhss_get_tx_time(fhss_structure, tx_length, phy_header_length, phy_tail_length);
uint32_t time_to_bc_channel = fhss_structure->platform_functions.fhss_get_remaining_slots(fhss_broadcast_handler, fhss_structure->fhss_api);
if (tx_time > time_to_bc_channel) {
return false;
}
return true;
}

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)
{
(void) handle;
(void) frame_type;
(void) frame_length;
(void) phy_header_length;
(void) phy_tail_length;
fhss_structure_t *fhss_structure = fhss_get_object_with_api(api);
if (!fhss_structure) {
return true;
}
if (fhss_structure->ws->fhss_configuration.ws_channel_function == WS_FIXED_CHANNEL) {
return true;
}
// This condition will check that message is not sent on bad channel
if (fhss_check_bad_channel(fhss_structure, handle) == false) {
return false;
}
// Do not allow broadcast destination on unicast channel
if (is_broadcast_addr && (fhss_structure->ws->is_on_bc_channel == false)) {
return false;
Expand All @@ -365,6 +370,14 @@ static bool fhss_ws_check_tx_conditions_callback(const fhss_api_t *api, bool is_
if (!is_broadcast_addr && (fhss_structure->ws->is_on_bc_channel == true)) {
return false;
}
// This condition will check that message is not sent on bad channel
if (fhss_check_bad_channel(fhss_structure, handle) == false) {
return false;
}
// Check that there is enough unicast TX time before next broadcast channel. We try to avoid delaying the change to broadcast channel because of ongoing transmission.
if (!is_broadcast_addr && !fhss_ws_check_tx_time(fhss_structure, frame_length, phy_header_length, phy_tail_length)) {
return false;
}
// Check TX/RX slot for unicast frames
if (!is_broadcast_addr && !fhss_ws_check_tx_allowed(fhss_structure)) {
return false;
Expand Down
1 change: 0 additions & 1 deletion test/nanostack/unittest/service_libs/fhss/test_fhss.c
Expand Up @@ -117,7 +117,6 @@ static void test_set_fhss_default_configs(void)
FHSS.number_of_channels = 50;
FHSS.rx_channel = DEFAULT_CHANNEL;
FHSS.fhss_state = FHSS_UNSYNCHRONIZED;
FHSS.datarate = 250000;
FHSS.own_hop = 2;
}

Expand Down
Expand Up @@ -26,11 +26,6 @@ TEST(fhss_common, test_fhss_free_instance)
CHECK(test_fhss_free_instance());
}

TEST(fhss_common, test_fhss_set_datarate)
{
CHECK(test_fhss_set_datarate());
}

TEST(fhss_common, test_fhss_get_object_with_api)
{
CHECK(test_fhss_get_object_with_api());
Expand Down
Expand Up @@ -100,24 +100,6 @@ bool test_fhss_free_instance()
return true;
}

bool test_fhss_set_datarate()
{
uint32_t datarate = 50000;
// Test without API
if (-1 != fhss_set_datarate(NULL, datarate)) {
return false;
}
// Test without datarate
if ((0 != fhss_set_datarate(&fhss_structure, 0)) || (fhss_structure.datarate != 250000)) {
return false;
}
// Test with datarate
if ((0 != fhss_set_datarate(&fhss_structure, datarate)) || (fhss_structure.datarate != datarate)) {
return false;
}
return true;
}

bool test_fhss_get_object_with_api()
{
nsdynmemlib_stub.returnCounter = 1;
Expand Down
Expand Up @@ -12,7 +12,6 @@ extern "C" {

bool test_fhss_allocate_instance();
bool test_fhss_free_instance();
bool test_fhss_set_datarate();
bool test_fhss_get_object_with_api();
bool test_fhss_disable();
bool test_fhss_start_timer();
Expand Down
5 changes: 5 additions & 0 deletions test/nanostack/unittest/stub/fhss_common_stub.c
Expand Up @@ -149,3 +149,8 @@ void fhss_failed_list_free(fhss_structure_t *fhss_structure)
{

}

uint32_t fhss_get_tx_time(fhss_structure_t *fhss_structure, uint16_t bytes_to_send, uint8_t phy_header_length, uint8_t phy_tail_length)
{
return 0;
}
5 changes: 0 additions & 5 deletions test/nanostack/unittest/stub/fhss_stub.c
Expand Up @@ -89,11 +89,6 @@ uint32_t fhss_get_remaining_time_to_next_superframe(const fhss_structure_t *fhss
return 0;
}

uint32_t fhss_get_tx_time(fhss_structure_t *fhss_structure, uint16_t bytes_to_send, uint8_t phy_header_length, uint8_t phy_tail_length)
{
return 0;
}

int fhss_sync_with_beacon(fhss_structure_t *fhss_structure, const fhss_synchronization_beacon_payload_s *payload)
{
return 0;
Expand Down

0 comments on commit 1f9162d

Please sign in to comment.