Skip to content

Commit 9ecf64a

Browse files
committed
[nrf noup] [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 c36fcaf commit 9ecf64a

File tree

2 files changed

+71
-27
lines changed

2 files changed

+71
-27
lines changed

src/platform/Zephyr/BLEManagerImpl.cpp

+69-27
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ BLEManagerImpl BLEManagerImpl::sInstance;
161161
CHIP_ERROR BLEManagerImpl::_Init()
162162
{
163163
int err = 0;
164-
int id = 0;
164+
int id = 0;
165165

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

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

277281
struct BLEManagerImpl::ServiceData
@@ -316,37 +320,67 @@ inline CHIP_ERROR BLEManagerImpl::PrepareAdvertisingRequest()
316320
else
317321
{
318322
ChipLogError(DeviceLayer, "Failed to start CHIPoBLE advertising: %d", rc);
323+
BLEManagerImpl().StopAdvertising();
319324
}
320325
};
321326

322327
return CHIP_NO_ERROR;
323328
}
324329

325-
CHIP_ERROR BLEManagerImpl::StartAdvertising()
330+
CHIP_ERROR BLEManagerImpl::RegisterGattService()
326331
{
327-
// Prepare advertising request
328-
ReturnErrorOnFailure(PrepareAdvertisingRequest());
329-
330-
// Register dynamically CHIPoBLE GATT service
332+
// Register CHIPoBLE GATT service
331333
if (!mFlags.Has(Flags::kChipoBleGattServiceRegister))
332334
{
333335
int err = bt_gatt_service_register(&sChipoBleService);
334-
335336
if (err != 0)
336-
ChipLogError(DeviceLayer, "Failed to register CHIPoBLE GATT service");
337+
{
338+
ChipLogError(DeviceLayer, "Failed to register CHIPoBLE GATT service: %d", err);
339+
}
337340

338341
VerifyOrReturnError(err == 0, MapErrorZephyr(err));
339-
340342
mFlags.Set(Flags::kChipoBleGattServiceRegister);
341343
}
344+
return CHIP_NO_ERROR;
345+
}
346+
347+
CHIP_ERROR BLEManagerImpl::UnregisterGattService()
348+
{
349+
// Unregister CHIPoBLE GATT service
350+
if (mFlags.Has(Flags::kChipoBleGattServiceRegister))
351+
{
352+
int err = bt_gatt_service_unregister(&sChipoBleService);
353+
if (err != 0)
354+
{
355+
ChipLogError(DeviceLayer, "Failed to unregister CHIPoBLE GATT service: %d", err);
356+
}
357+
358+
VerifyOrReturnError(err == 0, MapErrorZephyr(err));
359+
mFlags.Clear(Flags::kChipoBleGattServiceRegister);
360+
}
361+
return CHIP_NO_ERROR;
362+
}
363+
364+
CHIP_ERROR BLEManagerImpl::StartAdvertising()
365+
{
366+
// Prepare advertising request
367+
ReturnErrorOnFailure(PrepareAdvertisingRequest());
368+
// We need to register GATT service before issuing the advertising to start
369+
ReturnErrorOnFailure(RegisterGattService());
342370

343371
// Initialize C3 characteristic data
344372
#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
345373
ReturnErrorOnFailure(PrepareC3CharData());
346374
#endif
347375

348376
// Request advertising
349-
ReturnErrorOnFailure(BLEAdvertisingArbiter::InsertRequest(mAdvertisingRequest));
377+
CHIP_ERROR err = BLEAdvertisingArbiter::InsertRequest(mAdvertisingRequest);
378+
if (CHIP_NO_ERROR != err)
379+
{
380+
// It makes not sense to keep GATT services registered after the advertising request failed
381+
(void) UnregisterGattService();
382+
return err;
383+
}
350384

351385
// Transition to the Advertising state...
352386
if (!mFlags.Has(Flags::kAdvertising))
@@ -396,19 +430,20 @@ CHIP_ERROR BLEManagerImpl::StopAdvertising()
396430
// Cancel timer event changing CHIPoBLE advertisement interval
397431
DeviceLayer::SystemLayer().CancelTimer(HandleBLEAdvertisementIntervalChange, this);
398432
}
433+
else
434+
{
435+
ChipLogProgress(DeviceLayer, "CHIPoBLE advertising already stopped");
436+
}
399437

400438
return CHIP_NO_ERROR;
401439
}
402440

403441
CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val)
404442
{
405-
if (mFlags.Has(Flags::kAdvertisingEnabled) != val)
406-
{
407-
ChipLogDetail(DeviceLayer, "CHIPoBLE advertising set to %s", val ? "on" : "off");
443+
ChipLogDetail(DeviceLayer, "CHIPoBLE advertising set to %s", val ? "on" : "off");
408444

409-
mFlags.Set(Flags::kAdvertisingEnabled, val);
410-
PlatformMgr().ScheduleWork(DriveBLEState, 0);
411-
}
445+
mFlags.Set(Flags::kAdvertisingEnabled, val);
446+
PlatformMgr().ScheduleWork(DriveBLEState, 0);
412447

413448
return CHIP_NO_ERROR;
414449
}
@@ -472,7 +507,10 @@ CHIP_ERROR BLEManagerImpl::HandleGAPDisconnect(const ChipDeviceEvent * event)
472507

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

475-
mMatterConnNum--;
510+
if (mMatterConnNum > 0)
511+
{
512+
mMatterConnNum--;
513+
}
476514

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

859897
PlatformMgr().LockChipStack();
860898

861-
sInstance.mTotalConnNum--;
899+
if (sInstance.mTotalConnNum > 0)
900+
{
901+
sInstance.mTotalConnNum--;
902+
}
903+
862904
ChipLogProgress(DeviceLayer, "Current number of connections: %u/%u", sInstance.mTotalConnNum, CONFIG_BT_MAX_CONN);
863905

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

src/platform/Zephyr/BLEManagerImpl.h

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

128130
static void DriveBLEState(intptr_t arg);
129131

0 commit comments

Comments
 (0)