@@ -417,7 +417,6 @@ static fhss_ws_neighbor_timing_info_t *ws_get_neighbor_info(const fhss_api_t *ap
417
417
}
418
418
static void ws_bootstrap_llc_hopping_update (struct protocol_interface_info_entry * cur , const fhss_ws_configuration_t * fhss_configuration )
419
419
{
420
- memcpy (cur -> ws_info -> hopping_schdule .channel_mask , fhss_configuration -> channel_mask , sizeof (uint32_t ) * 8 );
421
420
cur -> ws_info -> hopping_schdule .uc_fixed_channel = fhss_configuration -> unicast_fixed_channel ;
422
421
cur -> ws_info -> hopping_schdule .bc_fixed_channel = fhss_configuration -> broadcast_fixed_channel ;
423
422
// Read UC channel function from WS info because FHSS might be temporarily configured to fixed channel during discovery.
@@ -429,19 +428,80 @@ static void ws_bootstrap_llc_hopping_update(struct protocol_interface_info_entry
429
428
cur -> ws_info -> hopping_schdule .fhss_bsi = fhss_configuration -> bsi ;
430
429
}
431
430
431
+ static uint8_t ws_generate_exluded_channel_list_from_active_channels (ws_excluded_channel_data_t * excluded_data , const uint32_t * selected_channel_mask , uint16_t number_of_channels )
432
+ {
433
+ bool active_range = false;
434
+
435
+ //Clear Old Data
436
+ memset (excluded_data , 0 , sizeof (ws_excluded_channel_data_t ));
437
+
438
+ for (uint8_t i = 0 ; i < number_of_channels ; i ++ ) {
439
+ if (selected_channel_mask [0 + (i / 32 )] & (1 << (i % 32 ))) {
440
+ if (active_range ) {
441
+ //Mark range stop here
442
+ active_range = false;
443
+ }
444
+ } else {
445
+ //Mark excluded channel
446
+ //Swap Order already here
447
+ excluded_data -> channel_mask [0 + (i / 32 )] |= 1 << (31 - (i % 32 ));
448
+ excluded_data -> excluded_channel_count ++ ;
449
+
450
+ if (excluded_data -> excluded_range_length < WS_EXCLUDED_MAX_RANGE_TO_SEND ) {
451
+ if (!active_range ) {
452
+ excluded_data -> excluded_range_length ++ ;
453
+ active_range = true;
454
+ //Set start channel
455
+ excluded_data -> exluded_range [excluded_data -> excluded_range_length - 1 ].range_start = i ;
456
+ } else {
457
+ excluded_data -> exluded_range [excluded_data -> excluded_range_length - 1 ].range_end = i ;
458
+ }
459
+ }
460
+ }
461
+ }
462
+
463
+ excluded_data -> channel_mask_bytes_inline = ((number_of_channels + 7 ) / 8 );
464
+
465
+ uint8_t channel_plan = 0 ;
466
+ if (excluded_data -> excluded_range_length == 0 ) {
467
+ excluded_data -> excuded_channel_ctrl = WS_EXC_CHAN_CTRL_NONE ;
468
+ } else if (excluded_data -> excluded_range_length <= WS_EXCLUDED_MAX_RANGE_TO_SEND ) {
469
+
470
+ uint8_t range_length = (excluded_data -> excluded_range_length * 4 ) + 3 ;
471
+ if (range_length <= ((number_of_channels + 7 ) / 8 ) + 6 ) {
472
+ excluded_data -> excuded_channel_ctrl = WS_EXC_CHAN_CTRL_RANGE ;
473
+ } else {
474
+ excluded_data -> excuded_channel_ctrl = WS_EXC_CHAN_CTRL_BITMASK ;
475
+ channel_plan = 1 ;
476
+ }
477
+ } else {
478
+ excluded_data -> excuded_channel_ctrl = WS_EXC_CHAN_CTRL_BITMASK ;
479
+ channel_plan = 1 ;
480
+ }
481
+ tr_debug ("Excluded ctrl %u, exluded channel count %u, total domain channels %u" , excluded_data -> excuded_channel_ctrl , excluded_data -> excluded_channel_count , number_of_channels );
482
+ return channel_plan ;
483
+ }
484
+
485
+ static void ws_fhss_configure_channel_masks (protocol_interface_info_entry_t * cur , fhss_ws_configuration_t * fhss_configuration )
486
+ {
487
+ ws_generate_channel_list (fhss_configuration -> channel_mask , cur -> ws_info -> hopping_schdule .number_of_channels , cur -> ws_info -> hopping_schdule .regulatory_domain );
488
+ ws_generate_channel_list (fhss_configuration -> unicast_channel_mask , cur -> ws_info -> hopping_schdule .number_of_channels , cur -> ws_info -> hopping_schdule .regulatory_domain );
489
+ // using bitwise AND operation for user set channel mask to remove channels not allowed in this device
490
+ for (uint8_t n = 0 ; n < 8 ; n ++ ) {
491
+ fhss_configuration -> unicast_channel_mask [n ] &= cur -> ws_info -> cfg -> fhss .fhss_channel_mask [n ];
492
+ }
493
+ //Update Exluded channels
494
+ cur -> ws_info -> hopping_schdule .channel_plan = ws_generate_exluded_channel_list_from_active_channels (& cur -> ws_info -> hopping_schdule .excluded_channels , fhss_configuration -> unicast_channel_mask , cur -> ws_info -> hopping_schdule .number_of_channels );
495
+ }
496
+
432
497
static int8_t ws_fhss_initialize (protocol_interface_info_entry_t * cur )
433
498
{
434
499
fhss_api_t * fhss_api = ns_sw_mac_get_fhss_api (cur -> mac_api );
500
+ fhss_ws_configuration_t fhss_configuration ;
501
+ memset (& fhss_configuration , 0 , sizeof (fhss_ws_configuration_t ));
435
502
if (!fhss_api ) {
436
503
// When FHSS doesn't exist yet, create one
437
- fhss_ws_configuration_t fhss_configuration ;
438
- memset (& fhss_configuration , 0 , sizeof (fhss_ws_configuration_t ));
439
- ws_generate_channel_list (fhss_configuration .channel_mask , cur -> ws_info -> hopping_schdule .number_of_channels , cur -> ws_info -> hopping_schdule .regulatory_domain );
440
-
441
- // using bitwise AND operation for user set channel mask to remove channels not allowed in this device
442
- for (uint8_t n = 0 ; n < 8 ; n ++ ) {
443
- fhss_configuration .channel_mask [n ] &= cur -> ws_info -> cfg -> fhss .fhss_channel_mask [n ];
444
- }
504
+ ws_fhss_configure_channel_masks (cur , & fhss_configuration );
445
505
446
506
fhss_configuration .fhss_uc_dwell_interval = cur -> ws_info -> cfg -> fhss .fhss_uc_dwell_interval ;
447
507
fhss_configuration .ws_uc_channel_function = (fhss_ws_channel_functions )cur -> ws_info -> cfg -> fhss .fhss_uc_channel_function ;
@@ -456,22 +516,27 @@ static int8_t ws_fhss_initialize(protocol_interface_info_entry_t *cur)
456
516
ns_sw_mac_fhss_register (cur -> mac_api , fhss_api );
457
517
} else {
458
518
// Read defaults from the configuration to help FHSS testing
459
- const fhss_ws_configuration_t * fhss_configuration = ns_fhss_ws_configuration_get (fhss_api );
460
- if (!fhss_configuration ) {
519
+ const fhss_ws_configuration_t * fhss_configuration_copy = ns_fhss_ws_configuration_get (fhss_api );
520
+ if (!fhss_configuration_copy ) {
461
521
// no configuration set yet
462
522
return 0 ;
463
523
}
464
- memcpy (cur -> ws_info -> cfg -> fhss .fhss_channel_mask , fhss_configuration -> channel_mask , sizeof (uint32_t ) * 8 );
465
- cur -> ws_info -> cfg -> fhss .fhss_uc_channel_function = fhss_configuration -> ws_uc_channel_function ;
466
- cur -> ws_info -> cfg -> fhss .fhss_bc_channel_function = fhss_configuration -> ws_bc_channel_function ;
467
- cur -> ws_info -> cfg -> fhss .fhss_bc_dwell_interval = fhss_configuration -> fhss_bc_dwell_interval ;
468
- cur -> ws_info -> cfg -> fhss .fhss_bc_interval = fhss_configuration -> fhss_broadcast_interval ;
469
- cur -> ws_info -> cfg -> fhss .fhss_uc_dwell_interval = fhss_configuration -> fhss_uc_dwell_interval ;
470
- cur -> ws_info -> cfg -> fhss .fhss_bc_fixed_channel = fhss_configuration -> broadcast_fixed_channel ;
471
- cur -> ws_info -> cfg -> fhss .fhss_uc_fixed_channel = fhss_configuration -> unicast_fixed_channel ;
524
+ fhss_configuration = * fhss_configuration_copy ;
525
+ memcpy (cur -> ws_info -> cfg -> fhss .fhss_channel_mask , fhss_configuration_copy -> unicast_channel_mask , sizeof (uint32_t ) * 8 );
526
+ cur -> ws_info -> cfg -> fhss .fhss_uc_channel_function = fhss_configuration_copy -> ws_uc_channel_function ;
527
+ cur -> ws_info -> cfg -> fhss .fhss_bc_channel_function = fhss_configuration_copy -> ws_bc_channel_function ;
528
+ cur -> ws_info -> cfg -> fhss .fhss_bc_dwell_interval = fhss_configuration_copy -> fhss_bc_dwell_interval ;
529
+ cur -> ws_info -> cfg -> fhss .fhss_bc_interval = fhss_configuration_copy -> fhss_broadcast_interval ;
530
+ cur -> ws_info -> cfg -> fhss .fhss_uc_dwell_interval = fhss_configuration_copy -> fhss_uc_dwell_interval ;
531
+ cur -> ws_info -> cfg -> fhss .fhss_bc_fixed_channel = fhss_configuration_copy -> broadcast_fixed_channel ;
532
+ cur -> ws_info -> cfg -> fhss .fhss_uc_fixed_channel = fhss_configuration_copy -> unicast_fixed_channel ;
533
+ ws_fhss_configure_channel_masks (cur , & fhss_configuration );
534
+ ns_fhss_ws_configuration_set (fhss_api , & fhss_configuration );
472
535
}
536
+
473
537
return 0 ;
474
538
}
539
+
475
540
static int8_t ws_fhss_set_defaults (protocol_interface_info_entry_t * cur , fhss_ws_configuration_t * fhss_configuration )
476
541
{
477
542
fhss_configuration -> fhss_uc_dwell_interval = cur -> ws_info -> cfg -> fhss .fhss_uc_dwell_interval ;
@@ -483,12 +548,6 @@ static int8_t ws_fhss_set_defaults(protocol_interface_info_entry_t *cur, fhss_ws
483
548
fhss_configuration -> unicast_fixed_channel = cur -> ws_info -> cfg -> fhss .fhss_uc_fixed_channel ;
484
549
}
485
550
fhss_configuration -> broadcast_fixed_channel = cur -> ws_info -> cfg -> fhss .fhss_bc_fixed_channel ;
486
- ws_generate_channel_list (fhss_configuration -> channel_mask , cur -> ws_info -> hopping_schdule .number_of_channels , cur -> ws_info -> hopping_schdule .regulatory_domain );
487
-
488
- // using bitwise AND operation for user set channel mask to remove channels not allowed in this device
489
- for (uint8_t n = 0 ; n < 8 ; n ++ ) {
490
- fhss_configuration -> channel_mask [n ] &= cur -> ws_info -> cfg -> fhss .fhss_channel_mask [n ];
491
- }
492
551
return 0 ;
493
552
}
494
553
static int8_t ws_fhss_border_router_configure (protocol_interface_info_entry_t * cur )
@@ -501,6 +560,7 @@ static int8_t ws_fhss_border_router_configure(protocol_interface_info_entry_t *c
501
560
memcpy (& fhss_configuration , ns_fhss_ws_configuration_get (cur -> ws_info -> fhss_api ), sizeof (fhss_ws_configuration_t ));
502
561
}
503
562
ws_fhss_set_defaults (cur , & fhss_configuration );
563
+ ws_fhss_configure_channel_masks (cur , & fhss_configuration );
504
564
ns_fhss_ws_configuration_set (cur -> ws_info -> fhss_api , & fhss_configuration );
505
565
ws_bootstrap_llc_hopping_update (cur , & fhss_configuration );
506
566
@@ -525,6 +585,7 @@ static int8_t ws_fhss_configure(protocol_interface_info_entry_t *cur, bool disco
525
585
if (ns_fhss_ws_configuration_get (cur -> ws_info -> fhss_api )) {
526
586
memcpy (& fhss_configuration , ns_fhss_ws_configuration_get (cur -> ws_info -> fhss_api ), sizeof (fhss_ws_configuration_t ));
527
587
ws_fhss_set_defaults (cur , & fhss_configuration );
588
+ ws_fhss_configure_channel_masks (cur , & fhss_configuration );
528
589
}
529
590
// Discovery is done using fixed channel
530
591
if (discovery ) {
@@ -907,12 +968,54 @@ static parent_info_t *ws_bootstrap_candidate_parent_get_best(protocol_interface_
907
968
return ns_list_get_first (& cur -> ws_info -> parent_list_reserved );
908
969
}
909
970
971
+ static void ws_bootstrap_decode_exclude_range_to_mask_by_range (void * mask_buffer , ws_excluded_channel_range_t * range_info , uint16_t number_of_channels )
972
+ {
973
+ uint16_t range_start , range_stop ;
974
+ uint8_t mask_index = 0 ;
975
+ //uint8_t channel_index = 0;
976
+ uint8_t * range_ptr = range_info -> range_start ;
977
+ uint32_t * mask_ptr = mask_buffer ;
978
+ while (range_info -> number_of_range ) {
979
+ range_start = common_read_16_bit_inverse (range_ptr );
980
+ range_ptr += 2 ;
981
+ range_stop = common_read_16_bit_inverse (range_ptr );
982
+ range_ptr += 2 ;
983
+ range_info -> number_of_range -- ;
984
+ for (uint16_t channel = 0 ; channel < number_of_channels ; channel ++ ) {
985
+
986
+ if (channel && (channel % 32 == 0 )) {
987
+ mask_index ++ ;
988
+ //channel_index = 0;
989
+ }
990
+ if (channel >= range_start && channel <= range_stop ) {
991
+ //mask_ptr[mask_index] |= 1 << (31 - channel_index);
992
+ mask_ptr [0 + (channel / 32 )] |= 1 << (31 - (channel % 32 ));
993
+ } else if (channel > range_stop ) {
994
+ break ;
995
+ }
996
+ }
997
+ }
998
+ }
999
+
910
1000
static void ws_bootstrap_candidate_parent_store (parent_info_t * parent , const struct mcps_data_ind_s * data , ws_utt_ie_t * ws_utt , ws_us_ie_t * ws_us , ws_pan_information_t * pan_information )
911
1001
{
912
1002
parent -> ws_utt = * ws_utt ;
913
1003
// Saved from unicast IE
914
1004
parent -> ws_us = * ws_us ;
915
1005
1006
+ //copy excluded channel here if it is inline
1007
+ if (ws_us -> excluded_channel_ctrl == WS_EXC_CHAN_CTRL_RANGE ) {
1008
+ memset (parent -> excluded_channel_data , 0 , 32 );
1009
+ //Decode Range to mask here
1010
+ ws_bootstrap_decode_exclude_range_to_mask_by_range (parent -> excluded_channel_data , & parent -> ws_us .excluded_channels .range , 256 );
1011
+ parent -> ws_us .excluded_channels .mask .channel_mask = parent -> excluded_channel_data ;
1012
+ parent -> ws_us .excluded_channels .mask .mask_len_inline = 32 ;
1013
+ parent -> ws_us .excluded_channel_ctrl = WS_EXC_CHAN_CTRL_BITMASK ;
1014
+ } else if (ws_us -> excluded_channel_ctrl == WS_EXC_CHAN_CTRL_BITMASK ) {
1015
+ parent -> ws_us .excluded_channels .mask .channel_mask = parent -> excluded_channel_data ;
1016
+ memcpy (parent -> excluded_channel_data , ws_us -> excluded_channels .mask .channel_mask , ws_us -> excluded_channels .mask .mask_len_inline );
1017
+ }
1018
+
916
1019
// Saved from Pan information, do not overwrite pan_version as it is not valid here
917
1020
parent -> pan_information .pan_size = pan_information -> pan_size ;
918
1021
parent -> pan_information .routing_cost = pan_information -> routing_cost ;
@@ -1099,6 +1202,13 @@ static void ws_bootstrap_pan_advertisement_analyse(struct protocol_interface_inf
1099
1202
return ;
1100
1203
}
1101
1204
1205
+ if (ws_us -> excluded_channel_ctrl ) {
1206
+ //Validate that we can storage data
1207
+ if (ws_us -> excluded_channel_ctrl == WS_EXC_CHAN_CTRL_BITMASK && ws_us -> excluded_channels .mask .mask_len_inline > 32 ) {
1208
+ return ;
1209
+ }
1210
+ }
1211
+
1102
1212
// Check pan flags so that it is valid
1103
1213
if (!pan_information .rpl_routing_method ) {
1104
1214
// NOT RPL routing
@@ -1415,11 +1525,6 @@ static void ws_bootstrap_asynch_ind(struct protocol_interface_info_entry *cur, c
1415
1525
return ;
1416
1526
}
1417
1527
1418
- //Compare Unicast channel Plan
1419
- if (ws_us .channel_plan != cur -> ws_info -> hopping_schdule .channel_plan ) {
1420
- return ;
1421
- }
1422
-
1423
1528
if (ws_us .channel_plan == 0 ) {
1424
1529
if (!ws_channel_plan_zero_compare (& ws_us .plan .zero , & cur -> ws_info -> hopping_schdule )) {
1425
1530
return ;
0 commit comments