Skip to content

Commit

Permalink
FHSS: Cleaning. Static functions. Separated tx fail and retry callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
Jarkko Paso committed Feb 15, 2018
1 parent 8b9d39b commit 07d4089
Show file tree
Hide file tree
Showing 18 changed files with 168 additions and 565 deletions.
2 changes: 1 addition & 1 deletion source/MAC/IEEE802_15_4/mac_pd_sap.c
Expand Up @@ -265,7 +265,7 @@ static void mac_sap_cca_fail_cb(protocol_interface_rf_mac_setup_s *rf_ptr) {

static uint16_t mac_get_retry_period(protocol_interface_rf_mac_setup_s *rf_ptr)
{
if (rf_ptr->fhss_api) {
if (rf_ptr->fhss_api && rf_ptr->fhss_api->get_retry_period) {
return rf_ptr->fhss_api->get_retry_period(rf_ptr->fhss_api, rf_ptr->active_pd_data_request->DstAddr, rf_ptr->dev_driver->phy_driver->phy_MTU);
}
uint8_t backoff_length = mac_csma_random_backoff_get(rf_ptr);
Expand Down
147 changes: 137 additions & 10 deletions source/Service_Libs/fhss/fhss.c
Expand Up @@ -40,6 +40,9 @@ static void fhss_destroy_scramble_table(fhss_structure_t *fhss_structure);
static bool fhss_is_bc_sending_superframe(fhss_structure_t *fhss_structure);
static bool fhss_check_remaining_tx_time(fhss_structure_t *fhss_structure, uint16_t tx_length, uint8_t phy_header_length, uint8_t phy_tail_length);
static bool fhss_is_there_common_divisor(uint16_t i, uint8_t j);
static fhss_failed_tx_t *fhss_failed_handle_find(fhss_structure_t *fhss_structure, uint8_t handle);
static void fhss_failed_list_free(fhss_structure_t *fhss_structure);
static void fhss_beacon_received(fhss_structure_t *fhss_structure, const uint8_t *synch_info, const uint32_t elapsed_time);

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)
{
Expand Down Expand Up @@ -195,7 +198,7 @@ static bool fhss_check_tx_allowed(fhss_structure_t *fhss_structure, bool is_bc,
return true;
}

int fhss_reset_synch_monitor(fhss_synch_monitor_s *synch_monitor)
static int fhss_reset_synch_monitor(fhss_synch_monitor_s *synch_monitor)
{
if (synch_monitor) {
synch_monitor->avg_synch_fix = 0;
Expand Down Expand Up @@ -326,7 +329,7 @@ static int fhss_update_synch_monitor(fhss_structure_t *fhss_structure, const fhs
return retval;
}

int fhss_sync_with_beacon(fhss_structure_t *fhss_structure,
static int fhss_sync_with_beacon(fhss_structure_t *fhss_structure,
const fhss_synchronization_beacon_payload_s *payload)
{
int ret_val = -1;
Expand Down Expand Up @@ -654,7 +657,7 @@ static int fhss_reset(fhss_structure_t *fhss_structure)
return 0;
}

int fhss_add_beacon_info(fhss_structure_t *fhss_structure, uint16_t pan_id, uint8_t *source_address, uint32_t timestamp, uint8_t *synch_info)
static int fhss_add_beacon_info(fhss_structure_t *fhss_structure, uint16_t pan_id, uint8_t *source_address, uint32_t timestamp, uint8_t *synch_info)
{
if (!fhss_structure || !source_address || !synch_info) {
return -1;
Expand Down Expand Up @@ -687,7 +690,7 @@ void fhss_update_beacon_info_lifetimes(fhss_structure_t *fhss_structure, uint32_
}
}

fhss_failed_tx_t *fhss_failed_handle_find(fhss_structure_t *fhss_structure, uint8_t handle)
static fhss_failed_tx_t *fhss_failed_handle_find(fhss_structure_t *fhss_structure, uint8_t handle)
{
ns_list_foreach(fhss_failed_tx_t, cur, &fhss_structure->fhss_failed_tx_list) {
if (cur->handle == handle) {
Expand All @@ -697,7 +700,7 @@ fhss_failed_tx_t *fhss_failed_handle_find(fhss_structure_t *fhss_structure, uint
return NULL;
}

int fhss_failed_handle_add(fhss_structure_t *fhss_structure, uint8_t handle)
static int fhss_failed_handle_add(fhss_structure_t *fhss_structure, uint8_t handle)
{
fhss_failed_tx_t *failed_tx = ns_dyn_mem_alloc(sizeof(fhss_failed_tx_t));
if (!failed_tx) {
Expand All @@ -710,7 +713,7 @@ int fhss_failed_handle_add(fhss_structure_t *fhss_structure, uint8_t handle)
return 0;
}

int fhss_failed_handle_remove(fhss_structure_t *fhss_structure, uint8_t handle)
static int fhss_failed_handle_remove(fhss_structure_t *fhss_structure, uint8_t handle)
{
fhss_failed_tx_t *failed_tx = fhss_failed_handle_find(fhss_structure, handle);
if (!failed_tx) {
Expand All @@ -721,7 +724,7 @@ int fhss_failed_handle_remove(fhss_structure_t *fhss_structure, uint8_t handle)
return 0;
}

void fhss_failed_list_free(fhss_structure_t *fhss_structure)
static void fhss_failed_list_free(fhss_structure_t *fhss_structure)
{
for (uint16_t i = 0; i<256; i++) {
fhss_failed_handle_remove(fhss_structure, i);
Expand Down Expand Up @@ -797,6 +800,22 @@ static void fhss_destroy_scramble_table(fhss_structure_t *fhss_structure)
}
}

static void fhss_beacon_received(fhss_structure_t *fhss_structure, const uint8_t *synch_info, const uint32_t elapsed_time)
{

if (fhss_structure) {

if (synch_info) {
fhss_synchronization_beacon_payload_s temp_payload;
temp_payload.processing_delay = fhss_structure->fhss_conf.fhss_configuration.fhss_tuning_parameters.rx_processing_delay;
fhss_beacon_decode(&temp_payload, synch_info, elapsed_time, fhss_structure->number_of_channels);

// use the received information
fhss_sync_with_beacon(fhss_structure, &temp_payload);
}
}
}

static uint32_t fhss_get_sf_timeout_callback(fhss_structure_t *fhss_structure)
{
uint32_t compensation = 0;
Expand Down Expand Up @@ -955,19 +974,127 @@ static void fhss_data_tx_done_callback(const fhss_api_t *api, bool waiting_ack,
}
}

static bool fhss_data_tx_fail_callback(const fhss_api_t *api, uint8_t handle, int frame_type)
{
fhss_structure_t *fhss_structure = fhss_get_object_with_api(api);
if (!fhss_structure) {
return false;
}
// Only use channel retries when device is synchronized
if (fhss_structure->fhss_state == FHSS_UNSYNCHRONIZED) {
return false;
}
// Channel retries are disabled -> return
if (fhss_structure->fhss_conf.fhss_configuration.fhss_number_of_channel_retries == 0) {
return false;
}
// Use channel retries only for data frames
if (FHSS_DATA_FRAME != frame_type) {
return false;
}

fhss_failed_tx_t *fhss_failed_tx = fhss_failed_handle_find(fhss_structure, handle);
if (fhss_failed_tx) {
fhss_failed_tx->retries_done++;
if (fhss_failed_tx->retries_done >= fhss_structure->fhss_conf.fhss_configuration.fhss_number_of_channel_retries) {
// No more retries. Return false to stop retransmitting.
fhss_failed_handle_remove(fhss_structure, handle);
return false;
}
} else {
// Create new failure handle and return true to retransmit
fhss_failed_handle_add(fhss_structure, handle);
}
return true;
}

static void fhss_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)
{
fhss_structure_t *fhss_structure = fhss_get_object_with_api(api);
if (!fhss_structure) {
return;
}
if (FHSS_SYNCH_FRAME == frame_type) {
if ((fhss_structure->fhss_state == FHSS_UNSYNCHRONIZED) || fhss_structure->synch_panid != pan_id) {
fhss_add_beacon_info(fhss_structure, pan_id, source_address, timestamp, synch_info);
} else {
if (!fhss_compare_with_synch_parent_address(fhss_structure, source_address)) {
// Synch parent address needs to be updated in case parent has changed
fhss_update_synch_parent_address(fhss_structure);
platform_enter_critical();
// Calculate time since the Beacon was received
uint32_t elapsed_time = api->read_timestamp(api) - timestamp;
// Synchronize to given PAN
fhss_beacon_received(fhss_structure, synch_info, elapsed_time);
platform_exit_critical();
}
}
} else if (FHSS_SYNCH_REQUEST_FRAME == frame_type) {
// If current channel is broadcast, we don't need to send another synch info on next broadcast channel.
// Only send number of MAX_SYNCH_INFOS_PER_CHANNEL_LIST synch infos per one channel list cycle
if ((fhss_structure->fhss_state == FHSS_SYNCHRONIZED) && (fhss_is_current_channel_broadcast(fhss_structure) == false)
&& (fhss_structure->synch_infos_sent_counter < MAX_SYNCH_INFOS_PER_CHANNEL_LIST)) {
fhss_structure->send_synch_info_on_next_broadcast_channel = true;
}
}
}

static uint16_t fhss_get_retry_period_callback(const fhss_api_t *api, uint8_t *destination_address, uint16_t phy_mtu)
{
uint16_t retry_period = 0;
uint16_t random_number = randLIB_get_16bit();
uint16_t rnd_mask;

/* Generate retry back-off period. FHSS is using the known synchronization parent info to delay retransmissions upstream.
*
*/
if (phy_mtu < 128) {
// Max. random when PHY MTU below 128 is 6.4ms
rnd_mask = 0x7f;
} else if (phy_mtu < 256) {
// Max. random when PHY MTU below 256 is 12.8ms
rnd_mask = 0xff;
} else {
// Max. random when PHY MTU above 255 is 25.6ms
rnd_mask = 0x1ff;
}

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

if (datarate && phy_mtu) {
if (fhss_compare_with_synch_parent_address(fhss_structure, destination_address) == 0) {
// E.g. (1000000 / (250000bit/s / 8 bits)) * 255 bytes = 8160us
max_tx_length = ((1000000 / (datarate / 8)) * phy_mtu);
/* Retrying upstream: delay the transmission until assumed hidden node has retried downstream:
* Static period: max random + max tx length
* 50 comes from MAC timer resolution (50us)
*/
retry_period = (rnd_mask + (max_tx_length / 50));
}
}
}

// Add 1 to not to ever return zero value.
retry_period += ((random_number & rnd_mask) + 1);
return retry_period;
}

int fhss_set_callbacks(fhss_structure_t *fhss_structure)
{
// Set external API
fhss_structure->fhss_api->is_broadcast_channel = &fhss_is_broadcast_channel_cb;
fhss_structure->fhss_api->use_broadcast_queue = &fhss_use_broadcast_queue_cb;
fhss_structure->fhss_api->tx_handle = &fhss_tx_handle_callback;
fhss_structure->fhss_api->check_tx_conditions = &fhss_check_tx_conditions_callback;
fhss_structure->fhss_api->receive_frame = &fhss_receive_frame_cb;
fhss_structure->fhss_api->receive_frame = &fhss_receive_frame_callback;
fhss_structure->fhss_api->data_tx_done = &fhss_data_tx_done_callback;
fhss_structure->fhss_api->data_tx_fail = &fhss_data_tx_fail_cb;
fhss_structure->fhss_api->data_tx_fail = &fhss_data_tx_fail_callback;
fhss_structure->fhss_api->synch_state_set = &fhss_handle_state_set;
fhss_structure->fhss_api->read_timestamp = &fhss_read_timestamp_cb;
fhss_structure->fhss_api->get_retry_period = &fhss_get_retry_period_cb;
fhss_structure->fhss_api->get_retry_period = &fhss_get_retry_period_callback;
fhss_structure->fhss_api->write_synch_info = &fhss_write_synch_info_callback;
fhss_structure->fhss_api->init_callbacks = &fhss_init_callbacks_cb;
// Set internal API
Expand Down
14 changes: 0 additions & 14 deletions source/Service_Libs/fhss/fhss.h
Expand Up @@ -59,22 +59,8 @@ struct fhss_failed_tx

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);
int fhss_add_beacon_info(fhss_structure_t *fhss_structure, uint16_t pan_id, uint8_t *source_address, uint32_t timestamp, uint8_t *synch_info);
void fhss_update_beacon_info_lifetimes(fhss_structure_t *fhss_structure, uint32_t timestamp);
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);
fhss_failed_tx_t *fhss_failed_handle_find(fhss_structure_t *fhss_structure, uint8_t handle);
int fhss_failed_handle_add(fhss_structure_t *fhss_structure, uint8_t handle);
int fhss_failed_handle_remove(fhss_structure_t *fhss_structure, uint8_t handle);
void fhss_failed_list_free(fhss_structure_t *fhss_structure);
int fhss_reset_synch_monitor(fhss_synch_monitor_s *synch_monitor);
int fhss_set_callbacks(fhss_structure_t *fhss_structure);

/**
* Calculate time in microseconds to start of next superframe.
*
* @param fhss_struct FHSS state
* @return microseconds left to start of next superframe
*/
uint32_t fhss_get_remaining_time_to_next_superframe(const fhss_structure_t *fhss_struct);

#endif /* FHSS_H_ */
18 changes: 0 additions & 18 deletions source/Service_Libs/fhss/fhss_beacon.h
Expand Up @@ -149,24 +149,6 @@ void fhss_beacon_decode_raw(fhss_synchronization_beacon_payload_s* dest, const u
int fhss_beacon_update_payload(fhss_structure_t *fhss_structure,
fhss_synchronization_beacon_payload_s *payload);

void fhss_beacon_received(fhss_structure_t *fhss_structure, const uint8_t *synch_info, const uint32_t elapsed_time);

/**
* This function is called whenever a node receives a beacon in the "proper state".
* The implmentation of it stores the data received and eventually synchronizes
* itself.
*
* Note: this is in completely illogical header file, but we have a
* circular dependency with net_fhss.h and protocol.h.
*
* @param cur the network interface which received beacon
* @param payload decoded beacon payload information
*
* @return 0 on success
*/
int fhss_sync_with_beacon(fhss_structure_t *fhss_structure,
const fhss_synchronization_beacon_payload_s *payload);

uint8_t fhss_calculate_uc_index(uint8_t channel_index, uint16_t number_of_channels, uint8_t number_of_broadcast_channels);
int8_t fhss_beacon_create_tasklet(fhss_structure_t *fhss_structure);

Expand Down
18 changes: 0 additions & 18 deletions source/Service_Libs/fhss/fhss_beacon_tasklet.c
Expand Up @@ -136,21 +136,3 @@ void fhss_beacon_build(fhss_structure_t *fhss_structure, uint8_t* dest)
platform_exit_critical();
fhss_beacon_encode_raw(dest, &temp_payload);
}

// this assumes that the buffer's data pointer is seeked to the beacon payload
void fhss_beacon_received(fhss_structure_t *fhss_structure, const uint8_t *synch_info, const uint32_t elapsed_time) {

if (fhss_structure) {

if (synch_info) {
fhss_synchronization_beacon_payload_s temp_payload;
temp_payload.processing_delay = fhss_structure->fhss_conf.fhss_configuration.fhss_tuning_parameters.rx_processing_delay;
fhss_beacon_decode(&temp_payload, synch_info, elapsed_time, fhss_structure->number_of_channels);

// use the received information
fhss_sync_with_beacon(fhss_structure, &temp_payload);
}
}
}


8 changes: 7 additions & 1 deletion source/Service_Libs/fhss/fhss_common.h
Expand Up @@ -127,6 +127,12 @@ int fhss_update_synch_parent_address(fhss_structure_t *fhss_structure);
void fhss_trig_event(fhss_structure_t *fhss_structure, uint8_t event_type);
int fhss_get_parent_address(fhss_structure_t *fhss_structure, uint8_t *p_addr);
int fhss_compare_with_synch_parent_address(fhss_structure_t *fhss_structure, const uint8_t *source_addr);

void fhss_superframe_handler(const fhss_api_t *fhss_api, uint16_t delay);
/**
* Calculate time in microseconds to start of next superframe.
*
* @param fhss_struct FHSS structure
* @return microseconds left to start of next superframe
*/
uint32_t fhss_get_remaining_time_to_next_superframe(const fhss_structure_t *fhss_struct);
#endif /*FHSS_COMMON_H_*/

0 comments on commit 07d4089

Please sign in to comment.