Skip to content

Commit

Permalink
FHSS: Calculate destination slot and ufsi
Browse files Browse the repository at this point in the history
  • Loading branch information
Jarkko Paso committed Feb 13, 2018
1 parent b4e1616 commit c718985
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 14 deletions.
3 changes: 2 additions & 1 deletion nanostack/fhss_api.h
Expand Up @@ -86,13 +86,14 @@ typedef bool fhss_use_broadcast_queue(const fhss_api_t *api, bool is_broadcast_a
* @param frame_length MSDU length of the frame.
* @param phy_header_length PHY header length.
* @param phy_tail_length PHY tail length.
* @param tx_time TX time.
* @return 0 Success.
* @return -1 Transmission of the packet is currently not allowed, try again.
* @return -2 Invalid api.
* @return -3 Broadcast packet on Unicast channel (not allowed), push packet back to queue.
* @return -4 Synchronization info missing.
*/
typedef int fhss_tx_handle(const fhss_api_t *api, bool is_broadcast_addr, uint8_t *destination_address, int frame_type, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length);
typedef int fhss_tx_handle(const fhss_api_t *api, bool is_broadcast_addr, uint8_t *destination_address, int frame_type, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length, uint32_t tx_time);

/**
* @brief Check TX permission.
Expand Down
2 changes: 1 addition & 1 deletion source/MAC/IEEE802_15_4/mac_pd_sap.c
Expand Up @@ -227,7 +227,7 @@ void mac_pd_sap_state_machine(protocol_interface_rf_mac_setup_s *rf_mac_setup)
int tx_handle_retval = rf_mac_setup->fhss_api->tx_handle(rf_mac_setup->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_mac_setup->dev_driver->phy_driver->phy_header_length,
rf_mac_setup->dev_driver->phy_driver->phy_tail_length);
rf_mac_setup->dev_driver->phy_driver->phy_tail_length, 0);
// When FHSS TX handle returns -1, transmission of the packet is currently not allowed -> restart CCA timer
if (tx_handle_retval == -1) {
timer_mac_start(rf_mac_setup, MAC_TIMER_CCA, randLIB_get_random_in_range(20, 400) + 1);
Expand Down
3 changes: 2 additions & 1 deletion source/Service_Libs/fhss/fhss.c
Expand Up @@ -841,8 +841,9 @@ static void fhss_superframe_callback(fhss_structure_t *fhss_structure)
}
}

static int fhss_tx_handle_callback(const fhss_api_t *api, bool is_broadcast_addr, uint8_t *destination_address, int frame_type, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length)
static int fhss_tx_handle_callback(const fhss_api_t *api, bool is_broadcast_addr, uint8_t *destination_address, int frame_type, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length, uint32_t tx_time)
{
(void) tx_time;
fhss_structure_t *fhss_structure = fhss_get_object_with_api(api);
if (!fhss_structure) {
return -2;
Expand Down
52 changes: 49 additions & 3 deletions source/Service_Libs/fhss/fhss_ws.c
Expand Up @@ -33,6 +33,8 @@
// Enable this flag to use channel traces
#define FHSS_CHANNEL_DEBUG

#define DEF_2E16 16777216

static void fhss_ws_update_uc_channel_callback(fhss_structure_t *fhss_structure);

fhss_structure_t *fhss_ws_enable(fhss_api_t *fhss_api, const fhss_ws_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer)
Expand Down Expand Up @@ -102,6 +104,50 @@ static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
}
}

static int own_floor(float value)
{
return (int)value;
}

static int own_ceil(float value)
{
int ivalue = (int)value;
if (value == (float)ivalue) {
return ivalue;
}
return ivalue + 1;
}

static uint32_t fhss_ws_calculate_ufsi(fhss_structure_t *fhss_structure, uint32_t tx_time)
{
uint8_t dwell_time = fhss_structure->fhss_conf.fhss_ws_configuration.fhss_uc_dwell_interval;
uint16_t cur_slot = fhss_structure->ws->uc_slot;
if (cur_slot == 0) {
cur_slot = fhss_structure->number_of_channels;
}
cur_slot--;
uint32_t remaining_time = (fhss_structure->platform_functions.fhss_get_remaining_slots(fhss_superframe_handler, fhss_structure->fhss_api) / 1000);
uint32_t time_to_tx = (tx_time - fhss_structure->fhss_api->read_timestamp(fhss_structure->fhss_api)) / 1000;
uint32_t ms_since_seq_start = (cur_slot * dwell_time) + (dwell_time-remaining_time) + time_to_tx;
ms_since_seq_start %= (dwell_time*fhss_structure->number_of_channels);
uint32_t seq_length = 0x10000;
if (fhss_structure->ws->channel_function == WS_TR51CF) {
seq_length = fhss_structure->number_of_channels;
}

return own_floor((float)(ms_since_seq_start * DEF_2E16) / (seq_length*dwell_time));
}

static uint16_t fhss_ws_calculate_destination_slot(fhss_structure_t *fhss_structure, uint32_t ufsi, uint32_t ufsi_timestamp, uint8_t dwell_time, uint32_t tx_time)
{
uint32_t seq_length = 0x10000;
if (fhss_structure->ws->channel_function == WS_TR51CF) {
seq_length = fhss_structure->number_of_channels;
}
uint32_t dest_ms_since_seq_start = own_ceil((float)(ufsi*seq_length*dwell_time) / DEF_2E16);
return (own_floor(((float)((tx_time - ufsi_timestamp)/1000 + dest_ms_since_seq_start) / dwell_time)) % seq_length);
}

static uint32_t fhss_ws_get_sf_timeout_callback(fhss_structure_t *fhss_structure)
{
return fhss_structure->fhss_conf.fhss_ws_configuration.fhss_uc_dwell_interval * 1000;
Expand Down Expand Up @@ -159,7 +205,7 @@ static void fhss_ws_update_uc_channel_callback(fhss_structure_t *fhss_structure)
fhss_structure->callbacks.change_channel(fhss_structure->fhss_api, next_channel);
}

static int fhss_ws_tx_handle_callback(const fhss_api_t *api, bool is_broadcast_addr, uint8_t *destination_address, int frame_type, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length)
static int fhss_ws_tx_handle_callback(const fhss_api_t *api, bool is_broadcast_addr, uint8_t *destination_address, int frame_type, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length, uint32_t tx_time)
{
(void) is_broadcast_addr;
(void) frame_type;
Expand All @@ -172,8 +218,8 @@ static int fhss_ws_tx_handle_callback(const fhss_api_t *api, bool is_broadcast_a
}
if (fhss_structure->fhss_state == FHSS_SYNCHRONIZED) {
int32_t tx_channel;
//TODO: Compute destination slot using neighbour table
uint16_t destination_slot = fhss_structure->ws->uc_slot;
//TODO: Get destination UFSI, timestamp and dwell time from neighbour table
uint16_t destination_slot = fhss_ws_calculate_destination_slot(fhss_structure, 0, 0, fhss_structure->fhss_conf.fhss_ws_configuration.fhss_uc_dwell_interval, tx_time);
if (fhss_structure->ws->channel_function == WS_TR51CF) {
tx_channel = tr51_get_uc_channel_index(destination_slot, destination_address, fhss_structure->number_of_channels);
} else if(fhss_structure->ws->channel_function == WS_DH1CF) {
Expand Down
Expand Up @@ -261,7 +261,7 @@ static protocol_interface_rf_mac_setup_s * test_mac_rf_mac_class_allocate(void)
return rf_mac_setup;
}

static int fhss_tx_handle_callback(const fhss_api_t *api, bool is_broadcast_addr, uint8_t *destination_address, int frame_type, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length)
static int fhss_tx_handle_callback(const fhss_api_t *api, bool is_broadcast_addr, uint8_t *destination_address, int frame_type, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length, uint32_t tx_time)
{
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion test/nanostack/unittest/mac/mac_pd_sap/test_mac_pd_sap.c
Expand Up @@ -51,7 +51,7 @@ static int8_t test_rf_virtual_tx(const virtual_data_req_t *data_req,int8_t drive
return 0;
}

static int fhss_tx_handle_callback(const fhss_api_t *api, bool is_broadcast_addr, uint8_t *destination_address, int frame_type, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length)
static int fhss_tx_handle_callback(const fhss_api_t *api, bool is_broadcast_addr, uint8_t *destination_address, int frame_type, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length, uint32_t tx_time)
{
return 0;
}
Expand Down
10 changes: 5 additions & 5 deletions test/nanostack/unittest/service_libs/fhss/test_fhss.c
Expand Up @@ -729,27 +729,27 @@ bool test_fhss_tx_handle_callback()
fhss_struct->synch_configuration.fhss_number_of_tx_slots = 1;
fhss_set_callbacks(fhss_struct);
// Broadcast data on unicast channel should return -3
if (fhss_struct->fhss_api->tx_handle(&fhss_api, true, NULL, FHSS_DATA_FRAME, 0, 0, 0) != -3) {
if (fhss_struct->fhss_api->tx_handle(&fhss_api, true, NULL, FHSS_DATA_FRAME, 0, 0, 0, 0) != -3) {
return false;
}
// Test sending of Beacon
if (fhss_struct->fhss_api->tx_handle(&fhss_api, true, NULL, FHSS_SYNCH_FRAME, 0, 0, 0) != 0) {
if (fhss_struct->fhss_api->tx_handle(&fhss_api, true, NULL, FHSS_SYNCH_FRAME, 0, 0, 0, 0) != 0) {
return false;
}
// When TX is not allowed, should return -1 for data frame
fhss_struct->tx_allowed = false;
fhss_struct->fhss_state = FHSS_SYNCHRONIZED;
if (fhss_struct->fhss_api->tx_handle(&fhss_api, false, NULL, FHSS_DATA_FRAME, 0, 0, 0) != -1) {
if (fhss_struct->fhss_api->tx_handle(&fhss_api, false, NULL, FHSS_DATA_FRAME, 0, 0, 0, 0) != -1) {
return false;
}
// When TX is allowed, should return 0 for data frame
fhss_struct->tx_allowed = true;
fhss_struct->fhss_state = FHSS_UNSYNCHRONIZED;
if (fhss_struct->fhss_api->tx_handle(&fhss_api, false, NULL, FHSS_DATA_FRAME, 0, 0, 0) != 0) {
if (fhss_struct->fhss_api->tx_handle(&fhss_api, false, NULL, FHSS_DATA_FRAME, 0, 0, 0, 0) != 0) {
return false;
}
// Test changing to parent channel to send synch request
if (fhss_struct->fhss_api->tx_handle(&fhss_api, false, NULL, FHSS_SYNCH_REQUEST_FRAME, 0, 0, 0) != 0) {
if (fhss_struct->fhss_api->tx_handle(&fhss_api, false, NULL, FHSS_SYNCH_REQUEST_FRAME, 0, 0, 0, 0) != 0) {
return false;
}
free(fhss_struct);
Expand Down
2 changes: 1 addition & 1 deletion test/nanostack/unittest/stub/fhss_mac_interface_stub.h
Expand Up @@ -34,7 +34,7 @@ extern fhss_mac_interface_stub_def fhss_mac_interface_stub;

bool fhss_is_broadcast_channel_cb(const fhss_api_t *api);
bool fhss_use_broadcast_queue_cb(const fhss_api_t *api, bool is_broadcast_addr, int frame_type);
int fhss_tx_handle_cb(const fhss_api_t *api, bool is_broadcast_addr, uint8_t *destination_address, int frame_type, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length);
int fhss_tx_handle_cb(const fhss_api_t *api, bool is_broadcast_addr, uint8_t *destination_address, int frame_type, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length, uint32_t tx_time);
bool fhss_check_tx_conditions_cb(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 fhss_receive_frame_cb(const fhss_api_t *api, uint16_t pan_id, uint8_t *source_address, uint32_t timestamp, uint8_t *synch_info, int frame_type);
void fhss_data_tx_done_cb(const fhss_api_t *api, bool waiting_ack, bool tx_completed, uint8_t handle);
Expand Down

0 comments on commit c718985

Please sign in to comment.