@@ -175,41 +175,92 @@ static fhss_ws_neighbor_timing_info_t *ws_get_neighbor_info(const fhss_api_t *ap
175175 }
176176 return & ws_neighbor -> fhss_data ;
177177}
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+ }
178187
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 )
180189{
181190 fhss_api_t * fhss_api = ns_sw_mac_get_fhss_api (cur -> mac_api );
191+
182192 if (!fhss_api ) {
183193 // When FHSS doesn't exist yet, create one
184194 fhss_ws_configuration_t fhss_configuration ;
185195 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 ];
194201 }
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+
195208 fhss_api = ns_fhss_ws_create (& fhss_configuration , cur -> ws_info -> fhss_timer_ptr );
196209 if (!fhss_api ) {
210+ tr_error ("fhss create failed" );
197211 return -1 ;
198212 }
199213 ns_sw_mac_fhss_register (cur -> mac_api , fhss_api );
200214 } else {
201- // Read configuration of existing FHSS
215+ // Read defaults from the configuration to help FHSS testing
202216 const fhss_ws_configuration_t * fhss_configuration = ns_fhss_ws_configuration_get (fhss_api );
203217 if (!fhss_configuration ) {
204- return -1 ;
218+ // no configuration set yet
219+ return 0 ;
205220 }
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 ;
212260 }
261+ // Set the LLC information to follow the actual fhss settings
262+ ws_bootstrap_llc_hopping_update (cur ,fhss_configuration );
263+
213264 // Set neighbor info callback
214265 if (ns_fhss_set_neighbor_info_fp (fhss_api , & ws_get_neighbor_info )) {
215266 return -1 ;
@@ -220,6 +271,45 @@ static int8_t ws_enable_fhss(protocol_interface_info_entry_t *cur)
220271 cur -> ws_info -> fhss_api = fhss_api ;
221272 return 0 ;
222273}
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+ }
223313/* \return 0x0100 to 0xFFFF ETX value (8 bit fraction)
224314 * \return 0xFFFF address not associated
225315 * \return 0x0000 address unknown or other error
@@ -271,8 +361,12 @@ static int8_t ws_bootstrap_up(protocol_interface_info_entry_t *cur)
271361 }
272362
273363 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 ;
276370 }
277371
278372 addr_interface_set_ll64 (cur , NULL );
@@ -602,8 +696,6 @@ static void ws_bootstrap_pan_config_analyse(struct protocol_interface_info_entry
602696 }
603697 trickle_consistent_heard (& cur -> ws_info -> trickle_pan_config );
604698
605- // TODO update and learn new neighbour
606-
607699 if (cur -> bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER ) {
608700 //Border router does not learn network information
609701 return ;
@@ -623,31 +715,21 @@ static void ws_bootstrap_pan_config_analyse(struct protocol_interface_info_entry
623715 cur -> ws_info -> pan_information .pan_version = pan_version ;
624716 memcpy (cur -> ws_info -> gtkhash ,gtkhash_ptr ,32 );
625717
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+ }
642722
643723 if (!cur -> ws_info -> configuration_learned ) {
644724 // Generate own hopping schedules Follow first parent broadcast and plans and also use same unicast dwell
645725 cur -> ws_info -> configuration_learned = true;
646726 // return to state machine after 1-2 s
647727 cur -> bootsrap_state_machine_cnt = randLIB_get_random_in_range (10 ,20 );
728+ ws_bootstrap_primary_parent_set (cur , & neighbor_info );
648729 }
649730
650731}
732+
651733static 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 )
652734{
653735 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
9811063static void ws_bootstrap_fhss_activate (protocol_interface_info_entry_t * cur )
9821064{
9831065 tr_debug ("FHSS activate" );
984- ws_enable_fhss (cur );
1066+ ws_fhss_enable (cur );
9851067 ws_llc_hopping_schedule_config (cur , & cur -> ws_info -> hopping_schdule );
9861068 // Only supporting fixed channel
9871069
@@ -996,8 +1078,8 @@ static void ws_bootstrap_network_information_learn(protocol_interface_info_entry
9961078{
9971079 tr_debug ("learn network information from parent" );
9981080
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+
10011083 // Regulatory domain saving? cant change?
10021084
10031085 // Save network information
@@ -1119,9 +1201,9 @@ static void ws_bootstrap_network_discovery_configure(protocol_interface_info_ent
11191201 ws_common_regulatory_domain_config (cur );
11201202
11211203 // 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 ;
11251207 // By default, uses fixed channel
11261208 cur -> ws_info -> hopping_schdule .channel_function = WS_FIXED_CHANNEL ;
11271209 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)
13921474 trickle_stop (& cur -> ws_info -> trickle_pan_advertisement );
13931475 trickle_stop (& cur -> ws_info -> trickle_pan_config );
13941476
1477+ // Set default parameters for FHSS when starting a discovery
1478+ ws_fhss_set_defaults (cur );
1479+
13951480 if (cur -> bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER ) {
13961481 tr_debug ("Border router start network" );
13971482 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)
14821567 return ;
14831568 }
14841569
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 );
14901571 ws_bootstrap_network_information_learn (cur );
14911572 ws_bootstrap_fhss_activate (cur );
14921573 ws_bootstrap_event_authentication_start (cur );
0 commit comments