Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[nrf noup] [zephyr] Allow BLE advertising restarts #389

Merged
merged 1 commit into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 69 additions & 27 deletions src/platform/Zephyr/BLEManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ BLEManagerImpl BLEManagerImpl::sInstance;
CHIP_ERROR BLEManagerImpl::_Init()
{
int err = 0;
int id = 0;
int id = 0;

mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled;
mFlags.ClearAll().Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART);
Expand Down Expand Up @@ -240,15 +240,26 @@ void BLEManagerImpl::DriveBLEState()
{
mFlags.Clear(Flags::kAdvertisingRefreshNeeded);
err = StartAdvertising();
SuccessOrExit(err);
if (err != CHIP_NO_ERROR)
{
// Return prematurely but keep the CHIPoBLE service mode enabled to allow advertising retries
kkasperczyk-no marked this conversation as resolved.
Show resolved Hide resolved
mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled;
ArekBalysNordic marked this conversation as resolved.
Show resolved Hide resolved
ChipLogError(DeviceLayer, "Could not start CHIPoBLE service due to error: %" CHIP_ERROR_FORMAT, err.Format());
return;
}
}
}
else
{
if (mFlags.Has(Flags::kAdvertising))
{
err = StopAdvertising();
SuccessOrExit(err);
if (err != CHIP_NO_ERROR)
{
ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %" CHIP_ERROR_FORMAT, err.Format());
mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled;
kkasperczyk-no marked this conversation as resolved.
Show resolved Hide resolved
return;
}
}

// If no connections are active unregister also CHIPoBLE GATT service
Expand All @@ -265,13 +276,6 @@ void BLEManagerImpl::DriveBLEState()
}
}
}

exit:
if (err != CHIP_NO_ERROR)
{
ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %" CHIP_ERROR_FORMAT, err.Format());
mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled;
}
}

struct BLEManagerImpl::ServiceData
Expand Down Expand Up @@ -316,37 +320,67 @@ inline CHIP_ERROR BLEManagerImpl::PrepareAdvertisingRequest()
else
{
ChipLogError(DeviceLayer, "Failed to start CHIPoBLE advertising: %d", rc);
BLEManagerImpl().StopAdvertising();
}
};

return CHIP_NO_ERROR;
}

CHIP_ERROR BLEManagerImpl::StartAdvertising()
CHIP_ERROR BLEManagerImpl::RegisterGattService()
{
// Prepare advertising request
ReturnErrorOnFailure(PrepareAdvertisingRequest());

// Register dynamically CHIPoBLE GATT service
// Register CHIPoBLE GATT service
if (!mFlags.Has(Flags::kChipoBleGattServiceRegister))
{
int err = bt_gatt_service_register(&sChipoBleService);

if (err != 0)
ChipLogError(DeviceLayer, "Failed to register CHIPoBLE GATT service");
{
ChipLogError(DeviceLayer, "Failed to register CHIPoBLE GATT service: %d", err);
}

VerifyOrReturnError(err == 0, MapErrorZephyr(err));

mFlags.Set(Flags::kChipoBleGattServiceRegister);
}
return CHIP_NO_ERROR;
}

CHIP_ERROR BLEManagerImpl::UnregisterGattService()
{
// Unregister CHIPoBLE GATT service
if (mFlags.Has(Flags::kChipoBleGattServiceRegister))
{
int err = bt_gatt_service_unregister(&sChipoBleService);
if (err != 0)
{
ChipLogError(DeviceLayer, "Failed to unregister CHIPoBLE GATT service: %d", err);
}

VerifyOrReturnError(err == 0, MapErrorZephyr(err));
mFlags.Clear(Flags::kChipoBleGattServiceRegister);
}
return CHIP_NO_ERROR;
}

CHIP_ERROR BLEManagerImpl::StartAdvertising()
{
// Prepare advertising request
ReturnErrorOnFailure(PrepareAdvertisingRequest());
// We need to register GATT service before issuing the advertising to start
ReturnErrorOnFailure(RegisterGattService());

// Initialize C3 characteristic data
#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
ReturnErrorOnFailure(PrepareC3CharData());
#endif

// Request advertising
ReturnErrorOnFailure(BLEAdvertisingArbiter::InsertRequest(mAdvertisingRequest));
CHIP_ERROR err = BLEAdvertisingArbiter::InsertRequest(mAdvertisingRequest);
if (CHIP_NO_ERROR != err)
{
// It makes not sense to keep GATT services registered after the advertising request failed
(void) UnregisterGattService();
return err;
}

// Transition to the Advertising state...
if (!mFlags.Has(Flags::kAdvertising))
Expand Down Expand Up @@ -396,19 +430,20 @@ CHIP_ERROR BLEManagerImpl::StopAdvertising()
// Cancel timer event changing CHIPoBLE advertisement interval
DeviceLayer::SystemLayer().CancelTimer(HandleBLEAdvertisementIntervalChange, this);
}
else
{
ChipLogProgress(DeviceLayer, "CHIPoBLE advertising already stopped");
}

return CHIP_NO_ERROR;
}

CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val)
{
if (mFlags.Has(Flags::kAdvertisingEnabled) != val)
{
ChipLogDetail(DeviceLayer, "CHIPoBLE advertising set to %s", val ? "on" : "off");
ChipLogDetail(DeviceLayer, "CHIPoBLE advertising set to %s", val ? "on" : "off");

mFlags.Set(Flags::kAdvertisingEnabled, val);
PlatformMgr().ScheduleWork(DriveBLEState, 0);
}
mFlags.Set(Flags::kAdvertisingEnabled, val);
PlatformMgr().ScheduleWork(DriveBLEState, 0);

return CHIP_NO_ERROR;
}
Expand Down Expand Up @@ -472,7 +507,10 @@ CHIP_ERROR BLEManagerImpl::HandleGAPDisconnect(const ChipDeviceEvent * event)

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

mMatterConnNum--;
if (mMatterConnNum > 0)
{
mMatterConnNum--;
}

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

PlatformMgr().LockChipStack();

sInstance.mTotalConnNum--;
if (sInstance.mTotalConnNum > 0)
{
sInstance.mTotalConnNum--;
}

ChipLogProgress(DeviceLayer, "Current number of connections: %u/%u", sInstance.mTotalConnNum, CONFIG_BT_MAX_CONN);

VerifyOrExit(bt_conn_get_info(conId, &bt_info) == 0, );
Expand Down
2 changes: 2 additions & 0 deletions src/platform/Zephyr/BLEManagerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePla
bool SetSubscribed(bt_conn * conn);
bool UnsetSubscribed(bt_conn * conn);
uint32_t GetAdvertisingInterval();
CHIP_ERROR RegisterGattService();
CHIP_ERROR UnregisterGattService();

static void DriveBLEState(intptr_t arg);

Expand Down
Loading