Skip to content
This repository was archived by the owner on May 23, 2023. It is now read-only.

Commit b4e1616

Browse files
author
Jarkko Paso
authored
Merge pull request ARMmbed#1561 from ARMmbed/IOTTHD-2172
Iotthd 2172
2 parents 096aeef + 77c851a commit b4e1616

File tree

5 files changed

+107
-15
lines changed

5 files changed

+107
-15
lines changed

nanostack/fhss_config.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ typedef struct fhss_ws_configuration
8686
/** WS channel function. */
8787
fhss_ws_channel_functions ws_channel_function;
8888

89+
/** Broadcast schedule identifier. */
90+
uint16_t bsi;
91+
8992
/** Unicast dwell interval. Range: 15-250 milliseconds. */
9093
uint8_t fhss_uc_dwell_interval;
9194

source/Service_Libs/fhss/channel_functions.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,3 +193,19 @@ int32_t tr51_get_uc_channel_index(uint16_t slot_number, uint8_t *mac, int16_t nu
193193
tr51_calculate_hopping_sequence(channel_table, nearest_prime, first_element, step_size, output_table, NULL, 0);
194194
return output_table[slot_number];
195195
}
196+
197+
int32_t tr51_get_bc_channel_index(uint16_t slot_number, uint16_t bsi, int16_t number_of_channels)
198+
{
199+
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];
202+
uint8_t mac[8] = {0, 0, 0, 0, 0, 0, (uint8_t)(bsi >> 8), (uint8_t)bsi};
203+
uint8_t first_element;
204+
uint8_t step_size;
205+
tr51_calculate_channel_table(number_of_channels, nearest_prime, channel_table);
206+
tr51_compute_cfd(mac, &first_element, &step_size, nearest_prime);
207+
// Not sure yet which one is the correct second parameter
208+
// tr51_calculate_hopping_sequence(channel_table, number_of_channels, first_element, step_size, output_table, NULL, 0);
209+
tr51_calculate_hopping_sequence(channel_table, nearest_prime, first_element, step_size, output_table, NULL, 0);
210+
return output_table[slot_number];
211+
}

source/Service_Libs/fhss/channel_functions.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ uint16_t tr51_calculate_hopping_sequence(int32_t *channel_table, uint16_t channe
4646
*/
4747
int32_t tr51_get_uc_channel_index(uint16_t slot_number, uint8_t *mac, int16_t number_of_channels);
4848

49+
/**
50+
* @brief Compute the broadcast schedule channel index using tr51 channel function.
51+
* @param slot_number Current slot number.
52+
* @param bsi Broadcast schedule identifier of the node for which the index is calculated.
53+
* @param number_of_channels Number of channels.
54+
* @return Channel index.
55+
*/
56+
int32_t tr51_get_bc_channel_index(uint16_t slot_number, uint16_t bsi, int16_t number_of_channels);
57+
4958
/**
5059
* @brief Compute the unicast schedule channel index using direct hash channel function.
5160
* @param slot_number Current slot number.

source/Service_Libs/fhss/fhss_ws.c

Lines changed: 76 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
// Enable this flag to use channel traces
3434
#define FHSS_CHANNEL_DEBUG
3535

36+
static void fhss_ws_update_uc_channel_callback(fhss_structure_t *fhss_structure);
37+
3638
fhss_structure_t *fhss_ws_enable(fhss_api_t *fhss_api, const fhss_ws_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer)
3739
{
3840
if (!fhss_api || !fhss_configuration || !fhss_timer) {
@@ -50,22 +52,77 @@ fhss_structure_t *fhss_ws_enable(fhss_api_t *fhss_api, const fhss_ws_configurati
5052
}
5153
fhss_struct->fhss_conf.fhss_ws_configuration = *fhss_configuration;
5254
fhss_struct->number_of_channels = channel_count;
53-
5455
return fhss_struct;
5556
}
5657

58+
static void fhss_ws_update_bc_channel(fhss_structure_t *fhss_structure)
59+
{
60+
uint8_t mac_address[8];
61+
int32_t next_channel;
62+
fhss_structure->callbacks.read_mac_address(fhss_structure->fhss_api, mac_address);
63+
if (fhss_structure->ws->channel_function == WS_FIXED_CHANNEL) {
64+
65+
} else if (fhss_structure->ws->channel_function == WS_TR51CF) {
66+
next_channel = tr51_get_bc_channel_index(fhss_structure->ws->bc_slot, fhss_structure->fhss_conf.fhss_ws_configuration.bsi, fhss_structure->number_of_channels);
67+
if (++fhss_structure->ws->bc_slot == fhss_structure->number_of_channels) {
68+
fhss_structure->ws->bc_slot = 0;
69+
}
70+
} else if (fhss_structure->ws->channel_function == WS_DH1CF) {
71+
next_channel = dh1cf_get_bc_channel_index(fhss_structure->ws->bc_slot, fhss_structure->fhss_conf.fhss_ws_configuration.bsi, fhss_structure->number_of_channels);
72+
fhss_structure->ws->bc_slot++;
73+
} else if (fhss_structure->ws->channel_function == WS_VENDOR_DEF_CF) {
74+
//TODO: Callback to get channel schedule from application
75+
}
76+
#ifdef FHSS_CHANNEL_DEBUG
77+
tr_info("%"PRIu32" BC %u %u", fhss_structure->platform_functions.fhss_get_timestamp(fhss_structure->fhss_api), next_channel, fhss_structure->ws->bc_slot);
78+
#endif /*FHSS_CHANNEL_DEBUG*/
79+
fhss_structure->callbacks.change_channel(fhss_structure->fhss_api, next_channel);
80+
}
81+
82+
static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
83+
{
84+
(void) delay;
85+
fhss_structure_t *fhss_structure = fhss_get_object_with_api(fhss_api);
86+
if (!fhss_structure) {
87+
return;
88+
}
89+
if (fhss_structure->ws->is_on_bc_channel == false) {
90+
fhss_start_timer(fhss_structure, fhss_structure->fhss_conf.fhss_ws_configuration.fhss_bc_dwell_interval*1000, fhss_broadcast_handler);
91+
fhss_structure->ws->is_on_bc_channel = true;
92+
fhss_ws_update_bc_channel(fhss_structure);
93+
} else {
94+
uint32_t timeout = (fhss_structure->fhss_conf.fhss_ws_configuration.fhss_broadcast_interval - fhss_structure->fhss_conf.fhss_ws_configuration.fhss_bc_dwell_interval) * 1000;
95+
fhss_start_timer(fhss_structure, timeout, fhss_broadcast_handler);
96+
fhss_structure->ws->is_on_bc_channel = false;
97+
// Should return to own (unicast) listening channel after broadcast channel
98+
fhss_structure->callbacks.change_channel(fhss_structure->fhss_api, fhss_structure->rx_channel);
99+
#ifdef FHSS_CHANNEL_DEBUG
100+
tr_info("%"PRIu32" UC %u", fhss_structure->platform_functions.fhss_get_timestamp(fhss_structure->fhss_api), fhss_structure->rx_channel);
101+
#endif /*FHSS_CHANNEL_DEBUG*/
102+
}
103+
}
104+
57105
static uint32_t fhss_ws_get_sf_timeout_callback(fhss_structure_t *fhss_structure)
58106
{
59107
return fhss_structure->fhss_conf.fhss_ws_configuration.fhss_uc_dwell_interval * 1000;
60108
}
61109

62110
static int fhss_ws_handle_state_set(fhss_structure_t *fhss_structure, fhss_states fhss_state, uint16_t pan_id)
63111
{
64-
(void) fhss_state;
65112
(void) pan_id;
66-
//TODO: Remove hard coded channel function
67-
fhss_structure->ws->channel_function = WS_TR51CF;
68-
fhss_start_timer(fhss_structure, fhss_structure->fhss_conf.fhss_ws_configuration.fhss_uc_dwell_interval*1000, fhss_superframe_handler);
113+
if (fhss_state == FHSS_SYNCHRONIZED) {
114+
uint32_t fhss_broadcast_interval = fhss_structure->fhss_conf.fhss_ws_configuration.fhss_broadcast_interval;
115+
uint8_t fhss_bc_dwell_interval = fhss_structure->fhss_conf.fhss_ws_configuration.fhss_bc_dwell_interval;
116+
// Start broadcast schedule when BC intervals are known
117+
if (fhss_broadcast_interval && fhss_bc_dwell_interval) {
118+
fhss_broadcast_handler(fhss_structure->fhss_api, 0);
119+
}
120+
// Start unicast schedule
121+
fhss_ws_update_uc_channel_callback(fhss_structure);
122+
fhss_start_timer(fhss_structure, fhss_structure->fhss_conf.fhss_ws_configuration.fhss_uc_dwell_interval*1000, fhss_superframe_handler);
123+
}
124+
125+
fhss_structure->fhss_state = fhss_state;
69126
return 0;
70127
}
71128

@@ -74,26 +131,30 @@ static void fhss_ws_superframe_callback(fhss_structure_t *fhss_structure)
74131
(void) fhss_structure;
75132
}
76133

77-
static void fhss_ws_update_channel_callback(fhss_structure_t *fhss_structure)
134+
static void fhss_ws_update_uc_channel_callback(fhss_structure_t *fhss_structure)
78135
{
79136
uint8_t mac_address[8];
80137
int32_t next_channel;
81138
fhss_structure->callbacks.read_mac_address(fhss_structure->fhss_api, mac_address);
82139
if (fhss_structure->ws->channel_function == WS_FIXED_CHANNEL) {
83140

84141
} else if (fhss_structure->ws->channel_function == WS_TR51CF) {
85-
next_channel = fhss_structure->rx_channel = tr51_get_uc_channel_index(fhss_structure->ws->slot, mac_address, fhss_structure->number_of_channels);
86-
if (++fhss_structure->ws->slot == fhss_structure->number_of_channels) {
87-
fhss_structure->ws->slot = 0;
142+
next_channel = fhss_structure->rx_channel = tr51_get_uc_channel_index(fhss_structure->ws->uc_slot, mac_address, fhss_structure->number_of_channels);
143+
if (++fhss_structure->ws->uc_slot == fhss_structure->number_of_channels) {
144+
fhss_structure->ws->uc_slot = 0;
88145
}
89146
} else if (fhss_structure->ws->channel_function == WS_DH1CF) {
90-
next_channel = fhss_structure->rx_channel = dh1cf_get_uc_channel_index(fhss_structure->ws->slot, mac_address, fhss_structure->number_of_channels);
91-
fhss_structure->ws->slot++;
147+
next_channel = fhss_structure->rx_channel = dh1cf_get_uc_channel_index(fhss_structure->ws->uc_slot, mac_address, fhss_structure->number_of_channels);
148+
fhss_structure->ws->uc_slot++;
92149
} else if (fhss_structure->ws->channel_function == WS_VENDOR_DEF_CF) {
93150
//TODO: Callback to get channel schedule from application
94151
}
152+
// Do not switch unicast channel when broadcast channel is active.
153+
if (fhss_structure->ws->is_on_bc_channel == true) {
154+
return;
155+
}
95156
#ifdef FHSS_CHANNEL_DEBUG
96-
tr_info("%"PRIu32" UC %u %u", fhss_structure->platform_functions.fhss_get_timestamp(fhss_structure->fhss_api), next_channel, fhss_structure->ws->slot);
157+
tr_info("%"PRIu32" UC %u %u", fhss_structure->platform_functions.fhss_get_timestamp(fhss_structure->fhss_api), next_channel, fhss_structure->ws->uc_slot);
97158
#endif /*FHSS_CHANNEL_DEBUG*/
98159
fhss_structure->callbacks.change_channel(fhss_structure->fhss_api, next_channel);
99160
}
@@ -112,7 +173,7 @@ static int fhss_ws_tx_handle_callback(const fhss_api_t *api, bool is_broadcast_a
112173
if (fhss_structure->fhss_state == FHSS_SYNCHRONIZED) {
113174
int32_t tx_channel;
114175
//TODO: Compute destination slot using neighbour table
115-
uint16_t destination_slot = fhss_structure->ws->slot;
176+
uint16_t destination_slot = fhss_structure->ws->uc_slot;
116177
if (fhss_structure->ws->channel_function == WS_TR51CF) {
117178
tx_channel = tr51_get_uc_channel_index(destination_slot, destination_address, fhss_structure->number_of_channels);
118179
} else if(fhss_structure->ws->channel_function == WS_DH1CF) {
@@ -156,7 +217,7 @@ int fhss_ws_set_callbacks(fhss_structure_t *fhss_structure)
156217
fhss_structure->fhss_api->write_synch_info = &fhss_write_synch_info_cb;
157218
fhss_structure->fhss_api->init_callbacks = &fhss_init_callbacks_cb;
158219
// Set internal API
159-
fhss_structure->update_channel = fhss_ws_update_channel_callback;
220+
fhss_structure->update_channel = fhss_ws_update_uc_channel_callback;
160221
fhss_structure->update_superframe = fhss_ws_superframe_callback;
161222
fhss_structure->read_superframe_timeout = fhss_ws_get_sf_timeout_callback;
162223
fhss_structure->handle_state_set = fhss_ws_handle_state_set;
@@ -165,5 +226,6 @@ int fhss_ws_set_callbacks(fhss_structure_t *fhss_structure)
165226
return -1;
166227
}
167228
memset(fhss_structure->ws, 0, sizeof(fhss_ws_t));
229+
fhss_structure->ws->channel_function = fhss_structure->fhss_conf.fhss_ws_configuration.ws_channel_function;
168230
return 0;
169231
}

source/Service_Libs/fhss/fhss_ws.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ typedef struct fhss_ws fhss_ws_t;
2121
struct fhss_ws
2222
{
2323
fhss_ws_channel_functions channel_function;
24-
uint16_t slot;
24+
uint16_t uc_slot;
25+
uint16_t bc_slot;
26+
bool is_on_bc_channel;
2527
};
2628

2729
fhss_structure_t *fhss_ws_enable(fhss_api_t *fhss_api, const fhss_ws_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer);

0 commit comments

Comments
 (0)