@@ -175,41 +175,92 @@ static fhss_ws_neighbor_timing_info_t *ws_get_neighbor_info(const fhss_api_t *ap
175
175
}
176
176
return & ws_neighbor -> fhss_data ;
177
177
}
178
+ static void ws_bootstrap_llc_hopping_update (struct protocol_interface_info_entry * cur , const fhss_ws_configuration_t * fhss_configuration )
179
+ {
180
+ memcpy (cur -> ws_info -> hopping_schdule .channel_mask , fhss_configuration -> channel_mask , sizeof (uint32_t ) * 8 );
181
+ cur -> ws_info -> hopping_schdule .channel_function = fhss_configuration -> ws_channel_function ;
182
+ cur -> ws_info -> hopping_schdule .fhss_bc_dwell_interval = fhss_configuration -> fhss_bc_dwell_interval ;
183
+ cur -> ws_info -> hopping_schdule .fhss_broadcast_interval = fhss_configuration -> fhss_broadcast_interval ;
184
+ cur -> ws_info -> hopping_schdule .fhss_uc_dwell_interval = fhss_configuration -> fhss_uc_dwell_interval ;
185
+ cur -> ws_info -> hopping_schdule .fhss_bsi = fhss_configuration -> bsi ;
186
+ }
178
187
179
- static int8_t ws_enable_fhss (protocol_interface_info_entry_t * cur )
188
+ static int8_t ws_fhss_initialize (protocol_interface_info_entry_t * cur )
180
189
{
181
190
fhss_api_t * fhss_api = ns_sw_mac_get_fhss_api (cur -> mac_api );
191
+
182
192
if (!fhss_api ) {
183
193
// When FHSS doesn't exist yet, create one
184
194
fhss_ws_configuration_t fhss_configuration ;
185
195
memset (& fhss_configuration , 0 , sizeof (fhss_ws_configuration_t ));
186
- fhss_configuration .bsi = cur -> ws_info -> hopping_schdule .fhss_bsi ;
187
- memcpy (fhss_configuration .channel_mask , cur -> ws_info -> hopping_schdule .channel_mask , sizeof (uint32_t ) * 8 );
188
- fhss_configuration .fhss_uc_dwell_interval = cur -> ws_info -> hopping_schdule .fhss_uc_dwell_interval ;
189
- fhss_configuration .ws_channel_function = cur -> ws_info -> hopping_schdule .channel_function ;
190
- if (cur -> bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER ) {
191
- fhss_configuration .fhss_bc_dwell_interval = cur -> ws_info -> hopping_schdule .fhss_bc_dwell_interval ;
192
- fhss_configuration .fhss_broadcast_interval = cur -> ws_info -> hopping_schdule .fhss_broadcast_interval ;
193
- fhss_configuration .bsi = cur -> ws_info -> hopping_schdule .fhss_bsi ;
196
+ ws_generate_channel_list (fhss_configuration .channel_mask , cur -> ws_info -> hopping_schdule .number_of_channels , cur -> ws_info -> hopping_schdule .regulatory_domain );
197
+
198
+ // using bitwise AND operation for user set channel mask to remove channels not allowed in this device
199
+ for (uint8_t n = 0 ;n < 8 ;n ++ ) {
200
+ fhss_configuration .channel_mask [n ] &= cur -> ws_info -> fhss_channel_mask [n ];
194
201
}
202
+
203
+ fhss_configuration .fhss_uc_dwell_interval = cur -> ws_info -> fhss_uc_dwell_interval ;
204
+ fhss_configuration .ws_channel_function = cur -> ws_info -> fhss_channel_function ;
205
+ fhss_configuration .fhss_bc_dwell_interval = cur -> ws_info -> fhss_bc_dwell_interval ;
206
+ fhss_configuration .fhss_broadcast_interval = cur -> ws_info -> fhss_bc_interval ;
207
+
195
208
fhss_api = ns_fhss_ws_create (& fhss_configuration , cur -> ws_info -> fhss_timer_ptr );
196
209
if (!fhss_api ) {
210
+ tr_error ("fhss create failed" );
197
211
return -1 ;
198
212
}
199
213
ns_sw_mac_fhss_register (cur -> mac_api , fhss_api );
200
214
} else {
201
- // Read configuration of existing FHSS
215
+ // Read defaults from the configuration to help FHSS testing
202
216
const fhss_ws_configuration_t * fhss_configuration = ns_fhss_ws_configuration_get (fhss_api );
203
217
if (!fhss_configuration ) {
204
- return -1 ;
218
+ // no configuration set yet
219
+ return 0 ;
205
220
}
206
- memcpy (cur -> ws_info -> hopping_schdule .channel_mask , fhss_configuration -> channel_mask , sizeof (uint32_t ) * 8 );
207
- cur -> ws_info -> hopping_schdule .channel_function = fhss_configuration -> ws_channel_function ;
208
- cur -> ws_info -> hopping_schdule .fhss_bc_dwell_interval = fhss_configuration -> fhss_bc_dwell_interval ;
209
- cur -> ws_info -> hopping_schdule .fhss_broadcast_interval = fhss_configuration -> fhss_broadcast_interval ;
210
- cur -> ws_info -> hopping_schdule .fhss_uc_dwell_interval = fhss_configuration -> fhss_uc_dwell_interval ;
211
- cur -> ws_info -> hopping_schdule .fhss_bsi = fhss_configuration -> bsi ;
221
+ memcpy (cur -> ws_info -> fhss_channel_mask , fhss_configuration -> channel_mask , sizeof (uint32_t ) * 8 );
222
+ cur -> ws_info -> fhss_channel_function = fhss_configuration -> ws_channel_function ;
223
+ cur -> ws_info -> fhss_bc_dwell_interval = fhss_configuration -> fhss_bc_dwell_interval ;
224
+ cur -> ws_info -> fhss_bc_interval = fhss_configuration -> fhss_broadcast_interval ;
225
+ cur -> ws_info -> fhss_uc_dwell_interval = fhss_configuration -> fhss_uc_dwell_interval ;
226
+ }
227
+ return 0 ;
228
+ }
229
+ static int8_t ws_fhss_set_defaults (protocol_interface_info_entry_t * cur )
230
+ {
231
+ // Read configuration of existing FHSS and start using the default values for any network
232
+ fhss_ws_configuration_t fhss_configuration = {0 };
233
+ if (ns_fhss_ws_configuration_get (cur -> ws_info -> fhss_api )) {
234
+ memcpy (& fhss_configuration , ns_fhss_ws_configuration_get (cur -> ws_info -> fhss_api ), sizeof (fhss_ws_configuration_t ));
235
+ }
236
+
237
+ fhss_configuration .fhss_uc_dwell_interval = cur -> ws_info -> fhss_uc_dwell_interval ;
238
+ fhss_configuration .ws_channel_function = cur -> ws_info -> fhss_channel_function ;
239
+ fhss_configuration .fhss_bc_dwell_interval = cur -> ws_info -> fhss_bc_dwell_interval ;
240
+ fhss_configuration .fhss_broadcast_interval = cur -> ws_info -> fhss_bc_interval ;
241
+ ws_generate_channel_list (fhss_configuration .channel_mask , cur -> ws_info -> hopping_schdule .number_of_channels , cur -> ws_info -> hopping_schdule .regulatory_domain );
242
+
243
+ // using bitwise AND operation for user set channel mask to remove channels not allowed in this device
244
+ for (uint8_t n = 0 ;n < 8 ;n ++ ) {
245
+ fhss_configuration .channel_mask [n ] &= cur -> ws_info -> fhss_channel_mask [n ];
246
+ }
247
+
248
+ ns_fhss_ws_configuration_set (cur -> ws_info -> fhss_api ,& fhss_configuration );
249
+
250
+ return 0 ;
251
+ }
252
+
253
+ static int8_t ws_fhss_enable (protocol_interface_info_entry_t * cur )
254
+ {
255
+ fhss_api_t * fhss_api = ns_sw_mac_get_fhss_api (cur -> mac_api );
256
+ const fhss_ws_configuration_t * fhss_configuration = ns_fhss_ws_configuration_get (fhss_api );
257
+
258
+ if (!fhss_api || !fhss_configuration ) {
259
+ return -1 ;
212
260
}
261
+ // Set the LLC information to follow the actual fhss settings
262
+ ws_bootstrap_llc_hopping_update (cur ,fhss_configuration );
263
+
213
264
// Set neighbor info callback
214
265
if (ns_fhss_set_neighbor_info_fp (fhss_api , & ws_get_neighbor_info )) {
215
266
return -1 ;
@@ -220,6 +271,45 @@ static int8_t ws_enable_fhss(protocol_interface_info_entry_t *cur)
220
271
cur -> ws_info -> fhss_api = fhss_api ;
221
272
return 0 ;
222
273
}
274
+
275
+ /* Sets the parent and broadcast schedule we are following
276
+ *
277
+ */
278
+ static void ws_bootstrap_primary_parent_set (struct protocol_interface_info_entry * cur , llc_neighbour_req_t * neighbor_info )
279
+ {
280
+
281
+ fhss_ws_configuration_t fhss_configuration ;
282
+ memcpy (& fhss_configuration , ns_fhss_ws_configuration_get (cur -> ws_info -> fhss_api ), sizeof (fhss_ws_configuration_t ));
283
+
284
+ // unicast information is only followed from parent if fixed channel is selected
285
+ if (neighbor_info -> ws_neighbor -> fhss_data .uc_timing_info .unicast_channel_function == WS_FIXED_CHANNEL ) {
286
+ cur -> ws_info -> hopping_schdule .fixed_channel = neighbor_info -> ws_neighbor -> fhss_data .uc_timing_info .fixed_channel ;
287
+ fhss_configuration .ws_channel_function = WS_FIXED_CHANNEL ;
288
+ tr_info ("attaching to fixed channel network following configurtion" );
289
+ } else if (fhss_configuration .ws_channel_function == WS_FIXED_CHANNEL ) {
290
+ // fixed channel cannot be mixed with other channel functions as it messes the broadcast schedule
291
+ fhss_configuration .ws_channel_function = WS_DH1CF ;
292
+ tr_info ("attaching channel hopping network changing to hopping" );
293
+ }
294
+ // Learn broadcast information from selected parent
295
+ fhss_configuration .bsi = neighbor_info -> ws_neighbor -> fhss_data .bc_timing_info .broadcast_schedule_id ;
296
+ fhss_configuration .fhss_bc_dwell_interval = neighbor_info -> ws_neighbor -> fhss_data .bc_timing_info .broadcast_dwell_interval ;
297
+ fhss_configuration .fhss_broadcast_interval = neighbor_info -> ws_neighbor -> fhss_data .bc_timing_info .broadcast_interval ;
298
+ ns_fhss_ws_configuration_set (cur -> ws_info -> fhss_api , & fhss_configuration );
299
+
300
+ if (fhss_configuration .fhss_bc_dwell_interval && fhss_configuration .fhss_broadcast_interval ) {
301
+ // We have broadcast schedule set up set the broadcast parent schedule
302
+ ns_fhss_ws_set_parent (cur -> ws_info -> fhss_api , neighbor_info -> neighbor -> mac64 , & neighbor_info -> ws_neighbor -> fhss_data .bc_timing_info );
303
+ }
304
+
305
+ // Update LLC to follow updated fhss settings
306
+ ws_bootstrap_llc_hopping_update (cur ,& fhss_configuration );
307
+
308
+ // set neighbor as priority parent clear if there is others
309
+ protocol_6lowpan_neighbor_priority_clear_all (cur -> id , PRIORITY_1ST );
310
+ neighbor_info -> neighbor -> link_role = PRIORITY_PARENT_NEIGHBOUR ;
311
+
312
+ }
223
313
/* \return 0x0100 to 0xFFFF ETX value (8 bit fraction)
224
314
* \return 0xFFFF address not associated
225
315
* \return 0x0000 address unknown or other error
@@ -271,8 +361,12 @@ static int8_t ws_bootstrap_up(protocol_interface_info_entry_t *cur)
271
361
}
272
362
273
363
if ((cur -> configure_flags & INTERFACE_SETUP_MASK ) != INTERFACE_SETUP_READY ) {
274
- tr_debug ("Interface not yet fully configured" );
275
- return -5 ;
364
+ tr_error ("Interface not yet fully configured" );
365
+ return -2 ;
366
+ }
367
+ if (ws_fhss_initialize (cur ) != 0 ) {
368
+ tr_error ("fhss initialization failed" );
369
+ return -3 ;
276
370
}
277
371
278
372
addr_interface_set_ll64 (cur , NULL );
@@ -602,8 +696,6 @@ static void ws_bootstrap_pan_config_analyse(struct protocol_interface_info_entry
602
696
}
603
697
trickle_consistent_heard (& cur -> ws_info -> trickle_pan_config );
604
698
605
- // TODO update and learn new neighbour
606
-
607
699
if (cur -> bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER ) {
608
700
//Border router does not learn network information
609
701
return ;
@@ -623,31 +715,21 @@ static void ws_bootstrap_pan_config_analyse(struct protocol_interface_info_entry
623
715
cur -> ws_info -> pan_information .pan_version = pan_version ;
624
716
memcpy (cur -> ws_info -> gtkhash ,gtkhash_ptr ,32 );
625
717
626
- //Broadcast schedule
627
- cur -> ws_info -> hopping_schdule .fhss_broadcast_interval = ws_bs_ie .broadcast_interval ;
628
- cur -> ws_info -> hopping_schdule .fhss_bsi = ws_bs_ie .broadcast_schedule_identifier ;
629
- cur -> ws_info -> hopping_schdule .fhss_bc_dwell_interval = ws_bs_ie .dwell_interval ;
630
-
631
- cur -> ws_info -> hopping_schdule .channel_function = ws_bs_ie .channel_function ;
632
- cur -> ws_info -> hopping_schdule .fhss_uc_dwell_interval = ws_us -> dwell_interval ;
633
-
634
- fhss_ws_configuration_t fhss_configuration ;
635
- memcpy (& fhss_configuration , ns_fhss_ws_configuration_get (cur -> ws_info -> fhss_api ), sizeof (fhss_ws_configuration_t ));
636
- fhss_configuration .fhss_uc_dwell_interval = neighbor_info .ws_neighbor -> fhss_data .uc_timing_info .unicast_dwell_interval ;
637
- fhss_configuration .ws_channel_function = neighbor_info .ws_neighbor -> fhss_data .uc_timing_info .unicast_channel_function ;
638
- fhss_configuration .bsi = neighbor_info .ws_neighbor -> fhss_data .bc_timing_info .broadcast_schedule_id ;
639
- ns_fhss_ws_configuration_set (cur -> ws_info -> fhss_api , & fhss_configuration );
640
-
641
- ns_fhss_ws_set_parent (cur -> ws_info -> fhss_api , data -> SrcAddr , & neighbor_info .ws_neighbor -> fhss_data .bc_timing_info );
718
+ if (neighbor_info .neighbor -> link_role == PRIORITY_PARENT_NEIGHBOUR ) {
719
+ // RPL priority parent configuration we must update FHSS data
720
+ ws_bootstrap_primary_parent_set (cur , & neighbor_info );
721
+ }
642
722
643
723
if (!cur -> ws_info -> configuration_learned ) {
644
724
// Generate own hopping schedules Follow first parent broadcast and plans and also use same unicast dwell
645
725
cur -> ws_info -> configuration_learned = true;
646
726
// return to state machine after 1-2 s
647
727
cur -> bootsrap_state_machine_cnt = randLIB_get_random_in_range (10 ,20 );
728
+ ws_bootstrap_primary_parent_set (cur , & neighbor_info );
648
729
}
649
730
650
731
}
732
+
651
733
static void ws_bootstrap_pan_config_solicit_analyse (struct protocol_interface_info_entry * cur , const struct mcps_data_ind_s * data , ws_utt_ie_t * ws_utt , ws_us_ie_t * ws_us )
652
734
{
653
735
if (data -> SrcPANId != cur -> ws_info -> network_pan_id ) {
@@ -981,7 +1063,7 @@ static void ws_bootstrap_mac_activate(protocol_interface_info_entry_t *cur, uint
981
1063
static void ws_bootstrap_fhss_activate (protocol_interface_info_entry_t * cur )
982
1064
{
983
1065
tr_debug ("FHSS activate" );
984
- ws_enable_fhss (cur );
1066
+ ws_fhss_enable (cur );
985
1067
ws_llc_hopping_schedule_config (cur , & cur -> ws_info -> hopping_schdule );
986
1068
// Only supporting fixed channel
987
1069
@@ -996,8 +1078,8 @@ static void ws_bootstrap_network_information_learn(protocol_interface_info_entry
996
1078
{
997
1079
tr_debug ("learn network information from parent" );
998
1080
999
- // Start following network timing schedules
1000
- cur -> ws_info -> hopping_schdule . fhss_uc_dwell_interval = cur -> ws_info -> parent_info . ws_us . dwell_interval ;
1081
+ // Start following network broadcast timing schedules
1082
+
1001
1083
// Regulatory domain saving? cant change?
1002
1084
1003
1085
// Save network information
@@ -1119,9 +1201,9 @@ static void ws_bootstrap_network_discovery_configure(protocol_interface_info_ent
1119
1201
ws_common_regulatory_domain_config (cur );
1120
1202
1121
1203
// Set default schedules for discovery
1122
- cur -> ws_info -> hopping_schdule .fhss_uc_dwell_interval = 250 ;
1123
- cur -> ws_info -> hopping_schdule .fhss_broadcast_interval = 800 ;
1124
- cur -> ws_info -> hopping_schdule .fhss_bc_dwell_interval = 200 ;
1204
+ cur -> ws_info -> hopping_schdule .fhss_uc_dwell_interval = WS_FHSS_UC_DWELL_INTERVAL ;
1205
+ cur -> ws_info -> hopping_schdule .fhss_broadcast_interval = WS_FHSS_BC_INTERVAL ;
1206
+ cur -> ws_info -> hopping_schdule .fhss_bc_dwell_interval = WS_FHSS_BC_DWELL_INTERVAL ;
1125
1207
// By default, uses fixed channel
1126
1208
cur -> ws_info -> hopping_schdule .channel_function = WS_FIXED_CHANNEL ;
1127
1209
cur -> ws_info -> hopping_schdule .fixed_channel = randLIB_get_random_in_range (11 ,25 );
@@ -1392,6 +1474,9 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
1392
1474
trickle_stop (& cur -> ws_info -> trickle_pan_advertisement );
1393
1475
trickle_stop (& cur -> ws_info -> trickle_pan_config );
1394
1476
1477
+ // Set default parameters for FHSS when starting a discovery
1478
+ ws_fhss_set_defaults (cur );
1479
+
1395
1480
if (cur -> bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER ) {
1396
1481
tr_debug ("Border router start network" );
1397
1482
cur -> ws_info -> network_pan_id = randLIB_get_random_in_range (0 ,0xfffd );
@@ -1482,11 +1567,7 @@ void ws_bootstrap_network_scan_process(protocol_interface_info_entry_t *cur)
1482
1567
return ;
1483
1568
}
1484
1569
1485
- ws_neighbor_class_neighbor_unicast_time_info_update (neighbor_info .ws_neighbor , & cur -> ws_info -> parent_info .ws_utt , cur -> ws_info -> parent_info .timestamp );
1486
- ws_neighbor_class_neighbor_unicast_schedule_set (neighbor_info .ws_neighbor , & cur -> ws_info -> parent_info .ws_us );
1487
- //SET parent
1488
- neighbor_info .neighbor -> link_role = PRIORITY_PARENT_NEIGHBOUR ;
1489
-
1570
+ ws_bootstrap_primary_parent_set (cur , & neighbor_info );
1490
1571
ws_bootstrap_network_information_learn (cur );
1491
1572
ws_bootstrap_fhss_activate (cur );
1492
1573
ws_bootstrap_event_authentication_start (cur );
0 commit comments