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

Commit 8b43c6e

Browse files
author
Jarkko Paso
authored
Merge pull request ARMmbed#1555 from ARMmbed/IOTTHD-2215
Iotthd 2215
2 parents 7ace04b + 78314e8 commit 8b43c6e

File tree

20 files changed

+206
-171
lines changed

20 files changed

+206
-171
lines changed

nanostack/fhss_config.h

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,21 @@
2828
extern "C" {
2929
#endif
3030

31+
/**
32+
* @brief WS channel functions.
33+
*/
34+
typedef enum
35+
{
36+
/** Fixed channel. */
37+
WS_FIXED_CHANNEL,
38+
/** TR51 channel function. */
39+
WS_TR51CF,
40+
/** Direct Hash channel function. */
41+
WS_DH1CF,
42+
/** Vendor Defined channel function. */
43+
WS_VENDOR_DEF_CF
44+
} fhss_ws_channel_functions;
45+
3146
/**
3247
* \brief Struct fhss_tuning_parameter defines FHSS tuning parameters.
3348
* All delays are given in microseconds.
@@ -63,6 +78,28 @@ typedef struct fhss_configuration
6378

6479
} fhss_configuration_t;
6580

81+
/**
82+
* \brief Struct fhss_ws_configuration defines configuration of WS FHSS.
83+
*/
84+
typedef struct fhss_ws_configuration
85+
{
86+
/** WS channel function. */
87+
fhss_ws_channel_functions ws_channel_function;
88+
89+
/** Unicast dwell interval. Range: 15-250 milliseconds. */
90+
uint8_t fhss_uc_dwell_interval;
91+
92+
/** Broadcast interval. Duration between broadcast dwell intervals. Range: 0-16777216 milliseconds. */
93+
uint32_t fhss_broadcast_interval;
94+
95+
/** Broadcast dwell interval. Range: 15-250 milliseconds. */
96+
uint8_t fhss_bc_dwell_interval;
97+
98+
/** Channel mask. */
99+
uint32_t channel_mask[8];
100+
101+
} fhss_ws_configuration_t;
102+
66103
/**
67104
* \brief Struct fhss_timer defines interface between FHSS and FHSS platform timer.
68105
* Application must implement FHSS timer driver which is then used by FHSS with this interface.
@@ -103,12 +140,6 @@ typedef struct fhss_synch_configuration
103140

104141
/** Number of superframes. */
105142
uint8_t fhss_number_of_superframes;
106-
107-
/** Broadcast interval. Interval between started broadcast channels. (milliseconds) */
108-
uint32_t fhss_broadcast_interval;
109-
110-
/** Broadcast dwell time. (milliseconds) */
111-
uint8_t fhss_bc_dwell_interval;
112143
} fhss_synch_configuration_t;
113144

114145

nanostack/net_fhss.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ extern fhss_api_t *ns_fhss_create(const fhss_configuration_t *fhss_configuration
4545
* @param fhss_statistics FHSS statistics storage.
4646
* @return New FHSS instance if successful, NULL otherwise.
4747
*/
48-
extern fhss_api_t *ns_fhss_ws_create(const fhss_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer, fhss_statistics_t *fhss_statistics);
48+
extern fhss_api_t *ns_fhss_ws_create(const fhss_ws_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer);
4949

5050
/**
5151
* @brief Set synchronization time configuration for FHSS network. Should be only called from Border router.

source/Service_Libs/fhss/fhss.c

Lines changed: 92 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,50 @@
3535

3636
#define TRACE_GROUP "fhss"
3737

38+
static int fhss_reset(fhss_structure_t *fhss_structure);
39+
static void fhss_destroy_scramble_table(fhss_structure_t *fhss_structure);
3840
static bool fhss_is_bc_sending_superframe(fhss_structure_t *fhss_structure);
3941
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);
4042
static bool fhss_is_there_common_divisor(uint16_t i, uint8_t j);
4143

44+
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)
45+
{
46+
if (!fhss_api || !fhss_configuration || !fhss_timer) {
47+
tr_err("Invalid FHSS enable configuration");
48+
return NULL;
49+
}
50+
int channel_count = channel_list_count_channels(fhss_configuration->channel_mask);
51+
if (channel_count <= 0) {
52+
// There must be at least one configured channel in channel list
53+
return NULL;
54+
}
55+
fhss_structure_t *fhss_struct = fhss_allocate_instance(fhss_api, fhss_timer);
56+
if (!fhss_struct) {
57+
return NULL;
58+
}
59+
fhss_struct->fhss_conf.fhss_configuration = *fhss_configuration;
60+
fhss_struct->fhss_stats_ptr = fhss_statistics;
61+
fhss_struct->number_of_channels = channel_count;
62+
63+
// set a invalid id to tasklet_id, so we know that one is not started yet
64+
fhss_struct->beacon_tasklet_id = -1;
65+
66+
// Default synch interval is 240 seconds
67+
if (!fhss_struct->fhss_conf.fhss_configuration.fhss_max_synch_interval) {
68+
fhss_struct->fhss_conf.fhss_configuration.fhss_max_synch_interval = 240;
69+
}
70+
ns_list_init(&fhss_struct->fhss_failed_tx_list);
71+
fhss_struct->own_hop = 0xff;
72+
fhss_reset(fhss_struct);
73+
74+
if (fhss_beacon_create_tasklet(fhss_struct) < 0) {
75+
// XXX: should we free the fhss_structure here?
76+
return NULL;
77+
}
78+
79+
return fhss_struct;
80+
}
81+
4282
bool fhss_is_synch_root(fhss_structure_t *fhss_structure)
4383
{
4484
if (fhss_structure->own_hop > 0) {
@@ -219,7 +259,7 @@ static int fhss_update_drift_compensation(fhss_structure_t *fhss_structure)
219259
bc_density = (fhss_structure->number_of_channels / fhss_structure->synch_configuration.fhss_number_of_bc_channels);
220260
channel_dwell_time = ((uint32_t)fhss_structure->synch_configuration.fhss_superframe_length * fhss_structure->synch_configuration.fhss_number_of_superframes) / 1000;
221261
// Calculate last synchronisation period
222-
if (fhss_structure->synch_interval != ((uint32_t)fhss_structure->fhss_configuration.fhss_max_synch_interval * 1000)) {
262+
if (fhss_structure->synch_interval != ((uint32_t)fhss_structure->fhss_conf.fhss_configuration.fhss_max_synch_interval * 1000)) {
223263
// Last period was half of the current started period and max random period is shorter
224264
synch_period = (fhss_structure->synch_interval / 2) + (bc_density * channel_dwell_time) * (fhss_structure->synch_configuration.fhss_number_of_bc_channels / 2);
225265
} else {
@@ -358,14 +398,14 @@ int fhss_sync_with_beacon(fhss_structure_t *fhss_structure,
358398

359399
if (fhss_structure->fhss_state == FHSS_SYNCHRONIZED) {
360400
if (fhss_update_synch_monitor(fhss_structure, payload, superframe_own, remaining_time_own, time_to_next_superframe)) {
361-
fhss_structure->synch_interval = (uint32_t) (fhss_structure->fhss_configuration.fhss_max_synch_interval/BEACON_INTERVAL_INIT_DIVIDER) * 1000;
401+
fhss_structure->synch_interval = (uint32_t) (fhss_structure->fhss_conf.fhss_configuration.fhss_max_synch_interval/BEACON_INTERVAL_INIT_DIVIDER) * 1000;
362402
}
363403
}
364404

365-
if (fhss_structure->synch_interval != ((uint32_t)fhss_structure->fhss_configuration.fhss_max_synch_interval * 1000)) {
405+
if (fhss_structure->synch_interval != ((uint32_t)fhss_structure->fhss_conf.fhss_configuration.fhss_max_synch_interval * 1000)) {
366406
fhss_structure->synch_interval *= 2;
367-
if (fhss_structure->synch_interval > ((uint32_t)fhss_structure->fhss_configuration.fhss_max_synch_interval * 1000)) {
368-
fhss_structure->synch_interval = ((uint32_t)fhss_structure->fhss_configuration.fhss_max_synch_interval * 1000);
407+
if (fhss_structure->synch_interval > ((uint32_t)fhss_structure->fhss_conf.fhss_configuration.fhss_max_synch_interval * 1000)) {
408+
fhss_structure->synch_interval = ((uint32_t)fhss_structure->fhss_conf.fhss_configuration.fhss_max_synch_interval * 1000);
369409
}
370410
beacon_interval_random = (bc_density * channel_dwell_time) * randLIB_get_random_in_range(0, fhss_number_of_bc_channels/2);
371411
} else {
@@ -448,8 +488,8 @@ static bool fhss_check_remaining_tx_time(fhss_structure_t *fhss_structure, uint1
448488
if (fhss_structure->fhss_state == FHSS_UNSYNCHRONIZED) {
449489
retval = true;
450490
} else {
451-
tx_processing_delay = fhss_structure->fhss_configuration.fhss_tuning_parameters.tx_processing_delay;
452-
ack_processing_delay = fhss_structure->fhss_configuration.fhss_tuning_parameters.ack_processing_delay;
491+
tx_processing_delay = fhss_structure->fhss_conf.fhss_configuration.fhss_tuning_parameters.tx_processing_delay;
492+
ack_processing_delay = fhss_structure->fhss_conf.fhss_configuration.fhss_tuning_parameters.ack_processing_delay;
453493
// Calculate needed TX time (us): CCA static period + TX processing delays + transmission time + Ack processing delays + Ack transmission time
454494
needed_tx_time = CCA_FHSS_PERIOD + tx_processing_delay + fhss_get_tx_time(fhss_structure, tx_length, phy_header_length, phy_tail_length)
455495
+ ack_processing_delay + fhss_get_tx_time(fhss_structure, ACK_LENGTH, phy_header_length, phy_tail_length);
@@ -585,6 +625,35 @@ static int fhss_flush_beacon_info_storage(fhss_structure_t *fhss_structure)
585625
return 0;
586626
}
587627

628+
static int fhss_reset(fhss_structure_t *fhss_structure)
629+
{
630+
if (!fhss_structure) {
631+
return -1;
632+
}
633+
fhss_destroy_scramble_table(fhss_structure);
634+
fhss_structure->platform_functions.fhss_timer_stop(fhss_superframe_handler, fhss_structure->fhss_api);
635+
fhss_structure->synch_panid = 0xffff;
636+
fhss_beacon_periodic_stop(fhss_structure);
637+
fhss_structure->current_superframe = 0;
638+
fhss_structure->current_channel_index = 0;
639+
fhss_structure->channel_list_counter = 0;
640+
if (fhss_is_synch_root(fhss_structure) == false) {
641+
fhss_structure->own_hop = 0xff;
642+
}
643+
fhss_structure->tx_allowed = false;
644+
fhss_structure->synch_interval = (uint32_t) (fhss_structure->fhss_conf.fhss_configuration.fhss_max_synch_interval/BEACON_INTERVAL_INIT_DIVIDER) * 1000;
645+
fhss_structure->rx_channel = 0;
646+
fhss_structure->beacons_received_timer = 0;
647+
memset(fhss_structure->synch_parent, 0xff, 8);
648+
fhss_structure->send_synch_info_on_next_broadcast_channel = false;
649+
memset(&fhss_structure->synch_configuration, 0, sizeof(fhss_synch_configuration_t));
650+
fhss_structure->synch_infos_sent_counter = 0;
651+
fhss_structure->broadcast_start_superframe = 0;
652+
fhss_failed_list_free(fhss_structure);
653+
fhss_structure->fhss_state = FHSS_UNSYNCHRONIZED;
654+
return 0;
655+
}
656+
588657
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)
589658
{
590659
if (!fhss_structure || !source_address || !synch_info) {
@@ -669,7 +738,11 @@ static int fhss_handle_state_set(fhss_structure_t *fhss_structure, fhss_states f
669738

670739
if (fhss_state == FHSS_UNSYNCHRONIZED) {
671740
tr_debug("FHSS down");
672-
fhss_down(fhss_structure);
741+
fhss_reset(fhss_structure);
742+
fhss_reset_synch_monitor(&fhss_structure->synch_monitor);
743+
fhss_stats_update(fhss_structure, STATS_FHSS_DRIFT_COMP, fhss_structure->synch_monitor.drift_compensation);
744+
fhss_stats_update(fhss_structure, STATS_FHSS_AVG_SYNCH_FIX, fhss_structure->synch_monitor.avg_synch_fix);
745+
fhss_stats_update(fhss_structure, STATS_FHSS_SYNCH_INTERVAL, fhss_structure->synch_interval / 1000);
673746
} else {
674747
// Do not synchronize to current pan
675748
if (fhss_structure->synch_panid == pan_id) {
@@ -711,7 +784,15 @@ static int fhss_handle_state_set(fhss_structure_t *fhss_structure, fhss_states f
711784
return 0;
712785
}
713786

714-
static uint32_t fhss_get_compensation(fhss_structure_t *fhss_structure)
787+
static void fhss_destroy_scramble_table(fhss_structure_t *fhss_structure)
788+
{
789+
if (fhss_structure->fhss_scramble_table) {
790+
ns_dyn_mem_free(fhss_structure->fhss_scramble_table);
791+
fhss_structure->fhss_scramble_table = NULL;
792+
}
793+
}
794+
795+
static uint32_t fhss_get_sf_timeout_callback(fhss_structure_t *fhss_structure)
715796
{
716797
uint32_t compensation = 0;
717798
/* Drift compensation doesn't work with Linux platform */
@@ -730,7 +811,7 @@ static uint32_t fhss_get_compensation(fhss_structure_t *fhss_structure)
730811
#else
731812
(void) fhss_structure;
732813
#endif //__linux__
733-
return compensation;
814+
return (fhss_structure->synch_configuration.fhss_superframe_length) + (compensation * fhss_structure->platform_functions.fhss_resolution_divider);
734815
}
735816

736817
static void fhss_superframe_callback(fhss_structure_t *fhss_structure)
@@ -850,7 +931,7 @@ int fhss_set_callbacks(fhss_structure_t *fhss_structure)
850931
// Set internal API
851932
fhss_structure->update_channel = fhss_update_channel_callback;
852933
fhss_structure->update_superframe = fhss_superframe_callback;
853-
fhss_structure->read_compensation = fhss_get_compensation;
934+
fhss_structure->read_superframe_timeout = fhss_get_sf_timeout_callback;
854935
fhss_structure->handle_state_set = fhss_handle_state_set;
855936
return 0;
856937
}

source/Service_Libs/fhss/fhss.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ struct fhss_failed_tx
5757
ns_list_link_t link;
5858
};
5959

60+
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);
6061
bool fhss_is_synch_root(fhss_structure_t *fhss_structure);
6162
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);
6263
void fhss_update_beacon_info_lifetimes(fhss_structure_t *fhss_structure, uint32_t timestamp);

source/Service_Libs/fhss/fhss_beacon.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ int fhss_beacon_update_payload(fhss_structure_t *fhss_structure,
5858
payload->time_since_last_beacon = 0; // XXX not available yet
5959
// TODO: Get Beacon length from MAC
6060
uint32_t tx_time = fhss_get_tx_time(fhss_structure, 71, 0, 0);
61-
payload->processing_delay = fhss_structure->fhss_configuration.fhss_tuning_parameters.tx_processing_delay + tx_time;
61+
payload->processing_delay = fhss_structure->fhss_conf.fhss_configuration.fhss_tuning_parameters.tx_processing_delay + tx_time;
6262

6363
payload->superframe_length = config->fhss_superframe_length;
6464

source/Service_Libs/fhss/fhss_beacon_tasklet.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ void fhss_beacon_received(fhss_structure_t *fhss_structure, const uint8_t *synch
144144

145145
if (synch_info) {
146146
fhss_synchronization_beacon_payload_s temp_payload;
147-
temp_payload.processing_delay = fhss_structure->fhss_configuration.fhss_tuning_parameters.rx_processing_delay;
147+
temp_payload.processing_delay = fhss_structure->fhss_conf.fhss_configuration.fhss_tuning_parameters.rx_processing_delay;
148148
fhss_beacon_decode(&temp_payload, synch_info, elapsed_time, fhss_structure->number_of_channels);
149149

150150
// use the received information

source/Service_Libs/fhss/fhss_channel.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ bool fhss_change_to_next_channel(fhss_structure_t *fhss_structure)
137137
// Reset Beacon received flag when channel has changed
138138
fhss_structure->beacon_received_on_this_bc_channel = false;
139139
channel_index_tmp = fhss_add_channel_list_counter(channel_index_tmp, fhss_structure->number_of_channels, fhss_structure->channel_list_counter, fhss_structure->fhss_scramble_table);
140-
next_channel = channel_list_get_channel(fhss_structure->fhss_configuration.channel_mask, channel_index_tmp);
140+
next_channel = channel_list_get_channel(fhss_structure->fhss_conf.fhss_configuration.channel_mask, channel_index_tmp);
141141

142142
fhss_structure->rx_channel = next_channel;
143143
#ifdef FHSS_CHANNEL_DEBUG
@@ -220,7 +220,7 @@ static uint8_t fhss_get_destination_channel(fhss_structure_t *fhss_structure, ui
220220

221221
uc_index = fhss_calc_channel_shuffle(uc_index, fhss_structure->number_of_channels, fhss_structure->synch_configuration.fhss_number_of_bc_channels);
222222
uc_index = fhss_add_channel_list_counter(uc_index, fhss_structure->number_of_channels, fhss_structure->channel_list_counter, fhss_structure->fhss_scramble_table);
223-
return channel_list_get_channel(fhss_structure->fhss_configuration.channel_mask, uc_index);
223+
return channel_list_get_channel(fhss_structure->fhss_conf.fhss_configuration.channel_mask, uc_index);
224224
}
225225
return fhss_structure->rx_channel;
226226
}
@@ -262,7 +262,7 @@ int fhss_change_to_parent_channel(fhss_structure_t *fhss_structure)
262262
}
263263
uc_index = fhss_calc_channel_shuffle(uc_index, fhss_structure->number_of_channels, fhss_structure->synch_configuration.fhss_number_of_bc_channels);
264264
uc_index = fhss_add_channel_list_counter(uc_index, fhss_structure->number_of_channels, fhss_structure->channel_list_counter, fhss_structure->fhss_scramble_table);
265-
destination_channel = channel_list_get_channel(fhss_structure->fhss_configuration.channel_mask, uc_index);
265+
destination_channel = channel_list_get_channel(fhss_structure->fhss_conf.fhss_configuration.channel_mask, uc_index);
266266
fhss_structure->callbacks.change_channel(fhss_structure->fhss_api, destination_channel);
267267
#ifdef FHSS_CHANNEL_DEBUG
268268
tr_info("Parent channel: %u", destination_channel);

0 commit comments

Comments
 (0)