Skip to content

Commit 5a3ce09

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 5a3ce09

File tree

2 files changed

+76
-30
lines changed

2 files changed

+76
-30
lines changed

src/platform/Zephyr/BLEManagerImpl.cpp

+74-30
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@
4444
#include <zephyr/sys/byteorder.h>
4545
#include <zephyr/sys/util.h>
4646

47+
#ifdef CONFIG_BT_BONDABLE
4748
#include <zephyr/settings/settings.h>
49+
#endif // CONFIG_BT_BONDABLE
4850

4951
#include <array>
5052

@@ -162,7 +164,7 @@ BLEManagerImpl BLEManagerImpl::sInstance;
162164
CHIP_ERROR BLEManagerImpl::_Init()
163165
{
164166
int err = 0;
165-
int id = 0;
167+
int id = 0;
166168

167169
mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled;
168170
mFlags.ClearAll().Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART);
@@ -241,15 +243,26 @@ void BLEManagerImpl::DriveBLEState()
241243
{
242244
mFlags.Clear(Flags::kAdvertisingRefreshNeeded);
243245
err = StartAdvertising();
244-
SuccessOrExit(err);
246+
if (err != CHIP_NO_ERROR)
247+
{
248+
// Return prematurely but keep the CHIPoBLE service mode enabled to allow advertising retries
249+
mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled;
250+
ChipLogError(DeviceLayer, "Could not start CHIPoBLE service due to error: %" CHIP_ERROR_FORMAT, err.Format());
251+
return;
252+
}
245253
}
246254
}
247255
else
248256
{
249257
if (mFlags.Has(Flags::kAdvertising))
250258
{
251259
err = StopAdvertising();
252-
SuccessOrExit(err);
260+
if (err != CHIP_NO_ERROR)
261+
{
262+
ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %" CHIP_ERROR_FORMAT, err.Format());
263+
mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled;
264+
return;
265+
}
253266
}
254267

255268
// If no connections are active unregister also CHIPoBLE GATT service
@@ -266,13 +279,6 @@ void BLEManagerImpl::DriveBLEState()
266279
}
267280
}
268281
}
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-
}
276282
}
277283

278284
struct BLEManagerImpl::ServiceData
@@ -338,37 +344,67 @@ inline CHIP_ERROR BLEManagerImpl::PrepareAdvertisingRequest()
338344
else
339345
{
340346
ChipLogError(DeviceLayer, "Failed to start CHIPoBLE advertising: %d", rc);
347+
BLEManagerImpl().StopAdvertising();
341348
}
342349
};
343350

344351
return CHIP_NO_ERROR;
345352
}
346353

347-
CHIP_ERROR BLEManagerImpl::StartAdvertising()
354+
CHIP_ERROR BLEManagerImpl::RegisterGattService()
348355
{
349-
// Prepare advertising request
350-
ReturnErrorOnFailure(PrepareAdvertisingRequest());
351-
352-
// Register dynamically CHIPoBLE GATT service
356+
// Register CHIPoBLE GATT service
353357
if (!mFlags.Has(Flags::kChipoBleGattServiceRegister))
354358
{
355359
int err = bt_gatt_service_register(&sChipoBleService);
356-
357360
if (err != 0)
358-
ChipLogError(DeviceLayer, "Failed to register CHIPoBLE GATT service");
361+
{
362+
ChipLogError(DeviceLayer, "Failed to register CHIPoBLE GATT service: %d", err);
363+
}
359364

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

365395
// Initialize C3 characteristic data
366396
#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
367397
ReturnErrorOnFailure(PrepareC3CharData());
368398
#endif
369399

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

373409
// Transition to the Advertising state...
374410
if (!mFlags.Has(Flags::kAdvertising))
@@ -430,22 +466,23 @@ CHIP_ERROR BLEManagerImpl::StopAdvertising()
430466
DeviceLayer::SystemLayer().CancelTimer(HandleSlowBLEAdvertisementInterval, this);
431467
DeviceLayer::SystemLayer().CancelTimer(HandleExtendedBLEAdvertisementInterval, this);
432468
}
469+
else
470+
{
471+
ChipLogProgress(DeviceLayer, "CHIPoBLE advertising already stopped");
472+
}
433473

434474
return CHIP_NO_ERROR;
435475
}
436476

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

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-
}
481+
mFlags.Set(Flags::kAdvertisingEnabled, val);
482+
// Ensure that each enabling/disabling of the general advertising clears
483+
// the extended mode, to make sure we always start fresh in the regular mode
484+
mFlags.Set(Flags::kExtendedAdvertisingEnabled, false);
485+
PlatformMgr().ScheduleWork(DriveBLEState, 0);
449486

450487
return CHIP_NO_ERROR;
451488
}
@@ -515,7 +552,10 @@ CHIP_ERROR BLEManagerImpl::HandleGAPDisconnect(const ChipDeviceEvent * event)
515552

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

518-
mMatterConnNum--;
555+
if (mMatterConnNum > 0)
556+
{
557+
mMatterConnNum--;
558+
}
519559

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

908948
PlatformMgr().LockChipStack();
909949

910-
sInstance.mTotalConnNum--;
950+
if (sInstance.mTotalConnNum > 0)
951+
{
952+
sInstance.mTotalConnNum--;
953+
}
954+
911955
ChipLogProgress(DeviceLayer, "Current number of connections: %u/%u", sInstance.mTotalConnNum, CONFIG_BT_MAX_CONN);
912956

913957
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)