Skip to content

Commit 332587a

Browse files
markaj-nordickkasperczyk-no
authored andcommitted
[zephyr]: allow BLE advertising restarts
* allow BLE advertising restarts in case of failures * which can be triggered by calling SetBLEAdvertisingEnabled(true) ConnectivityMgr public API from the application code * do not register CHIPoBLE GATT services when the advertising cannot be started * this allows the disconnection handler to filter out non-Matter BLE connections that were terminated * fix possible underflow of connection counters Signed-off-by: Marcin Kajor <marcin.kajor@nordicsemi.no>
1 parent 140858f commit 332587a

File tree

2 files changed

+74
-30
lines changed

2 files changed

+74
-30
lines changed

src/platform/Zephyr/BLEManagerImpl.cpp

+72-30
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ BLEManagerImpl BLEManagerImpl::sInstance;
162162
CHIP_ERROR BLEManagerImpl::_Init()
163163
{
164164
int err = 0;
165-
int id = 0;
165+
int id = 0;
166166

167167
mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled;
168168
mFlags.ClearAll().Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART);
@@ -241,15 +241,26 @@ void BLEManagerImpl::DriveBLEState()
241241
{
242242
mFlags.Clear(Flags::kAdvertisingRefreshNeeded);
243243
err = StartAdvertising();
244-
SuccessOrExit(err);
244+
if (err != CHIP_NO_ERROR)
245+
{
246+
// Return prematurely but keep the CHIPoBLE service mode enabled to allow advertising retries
247+
mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled;
248+
ChipLogError(DeviceLayer, "Could not start CHIPoBLE service due to error: %" CHIP_ERROR_FORMAT, err.Format());
249+
return;
250+
}
245251
}
246252
}
247253
else
248254
{
249255
if (mFlags.Has(Flags::kAdvertising))
250256
{
251257
err = StopAdvertising();
252-
SuccessOrExit(err);
258+
if (err != CHIP_NO_ERROR)
259+
{
260+
ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %" CHIP_ERROR_FORMAT, err.Format());
261+
mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled;
262+
return;
263+
}
253264
}
254265

255266
// If no connections are active unregister also CHIPoBLE GATT service
@@ -266,13 +277,6 @@ void BLEManagerImpl::DriveBLEState()
266277
}
267278
}
268279
}
269-
270-
exit:
271-
if (err != CHIP_NO_ERROR)
272-
{
273-
ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %" CHIP_ERROR_FORMAT, err.Format());
274-
mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled;
275-
}
276280
}
277281

278282
struct BLEManagerImpl::ServiceData
@@ -338,37 +342,67 @@ inline CHIP_ERROR BLEManagerImpl::PrepareAdvertisingRequest()
338342
else
339343
{
340344
ChipLogError(DeviceLayer, "Failed to start CHIPoBLE advertising: %d", rc);
345+
BLEManagerImpl().StopAdvertising();
341346
}
342347
};
343348

344349
return CHIP_NO_ERROR;
345350
}
346351

347-
CHIP_ERROR BLEManagerImpl::StartAdvertising()
352+
CHIP_ERROR BLEManagerImpl::RegisterGattService()
348353
{
349-
// Prepare advertising request
350-
ReturnErrorOnFailure(PrepareAdvertisingRequest());
351-
352-
// Register dynamically CHIPoBLE GATT service
354+
// Register CHIPoBLE GATT service
353355
if (!mFlags.Has(Flags::kChipoBleGattServiceRegister))
354356
{
355357
int err = bt_gatt_service_register(&sChipoBleService);
356-
357358
if (err != 0)
358-
ChipLogError(DeviceLayer, "Failed to register CHIPoBLE GATT service");
359+
{
360+
ChipLogError(DeviceLayer, "Failed to register CHIPoBLE GATT service: %d", err);
361+
}
359362

360363
VerifyOrReturnError(err == 0, MapErrorZephyr(err));
361-
362364
mFlags.Set(Flags::kChipoBleGattServiceRegister);
363365
}
366+
return CHIP_NO_ERROR;
367+
}
368+
369+
CHIP_ERROR BLEManagerImpl::UnregisterGattService()
370+
{
371+
// Unregister CHIPoBLE GATT service
372+
if (mFlags.Has(Flags::kChipoBleGattServiceRegister))
373+
{
374+
int err = bt_gatt_service_unregister(&sChipoBleService);
375+
if (err != 0)
376+
{
377+
ChipLogError(DeviceLayer, "Failed to unregister CHIPoBLE GATT service: %d", err);
378+
}
379+
380+
VerifyOrReturnError(err == 0, MapErrorZephyr(err));
381+
mFlags.Clear(Flags::kChipoBleGattServiceRegister);
382+
}
383+
return CHIP_NO_ERROR;
384+
}
385+
386+
CHIP_ERROR BLEManagerImpl::StartAdvertising()
387+
{
388+
// Prepare advertising request
389+
ReturnErrorOnFailure(PrepareAdvertisingRequest());
390+
// We need to register GATT service before issuing the advertising to start
391+
ReturnErrorOnFailure(RegisterGattService());
364392

365393
// Initialize C3 characteristic data
366394
#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
367395
ReturnErrorOnFailure(PrepareC3CharData());
368396
#endif
369397

370398
// Request advertising
371-
ReturnErrorOnFailure(BLEAdvertisingArbiter::InsertRequest(mAdvertisingRequest));
399+
CHIP_ERROR err = BLEAdvertisingArbiter::InsertRequest(mAdvertisingRequest);
400+
if (CHIP_NO_ERROR != err)
401+
{
402+
// It makes not sense to keep GATT services registered after the advertising request failed
403+
(void) UnregisterGattService();
404+
return err;
405+
}
372406

373407
// Transition to the Advertising state...
374408
if (!mFlags.Has(Flags::kAdvertising))
@@ -430,22 +464,23 @@ CHIP_ERROR BLEManagerImpl::StopAdvertising()
430464
DeviceLayer::SystemLayer().CancelTimer(HandleSlowBLEAdvertisementInterval, this);
431465
DeviceLayer::SystemLayer().CancelTimer(HandleExtendedBLEAdvertisementInterval, this);
432466
}
467+
else
468+
{
469+
ChipLogProgress(DeviceLayer, "CHIPoBLE advertising already stopped");
470+
}
433471

434472
return CHIP_NO_ERROR;
435473
}
436474

437475
CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val)
438476
{
439-
if (mFlags.Has(Flags::kAdvertisingEnabled) != val)
440-
{
441-
ChipLogDetail(DeviceLayer, "CHIPoBLE advertising set to %s", val ? "on" : "off");
477+
ChipLogDetail(DeviceLayer, "CHIPoBLE advertising set to %s", val ? "on" : "off");
442478

443-
mFlags.Set(Flags::kAdvertisingEnabled, val);
444-
// Ensure that each enabling/disabling of the standard advertising clears
445-
// the extended mode flag.
446-
mFlags.Set(Flags::kExtendedAdvertisingEnabled, false);
447-
PlatformMgr().ScheduleWork(DriveBLEState, 0);
448-
}
479+
mFlags.Set(Flags::kAdvertisingEnabled, val);
480+
// Ensure that each enabling/disabling of the general advertising clears
481+
// the extended mode, to make sure we always start fresh in the regular mode
482+
mFlags.Set(Flags::kExtendedAdvertisingEnabled, false);
483+
PlatformMgr().ScheduleWork(DriveBLEState, 0);
449484

450485
return CHIP_NO_ERROR;
451486
}
@@ -515,7 +550,10 @@ CHIP_ERROR BLEManagerImpl::HandleGAPDisconnect(const ChipDeviceEvent * event)
515550

516551
ChipLogProgress(DeviceLayer, "BLE GAP connection terminated (reason 0x%02x)", connEvent->HciResult);
517552

518-
mMatterConnNum--;
553+
if (mMatterConnNum > 0)
554+
{
555+
mMatterConnNum--;
556+
}
519557

520558
// If indications were enabled for this connection, record that they are now disabled and
521559
// notify the BLE Layer of a disconnect.
@@ -907,7 +945,11 @@ void BLEManagerImpl::HandleDisconnect(struct bt_conn * conId, uint8_t reason)
907945

908946
PlatformMgr().LockChipStack();
909947

910-
sInstance.mTotalConnNum--;
948+
if (sInstance.mTotalConnNum > 0)
949+
{
950+
sInstance.mTotalConnNum--;
951+
}
952+
911953
ChipLogProgress(DeviceLayer, "Current number of connections: %u/%u", sInstance.mTotalConnNum, CONFIG_BT_MAX_CONN);
912954

913955
VerifyOrExit(bt_conn_get_info(conId, &bt_info) == 0, );

src/platform/Zephyr/BLEManagerImpl.h

+2
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePla
125125
bool SetSubscribed(bt_conn * conn);
126126
bool UnsetSubscribed(bt_conn * conn);
127127
uint32_t GetAdvertisingInterval();
128+
CHIP_ERROR RegisterGattService();
129+
CHIP_ERROR UnregisterGattService();
128130

129131
static void DriveBLEState(intptr_t arg);
130132

0 commit comments

Comments
 (0)