diff --git a/source/Service_Libs/fhss/channel_functions.c b/source/Service_Libs/fhss/channel_functions.c index 58bad623004..04649a698f8 100644 --- a/source/Service_Libs/fhss/channel_functions.c +++ b/source/Service_Libs/fhss/channel_functions.c @@ -81,7 +81,7 @@ static int32_t tr51_get_rand(void) * @param nearest_prime Nearest prime number. Must be equal to or larger than number_of_channels. * @param channel_table Output channel table. Has to be at least nearest_prime in length. */ -static void tr51_calculate_channel_table(uint16_t number_of_channels, uint16_t nearest_prime, int32_t *channel_table) +static void tr51_calculate_channel_table(uint16_t number_of_channels, uint16_t nearest_prime, int16_t *channel_table) { int32_t i,j,k; tr51_seed_rand(1); @@ -131,7 +131,7 @@ static uint8_t tr51_find_excluded(int32_t channel, uint32_t *excluded_channels) * @param excluded_channels Bit mask where excluded channels are set to 1. * @return Number of channels in sequence. */ -static uint16_t tr51_calculate_hopping_sequence(int32_t *channel_table, uint16_t channel_table_length, uint8_t first_element, uint8_t step_size, int32_t *output_table, uint32_t *excluded_channels) +static uint16_t tr51_calculate_hopping_sequence(int16_t *channel_table, uint16_t channel_table_length, uint8_t first_element, uint8_t step_size, uint8_t *output_table, uint32_t *excluded_channels) { uint16_t cntr = channel_table_length; uint8_t index = first_element; @@ -194,33 +194,30 @@ int32_t dh1cf_get_bc_channel_index(uint16_t slot_number, uint16_t bsi, int16_t n return channel_number; } -int32_t tr51_get_uc_channel_index(uint16_t slot_number, uint8_t *mac, int16_t number_of_channels, uint32_t *excluded_channels) +int tr51_init_channel_table(int16_t *channel_table, int16_t number_of_channels) +{ + uint16_t nearest_prime = tr51_calc_nearest_prime_number(number_of_channels); + tr51_calculate_channel_table(number_of_channels, nearest_prime, channel_table); + return 0; +} + +int32_t tr51_get_uc_channel_index(int16_t *channel_table, uint8_t *output_table, uint16_t slot_number, uint8_t *mac, int16_t number_of_channels, uint32_t *excluded_channels) { uint16_t nearest_prime = tr51_calc_nearest_prime_number(number_of_channels); - int32_t channel_table[nearest_prime]; - int32_t output_table[number_of_channels]; uint8_t first_element; uint8_t step_size; - tr51_calculate_channel_table(number_of_channels, nearest_prime, channel_table); tr51_compute_cfd(mac, &first_element, &step_size, nearest_prime); -// Not sure yet which one is the correct second parameter -// tr51_calculate_hopping_sequence(channel_table, number_of_channels, first_element, step_size, output_table, NULL, 0); tr51_calculate_hopping_sequence(channel_table, nearest_prime, first_element, step_size, output_table, excluded_channels); return output_table[slot_number]; } -int32_t tr51_get_bc_channel_index(uint16_t slot_number, uint16_t bsi, int16_t number_of_channels, uint32_t *excluded_channels) +int32_t tr51_get_bc_channel_index(int16_t *channel_table, uint8_t *output_table, uint16_t slot_number, uint16_t bsi, int16_t number_of_channels, uint32_t *excluded_channels) { uint16_t nearest_prime = tr51_calc_nearest_prime_number(number_of_channels); - int32_t channel_table[nearest_prime]; - int32_t output_table[number_of_channels]; uint8_t mac[8] = {0, 0, 0, 0, 0, 0, (uint8_t)(bsi >> 8), (uint8_t)bsi}; uint8_t first_element; uint8_t step_size; - tr51_calculate_channel_table(number_of_channels, nearest_prime, channel_table); tr51_compute_cfd(mac, &first_element, &step_size, nearest_prime); -// Not sure yet which one is the correct second parameter -// tr51_calculate_hopping_sequence(channel_table, number_of_channels, first_element, step_size, output_table, NULL, 0); tr51_calculate_hopping_sequence(channel_table, nearest_prime, first_element, step_size, output_table, excluded_channels); return output_table[slot_number]; } diff --git a/source/Service_Libs/fhss/channel_functions.h b/source/Service_Libs/fhss/channel_functions.h index 990a7ac90e6..b36ea5418bd 100644 --- a/source/Service_Libs/fhss/channel_functions.h +++ b/source/Service_Libs/fhss/channel_functions.h @@ -17,25 +17,37 @@ #ifndef CHANNEL_FUNC_H_ #define CHANNEL_FUNC_H_ +/** + * @brief Initialize channel table for TR51 channel function. + * @param channel_table Channel table to be initialized. + * @param number_of_channels Number of channels. + * @return 0 Success, -1 Failure. + */ +int tr51_init_channel_table(int16_t *channel_table, int16_t number_of_channels); + /** * @brief Compute the unicast schedule channel index using tr51 channel function. + * @param channel_table Channel table. + * @param output_table Table used to generate output channel. * @param slot_number Current slot number. * @param mac MAC address of the node for which the index is calculated. * @param number_of_channels Number of channels. * @param excluded_channels Excluded channels. * @return Channel index. */ -int32_t tr51_get_uc_channel_index(uint16_t slot_number, uint8_t *mac, int16_t number_of_channels, uint32_t *excluded_channels); +int32_t tr51_get_uc_channel_index(int16_t *channel_table, uint8_t *output_table, uint16_t slot_number, uint8_t *mac, int16_t number_of_channels, uint32_t *excluded_channels); /** * @brief Compute the broadcast schedule channel index using tr51 channel function. + * @param channel_table Channel table. + * @param output_table Table used to generate output channel. * @param slot_number Current slot number. * @param bsi Broadcast schedule identifier of the node for which the index is calculated. * @param number_of_channels Number of channels. * @param excluded_channels Excluded channels. * @return Channel index. */ -int32_t tr51_get_bc_channel_index(uint16_t slot_number, uint16_t bsi, int16_t number_of_channels, uint32_t *excluded_channels); +int32_t tr51_get_bc_channel_index(int16_t *channel_table, uint8_t *output_table, uint16_t slot_number, uint16_t bsi, int16_t number_of_channels, uint32_t *excluded_channels); /** * @brief Compute the unicast schedule channel index using direct hash channel function. diff --git a/source/Service_Libs/fhss/fhss_ws.c b/source/Service_Libs/fhss/fhss_ws.c index 0118d35792d..c18701bb00f 100644 --- a/source/Service_Libs/fhss/fhss_ws.c +++ b/source/Service_Libs/fhss/fhss_ws.c @@ -58,6 +58,7 @@ struct ws_ie_t { uint8_t id; }; +static int fhss_ws_manage_channel_table_allocation(fhss_structure_t *fhss_structure, uint16_t channel_count); static void fhss_event_timer_cb(int8_t timer_id, uint16_t slots); static void fhss_ws_update_uc_channel_callback(fhss_structure_t *fhss_structure); static void fhss_unicast_handler(const fhss_api_t *fhss_api, uint16_t delay); @@ -91,6 +92,12 @@ fhss_structure_t *fhss_ws_enable(fhss_api_t *fhss_api, const fhss_ws_configurati return NULL; } memset(fhss_struct->ws, 0, sizeof(fhss_ws_t)); + if (fhss_ws_manage_channel_table_allocation(fhss_struct, channel_count)) { + ns_dyn_mem_free(fhss_struct->ws); + fhss_free_instance(fhss_api); + tr_error("Failed to allocate channel tables"); + return NULL; + } fhss_struct->fhss_event_timer = eventOS_callback_timer_register(fhss_event_timer_cb); fhss_struct->ws->fhss_configuration = *fhss_configuration; @@ -103,6 +110,24 @@ fhss_structure_t *fhss_ws_enable(fhss_api_t *fhss_api, const fhss_ws_configurati return fhss_struct; } +static int fhss_ws_manage_channel_table_allocation(fhss_structure_t *fhss_structure, uint16_t channel_count) +{ + // Must allocate channel table for TR51 + if (!fhss_structure->ws->tr51_channel_table && !fhss_structure->ws->tr51_output_table) { + fhss_structure->ws->tr51_channel_table = ns_dyn_mem_alloc(sizeof(int16_t)*channel_count); + if (!fhss_structure->ws->tr51_channel_table) { + return -1; + } + fhss_structure->ws->tr51_output_table = ns_dyn_mem_alloc(sizeof(int16_t)*channel_count); + if (!fhss_structure->ws->tr51_output_table) { + ns_dyn_mem_free(fhss_structure->ws->tr51_channel_table); + return -1; + } + tr51_init_channel_table(fhss_structure->ws->tr51_channel_table, channel_count); + } + return 0; +} + static uint8_t fhss_set_txrx_slot_length(fhss_structure_t *fhss_structure) { uint8_t number_of_tx_slots = ((fhss_structure->ws->fhss_configuration.fhss_broadcast_interval - fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) / WS_MAX_TXRX_SLOT_LEN_MS) / 2; @@ -118,7 +143,7 @@ static int32_t fhss_ws_calc_bc_channel(fhss_structure_t *fhss_structure) int32_t next_channel = fhss_structure->ws->fhss_configuration.broadcast_fixed_channel; if (fhss_structure->ws->fhss_configuration.ws_bc_channel_function == WS_TR51CF) { - next_channel = tr51_get_bc_channel_index(fhss_structure->ws->bc_slot, fhss_structure->ws->fhss_configuration.bsi, fhss_structure->number_of_channels, NULL); + next_channel = tr51_get_bc_channel_index(fhss_structure->ws->tr51_channel_table, fhss_structure->ws->tr51_output_table, fhss_structure->ws->bc_slot, fhss_structure->ws->fhss_configuration.bsi, fhss_structure->number_of_channels, NULL); if (++fhss_structure->ws->bc_slot == fhss_structure->number_of_channels) { fhss_structure->ws->bc_slot = 0; } @@ -332,7 +357,7 @@ static void fhss_ws_update_uc_channel_callback(fhss_structure_t *fhss_structure) if (fhss_structure->ws->fhss_configuration.ws_uc_channel_function == WS_FIXED_CHANNEL) { return; } else if (fhss_structure->ws->fhss_configuration.ws_uc_channel_function == WS_TR51CF) { - next_channel = fhss_structure->rx_channel = tr51_get_uc_channel_index(fhss_structure->ws->uc_slot, mac_address, fhss_structure->number_of_channels, NULL); + next_channel = fhss_structure->rx_channel = tr51_get_uc_channel_index(fhss_structure->ws->tr51_channel_table, fhss_structure->ws->tr51_output_table, fhss_structure->ws->uc_slot, mac_address, fhss_structure->number_of_channels, NULL); if (++fhss_structure->ws->uc_slot == fhss_structure->number_of_channels) { fhss_structure->ws->uc_slot = 0; } @@ -391,7 +416,7 @@ static int fhss_ws_tx_handle_callback(const fhss_api_t *api, bool is_broadcast_a uint16_t destination_slot = fhss_ws_calculate_destination_slot(neighbor_timing_info, tx_time); int32_t tx_channel = neighbor_timing_info->uc_timing_info.fixed_channel; if (neighbor_timing_info->uc_timing_info.unicast_channel_function == WS_TR51CF) { - tx_channel = tr51_get_uc_channel_index(destination_slot, destination_address, neighbor_timing_info->uc_timing_info.unicast_number_of_channels, NULL); + tx_channel = tr51_get_uc_channel_index(fhss_structure->ws->tr51_channel_table, fhss_structure->ws->tr51_output_table, destination_slot, destination_address, neighbor_timing_info->uc_timing_info.unicast_number_of_channels, NULL); } else if(neighbor_timing_info->uc_timing_info.unicast_channel_function == WS_DH1CF) { tx_channel = dh1cf_get_uc_channel_index(destination_slot, destination_address, neighbor_timing_info->uc_timing_info.unicast_number_of_channels); } else if (neighbor_timing_info->uc_timing_info.unicast_channel_function == WS_VENDOR_DEF_CF) { diff --git a/source/Service_Libs/fhss/fhss_ws.h b/source/Service_Libs/fhss/fhss_ws.h index f09fb4b2461..cf4af1040cb 100644 --- a/source/Service_Libs/fhss/fhss_ws.h +++ b/source/Service_Libs/fhss/fhss_ws.h @@ -35,6 +35,8 @@ struct fhss_ws uint16_t min_synch_interval; uint32_t txrx_slot_length_ms; uint32_t synchronization_time; + int16_t *tr51_channel_table; + uint8_t *tr51_output_table; bool unicast_timer_running; bool is_on_bc_channel; struct fhss_ws_configuration fhss_configuration;