Skip to content

Commit 0931709

Browse files
replace current bool state combination for keeping track of ble scanning with an enum that covers all states
1 parent eb38298 commit 0931709

File tree

2 files changed

+122
-97
lines changed

2 files changed

+122
-97
lines changed

connectivity/FEATURE_BLE/source/generic/GapImpl.cpp

Lines changed: 106 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,6 @@ Gap::Gap(
362362
_central_privacy_configuration(default_central_privacy_configuration),
363363
#endif // BLE_ROLE_OBSERVER
364364
#endif // BLE_FEATURE_PRIVACY
365-
_scan_enabled(false),
366365
_advertising_timeout(),
367366
_scan_timeout(),
368367
_user_manage_connection_parameter_requests(false)
@@ -483,34 +482,36 @@ ble_error_t Gap::getRandomAddressType(
483482
}
484483
}
485484

486-
487485
#if BLE_ROLE_OBSERVER
488486
ble_error_t Gap::stopScan()
489487
{
490488
ble_error_t err;
491489

492-
if ((!_scan_enabled && !_scan_pending) || _scan_pending || _initiating) {
490+
if (_initiating) {
493491
return BLE_STACK_BUSY;
494492
}
495493

496-
if (is_extended_advertising_available()) {
497-
err = _pal_gap.extended_scan_enable(false, duplicates_filter_t::DISABLE, 0, 0);
498-
} else {
499-
err = _pal_gap.scan_enable(false, false);
500-
}
494+
_scan_requested = false;
501495

502-
if (err) {
503-
return err;
496+
if (_scan_state == ScanState::scan) {
497+
if (is_extended_advertising_available()) {
498+
err = _pal_gap.extended_scan_enable(false, duplicates_filter_t::DISABLE, 0, 0);
499+
} else {
500+
err = _pal_gap.scan_enable(false, false);
501+
}
502+
503+
if (err) {
504+
return err;
505+
}
506+
_scan_state = ScanState::pending_stop_scan;
504507
}
505508

506-
_scan_pending = true;
507509
_scan_timeout.detach();
508510

509511
return BLE_ERROR_NONE;
510512
}
511513
#endif
512514

513-
514515
#if BLE_ROLE_CENTRAL
515516
ble_error_t Gap::connect(
516517
peer_address_type_t peerAddressType,
@@ -582,7 +583,7 @@ ble_error_t Gap::connect(
582583
return BLE_ERROR_INVALID_PARAM;
583584
}
584585

585-
if (!_scan_enabled) {
586+
if (_scan_state == ScanState::idle) {
586587
if (!_active_sets.get(LEGACY_ADVERTISING_HANDLE) &&
587588
!_pending_sets.get(LEGACY_ADVERTISING_HANDLE)
588589
) {
@@ -593,11 +594,7 @@ ble_error_t Gap::connect(
593594
}
594595
#if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
595596
if (_connect_to_host_resolved_address_state == ConnectionToHostResolvedAddressState::scan) {
596-
ret = startScan(
597-
scan_duration_t::forever(),
598-
duplicates_filter_t::ENABLE,
599-
(scan_period_t)0
600-
);
597+
ret = startScan(scan_duration_t::forever(), duplicates_filter_t::ENABLE, scan_period_t(0));
601598
if (ret != BLE_ERROR_NONE) {
602599
_connect_to_host_resolved_address_state = ConnectionToHostResolvedAddressState::idle;
603600
}
@@ -621,7 +618,7 @@ ble_error_t Gap::connect(
621618
}
622619
} else {
623620
// set the correct mac address before starting scanning.
624-
if (!_scan_enabled) {
621+
if (_scan_state == ScanState::idle) {
625622
_pal_gap.set_random_address(*address);
626623
} else {
627624
// ensure scan is stopped.
@@ -1065,6 +1062,8 @@ ble_error_t Gap::reset()
10651062

10661063
_event_handler = nullptr;
10671064
_initiating = false;
1065+
_scan_state = ScanState::idle;
1066+
_scan_requested = false;
10681067
#if BLE_FEATURE_PRIVACY
10691068
_privacy_initialization_pending = false;
10701069
#if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
@@ -1148,51 +1147,56 @@ Gap::GapShutdownCallbackChain_t &Gap::onShutdown()
11481147
#if BLE_ROLE_OBSERVER
11491148
void Gap::on_scan_started(bool success)
11501149
{
1151-
_scan_pending = false;
1152-
_scan_enabled = success;
1150+
MBED_ASSERT(_scan_state == ScanState::pending_scan);
1151+
1152+
if (success) {
1153+
_scan_state = ScanState::scan;
1154+
/* if no longer want the scan */
1155+
if (!_scan_requested) {
1156+
stopScan();
1157+
}
1158+
} else {
1159+
_scan_state = ScanState::idle;
1160+
}
11531161
}
11541162

11551163
void Gap::on_scan_stopped(bool success)
11561164
{
1157-
_scan_pending = false;
1158-
_scan_enabled = false;
1159-
11601165
if (!success) {
1161-
_scan_address_refresh = false;
11621166
return;
11631167
}
11641168

1165-
// The address is refreshed only if there's no other pending request to refresh
1166-
// the main address
1167-
1168-
bool wait_for_advertising_stop =
1169-
_address_refresh_sets.get(LEGACY_ADVERTISING_HANDLE) &&
1170-
_active_sets.get(LEGACY_ADVERTISING_HANDLE) &&
1171-
_pending_sets.get(LEGACY_ADVERTISING_HANDLE);
1169+
_scan_state = ScanState::idle;
11721170

1173-
bool restart_advertising =
1174-
!_active_sets.get(LEGACY_ADVERTISING_HANDLE) &&
1175-
!_pending_sets.get(LEGACY_ADVERTISING_HANDLE) &&
1176-
_address_refresh_sets.get(LEGACY_ADVERTISING_HANDLE);
1171+
#if BLE_ROLE_BROADCASTER
1172+
/* with legacy advertising we might need to wait for scanning and advertising to both stop */
1173+
if (!is_extended_advertising_available()) {
1174+
bool wait_for_advertising_stop =
1175+
_address_refresh_sets.get(LEGACY_ADVERTISING_HANDLE) &&
1176+
_active_sets.get(LEGACY_ADVERTISING_HANDLE) &&
1177+
_pending_sets.get(LEGACY_ADVERTISING_HANDLE);
1178+
1179+
if (wait_for_advertising_stop) {
1180+
/* return early if we're waiting for advertising to stop and do not restart scan even if requested */
1181+
return;
1182+
}
11771183

1178-
#ifdef BLE_FEATURE_EXTENDED_ADVERTISING
1179-
if (is_extended_advertising_available()) {
1180-
wait_for_advertising_stop = false;
1181-
restart_advertising = false;
1182-
}
1183-
#endif // BLE_FEATURE_EXTENDED_ADVERTISING
1184+
bool restart_advertising =
1185+
!_active_sets.get(LEGACY_ADVERTISING_HANDLE) &&
1186+
!_pending_sets.get(LEGACY_ADVERTISING_HANDLE) &&
1187+
_address_refresh_sets.get(LEGACY_ADVERTISING_HANDLE);
11841188

1185-
if (_scan_address_refresh && !wait_for_advertising_stop) {
1186-
#if BLE_ROLE_BROADCASTER
11871189
if (restart_advertising) {
1190+
/* this will refresh the address and we can continue scan if we want as well */
11881191
_address_refresh_sets.clear(LEGACY_ADVERTISING_HANDLE);
11891192
startAdvertising(LEGACY_ADVERTISING_HANDLE);
11901193
_adv_started_from_refresh.set(LEGACY_ADVERTISING_HANDLE);
11911194
}
1195+
}
11921196
#endif // BLE_ROLE_BROADCASTER
11931197

1194-
_scan_address_refresh = false;
1195-
startScan();
1198+
if (_scan_requested) {
1199+
initiate_scan();
11961200
}
11971201
}
11981202
#endif // BLE_ROLE_OBSERVER
@@ -1227,13 +1231,12 @@ void Gap::connecting_to_host_resolved_address_failed(bool inform_user)
12271231
#if BLE_ROLE_OBSERVER
12281232
void Gap::on_scan_timeout()
12291233
{
1230-
if (!_scan_enabled) {
1234+
if (_scan_state == ScanState::idle) {
12311235
return;
12321236
}
12331237

1234-
_scan_address_refresh = false;
1235-
_scan_enabled = false;
1236-
_scan_pending = false;
1238+
_scan_state = ScanState::idle;
1239+
_scan_requested = false;
12371240

12381241
if (_event_handler) {
12391242
_event_handler->onScanTimeout(ScanTimeoutEvent());
@@ -1244,12 +1247,11 @@ void Gap::on_scan_timeout()
12441247
#if BLE_ROLE_OBSERVER
12451248
void Gap::process_legacy_scan_timeout()
12461249
{
1247-
if (!_scan_enabled) {
1250+
if (_scan_state == ScanState::idle) {
12481251
return;
12491252
}
12501253

1251-
/* legacy scanning timed out is based on timer so we need to stop the scan manually */
1252-
_pal_gap.scan_enable(false, false);
1254+
stopScan();
12531255

12541256
if (_event_handler) {
12551257
_event_handler->onScanTimeout(ScanTimeoutEvent());
@@ -2064,7 +2066,7 @@ ble_error_t Gap::startAdvertising(
20642066
}
20652067

20662068
// Address can be updated if the device is not scanning or advertising
2067-
if (!_scan_enabled && !_scan_pending && !_active_sets.get(LEGACY_ADVERTISING_HANDLE)) {
2069+
if ((_scan_state == ScanState::idle) && !_active_sets.get(LEGACY_ADVERTISING_HANDLE)) {
20682070
_pal_gap.set_random_address(*random_address);
20692071
}
20702072

@@ -2824,18 +2826,15 @@ void Gap::on_legacy_advertising_stopped()
28242826
_active_sets.clear(LEGACY_ADVERTISING_HANDLE);
28252827
_pending_sets.clear(LEGACY_ADVERTISING_HANDLE);
28262828

2827-
bool wait_for_scan_stop = _scan_enabled && _scan_pending && _scan_address_refresh;
2828-
bool restart_scan = _scan_address_refresh && !_scan_enabled && !_scan_pending;
2829-
28302829
// restart advertising if it was stopped to refresh the address
2831-
if (_address_refresh_sets.get(LEGACY_ADVERTISING_HANDLE) && !wait_for_scan_stop) {
2830+
if (_address_refresh_sets.get(LEGACY_ADVERTISING_HANDLE) && (_scan_state == ScanState::idle)) {
28322831
_address_refresh_sets.clear(LEGACY_ADVERTISING_HANDLE);
28332832
startAdvertising(LEGACY_ADVERTISING_HANDLE);
28342833
_adv_started_from_refresh.set(LEGACY_ADVERTISING_HANDLE);
28352834
#if BLE_ROLE_OBSERVER
2836-
if (restart_scan) {
2837-
_scan_address_refresh = false;
2838-
startScan();
2835+
/* scan is idle but we might still want to be scan since this could've been caused be address refresh */
2836+
if (_scan_requested) {
2837+
initiate_scan();
28392838
}
28402839
#endif // BLE_ROLE_OBSERVER
28412840
} else if (_event_handler) {
@@ -3025,26 +3024,46 @@ ble_error_t Gap::startScan(
30253024
scan_period_t period
30263025
)
30273026
{
3028-
if (_scan_pending || _scan_address_refresh || _initiating) {
3027+
if (_initiating) {
30293028
return BLE_STACK_BUSY;
30303029
}
30313030

3031+
_scan_requested_duration = duration;
3032+
_scan_requested_filtering = filtering;
3033+
_scan_requested_period = period;
3034+
3035+
/* only initiate scan if we're not already busy */
3036+
if (_scan_state == ScanState::idle) {
3037+
ble_error_t ret = initiate_scan();
3038+
if (ret != BLE_ERROR_NONE) {
3039+
return ret;
3040+
}
3041+
}
3042+
3043+
_scan_requested = true;
3044+
3045+
return BLE_ERROR_NONE;
3046+
}
3047+
3048+
ble_error_t Gap::initiate_scan()
3049+
{
30323050
const address_t *address = get_random_address(controller_operation_t::scanning);
30333051
if (!address) {
30343052
return BLE_ERROR_INVALID_STATE;
30353053
}
3054+
30363055
#if BLE_FEATURE_EXTENDED_ADVERTISING
30373056
if (is_extended_advertising_available()) {
30383057
// set the correct mac address before starting scanning.
3039-
if (!_scan_enabled) {
3058+
if (_scan_state == ScanState::idle) {
30403059
_pal_gap.set_random_address(*address);
30413060
}
30423061

30433062
ble_error_t err = _pal_gap.extended_scan_enable(
30443063
/* enable */true,
3045-
filtering,
3046-
duration.value(),
3047-
period.value()
3064+
_scan_requested_filtering,
3065+
_scan_requested_duration.value(),
3066+
_scan_requested_period.value()
30483067
);
30493068

30503069
if (err) {
@@ -3053,49 +3072,40 @@ ble_error_t Gap::startScan(
30533072
} else
30543073
#endif // BLE_FEATURE_EXTENDED_ADVERTISING
30553074
{
3056-
if (period.value() != 0) {
3075+
if (_scan_requested_period.value() != 0) {
30573076
return BLE_ERROR_INVALID_PARAM;
30583077
}
30593078

30603079
// update the address if no scan or advertising is running
30613080
auto adv_handle = LEGACY_ADVERTISING_HANDLE;
3062-
if (!_scan_enabled && !_active_sets.get(adv_handle) && !_pending_sets.get(adv_handle)) {
3081+
if ((_scan_state == ScanState::idle) && !_active_sets.get(adv_handle) && !_pending_sets.get(adv_handle)) {
30633082
_pal_gap.set_random_address(*address);
30643083
}
30653084

30663085
ble_error_t err = _pal_gap.scan_enable(
30673086
true,
3068-
filtering == duplicates_filter_t::DISABLE ? false : true
3087+
_scan_requested_filtering == duplicates_filter_t::DISABLE ? false : true
30693088
);
30703089

30713090
if (err) {
30723091
return err;
30733092
}
30743093

30753094
_scan_timeout.detach();
3076-
if (duration.value()) {
3077-
_scan_timeout.attach([this]() {
3078-
_event_queue.post([this] { process_legacy_scan_timeout(); });
3079-
},
3080-
duration.valueChrono()
3095+
if (_scan_requested_duration.value()) {
3096+
_scan_timeout.attach(
3097+
[this]() { _event_queue.post([this] { process_legacy_scan_timeout(); }); },
3098+
_scan_requested_duration.valueChrono()
30813099
);
30823100
}
30833101
}
30843102

3085-
if (!_scan_enabled) {
3086-
_scan_pending = true;
3087-
}
3088-
if (duration == scan_duration_t::forever() && period == scan_period_t(0)) {
3089-
_scan_interruptible = true;
3090-
} else {
3091-
_scan_interruptible = false;
3092-
}
3103+
_scan_state = ScanState::pending_scan;
30933104

30943105
return BLE_ERROR_NONE;
30953106
}
30963107
#endif
30973108

3098-
30993109
#if BLE_ROLE_OBSERVER
31003110
#if BLE_FEATURE_PERIODIC_ADVERTISING
31013111
ble_error_t Gap::createSync(
@@ -3358,15 +3368,18 @@ void Gap::on_private_address_generated(bool connectable)
33583368
#endif // BLE_ROLE_BROADCASTER
33593369

33603370
#if BLE_ROLE_OBSERVER
3361-
// refresh scanning address
3362-
if (_scan_enabled && !_scan_pending && _scan_interruptible &&
3363-
!_central_privacy_configuration.use_non_resolvable_random_address == connectable
3364-
) {
3365-
ble_error_t err = stopScan();
3366-
if (err) {
3367-
return;
3371+
/* if we are connectable and we want to use a resolvable address we want to refresh it */
3372+
if (!_central_privacy_configuration.use_non_resolvable_random_address == connectable) {
3373+
/* if we're scanning we need to stop */
3374+
if (_scan_state == ScanState::scan) {
3375+
/* but we can only stop if we're scanning forever */
3376+
if (_scan_requested_duration == scan_duration_t::forever() && _scan_requested_period == scan_period_t(0)) {
3377+
/* when the scan stops it will refresh the address and restart scan */
3378+
ble_error_t err = stopScan();
3379+
/* but after we stop we actually want to continue */
3380+
_scan_requested = true;
3381+
}
33683382
}
3369-
_scan_address_refresh = true;
33703383
}
33713384
#endif // BLE_ROLE_OBSERVER
33723385
}
@@ -3449,7 +3462,7 @@ bool Gap::is_advertising() const
34493462
}
34503463

34513464
bool Gap::is_radio_active() const {
3452-
return _initiating || _scan_enabled || _scan_pending || is_advertising();
3465+
return _initiating || (_scan_state != ScanState::idle) || is_advertising();
34533466
}
34543467

34553468
void Gap::update_advertising_set_connectable_attribute(
@@ -3514,7 +3527,7 @@ const address_t *Gap::get_random_address(controller_operation_t operation, size_
35143527
// it to the address to use to determine if the address is correct or not.
35153528
if (_initiating) {
35163529
address_in_use = &resolvable_address;
3517-
} else if (_scan_enabled || _scan_pending) {
3530+
} else if (_scan_state != ScanState::idle) {
35183531
if (central_non_resolvable) {
35193532
address_in_use = &non_resolvable_address;
35203533
} else {

0 commit comments

Comments
 (0)