Skip to content

Commit b6e40af

Browse files
author
Jarkko Paso
authored
Merge pull request ARMmbed#1653 from ARMmbed/IOTTHD-2366
Iotthd 2366
2 parents fbe7795 + b28fcaa commit b6e40af

File tree

16 files changed

+249
-99
lines changed

16 files changed

+249
-99
lines changed

source/Service_Libs/fhss/fhss.c

Lines changed: 2 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ static int fhss_reset(fhss_structure_t *fhss_structure);
3838
static bool fhss_is_bc_sending_superframe(fhss_structure_t *fhss_structure);
3939
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);
4040
static bool fhss_is_there_common_divisor(uint16_t i, uint8_t j);
41-
static fhss_failed_tx_t *fhss_failed_handle_find(fhss_structure_t *fhss_structure, uint8_t handle);
42-
static void fhss_failed_list_free(fhss_structure_t *fhss_structure);
4341
static void fhss_beacon_received(fhss_structure_t *fhss_structure, const uint8_t *synch_info, const uint32_t elapsed_time);
4442
static void fhss_superframe_handler(const fhss_api_t *fhss_api, uint16_t delay);
4543
static int8_t fhss_beacon_create_tasklet(fhss_structure_t *fhss_structure);
@@ -80,7 +78,7 @@ fhss_structure_t *fhss_enable(fhss_api_t *fhss_api, const fhss_configuration_t *
8078
if (!fhss_struct->bs->fhss_configuration.fhss_max_synch_interval) {
8179
fhss_struct->bs->fhss_configuration.fhss_max_synch_interval = 240;
8280
}
83-
ns_list_init(&fhss_struct->bs->fhss_failed_tx_list);
81+
ns_list_init(&fhss_struct->fhss_failed_tx_list);
8482
fhss_struct->bs->own_hop = 0xff;
8583
fhss_reset(fhss_struct);
8684

@@ -696,47 +694,6 @@ static void fhss_update_beacon_info_lifetimes(fhss_structure_t *fhss_structure,
696694
}
697695
}
698696

699-
static fhss_failed_tx_t *fhss_failed_handle_find(fhss_structure_t *fhss_structure, uint8_t handle)
700-
{
701-
ns_list_foreach(fhss_failed_tx_t, cur, &fhss_structure->bs->fhss_failed_tx_list) {
702-
if (cur->handle == handle) {
703-
return cur;
704-
}
705-
}
706-
return NULL;
707-
}
708-
709-
static int fhss_failed_handle_add(fhss_structure_t *fhss_structure, uint8_t handle)
710-
{
711-
fhss_failed_tx_t *failed_tx = ns_dyn_mem_alloc(sizeof(fhss_failed_tx_t));
712-
if (!failed_tx) {
713-
return -2;
714-
}
715-
failed_tx->bad_channel = fhss_structure->rx_channel;
716-
failed_tx->retries_done = 0;
717-
failed_tx->handle = handle;
718-
ns_list_add_to_end(&fhss_structure->bs->fhss_failed_tx_list, failed_tx);
719-
return 0;
720-
}
721-
722-
static int fhss_failed_handle_remove(fhss_structure_t *fhss_structure, uint8_t handle)
723-
{
724-
fhss_failed_tx_t *failed_tx = fhss_failed_handle_find(fhss_structure, handle);
725-
if (!failed_tx) {
726-
return -1;
727-
}
728-
ns_list_remove(&fhss_structure->bs->fhss_failed_tx_list, failed_tx);
729-
ns_dyn_mem_free(failed_tx); // Free entry
730-
return 0;
731-
}
732-
733-
static void fhss_failed_list_free(fhss_structure_t *fhss_structure)
734-
{
735-
for (uint16_t i = 0; i<256; i++) {
736-
fhss_failed_handle_remove(fhss_structure, i);
737-
}
738-
}
739-
740697
static void fhss_synch_state_set_callback(const fhss_api_t *api, fhss_states fhss_state, uint16_t pan_id)
741698
{
742699
fhss_structure_t *fhss_structure = fhss_get_object_with_api(api);
@@ -1151,7 +1108,7 @@ static bool fhss_data_tx_fail_callback(const fhss_api_t *api, uint8_t handle, in
11511108
}
11521109
} else {
11531110
// Create new failure handle and return true to retransmit
1154-
fhss_failed_handle_add(fhss_structure, handle);
1111+
fhss_failed_handle_add(fhss_structure, handle, fhss_structure->rx_channel);
11551112
}
11561113
return true;
11571114
}

source/Service_Libs/fhss/fhss.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
*/
1717
#ifndef FHSS_H_
1818
#define FHSS_H_
19-
#include "ns_list.h"
2019
#define MAX_SCRAMBLE_TABLE_INDEXES 20
2120
// Lifetime is given as seconds
2221
#define BEACON_INFO_LIFETIME 600
@@ -87,16 +86,6 @@ struct fhss_synch_monitor
8786
int channel_counter;
8887
};
8988

90-
struct fhss_failed_tx
91-
{
92-
uint8_t handle;
93-
uint8_t bad_channel;
94-
uint8_t retries_done;
95-
ns_list_link_t link;
96-
};
97-
typedef NS_LIST_HEAD(fhss_failed_tx_t, link) fhss_failed_tx_list_t;
98-
99-
10089
struct fhss_bs
10190
{
10291
uint8_t uc_channel_index;
@@ -117,7 +106,6 @@ struct fhss_bs
117106
struct fhss_configuration fhss_configuration;
118107
struct fhss_synch_configuration synch_configuration;
119108
struct fhss_synch_monitor synch_monitor;
120-
fhss_failed_tx_list_t fhss_failed_tx_list;
121109
uint8_t fhss_scramble_table[MAX_SCRAMBLE_TABLE_INDEXES];
122110
};
123111

source/Service_Libs/fhss/fhss_common.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,3 +271,45 @@ int fhss_init_callbacks_cb(const fhss_api_t *api, fhss_callback_t *callbacks)
271271
fhss_structure->callbacks = *callbacks;
272272
return 0;
273273
}
274+
275+
276+
fhss_failed_tx_t *fhss_failed_handle_find(fhss_structure_t *fhss_structure, uint8_t handle)
277+
{
278+
ns_list_foreach(fhss_failed_tx_t, cur, &fhss_structure->fhss_failed_tx_list) {
279+
if (cur->handle == handle) {
280+
return cur;
281+
}
282+
}
283+
return NULL;
284+
}
285+
286+
int fhss_failed_handle_add(fhss_structure_t *fhss_structure, uint8_t handle, uint8_t bad_channel)
287+
{
288+
fhss_failed_tx_t *failed_tx = ns_dyn_mem_alloc(sizeof(fhss_failed_tx_t));
289+
if (!failed_tx) {
290+
return -1;
291+
}
292+
failed_tx->bad_channel = bad_channel;
293+
failed_tx->retries_done = 0;
294+
failed_tx->handle = handle;
295+
ns_list_add_to_end(&fhss_structure->fhss_failed_tx_list, failed_tx);
296+
return 0;
297+
}
298+
299+
int fhss_failed_handle_remove(fhss_structure_t *fhss_structure, uint8_t handle)
300+
{
301+
fhss_failed_tx_t *failed_tx = fhss_failed_handle_find(fhss_structure, handle);
302+
if (!failed_tx) {
303+
return -1;
304+
}
305+
ns_list_remove(&fhss_structure->fhss_failed_tx_list, failed_tx);
306+
ns_dyn_mem_free(failed_tx); // Free entry
307+
return 0;
308+
}
309+
310+
void fhss_failed_list_free(fhss_structure_t *fhss_structure)
311+
{
312+
for (uint16_t i = 0; i<256; i++) {
313+
fhss_failed_handle_remove(fhss_structure, i);
314+
}
315+
}

source/Service_Libs/fhss/fhss_common.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,23 @@
1616
*/
1717
#ifndef FHSS_COMMON_H_
1818
#define FHSS_COMMON_H_
19+
#include "ns_list.h"
20+
1921
#define FHSS_TASKLET_INIT_EVENT 0
2022
#define FHSS_TIMER_EVENT 1
2123
#define FHSS_COMPARE_SYNCH_PARENT 2
2224
#define FHSS_BROADCAST_CHANNEL 3
2325
#define FHSS_UPDATE_SYNCH_INFO_STORAGE 4
2426

27+
struct fhss_failed_tx
28+
{
29+
uint8_t handle;
30+
uint8_t bad_channel;
31+
uint8_t retries_done;
32+
ns_list_link_t link;
33+
};
34+
typedef NS_LIST_HEAD(fhss_failed_tx_t, link) fhss_failed_tx_list_t;
35+
2536
struct fhss_structure
2637
{
2738
uint8_t fhss_resolution_divider;
@@ -39,6 +50,7 @@ struct fhss_structure
3950
struct fhss_ws *ws;
4051
struct fhss_timer platform_functions;
4152
struct fhss_callback callbacks;
53+
fhss_failed_tx_list_t fhss_failed_tx_list;
4254
uint8_t synch_parent[8];
4355
};
4456

@@ -58,4 +70,8 @@ int fhss_compare_with_synch_parent_address(fhss_structure_t *fhss_structure, con
5870
bool fhss_use_broadcast_queue_cb(const fhss_api_t *api, bool is_broadcast_addr, int frame_type);
5971
uint32_t fhss_read_timestamp_cb(const fhss_api_t *api);
6072
int fhss_init_callbacks_cb(const fhss_api_t *api, fhss_callback_t *callbacks);
73+
int fhss_failed_handle_remove(fhss_structure_t *fhss_structure, uint8_t handle);
74+
int fhss_failed_handle_add(fhss_structure_t *fhss_structure, uint8_t handle, uint8_t bad_channel);
75+
fhss_failed_tx_t *fhss_failed_handle_find(fhss_structure_t *fhss_structure, uint8_t handle);
76+
void fhss_failed_list_free(fhss_structure_t *fhss_structure);
6177
#endif /*FHSS_COMMON_H_*/

source/Service_Libs/fhss/fhss_ws.c

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ fhss_structure_t *fhss_ws_enable(fhss_api_t *fhss_api, const fhss_ws_configurati
7373

7474
fhss_struct->ws->fhss_configuration = *fhss_configuration;
7575
fhss_struct->number_of_channels = channel_count;
76+
ns_list_init(&fhss_struct->fhss_failed_tx_list);
7677
return fhss_struct;
7778
}
7879

@@ -112,8 +113,6 @@ static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
112113
fhss_start_timer(fhss_structure, fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval*1000, fhss_broadcast_handler);
113114
fhss_structure->ws->is_on_bc_channel = true;
114115
next_channel = fhss_ws_calc_bc_channel(fhss_structure);
115-
// TODO: Randomize polling TX queue when on broadcast channel
116-
fhss_structure->callbacks.tx_poll(fhss_structure->fhss_api);
117116
} else {
118117
uint32_t timeout = (fhss_structure->ws->fhss_configuration.fhss_broadcast_interval - fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) * 1000;
119118
fhss_start_timer(fhss_structure, timeout, fhss_broadcast_handler);
@@ -125,6 +124,10 @@ static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
125124
#endif /*FHSS_CHANNEL_DEBUG*/
126125
}
127126
fhss_structure->callbacks.change_channel(fhss_structure->fhss_api, next_channel);
127+
if (fhss_structure->callbacks.read_tx_queue_size(fhss_structure->fhss_api, true)) {
128+
// TODO: Randomize polling TX queue when on broadcast channel
129+
fhss_structure->callbacks.tx_poll(fhss_structure->fhss_api);
130+
}
128131
}
129132

130133
static int own_floor(float value)
@@ -289,6 +292,18 @@ static int fhss_ws_tx_handle_callback(const fhss_api_t *api, bool is_broadcast_a
289292
return 0;
290293
}
291294

295+
static bool fhss_check_bad_channel(fhss_structure_t *fhss_structure, uint8_t handle)
296+
{
297+
fhss_failed_tx_t *failed_tx = fhss_failed_handle_find(fhss_structure, handle);
298+
if (!failed_tx) {
299+
return true;
300+
}
301+
if (failed_tx->bad_channel == fhss_structure->rx_channel) {
302+
return false;
303+
}
304+
return true;
305+
}
306+
292307
static bool fhss_ws_check_tx_conditions_callback(const fhss_api_t *api, bool is_broadcast_addr, uint8_t handle, int frame_type, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length)
293308
{
294309
(void) handle;
@@ -303,10 +318,18 @@ static bool fhss_ws_check_tx_conditions_callback(const fhss_api_t *api, bool is_
303318
if (fhss_structure->ws->fhss_configuration.ws_channel_function == WS_FIXED_CHANNEL) {
304319
return true;
305320
}
321+
// This condition will check that message is not sent on bad channel
322+
if (fhss_check_bad_channel(fhss_structure, handle) == false) {
323+
return false;
324+
}
306325
// Do not allow broadcast destination on unicast channel
307326
if (is_broadcast_addr && (fhss_structure->ws->is_on_bc_channel == false)) {
308327
return false;
309328
}
329+
// Do not allow unicast destination on broadcast channel
330+
if (!is_broadcast_addr && (fhss_structure->ws->is_on_bc_channel == true)) {
331+
return false;
332+
}
310333
return true;
311334
}
312335

@@ -372,10 +395,34 @@ static void fhss_ws_data_tx_done_callback(const fhss_api_t *api, bool waiting_ac
372395

373396
static bool fhss_ws_data_tx_fail_callback(const fhss_api_t *api, uint8_t handle, int frame_type)
374397
{
375-
(void) api;
376-
(void) handle;
377-
(void) frame_type;
378-
return false;
398+
fhss_structure_t *fhss_structure = fhss_get_object_with_api(api);
399+
if (!fhss_structure) {
400+
return false;
401+
}
402+
// Only use channel retries when device is synchronized
403+
if (fhss_structure->fhss_state == FHSS_UNSYNCHRONIZED) {
404+
return false;
405+
}
406+
407+
// Use channel retries only for data frames
408+
if (FHSS_DATA_FRAME != frame_type) {
409+
return false;
410+
}
411+
412+
fhss_failed_tx_t *fhss_failed_tx = fhss_failed_handle_find(fhss_structure, handle);
413+
if (fhss_failed_tx) {
414+
fhss_failed_tx->retries_done++;
415+
if (fhss_failed_tx->retries_done >= WS_NUMBER_OF_CHANNEL_RETRIES) {
416+
// No more retries. Return false to stop retransmitting.
417+
fhss_failed_handle_remove(fhss_structure, handle);
418+
return false;
419+
}
420+
fhss_failed_tx->bad_channel = fhss_structure->rx_channel;
421+
} else {
422+
// Create new failure handle and return true to retransmit
423+
fhss_failed_handle_add(fhss_structure, handle, fhss_structure->rx_channel);
424+
}
425+
return true;
379426
}
380427

381428
static void fhss_ws_receive_frame_callback(const fhss_api_t *api, uint16_t pan_id, uint8_t *source_address, uint32_t timestamp, uint8_t *synch_info, int frame_type)
@@ -407,6 +454,9 @@ static void fhss_unicast_handler(const fhss_api_t *fhss_api, uint16_t delay)
407454
timeout = fhss_ws_get_sf_timeout_callback(fhss_structure);
408455
fhss_start_timer(fhss_structure, timeout - (delay * fhss_structure->platform_functions.fhss_resolution_divider), fhss_unicast_handler);
409456
fhss_ws_update_uc_channel_callback(fhss_structure);
457+
if (fhss_structure->callbacks.read_tx_queue_size(fhss_structure->fhss_api, false)) {
458+
fhss_structure->callbacks.tx_poll(fhss_structure->fhss_api);
459+
}
410460
}
411461

412462
int fhss_ws_set_callbacks(fhss_structure_t *fhss_structure)

source/Service_Libs/fhss/fhss_ws.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@
1616
*/
1717
#ifndef FHSS_WS_H_
1818
#define FHSS_WS_H_
19+
20+
/* WS requires at least 19 MAC retransmissions (total 1+19=20 attempts). 802.15.4 macMaxFrameRetries is 3 (total 1+3=4 attempts).
21+
* At least 4 channel retries must be used: (Initial channel + WS_NUMBER_OF_CHANNEL_RETRIES) * MAC attempts = (1+4)*4=20 attempts
22+
*/
23+
#define WS_NUMBER_OF_CHANNEL_RETRIES 4
1924
typedef struct fhss_ws fhss_ws_t;
2025

2126
struct fhss_ws

test/nanostack/unittest/service_libs/fhss/test_fhss.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@ static fhss_api_t *test_generate_fhss_api(void)
129129
memset(&fhss_channel_stub, 0, sizeof(fhss_channel_stub_def));
130130
FHSS.fhss_api = &fhss_api;
131131
FHSS.bs = &bs;
132-
ns_list_init(&FHSS.bs->fhss_failed_tx_list);
133132
FHSS.callbacks.change_channel = &mac_set_channel;
134133
FHSS.callbacks.read_mac_address = &mac_read_64bit_mac_address;
135134
FHSS.callbacks.read_datarate = &mac_read_phy_datarate;
@@ -138,7 +137,6 @@ static fhss_api_t *test_generate_fhss_api(void)
138137
FHSS.callbacks.synch_lost_notification = &mac_synch_lost;
139138
FHSS.callbacks.broadcast_notify = &mac_broadcast_notification;
140139
test_set_fhss_default_configs();
141-
ns_list_init(&FHSS.bs->fhss_failed_tx_list);
142140
test_set_platform_api(&FHSS.platform_functions);
143141
fhss_set_callbacks(&FHSS);
144142
return &fhss_api;
@@ -409,15 +407,6 @@ bool test_fhss_data_tx_fail_callback()
409407
if (FHSS.fhss_api->data_tx_fail(api, DEFAULT_HANDLE, FHSS_SYNCH_FRAME) != false) {
410408
return false;
411409
}
412-
// Test adding failed handle
413-
nsdynmemlib_stub.returnCounter = 1;
414-
if (FHSS.fhss_api->data_tx_fail(api, DEFAULT_HANDLE, DEFAULT_FRAME_TYPE) != true) {
415-
return false;
416-
}
417-
// Test removing failed handle
418-
if (FHSS.fhss_api->data_tx_fail(api, DEFAULT_HANDLE, DEFAULT_FRAME_TYPE) != false) {
419-
return false;
420-
}
421410

422411
return true;
423412
}

test/nanostack/unittest/service_libs/fhss_common/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ TEST_SRC_FILES = \
1313
test_fhss_common.c \
1414
../../stub/mbed_trace_stub.c \
1515
../../stub/nsdynmemLIB_stub.c \
16+
../../stub/ns_list_stub.c \
1617
../../stub/event_stub.c \
1718
../../stub/ns_timer_stub.c \
1819
../../stub/fhss_stub.c \

test/nanostack/unittest/service_libs/fhss_common/fhsscommontest.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,13 @@ TEST(fhss_common, test_fhss_clear_active_event)
9090
{
9191
CHECK(test_fhss_clear_active_event());
9292
}
93+
94+
TEST(fhss_common, test_fhss_failed_handle_add)
95+
{
96+
CHECK(test_fhss_failed_handle_add());
97+
}
98+
99+
TEST(fhss_common, test_fhss_failed_list_free)
100+
{
101+
CHECK(test_fhss_failed_list_free());
102+
}

0 commit comments

Comments
 (0)