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

Commit 8f5c0bf

Browse files
author
Jarkko Paso
committed
FHSS: Removed fhss_beacon, fhss_beacon_tasklet and fhss_mac_interface
- Functions moved to fhss and fhss_common - Unit tests to be fixed in following commits
1 parent 1e94358 commit 8f5c0bf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+450
-1842
lines changed

source/Service_Libs/fhss/fhss.c

Lines changed: 267 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,13 @@
2323
#include "fhss_channel.h"
2424
#include "channel_list.h"
2525
#include "nsdynmemLIB.h"
26-
#include "fhss_beacon.h"
2726
#include "fhss_statistics.h"
28-
#include "fhss_mac_interface.h"
2927
#include "ns_trace.h"
3028
#include "eventOS_event.h"
3129
#include "eventOS_callback_timer.h"
3230
#include "platform/arm_hal_interrupt.h"
3331
#include "randLIB.h"
32+
#include "common_functions.h"
3433
#include <string.h>
3534

3635
#define TRACE_GROUP "fhss"
@@ -43,6 +42,10 @@ static fhss_failed_tx_t *fhss_failed_handle_find(fhss_structure_t *fhss_structur
4342
static void fhss_failed_list_free(fhss_structure_t *fhss_structure);
4443
static void fhss_beacon_received(fhss_structure_t *fhss_structure, const uint8_t *synch_info, const uint32_t elapsed_time);
4544
static void fhss_superframe_handler(const fhss_api_t *fhss_api, uint16_t delay);
45+
static int8_t fhss_beacon_create_tasklet(fhss_structure_t *fhss_structure);
46+
static void fhss_beacon_tasklet_func(arm_event_s* event);
47+
static int fhss_beacon_periodic_start(fhss_structure_t *fhss_structure, uint32_t time_to_first_beacon);
48+
static void fhss_beacon_periodic_stop(fhss_structure_t *fhss_structure);
4649

4750
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)
4851
{
@@ -791,6 +794,123 @@ static void fhss_handle_state_set(const fhss_api_t *api, fhss_states fhss_state,
791794
return;
792795
}
793796

797+
static void fhss_beacon_decode_raw(fhss_synchronization_beacon_payload_s* dest, const uint8_t* buffer)
798+
{
799+
dest->data_start_delimeter = *buffer++;
800+
dest->channel_index = *buffer++;
801+
dest->sender_unicast_channel = *buffer++;
802+
dest->current_superframe = common_read_16_bit(buffer);
803+
buffer += BEACON_FIELD_SIZE(current_superframe);
804+
dest->remaining_slots = common_read_16_bit(buffer);
805+
buffer += BEACON_FIELD_SIZE(remaining_slots);
806+
dest->channel_list_counter = common_read_16_bit(buffer);
807+
buffer += BEACON_FIELD_SIZE(channel_list_counter);
808+
dest->hop_count = *buffer++;
809+
dest->number_of_broadcast_channels = *buffer++;
810+
dest->number_of_tx_slots = *buffer++;
811+
dest->time_since_last_beacon = common_read_32_bit(buffer);
812+
buffer += BEACON_FIELD_SIZE(time_since_last_beacon);
813+
dest->processing_delay += common_read_16_bit(buffer);
814+
buffer += BEACON_FIELD_SIZE(processing_delay);
815+
dest->superframe_length = common_read_16_bit(buffer);
816+
buffer += BEACON_FIELD_SIZE(superframe_length);
817+
dest->number_of_superframes_per_channel = *buffer;
818+
}
819+
820+
static uint32_t fhss_get_time_to_next_channel_change(uint16_t remaining_slots_to_next_superframe, uint8_t number_of_superframes, uint8_t current_superframe, uint16_t superframe_length)
821+
{
822+
return remaining_slots_to_next_superframe + ((uint32_t)((number_of_superframes - 1) - current_superframe) * superframe_length);
823+
}
824+
825+
// Decode the given raw byte buffer into a struct into dest struct and calculate
826+
// the new values for elapsed_time, channel_index, current_superframe and remaining_slots
827+
// from current state and given data.
828+
static void fhss_beacon_decode(fhss_synchronization_beacon_payload_s* dest, const uint8_t* buffer, uint32_t elapsed_time, uint16_t number_of_channels)
829+
{
830+
fhss_beacon_decode_raw(dest, buffer);
831+
832+
elapsed_time += dest->processing_delay;
833+
834+
/* To calculate channel index after beacon scan, following calculation is performed
835+
*
836+
* rem. slots to channel change(X) Channel length (V)
837+
* |---------------------| |-----------------------------------------------|
838+
* | RX'd channel index (Y) | ... | Y+n |
839+
* ...| sf1 | sf2 | sf3 | sf4 | ... | sf1 | sf2 | sf3 | sf4 |...
840+
* ^ ^
841+
* |beacon received |beacon scan done
842+
* |-------------------------------------|
843+
* measured time after beacon RX'd(Z)
844+
* V = superframe length * number of superframes
845+
* X = remaining slots to superframe change + length of the remaining full superframes to channel change
846+
*
847+
* Y+n = Y + ((Z - X) / V) + 1
848+
*
849+
* Or if (Z < X)
850+
* Y+n = Y
851+
*/
852+
853+
uint32_t remaining_slots_to_next_channel = fhss_get_time_to_next_channel_change(dest->remaining_slots, dest->number_of_superframes_per_channel, dest->current_superframe, dest->superframe_length);
854+
uint16_t temp_channel_index = dest->channel_index;
855+
if (elapsed_time >= remaining_slots_to_next_channel) {
856+
uint32_t channel_length = (uint32_t) dest->number_of_superframes_per_channel * dest->superframe_length;
857+
temp_channel_index = dest->channel_index + ((elapsed_time - remaining_slots_to_next_channel) / channel_length) + 1;
858+
}
859+
while (temp_channel_index >= number_of_channels) {
860+
temp_channel_index -= number_of_channels;
861+
dest->channel_list_counter++;
862+
}
863+
dest->channel_index = temp_channel_index;
864+
while (dest->channel_list_counter >= (number_of_channels * MAX_SCRAMBLE_TABLE_INDEXES)) {
865+
dest->channel_list_counter -= (number_of_channels * MAX_SCRAMBLE_TABLE_INDEXES);
866+
}
867+
868+
/* To calculate superframe after beacon scan, following calculation is performed
869+
*
870+
* rem. slots(X) sf. length(V)
871+
* |---------------| |-----------------|
872+
*...| RX'd superframe (Y)| ... | Y+n | Y+n+1 |....
873+
* ^ ^
874+
* |beacon received |beacon scan done
875+
* |-------------------------------------|
876+
* measured time after beacon RX'd(Z)
877+
*
878+
* Y+n = Y + ((Z - X) / V) + 1
879+
*
880+
* Or if (Z < X)
881+
* Y+n = Y
882+
*/
883+
884+
if (elapsed_time >= dest->remaining_slots) {
885+
dest->current_superframe = dest->current_superframe + ((elapsed_time - dest->remaining_slots) / dest->superframe_length) + 1;
886+
}
887+
while (dest->current_superframe >= dest->number_of_superframes_per_channel) {
888+
dest->current_superframe -= dest->number_of_superframes_per_channel;
889+
}
890+
891+
/* To get the remaining slots after beacon scan, following calculation is performed
892+
*
893+
* rem. slots(Y) sf. length(V) new rem. slots(X)
894+
* |----------| |---------------| |-------------|
895+
*...| superframe 1 | superframe 2 | superframe 3 | superframe 4 |...
896+
* ^ ^
897+
* |beacon received |beacon scan done
898+
* |--------------------------------------------|
899+
* measured time after beacon RX'd(Z)
900+
*
901+
* X = V - ((Z - Y) % V)
902+
*
903+
* Or if (Z < Y)
904+
* X = Y - Z
905+
*/
906+
907+
if (elapsed_time < dest->remaining_slots) {
908+
dest->remaining_slots = dest->remaining_slots - elapsed_time;
909+
} else {
910+
dest->remaining_slots = dest->superframe_length - ((elapsed_time - dest->remaining_slots) % dest->superframe_length);
911+
}
912+
}
913+
794914
static void fhss_beacon_received(fhss_structure_t *fhss_structure, const uint8_t *synch_info, const uint32_t elapsed_time)
795915
{
796916

@@ -929,8 +1049,52 @@ static void fhss_update_channel_callback(fhss_structure_t *fhss_structure)
9291049
}
9301050
}
9311051

1052+
static uint8_t* fhss_beacon_encode_raw(uint8_t* buffer, const fhss_synchronization_beacon_payload_s* source)
1053+
{
1054+
*buffer++ = FHSS_DATA_START_DELIMETER;
1055+
*buffer++ = source->channel_index;
1056+
*buffer++ = source->sender_unicast_channel;
1057+
buffer = common_write_16_bit(source->current_superframe, buffer);
1058+
buffer = common_write_16_bit(source->remaining_slots, buffer);
1059+
buffer = common_write_16_bit(source->channel_list_counter, buffer);
1060+
*buffer++ = source->hop_count;
1061+
*buffer++ = source->number_of_broadcast_channels;
1062+
*buffer++ = source->number_of_tx_slots;
1063+
buffer = common_write_32_bit(source->time_since_last_beacon, buffer);
1064+
buffer = common_write_16_bit(source->processing_delay, buffer);
1065+
buffer = common_write_16_bit(source->superframe_length, buffer);
1066+
*buffer++ = source->number_of_superframes_per_channel;
1067+
1068+
return buffer;
1069+
}
1070+
1071+
static void fhss_beacon_build(fhss_structure_t *fhss_structure, uint8_t* dest)
1072+
{
1073+
fhss_synchronization_beacon_payload_s temp_payload;
1074+
platform_enter_critical();
1075+
const fhss_synch_configuration_t *config = &fhss_structure->bs->synch_configuration;
1076+
temp_payload.channel_index = fhss_structure->bs->current_channel_index;
1077+
temp_payload.sender_unicast_channel = 0;
1078+
temp_payload.current_superframe = fhss_structure->bs->current_superframe;
1079+
// This assumes that the time is always in the range of 0..2**16, which
1080+
// should be the case as the superframe length field is also in that range.
1081+
temp_payload.remaining_slots = (uint16_t) fhss_get_remaining_time_to_next_superframe(fhss_structure);
1082+
temp_payload.channel_list_counter = fhss_structure->bs->channel_list_counter;
1083+
temp_payload.hop_count = fhss_structure->bs->own_hop;
1084+
temp_payload.number_of_broadcast_channels = config->fhss_number_of_bc_channels;
1085+
temp_payload.number_of_tx_slots = config->fhss_number_of_tx_slots;
1086+
temp_payload.time_since_last_beacon = 0; // XXX not available yet
1087+
uint32_t tx_time = fhss_get_tx_time(fhss_structure, 71, 0, 0);
1088+
temp_payload.processing_delay = fhss_structure->bs->fhss_configuration.fhss_tuning_parameters.tx_processing_delay + tx_time;
1089+
temp_payload.superframe_length = config->fhss_superframe_length;
1090+
temp_payload.number_of_superframes_per_channel = config->fhss_number_of_superframes;
1091+
platform_exit_critical();
1092+
fhss_beacon_encode_raw(dest, &temp_payload);
1093+
}
1094+
9321095
static int16_t fhss_write_synch_info_callback(const fhss_api_t *api, uint8_t *ptr, uint8_t length, int frame_type, uint32_t tx_time)
9331096
{
1097+
(void) length;
9341098
fhss_structure_t *fhss_structure = fhss_get_object_with_api(api);
9351099
(void) tx_time;
9361100
if (!fhss_structure || !ptr || (frame_type != FHSS_SYNCH_FRAME)) {
@@ -1141,6 +1305,16 @@ int8_t fhss_set_synch_configuration(fhss_structure_t *fhss_structure, const fhss
11411305
return 0;
11421306
}
11431307

1308+
uint8_t fhss_calculate_uc_index(uint8_t channel_index, uint16_t number_of_channels, uint8_t number_of_broadcast_channels)
1309+
{
1310+
// When channel index is 0, return last unicast index
1311+
if (channel_index == 0) {
1312+
return (number_of_channels - number_of_broadcast_channels - 1);
1313+
}
1314+
uint16_t bc_channel_density = (number_of_channels/number_of_broadcast_channels);
1315+
return channel_index - (channel_index/bc_channel_density) - 1;
1316+
}
1317+
11441318
int fhss_set_callbacks(fhss_structure_t *fhss_structure)
11451319
{
11461320
// Set external API
@@ -1159,3 +1333,94 @@ int fhss_set_callbacks(fhss_structure_t *fhss_structure)
11591333

11601334
return 0;
11611335
}
1336+
1337+
static int8_t fhss_beacon_create_tasklet(fhss_structure_t *fhss_structure)
1338+
{
1339+
if (fhss_structure->beacon_tasklet_id < 0) {
1340+
fhss_structure->beacon_tasklet_id = eventOS_event_handler_create(fhss_beacon_tasklet_func, FHSS_TASKLET_INIT_EVENT);
1341+
}
1342+
return fhss_structure->beacon_tasklet_id;
1343+
}
1344+
1345+
static int fhss_beacon_periodic_start(fhss_structure_t *fhss_structure, uint32_t time_to_first_beacon)
1346+
{
1347+
int ret_val = -1;
1348+
1349+
if (fhss_structure) {
1350+
fhss_beacon_periodic_stop(fhss_structure);
1351+
ret_val = fhss_timeout_start(fhss_structure, time_to_first_beacon * 1000);
1352+
}
1353+
return ret_val;
1354+
}
1355+
1356+
static void fhss_beacon_periodic_stop(fhss_structure_t *fhss_structure)
1357+
{
1358+
if (fhss_structure) {
1359+
fhss_timeout_stop(fhss_structure);
1360+
}
1361+
}
1362+
1363+
static void fhss_beacon_tasklet_func(arm_event_s* event)
1364+
{
1365+
fhss_structure_t *fhss_structure = (fhss_structure_t *)event->data_ptr;
1366+
if (!fhss_structure) {
1367+
return;
1368+
}
1369+
uint8_t parent_address[8];
1370+
fhss_clear_active_event(fhss_structure, event->event_type);
1371+
// skip the init event as there will be a timer event after
1372+
if (event->event_type == FHSS_TIMER_EVENT) {
1373+
// Stop network when lost number of FHSS_SYNCHRONIZATION_LOST synchronization beacons from parent in a row.
1374+
if (fhss_structure->bs->beacons_received_timer >= FHSS_SYNCHRONIZATION_LOST) {
1375+
fhss_structure->callbacks.synch_lost_notification(fhss_structure->fhss_api);
1376+
fhss_stats_update(fhss_structure, STATS_FHSS_SYNCH_LOST, 1);
1377+
tr_err("FHSS synchronization lost");
1378+
} else {
1379+
uint16_t bc_density = (fhss_structure->number_of_channels / fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels);
1380+
uint16_t channel_dwell_time = ((uint32_t)fhss_structure->bs->synch_configuration.fhss_superframe_length * fhss_structure->bs->synch_configuration.fhss_number_of_superframes) / 1000;
1381+
1382+
fhss_beacon_periodic_start(fhss_structure, (bc_density * channel_dwell_time) * 2);
1383+
// Send synchronization request
1384+
fhss_structure->callbacks.send_fhss_frame(fhss_structure->fhss_api, FHSS_SYNCH_REQUEST_FRAME);
1385+
fhss_structure->bs->beacons_received_timer++;
1386+
#ifdef FEA_TRACE_SUPPORT
1387+
if (!fhss_get_parent_address(fhss_structure, parent_address)) {
1388+
tr_debug("Update synch, attempt: %u, %s", fhss_structure->bs->beacons_received_timer, trace_array(parent_address, 8));
1389+
} else {
1390+
tr_err("No synch parent found");
1391+
}
1392+
#endif /*FEA_TRACE_SUPPORT*/
1393+
}
1394+
}
1395+
// Compare if synchronization parent has changed and request beacon if needed
1396+
else if(event->event_type == FHSS_COMPARE_SYNCH_PARENT)
1397+
{
1398+
if (fhss_compare_with_synch_parent_address(fhss_structure, fhss_structure->synch_parent)) {
1399+
fhss_structure->bs->synch_monitor.avg_synch_fix = 0;
1400+
if(fhss_structure->bs->synch_monitor.avg_synch_fix_counter > 0) {
1401+
fhss_structure->bs->synch_monitor.avg_synch_fix_counter = 0;
1402+
}
1403+
// Send synchronization request
1404+
fhss_structure->callbacks.send_fhss_frame(fhss_structure->fhss_api, FHSS_SYNCH_REQUEST_FRAME);
1405+
#ifdef FEA_TRACE_SUPPORT
1406+
if (!fhss_get_parent_address(fhss_structure, parent_address)) {
1407+
tr_debug("Synch parent changed, New: %s, Old: %s\n", trace_array(parent_address, 8), trace_array(fhss_structure->synch_parent, 8));
1408+
} else {
1409+
tr_err("Synch parent changed : No parent found");
1410+
}
1411+
#endif /*FEA_TRACE_SUPPORT*/
1412+
}
1413+
}
1414+
else if(event->event_type == FHSS_BROADCAST_CHANNEL)
1415+
{
1416+
uint16_t superframe_length = fhss_structure->bs->synch_configuration.fhss_superframe_length;
1417+
uint8_t number_of_superframes = fhss_structure->bs->synch_configuration.fhss_number_of_superframes;
1418+
// Given broadcast time is channel length minus 1 superframe
1419+
fhss_structure->callbacks.broadcast_notify(fhss_structure->fhss_api, (uint32_t)superframe_length * (number_of_superframes - 1));
1420+
}
1421+
// Update Beacon info lifetimes
1422+
else if(event->event_type == FHSS_UPDATE_SYNCH_INFO_STORAGE)
1423+
{
1424+
fhss_update_beacon_info_lifetimes(fhss_structure, fhss_read_timestamp_cb(fhss_structure->fhss_api));
1425+
}
1426+
}

source/Service_Libs/fhss/fhss.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,49 @@
2626
#define NUMBER_OF_BC_START_SUPERFRAMES 3
2727
#define MAX_FHSS_TIMER_DIVIDER 100
2828
#define SYNCH_MONITOR_AVG_SAMPLES 5
29+
#define FHSS_DATA_START_DELIMETER 0x00
30+
#define FHSS_SYNCHRONIZATION_LOST 10
31+
#define BEACON_INTERVAL_INIT_DIVIDER 100
32+
#define FHSS_SYNCH_DRIFT_TOO_HIGH_LIMIT 20000
33+
#define CLOSE_TO_SUPERFRAME_LENGTH 2000
34+
#define BEACON_FIELD_SIZE(field) (sizeof((fhss_synchronization_beacon_payload_s*)0)->field)
2935

3036
typedef struct fhss_structure fhss_structure_t;
3137
typedef struct fhss_beacon_info fhss_beacon_info_t;
3238
typedef struct fhss_synch_monitor fhss_synch_monitor_s;
3339
typedef struct fhss_failed_tx fhss_failed_tx_t;
3440
typedef struct fhss_bs fhss_bs_t;
41+
typedef struct fhss_synchronization_beacon_payload fhss_synchronization_beacon_payload_s;
42+
43+
struct fhss_synchronization_beacon_payload
44+
{
45+
/** Start delimeter */
46+
uint8_t data_start_delimeter;
47+
/** Channel index */
48+
uint8_t channel_index;
49+
/** Sender unicast channel index */
50+
uint8_t sender_unicast_channel;
51+
/** Current superframe */
52+
uint16_t current_superframe;
53+
/** Remaining time (us) to next superframe */
54+
uint16_t remaining_slots;
55+
/** Channel list counter */
56+
uint16_t channel_list_counter;
57+
/** Hop count */
58+
uint8_t hop_count;
59+
/** Number of broadcast channels */
60+
uint8_t number_of_broadcast_channels;
61+
/** Number of TX slots per channel */
62+
uint8_t number_of_tx_slots;
63+
/** Time since last beacon (us) */
64+
uint32_t time_since_last_beacon;
65+
/** Processing delay (us) */
66+
uint16_t processing_delay;
67+
/** Superframe length */
68+
uint16_t superframe_length;
69+
/** Number of superframes per channel */
70+
uint8_t number_of_superframes_per_channel;
71+
};
3572

3673
struct fhss_beacon_info
3774
{
@@ -97,5 +134,6 @@ uint32_t fhss_get_tx_time(fhss_structure_t *fhss_structure, uint16_t bytes_to_se
97134
uint32_t fhss_get_remaining_time_to_next_superframe(const fhss_structure_t *fhss_struct);
98135
int8_t fhss_set_synch_configuration(fhss_structure_t *fhss_structure, const fhss_synch_configuration_t *fhss_synch_configuration);
99136
int fhss_set_callbacks(fhss_structure_t *fhss_structure);
137+
uint8_t fhss_calculate_uc_index(uint8_t channel_index, uint16_t number_of_channels, uint8_t number_of_broadcast_channels);
100138

101139
#endif /* FHSS_H_ */

0 commit comments

Comments
 (0)