Skip to content

Commit

Permalink
[nrf toup][Zephyr] Retry starting BLE advertising after releasing con…
Browse files Browse the repository at this point in the history
…nection.

In Zephyr 4.0, the BT_LE_ADV_OPT_CONNECTABLE and
BT_LE_ADV_OPT_CONNECTABLE advertising options have been deprecated
and we need to use BT_LE_ADV_OPT_CONN instead.

Due to the fact that the automatic advertiser resumption is
deprecated, we must ensure that the BLE advertising arbiter
restarts advertising in a different way if the service could not
be started, for example, due to an existing BLE connection,
or connection has been closed.

We can use the recycled callback of the BT_CONN_CB to check if there
is pending request in the list and if so, try to restart advertising.

Signed-off-by: Arkadiusz Balys <[email protected]>
  • Loading branch information
ArekBalysNordic committed Feb 28, 2025
1 parent c22e808 commit 93c7b09
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 3 deletions.
34 changes: 32 additions & 2 deletions src/platform/Zephyr/BLEAdvertisingArbiter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@

#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>
#include <platform/CHIPDeviceLayer.h>
#include <system/SystemError.h>
#include <zephyr/bluetooth/conn.h>

namespace chip {
namespace DeviceLayer {
Expand All @@ -29,8 +31,9 @@ namespace {
// List of advertising requests ordered by priority
sys_slist_t sRequests;

bool sIsInitialized = false;
uint8_t sBtId = 0;
bool sIsInitialized = false;
bool sWasDisconnection = false;
uint8_t sBtId = 0;

// Cast an intrusive list node to the containing request object
const BLEAdvertisingArbiter::Request & ToRequest(const sys_snode_t * node)
Expand Down Expand Up @@ -64,6 +67,11 @@ CHIP_ERROR RestartAdvertising()
const int result = bt_le_adv_start(&params, top.advertisingData.data(), top.advertisingData.size(), top.scanResponseData.data(),
top.scanResponseData.size());

if (result == -ENOMEM)
{
ChipLogProgress(DeviceLayer, "Advertising start failed, will retry once connection is released");
}

if (top.onStarted != nullptr)
{
top.onStarted(result);
Expand All @@ -72,6 +80,28 @@ CHIP_ERROR RestartAdvertising()
return System::MapErrorZephyr(result);
}

BT_CONN_CB_DEFINE(conn_callbacks) = {
.disconnected = [](struct bt_conn * conn, uint8_t reason) { sWasDisconnection = true; },
.recycled =
[]() {
// In this callback the connection object was returned to the pool and we can try to re-start connectable
// advertising, but only if the disconnection was detected.
if (sWasDisconnection)
{
SystemLayer().ScheduleLambda([] {
if (!sys_slist_is_empty(&sRequests))
{
// Starting from Zephyr 4.0 Automatic advertiser resumption is deprecated,
// so the BLE Advertising Arbiter has to take over the responsibility of restarting the advertiser.
// Restart advertising in this callback if there are pending requests after the connection is released.
RestartAdvertising();
}
});
// Reset the disconnection flag to avoid restarting advertising multiple times
sWasDisconnection = false;
}
},
};
} // namespace

CHIP_ERROR Init(uint8_t btId)
Expand Down
9 changes: 8 additions & 1 deletion src/platform/Zephyr/BLEManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include <zephyr/random/random.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/util.h>
#include <zephyr/version.h>

#ifdef CONFIG_BT_BONDABLE
#include <zephyr/settings/settings.h>
Expand All @@ -61,8 +62,14 @@ namespace Internal {

namespace {

#if KERNEL_VERSION_MAJOR >= 4
// In Zephyr 4.0 BT_LE_ADV_OPT_CONNECTABLE and BT_LE_ADV_OPT_ONE_TIME have been deprecated
// and replaced with BT_LE_ADV_OPT_CONN.
constexpr uint32_t kAdvertisingOptions = BT_LE_ADV_OPT_CONN;
#else
constexpr uint32_t kAdvertisingOptions = BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_ONE_TIME;
constexpr uint8_t kAdvertisingFlags = BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR;
#endif
constexpr uint8_t kAdvertisingFlags = BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR;

const bt_uuid_128 UUID128_CHIPoBLEChar_RX =
BT_UUID_INIT_128(0x11, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18);
Expand Down

0 comments on commit 93c7b09

Please sign in to comment.