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

Commit ba98835

Browse files
author
Jarkko Paso
authored
Merge pull request ARMmbed#1689 from ARMmbed/IOTTHD-2475
Iotthd 2475
2 parents 28307de + 3412f4a commit ba98835

File tree

14 files changed

+272
-32
lines changed

14 files changed

+272
-32
lines changed

nanostack/fhss_ws_extension.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,13 @@ extern int ns_fhss_ws_remove_parent(const fhss_api_t *fhss_api, const uint8_t eu
9898
*/
9999
extern int ns_fhss_set_neighbor_info_fp(const fhss_api_t *fhss_api, fhss_get_neighbor_info *get_neighbor_info);
100100

101+
/**
102+
* @brief Set node hop count. Hop count is used to specify TX/RX slot. When hop count is set to 0xFF, TX/RX slots are ignored.
103+
* @param fhss_api FHSS instance.
104+
* @param hop_count Hop count to be set.
105+
* @return 0 on success, -1 on fail.
106+
*/
107+
extern int ns_fhss_ws_set_hop_count(const fhss_api_t *fhss_api, const uint8_t hop_count);
101108

102109
#ifdef __cplusplus
103110
}

source/6LoWPAN/ws/ws_bootstrap.c

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ static bool ws_bootstrap_state_wait_rpl(struct protocol_interface_info_entry *cu
7878
static int8_t ws_bootsrap_event_trig(ws_bootsrap_event_type_e event_type, int8_t interface_id, arm_library_event_priority_e priority, void *event_data);
7979

8080
static bool ws_bootstrap_neighbor_info_request(struct protocol_interface_info_entry *interface, const uint8_t *mac_64, llc_neighbour_req_t * neighbor_buffer, bool request_new);
81+
static uint16_t ws_bootstrap_route_cost_calculate(protocol_interface_info_entry_t *cur);
82+
static uint16_t ws_bootstrap_get_min_rank_inc(protocol_interface_info_entry_t *cur);
8183

8284
mac_neighbor_table_entry_t * ws_bootstrap_mac_neighbor_add(struct protocol_interface_info_entry *interface, const uint8_t *src64)
8385
{
@@ -208,6 +210,9 @@ static int8_t ws_enable_fhss(protocol_interface_info_entry_t *cur)
208210
if (ns_fhss_set_neighbor_info_fp(fhss_api, &ws_get_neighbor_info)) {
209211
return -1;
210212
}
213+
if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
214+
ns_fhss_ws_set_hop_count(fhss_api, 0);
215+
}
211216
cur->ws_info->fhss_api = fhss_api;
212217
return 0;
213218
}
@@ -976,6 +981,19 @@ static void ws_bootstrap_ip_stack_activate(protocol_interface_info_entry_t *cur)
976981
ws_bootstrap_ip_stack_reset(cur);
977982
}
978983

984+
static void ws_set_fhss_hop(protocol_interface_info_entry_t *cur)
985+
{
986+
uint16_t own_rank = ws_bootstrap_route_cost_calculate(cur);
987+
uint16_t rank_inc = ws_bootstrap_get_min_rank_inc(cur);
988+
if (own_rank == 0xffff || rank_inc == 0xffff) {
989+
return;
990+
}
991+
// Calculate own hop count. This method gets inaccurate when hop count increases.
992+
uint8_t own_hop = (own_rank - rank_inc) / rank_inc;
993+
ns_fhss_ws_set_hop_count(cur->ws_info->fhss_api, own_hop);
994+
}
995+
996+
979997
static void ws_bootstrap_rpl_callback(rpl_event_t event, void *handle)
980998
{
981999

@@ -987,6 +1005,8 @@ static void ws_bootstrap_rpl_callback(rpl_event_t event, void *handle)
9871005
if (event == RPL_EVENT_DAO_DONE) {
9881006
// Trigger statemachine check
9891007
cur->bootsrap_state_machine_cnt = 1;
1008+
ws_set_fhss_hop(cur);
1009+
9901010
} else if(event == RPL_EVENT_LOCAL_REPAIR_NO_MORE_DIS) {
9911011
/*
9921012
* RPL goes to passive mode, but does not require any extra changed
@@ -1168,22 +1188,40 @@ static void ws_bootstrap_pan_config_solicit(protocol_interface_info_entry_t *cur
11681188

11691189
ws_llc_asynch_request(cur, &async_req);
11701190
}
1171-
static uint16_t ws_bootstrap_route_cost_calculate(protocol_interface_info_entry_t *cur)
1172-
{
1173-
// Find selected parent from RPL
11741191

1175-
struct rpl_instance *best_instance = NULL;
1176-
if (!cur->rpl_domain) {
1177-
return 0xffff;
1192+
static struct rpl_instance *ws_get_rpl_instance(protocol_interface_info_entry_t *cur)
1193+
{
1194+
if (!cur || !cur->rpl_domain) {
1195+
return NULL;
11781196
}
1197+
struct rpl_instance *best_instance = NULL;
11791198
ns_list_foreach(struct rpl_instance, instance, &cur->rpl_domain->instances) {
11801199
best_instance = instance;
11811200
// Select best grounded and lowest rank? But there should be only one really
11821201
}
1183-
if (!best_instance) {
1202+
return best_instance;
1203+
}
1204+
1205+
static uint16_t ws_bootstrap_route_cost_calculate(protocol_interface_info_entry_t *cur)
1206+
{
1207+
struct rpl_instance *rpl_instance = ws_get_rpl_instance(cur);
1208+
if (!rpl_instance) {
1209+
return 0xffff;
1210+
}
1211+
return rpl_control_current_rank(rpl_instance);
1212+
}
1213+
1214+
static uint16_t ws_bootstrap_get_min_rank_inc(protocol_interface_info_entry_t *cur)
1215+
{
1216+
struct rpl_instance *rpl_instance = ws_get_rpl_instance(cur);
1217+
if (!rpl_instance) {
1218+
return 0xffff;
1219+
}
1220+
struct rpl_dodag_info_t dodag_info;
1221+
if (!rpl_control_read_dodag_info(rpl_instance, &dodag_info)) {
11841222
return 0xffff;
11851223
}
1186-
return rpl_control_current_rank(best_instance);
1224+
return dodag_info.dag_min_hop_rank_inc;
11871225
}
11881226

11891227
static void ws_bootstrap_pan_advert(protocol_interface_info_entry_t *cur)

source/Service_Libs/fhss/fhss.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ fhss_structure_t *fhss_enable(fhss_api_t *fhss_api, const fhss_configuration_t *
7979
fhss_struct->bs->fhss_configuration.fhss_max_synch_interval = 240;
8080
}
8181
ns_list_init(&fhss_struct->fhss_failed_tx_list);
82-
fhss_struct->bs->own_hop = 0xff;
82+
fhss_struct->own_hop = 0xff;
8383
fhss_reset(fhss_struct);
8484

8585
if (fhss_beacon_create_tasklet(fhss_struct) < 0) {
@@ -93,7 +93,7 @@ fhss_structure_t *fhss_enable(fhss_api_t *fhss_api, const fhss_configuration_t *
9393

9494
bool fhss_is_synch_root(fhss_structure_t *fhss_structure)
9595
{
96-
if (fhss_structure->bs->own_hop > 0) {
96+
if (fhss_structure->own_hop > 0) {
9797
return false;
9898
}
9999
return true;
@@ -241,7 +241,7 @@ static int fhss_update_txrx_slots(fhss_structure_t *fhss_structure)
241241
*
242242
*/
243243

244-
if ((fhss_structure->bs->own_hop % 2)) {
244+
if ((fhss_structure->own_hop % 2)) {
245245
tx_slot_up_limit += tx_slot_length;
246246
}
247247
while(number_of_tx_slots--)
@@ -367,12 +367,12 @@ static int fhss_sync_with_beacon(fhss_structure_t *fhss_structure,
367367
configuration->fhss_number_of_superframes = payload->number_of_superframes_per_channel;
368368
// todo:
369369
// * payload->time_since_last_beacon
370-
uint8_t own_hop_tmp = fhss_structure->bs->own_hop;
370+
uint8_t own_hop_tmp = fhss_structure->own_hop;
371371
if (fhss_is_synch_root(fhss_structure) == false) {
372372
// my own hop count is one more than the parent's
373-
fhss_structure->bs->own_hop = payload->hop_count + 1;
373+
fhss_structure->own_hop = payload->hop_count + 1;
374374
}
375-
fhss_stats_update(fhss_structure, STATS_FHSS_HOP_COUNT, fhss_structure->bs->own_hop);
375+
fhss_stats_update(fhss_structure, STATS_FHSS_HOP_COUNT, fhss_structure->own_hop);
376376
fhss_structure->bs->channel_list_counter = payload->channel_list_counter;
377377
fhss_structure->bs->current_channel_index = payload->channel_index;
378378
uint8_t mac_address[8];
@@ -427,7 +427,7 @@ static int fhss_sync_with_beacon(fhss_structure_t *fhss_structure,
427427
fhss_beacon_periodic_start(fhss_structure, fhss_structure->bs->synch_interval + beacon_interval_random);
428428
}
429429
// Our hop has changed, needs to inform possible children by sending Beacon
430-
if ((own_hop_tmp != 0) && (own_hop_tmp != fhss_structure->bs->own_hop)) {
430+
if ((own_hop_tmp != 0) && (own_hop_tmp != fhss_structure->own_hop)) {
431431
fhss_structure->bs->send_synch_info_on_next_broadcast_channel = true;
432432
}
433433
ret_val = 0;
@@ -458,7 +458,7 @@ static uint32_t fhss_get_remaining_tx_time(fhss_structure_t *fhss_structure)
458458
uint8_t tx_slot_up_limit = tx_slot_length;
459459
uint16_t superframe_length = fhss_structure->bs->synch_configuration.fhss_superframe_length;
460460

461-
if ((fhss_structure->bs->own_hop % 2)) {
461+
if ((fhss_structure->own_hop % 2)) {
462462
tx_slot_up_limit += tx_slot_length;
463463
}
464464
while(number_of_tx_slots--)
@@ -645,7 +645,7 @@ static int fhss_reset(fhss_structure_t *fhss_structure)
645645
fhss_structure->bs->current_channel_index = 0;
646646
fhss_structure->bs->channel_list_counter = 0;
647647
if (fhss_is_synch_root(fhss_structure) == false) {
648-
fhss_structure->bs->own_hop = 0xff;
648+
fhss_structure->own_hop = 0xff;
649649
}
650650
fhss_structure->bs->tx_allowed = false;
651651
fhss_structure->bs->synch_interval = (uint32_t) (fhss_structure->bs->fhss_configuration.fhss_max_synch_interval/BEACON_INTERVAL_INIT_DIVIDER) * 1000;
@@ -1031,7 +1031,7 @@ static void fhss_update_channel_callback(fhss_structure_t *fhss_structure)
10311031
// If channel is broadcast channel (true), send event
10321032
if (fhss_change_to_next_channel(fhss_structure) == true) {
10331033
// Only if device is border router
1034-
if (fhss_structure->bs->own_hop == 0) {
1034+
if (fhss_structure->own_hop == 0) {
10351035
fhss_trig_event(fhss_structure, FHSS_BROADCAST_CHANNEL);
10361036
}
10371037
}
@@ -1068,7 +1068,7 @@ static void fhss_beacon_build(fhss_structure_t *fhss_structure, uint8_t* dest)
10681068
// should be the case as the superframe length field is also in that range.
10691069
temp_payload.remaining_slots = (uint16_t) fhss_get_remaining_time_to_next_superframe(fhss_structure);
10701070
temp_payload.channel_list_counter = fhss_structure->bs->channel_list_counter;
1071-
temp_payload.hop_count = fhss_structure->bs->own_hop;
1071+
temp_payload.hop_count = fhss_structure->own_hop;
10721072
temp_payload.number_of_broadcast_channels = config->fhss_number_of_bc_channels;
10731073
temp_payload.number_of_tx_slots = config->fhss_number_of_tx_slots;
10741074
temp_payload.time_since_last_beacon = 0; // XXX not available yet
@@ -1303,7 +1303,7 @@ int8_t fhss_set_synch_configuration(fhss_structure_t *fhss_structure, const fhss
13031303
return -4;
13041304
}
13051305
fhss_structure->bs->synch_configuration = *fhss_synch_configuration;
1306-
fhss_structure->bs->own_hop = 0;
1306+
fhss_structure->own_hop = 0;
13071307
return 0;
13081308
}
13091309

source/Service_Libs/fhss/fhss.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ struct fhss_bs
9292
uint8_t uc_channel_index;
9393
uint8_t current_superframe;
9494
uint8_t current_channel_index;
95-
uint8_t own_hop;
9695
uint8_t beacons_received_timer;
9796
uint8_t broadcast_start_superframe;
9897
uint8_t synch_infos_sent_counter;

source/Service_Libs/fhss/fhss_common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ typedef NS_LIST_HEAD(fhss_failed_tx_t, link) fhss_failed_tx_list_t;
3535

3636
struct fhss_structure
3737
{
38+
uint8_t own_hop;
3839
uint8_t fhss_resolution_divider;
3940
uint8_t rx_channel;
4041
int8_t beacon_tasklet_id;

source/Service_Libs/fhss/fhss_configuration_interface.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,12 @@ int ns_fhss_ws_configuration_set(const fhss_api_t *fhss_api, const fhss_ws_confi
129129
}
130130
return fhss_ws_configuration_set(fhss_structure, fhss_configuration);
131131
}
132+
133+
int ns_fhss_ws_set_hop_count(const fhss_api_t *fhss_api, const uint8_t hop_count)
134+
{
135+
fhss_structure_t *fhss_structure = fhss_get_object_with_api(fhss_api);
136+
if (!fhss_structure || !fhss_structure->ws) {
137+
return -1;
138+
}
139+
return fhss_ws_set_hop_count(fhss_structure, hop_count);
140+
}

source/Service_Libs/fhss/fhss_ws.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ fhss_structure_t *fhss_ws_enable(fhss_api_t *fhss_api, const fhss_ws_configurati
7676

7777
fhss_struct->ws->fhss_configuration = *fhss_configuration;
7878
fhss_struct->number_of_channels = channel_count;
79+
fhss_struct->own_hop = 0xff;
7980
ns_list_init(&fhss_struct->fhss_failed_tx_list);
8081
return fhss_struct;
8182
}
@@ -306,6 +307,33 @@ static bool fhss_check_bad_channel(fhss_structure_t *fhss_structure, uint8_t han
306307
return true;
307308
}
308309

310+
static bool fhss_ws_check_tx_allowed(fhss_structure_t *fhss_structure)
311+
{
312+
// Ignore TX/RX slots
313+
if (fhss_structure->own_hop == 0xff) {
314+
return true;
315+
}
316+
// Currently on broadcast channel
317+
if (fhss_structure->ws->is_on_bc_channel == true) {
318+
return true;
319+
}
320+
uint32_t slot_len_ms = (fhss_structure->ws->fhss_configuration.fhss_broadcast_interval - fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) / (WS_NUMBER_OF_TX_SLOTS * 2);
321+
uint32_t remaining_time_ms = fhss_structure->platform_functions.fhss_get_remaining_slots(fhss_broadcast_handler, fhss_structure->fhss_api) / 1000;
322+
uint32_t tx_slot_begin = (fhss_structure->ws->fhss_configuration.fhss_broadcast_interval - fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) - (slot_len_ms * (fhss_structure->own_hop & 1));
323+
uint32_t rx_slot_begin = tx_slot_begin - slot_len_ms;
324+
uint8_t n_o_tx_slots = WS_NUMBER_OF_TX_SLOTS;
325+
326+
while (n_o_tx_slots--) {
327+
if ((remaining_time_ms <= tx_slot_begin) && (remaining_time_ms > rx_slot_begin)) {
328+
return true;
329+
}
330+
tx_slot_begin -= (2*slot_len_ms);
331+
rx_slot_begin = tx_slot_begin - slot_len_ms;
332+
}
333+
334+
return false;
335+
}
336+
309337
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)
310338
{
311339
(void) handle;
@@ -332,6 +360,10 @@ static bool fhss_ws_check_tx_conditions_callback(const fhss_api_t *api, bool is_
332360
if (!is_broadcast_addr && (fhss_structure->ws->is_on_bc_channel == true)) {
333361
return false;
334362
}
363+
// Check TX/RX slot for unicast frames
364+
if (!is_broadcast_addr && !fhss_ws_check_tx_allowed(fhss_structure)) {
365+
return false;
366+
}
335367
return true;
336368
}
337369

@@ -573,3 +605,9 @@ int fhss_ws_configuration_set(fhss_structure_t *fhss_structure, const fhss_ws_co
573605
fhss_structure->number_of_channels = channel_count;
574606
return 0;
575607
}
608+
609+
int fhss_ws_set_hop_count(fhss_structure_t *fhss_structure, const uint8_t hop_count)
610+
{
611+
fhss_structure->own_hop = hop_count;
612+
return 0;
613+
}

source/Service_Libs/fhss/fhss_ws.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
* At least 4 channel retries must be used: (Initial channel + WS_NUMBER_OF_CHANNEL_RETRIES) * MAC attempts = (1+4)*4=20 attempts
2222
*/
2323
#define WS_NUMBER_OF_CHANNEL_RETRIES 4
24+
//TODO: Make this configurable
25+
#define WS_NUMBER_OF_TX_SLOTS 2
2426
typedef struct fhss_ws fhss_ws_t;
2527

2628
struct fhss_ws
@@ -39,5 +41,6 @@ int fhss_ws_set_callbacks(fhss_structure_t *fhss_structure);
3941
int fhss_ws_set_parent(fhss_structure_t *fhss_structure, const uint8_t eui64[8], const broadcast_timing_info_t *bc_timing_info);
4042
int fhss_ws_remove_parent(fhss_structure_t *fhss_structure, const uint8_t eui64[8]);
4143
int fhss_ws_configuration_set(fhss_structure_t *fhss_structure, const fhss_ws_configuration_t *fhss_configuration);
44+
int fhss_ws_set_hop_count(fhss_structure_t *fhss_structure, const uint8_t hop_count);
4245

4346
#endif /*FHSS_WS_H_*/

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ static void test_set_fhss_default_configs(void)
118118
FHSS.rx_channel = DEFAULT_CHANNEL;
119119
FHSS.fhss_state = FHSS_UNSYNCHRONIZED;
120120
FHSS.datarate = 250000;
121-
FHSS.bs->own_hop = 2;
121+
FHSS.own_hop = 2;
122122
}
123123

124124
static fhss_api_t *test_generate_fhss_api(void)
@@ -454,15 +454,15 @@ bool test_fhss_synch_state_set_callback()
454454
// Test when device is synch root
455455
FHSS.fhss_state = FHSS_UNSYNCHRONIZED;
456456
FHSS.bs->synch_panid = 0xffff;
457-
FHSS.bs->own_hop = 0;
457+
FHSS.own_hop = 0;
458458
FHSS.fhss_api->synch_state_set(api, DEFAULT_FHSS_STATE, DEFAULT_PANID);
459459
if (FHSS.fhss_state != DEFAULT_FHSS_STATE) {
460460
return false;
461461
}
462462
// Test when synch info not found
463463
FHSS.fhss_state = FHSS_UNSYNCHRONIZED;
464464
FHSS.bs->synch_panid = 0xffff;
465-
FHSS.bs->own_hop = 1;
465+
FHSS.own_hop = 1;
466466
FHSS.fhss_api->synch_state_set(api, DEFAULT_FHSS_STATE, DEFAULT_PANID);
467467
if (FHSS.fhss_state != FHSS_UNSYNCHRONIZED) {
468468
return false;
@@ -524,7 +524,7 @@ bool test_fhss_superframe_handler()
524524
fhss_api_t *api = test_generate_fhss_api();
525525
// Set superframe handler callback
526526
enable_fhss_struct();
527-
FHSS.bs->own_hop = 0;
527+
FHSS.own_hop = 0;
528528
FHSS.fhss_api->synch_state_set(api, DEFAULT_FHSS_STATE, DEFAULT_PANID);
529529

530530
// Test when FHSS struct not found
@@ -533,7 +533,7 @@ bool test_fhss_superframe_handler()
533533

534534
// Test updating channel for node
535535
enable_fhss_struct();
536-
FHSS.bs->own_hop = 1;
536+
FHSS.own_hop = 1;
537537
FHSS.bs->synch_infos_sent_counter = 1;
538538
FHSS.bs->current_superframe = FHSS.bs->synch_configuration.fhss_number_of_superframes - 1;
539539
FHSS.bs->current_channel_index = FHSS.number_of_channels - 1;
@@ -544,7 +544,7 @@ bool test_fhss_superframe_handler()
544544
}
545545

546546
// Test updating channel for synch root
547-
FHSS.bs->own_hop = 0;
547+
FHSS.own_hop = 0;
548548
FHSS.bs->tx_allowed = false;
549549
fhss_channel_stub.channel_bool_value = true;
550550
FHSS.bs->synch_infos_sent_counter = 1;
@@ -560,7 +560,7 @@ bool test_fhss_superframe_handler()
560560
fhss_channel_stub.channel_bool_value = true;
561561
fhss_callbacks_stub.uint8_value = 1;
562562
FHSS.bs->send_synch_info_on_next_broadcast_channel = true;
563-
FHSS.bs->own_hop = 1;
563+
FHSS.own_hop = 1;
564564
FHSS.bs->tx_allowed = false;
565565
FHSS.bs->synch_infos_sent_counter = 0;
566566
FHSS.bs->current_superframe = FHSS.bs->synch_configuration.fhss_number_of_superframes - 2;
@@ -689,13 +689,13 @@ bool test_fhss_set_synch_configuration()
689689
return false;
690690
}
691691
// Test success
692-
FHSS.bs->own_hop = 0xff;
692+
FHSS.own_hop = 0xff;
693693
FHSS.number_of_channels = 25;
694694
fhss_synch_configuration.fhss_number_of_bc_channels = 5;
695695
fhss_synch_configuration.fhss_number_of_superframes = 4;
696696
fhss_synch_configuration.fhss_number_of_tx_slots = 1;
697697
fhss_synch_configuration.fhss_superframe_length = 25000;
698-
if ((fhss_set_synch_configuration(&FHSS, &fhss_synch_configuration) != 0) || memcmp(&fhss_synch_configuration, &FHSS.bs->synch_configuration, sizeof(fhss_synch_configuration_t)) || FHSS.bs->own_hop) {
698+
if ((fhss_set_synch_configuration(&FHSS, &fhss_synch_configuration) != 0) || memcmp(&fhss_synch_configuration, &FHSS.bs->synch_configuration, sizeof(fhss_synch_configuration_t)) || FHSS.own_hop) {
699699
return false;
700700
}
701701

0 commit comments

Comments
 (0)