Skip to content

Commit 654dd44

Browse files
author
Jarkko Paso
authored
Merge pull request #1879 from ARMmbed/IOTTHD-2752
FHSS: Allocate TR51 channel table if TR51 used
2 parents 1ef5062 + 4c74f96 commit 654dd44

File tree

7 files changed

+88
-26
lines changed

7 files changed

+88
-26
lines changed

source/Service_Libs/fhss/channel_functions.c

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
static uint32_t global_seed = 1;
4343

4444

45-
static uint16_t tr51_calc_nearest_prime_number(uint16_t start_value)
45+
uint16_t tr51_calc_nearest_prime_number(uint16_t start_value)
4646
{
4747
if (start_value < 2) {
4848
return 0;
@@ -81,7 +81,7 @@ static int32_t tr51_get_rand(void)
8181
* @param nearest_prime Nearest prime number. Must be equal to or larger than number_of_channels.
8282
* @param channel_table Output channel table. Has to be at least nearest_prime in length.
8383
*/
84-
static void tr51_calculate_channel_table(uint16_t number_of_channels, uint16_t nearest_prime, int32_t *channel_table)
84+
static void tr51_calculate_channel_table(uint16_t number_of_channels, uint16_t nearest_prime, int16_t *channel_table)
8585
{
8686
int32_t i,j,k;
8787
tr51_seed_rand(1);
@@ -131,7 +131,7 @@ static uint8_t tr51_find_excluded(int32_t channel, uint32_t *excluded_channels)
131131
* @param excluded_channels Bit mask where excluded channels are set to 1.
132132
* @return Number of channels in sequence.
133133
*/
134-
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)
134+
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)
135135
{
136136
uint16_t cntr = channel_table_length;
137137
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
194194
return channel_number;
195195
}
196196

197-
int32_t tr51_get_uc_channel_index(uint16_t slot_number, uint8_t *mac, int16_t number_of_channels, uint32_t *excluded_channels)
197+
int tr51_init_channel_table(int16_t *channel_table, int16_t number_of_channels)
198+
{
199+
uint16_t nearest_prime = tr51_calc_nearest_prime_number(number_of_channels);
200+
tr51_calculate_channel_table(number_of_channels, nearest_prime, channel_table);
201+
return 0;
202+
}
203+
204+
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)
198205
{
199206
uint16_t nearest_prime = tr51_calc_nearest_prime_number(number_of_channels);
200-
int32_t channel_table[nearest_prime];
201-
int32_t output_table[number_of_channels];
202207
uint8_t first_element;
203208
uint8_t step_size;
204-
tr51_calculate_channel_table(number_of_channels, nearest_prime, channel_table);
205209
tr51_compute_cfd(mac, &first_element, &step_size, nearest_prime);
206-
// Not sure yet which one is the correct second parameter
207-
// tr51_calculate_hopping_sequence(channel_table, number_of_channels, first_element, step_size, output_table, NULL, 0);
208210
tr51_calculate_hopping_sequence(channel_table, nearest_prime, first_element, step_size, output_table, excluded_channels);
209211
return output_table[slot_number];
210212
}
211213

212-
int32_t tr51_get_bc_channel_index(uint16_t slot_number, uint16_t bsi, int16_t number_of_channels, uint32_t *excluded_channels)
214+
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)
213215
{
214216
uint16_t nearest_prime = tr51_calc_nearest_prime_number(number_of_channels);
215-
int32_t channel_table[nearest_prime];
216-
int32_t output_table[number_of_channels];
217217
uint8_t mac[8] = {0, 0, 0, 0, 0, 0, (uint8_t)(bsi >> 8), (uint8_t)bsi};
218218
uint8_t first_element;
219219
uint8_t step_size;
220-
tr51_calculate_channel_table(number_of_channels, nearest_prime, channel_table);
221220
tr51_compute_cfd(mac, &first_element, &step_size, nearest_prime);
222-
// Not sure yet which one is the correct second parameter
223-
// tr51_calculate_hopping_sequence(channel_table, number_of_channels, first_element, step_size, output_table, NULL, 0);
224221
tr51_calculate_hopping_sequence(channel_table, nearest_prime, first_element, step_size, output_table, excluded_channels);
225222
return output_table[slot_number];
226223
}

source/Service_Libs/fhss/channel_functions.h

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,44 @@
1717
#ifndef CHANNEL_FUNC_H_
1818
#define CHANNEL_FUNC_H_
1919

20+
/**
21+
* @brief Function calculates nearest (higher) prime number for given start value.
22+
* @param start_value Start value.
23+
* @return Calculated prime number.
24+
*/
25+
uint16_t tr51_calc_nearest_prime_number(uint16_t start_value);
26+
27+
/**
28+
* @brief Initialize channel table for TR51 channel function.
29+
* @param channel_table Channel table to be initialized.
30+
* @param number_of_channels Number of channels.
31+
* @return 0 Success, -1 Failure.
32+
*/
33+
int tr51_init_channel_table(int16_t *channel_table, int16_t number_of_channels);
34+
2035
/**
2136
* @brief Compute the unicast schedule channel index using tr51 channel function.
37+
* @param channel_table Channel table.
38+
* @param output_table Table used to generate output channel.
2239
* @param slot_number Current slot number.
2340
* @param mac MAC address of the node for which the index is calculated.
2441
* @param number_of_channels Number of channels.
2542
* @param excluded_channels Excluded channels.
2643
* @return Channel index.
2744
*/
28-
int32_t tr51_get_uc_channel_index(uint16_t slot_number, uint8_t *mac, int16_t number_of_channels, uint32_t *excluded_channels);
45+
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);
2946

3047
/**
3148
* @brief Compute the broadcast schedule channel index using tr51 channel function.
49+
* @param channel_table Channel table.
50+
* @param output_table Table used to generate output channel.
3251
* @param slot_number Current slot number.
3352
* @param bsi Broadcast schedule identifier of the node for which the index is calculated.
3453
* @param number_of_channels Number of channels.
3554
* @param excluded_channels Excluded channels.
3655
* @return Channel index.
3756
*/
38-
int32_t tr51_get_bc_channel_index(uint16_t slot_number, uint16_t bsi, int16_t number_of_channels, uint32_t *excluded_channels);
57+
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);
3958

4059
/**
4160
* @brief Compute the unicast schedule channel index using direct hash channel function.

source/Service_Libs/fhss/fhss_ws.c

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ struct ws_ie_t {
5858
uint8_t id;
5959
};
6060

61+
static int fhss_ws_manage_channel_table_allocation(fhss_structure_t *fhss_structure, uint16_t channel_count);
6162
static void fhss_event_timer_cb(int8_t timer_id, uint16_t slots);
6263
static void fhss_ws_update_uc_channel_callback(fhss_structure_t *fhss_structure);
6364
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
9192
return NULL;
9293
}
9394
memset(fhss_struct->ws, 0, sizeof(fhss_ws_t));
95+
if (fhss_ws_manage_channel_table_allocation(fhss_struct, channel_count)) {
96+
ns_dyn_mem_free(fhss_struct->ws);
97+
fhss_free_instance(fhss_api);
98+
tr_error("Failed to allocate channel tables");
99+
return NULL;
100+
}
94101

95102
fhss_struct->fhss_event_timer = eventOS_callback_timer_register(fhss_event_timer_cb);
96103
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
103110
return fhss_struct;
104111
}
105112

113+
static int fhss_ws_manage_channel_table_allocation(fhss_structure_t *fhss_structure, uint16_t channel_count)
114+
{
115+
// Must allocate channel table for TR51
116+
if (!fhss_structure->ws->tr51_channel_table && !fhss_structure->ws->tr51_output_table) {
117+
fhss_structure->ws->tr51_channel_table = ns_dyn_mem_alloc(sizeof(int16_t)*tr51_calc_nearest_prime_number(channel_count));
118+
if (!fhss_structure->ws->tr51_channel_table) {
119+
return -1;
120+
}
121+
fhss_structure->ws->tr51_output_table = ns_dyn_mem_alloc(sizeof(int16_t)*channel_count);
122+
if (!fhss_structure->ws->tr51_output_table) {
123+
ns_dyn_mem_free(fhss_structure->ws->tr51_channel_table);
124+
return -1;
125+
}
126+
tr51_init_channel_table(fhss_structure->ws->tr51_channel_table, channel_count);
127+
}
128+
return 0;
129+
}
130+
106131
static uint8_t fhss_set_txrx_slot_length(fhss_structure_t *fhss_structure)
107132
{
108133
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)
118143
int32_t next_channel = fhss_structure->ws->fhss_configuration.broadcast_fixed_channel;
119144

120145
if (fhss_structure->ws->fhss_configuration.ws_bc_channel_function == WS_TR51CF) {
121-
next_channel = tr51_get_bc_channel_index(fhss_structure->ws->bc_slot, fhss_structure->ws->fhss_configuration.bsi, fhss_structure->number_of_channels, NULL);
146+
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);
122147
if (++fhss_structure->ws->bc_slot == fhss_structure->number_of_channels) {
123148
fhss_structure->ws->bc_slot = 0;
124149
}
@@ -332,7 +357,7 @@ static void fhss_ws_update_uc_channel_callback(fhss_structure_t *fhss_structure)
332357
if (fhss_structure->ws->fhss_configuration.ws_uc_channel_function == WS_FIXED_CHANNEL) {
333358
return;
334359
} else if (fhss_structure->ws->fhss_configuration.ws_uc_channel_function == WS_TR51CF) {
335-
next_channel = fhss_structure->rx_channel = tr51_get_uc_channel_index(fhss_structure->ws->uc_slot, mac_address, fhss_structure->number_of_channels, NULL);
360+
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);
336361
if (++fhss_structure->ws->uc_slot == fhss_structure->number_of_channels) {
337362
fhss_structure->ws->uc_slot = 0;
338363
}
@@ -391,7 +416,7 @@ static int fhss_ws_tx_handle_callback(const fhss_api_t *api, bool is_broadcast_a
391416
uint16_t destination_slot = fhss_ws_calculate_destination_slot(neighbor_timing_info, tx_time);
392417
int32_t tx_channel = neighbor_timing_info->uc_timing_info.fixed_channel;
393418
if (neighbor_timing_info->uc_timing_info.unicast_channel_function == WS_TR51CF) {
394-
tx_channel = tr51_get_uc_channel_index(destination_slot, destination_address, neighbor_timing_info->uc_timing_info.unicast_number_of_channels, NULL);
419+
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);
395420
} else if(neighbor_timing_info->uc_timing_info.unicast_channel_function == WS_DH1CF) {
396421
tx_channel = dh1cf_get_uc_channel_index(destination_slot, destination_address, neighbor_timing_info->uc_timing_info.unicast_number_of_channels);
397422
} else if (neighbor_timing_info->uc_timing_info.unicast_channel_function == WS_VENDOR_DEF_CF) {

source/Service_Libs/fhss/fhss_ws.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ struct fhss_ws
3535
uint16_t min_synch_interval;
3636
uint32_t txrx_slot_length_ms;
3737
uint32_t synchronization_time;
38+
int16_t *tr51_channel_table;
39+
uint8_t *tr51_output_table;
3840
bool unicast_timer_running;
3941
bool is_on_bc_channel;
4042
struct fhss_ws_configuration fhss_configuration;

test/nanostack/unittest/service_libs/channel_functions/test_channel_functions.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,14 @@ bool test_tr51_get_uc_channel_index()
8686
int i;
8787
uint16_t number_of_channels = 129;
8888
int32_t channel;
89+
int16_t channel_table[number_of_channels+10];
90+
uint8_t output_table[number_of_channels];
8991
int32_t test_table[number_of_channels];
9092
uint8_t mac[8] = {0x00, 0x13, 0x50, 0x04, 0x00, 0x00, 0x05, 0xf8};
93+
94+
tr51_init_channel_table(channel_table, number_of_channels);
9195
for (i=0; i<number_of_channels; i++) {
92-
test_table[i] = channel = tr51_get_uc_channel_index(i, mac, number_of_channels, NULL);
96+
test_table[i] = channel = tr51_get_uc_channel_index(channel_table, output_table, i, mac, number_of_channels, NULL);
9397
// Not sure yet which one is correct since there might be bug in spec
9498
// if (channel != test_HopSequenceTable[i]) {
9599
if (channel != test_HopSequenceTable2[i]) {
@@ -114,7 +118,7 @@ bool test_tr51_get_uc_channel_index()
114118
uint32_t excluded_channels[8] = {0x40100401, 0x10040100, 0x04010040, 0, 0, 0, 0, 0};
115119
uint16_t number_of_excluded_channels = 10;
116120
for (i=0; i<number_of_channels-number_of_excluded_channels; i++) {
117-
test_table[i] = channel = tr51_get_uc_channel_index(i, mac, number_of_channels, excluded_channels);
121+
test_table[i] = channel = tr51_get_uc_channel_index(channel_table, output_table, i, mac, number_of_channels, excluded_channels);
118122
// Shouldn't find channel from excluded channels
119123
if (channel_on_the_list(excluded_channels, channel)) {
120124
return false;
@@ -137,8 +141,11 @@ bool test_tr51_get_bc_channel_index()
137141
int32_t channel;
138142
uint16_t bsi = 100;
139143
int32_t test_table[number_of_channels];
144+
int16_t channel_table[number_of_channels+10];
145+
uint8_t output_table[number_of_channels];
146+
tr51_init_channel_table(channel_table, number_of_channels);
140147
for (int i=0; i<number_of_channels; i++) {
141-
test_table[i] = channel = tr51_get_bc_channel_index(i, bsi, number_of_channels, NULL);
148+
test_table[i] = channel = tr51_get_bc_channel_index(channel_table, output_table, i, bsi, number_of_channels, NULL);
142149
if (channel != test_HopSequenceTable3[i]) {
143150
return false;
144151
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,12 @@ bool test_fhss_ws_enable()
179179
return false;
180180
}
181181
// Test success
182-
nsdynmemlib_stub.returnCounter = 1;
182+
nsdynmemlib_stub.returnCounter = 3;
183183
if (fhss_ws_enable(&fhss_api, &fhss_configuration, &fhss_timer) == NULL) {
184184
return false;
185185
}
186+
free(fhss_common_stub.fhss_struct.ws->tr51_channel_table);
187+
free(fhss_common_stub.fhss_struct.ws->tr51_output_table);
186188
free(fhss_common_stub.fhss_struct.ws);
187189
return true;
188190
}

test/nanostack/unittest/stub/channel_functions_stub.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,23 @@ int32_t dh1cf_get_bc_channel_index(uint16_t slot_number, uint16_t bsi, int16_t n
3030
return 2;
3131
}
3232

33-
int32_t tr51_get_uc_channel_index(uint16_t slot_number, uint8_t *mac, int16_t number_of_channels)
33+
int tr51_init_channel_table(int16_t *channel_table, int16_t number_of_channels)
34+
{
35+
return 0;
36+
}
37+
38+
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)
3439
{
3540
channel_functions_stub.uint8_value = slot_number;
3641
return 3;
3742
}
3843

39-
int32_t tr51_get_bc_channel_index(uint16_t slot_number, uint16_t bsi, int16_t number_of_channels)
44+
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)
4045
{
4146
return 4;
4247
}
48+
49+
uint16_t tr51_calc_nearest_prime_number(uint16_t start_value)
50+
{
51+
return 0;
52+
}

0 commit comments

Comments
 (0)