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

[zephyr] Added Bluetooth LE Extended Advertisement option #33005

Merged
merged 1 commit into from
Apr 17, 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
18 changes: 18 additions & 0 deletions config/zephyr/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -533,4 +533,22 @@ config CHIP_OTA_IMAGE_EXTRA_ARGS

endif

config CHIP_BLE_EXT_ADVERTISING
bool "Bluetooth LE extended advertising"
help
Enable Bluetooth LE extended advertising, which allows the device to advertise
Matter service over Bluetooth LE for a period of time longer than 15 minutes.
If this config is true,
CHIP_DEVICE_CONFIG_DISCOVERY_TIMEOUT_SECS define can be set up to 172800 seconds (48h).

config CHIP_BLE_ADVERTISING_DURATION
int "Bluetooth LE advertising duration in minutes"
range 15 2880 if CHIP_BLE_EXT_ADVERTISING
range 0 15
default 15
help
Specify how long the device will advertise Matter service over Bluetooth LE in minutes.
If CHIP_BLE_EXT_ADVERTISING is set to false, the maximum duration time is 15 minutes,
else the maximum duration time can be extended to 2880 minutes (48h).

endif
8 changes: 4 additions & 4 deletions src/app/server/CommissioningWindowManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ void CommissioningWindowManager::OnSessionEstablished(const SessionHandle & sess
}
}

CHIP_ERROR CommissioningWindowManager::OpenCommissioningWindow(Seconds16 commissioningTimeout)
CHIP_ERROR CommissioningWindowManager::OpenCommissioningWindow(Seconds32 commissioningTimeout)
{
VerifyOrReturnError(commissioningTimeout <= MaxCommissioningTimeout() && commissioningTimeout >= MinCommissioningTimeout(),
CHIP_ERROR_INVALID_ARGUMENT);
Expand Down Expand Up @@ -288,7 +288,7 @@ CHIP_ERROR CommissioningWindowManager::AdvertiseAndListenForPASE()
return CHIP_NO_ERROR;
}

CHIP_ERROR CommissioningWindowManager::OpenBasicCommissioningWindow(Seconds16 commissioningTimeout,
CHIP_ERROR CommissioningWindowManager::OpenBasicCommissioningWindow(Seconds32 commissioningTimeout,
CommissioningWindowAdvertisement advertisementMode)
{
RestoreDiscriminator();
Expand Down Expand Up @@ -316,7 +316,7 @@ CHIP_ERROR CommissioningWindowManager::OpenBasicCommissioningWindow(Seconds16 co

CHIP_ERROR
CommissioningWindowManager::OpenBasicCommissioningWindowForAdministratorCommissioningCluster(
System::Clock::Seconds16 commissioningTimeout, FabricIndex fabricIndex, VendorId vendorId)
System::Clock::Seconds32 commissioningTimeout, FabricIndex fabricIndex, VendorId vendorId)
{
ReturnErrorOnFailure(OpenBasicCommissioningWindow(commissioningTimeout, CommissioningWindowAdvertisement::kDnssdOnly));

Expand All @@ -326,7 +326,7 @@ CommissioningWindowManager::OpenBasicCommissioningWindowForAdministratorCommissi
return CHIP_NO_ERROR;
}

CHIP_ERROR CommissioningWindowManager::OpenEnhancedCommissioningWindow(Seconds16 commissioningTimeout, uint16_t discriminator,
CHIP_ERROR CommissioningWindowManager::OpenEnhancedCommissioningWindow(Seconds32 commissioningTimeout, uint16_t discriminator,
Spake2pVerifier & verifier, uint32_t iterations,
ByteSpan salt, FabricIndex fabricIndex, VendorId vendorId)
{
Expand Down
22 changes: 11 additions & 11 deletions src/app/server/CommissioningWindowManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,21 +58,21 @@ class CommissioningWindowManager : public Messaging::UnsolicitedMessageHandler,
return CHIP_NO_ERROR;
}

static constexpr System::Clock::Seconds16 MaxCommissioningTimeout()
static constexpr System::Clock::Seconds32 MaxCommissioningTimeout()
{
#if CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING
// Specification section 2.3.1 - Extended Announcement Duration up to 48h
return System::Clock::Seconds16(60 * 60 * 48);
return System::Clock::Seconds32(60 * 60 * 48);
#else
// Specification section 5.4.2.3. Announcement Duration says 15 minutes.
return System::Clock::Seconds16(15 * 60);
return System::Clock::Seconds32(15 * 60);
#endif
}

System::Clock::Seconds16 MinCommissioningTimeout() const
System::Clock::Seconds32 MinCommissioningTimeout() const
{
// Specification section 5.4.2.3. Announcement Duration says 3 minutes.
return mMinCommissioningTimeoutOverride.ValueOr(System::Clock::Seconds16(3 * 60));
return mMinCommissioningTimeoutOverride.ValueOr(System::Clock::Seconds32(3 * 60));
}

void SetAppDelegate(AppDelegate * delegate) { mAppDelegate = delegate; }
Expand All @@ -82,18 +82,18 @@ class CommissioningWindowManager : public Messaging::UnsolicitedMessageHandler,
*/
CHIP_ERROR
OpenBasicCommissioningWindow(
System::Clock::Seconds16 commissioningTimeout = System::Clock::Seconds16(CHIP_DEVICE_CONFIG_DISCOVERY_TIMEOUT_SECS),
System::Clock::Seconds32 commissioningTimeout = System::Clock::Seconds32(CHIP_DEVICE_CONFIG_DISCOVERY_TIMEOUT_SECS),
CommissioningWindowAdvertisement advertisementMode = chip::CommissioningWindowAdvertisement::kAllSupported);

/**
* Open the pairing window using default configured parameters, triggered by
* the Administrator Commmissioning cluster implementation.
*/
CHIP_ERROR
OpenBasicCommissioningWindowForAdministratorCommissioningCluster(System::Clock::Seconds16 commissioningTimeout,
OpenBasicCommissioningWindowForAdministratorCommissioningCluster(System::Clock::Seconds32 commissioningTimeout,
FabricIndex fabricIndex, VendorId vendorId);

CHIP_ERROR OpenEnhancedCommissioningWindow(System::Clock::Seconds16 commissioningTimeout, uint16_t discriminator,
CHIP_ERROR OpenEnhancedCommissioningWindow(System::Clock::Seconds32 commissioningTimeout, uint16_t discriminator,
Crypto::Spake2pVerifier & verifier, uint32_t iterations, chip::ByteSpan salt,
FabricIndex fabricIndex, VendorId vendorId);

Expand Down Expand Up @@ -128,7 +128,7 @@ class CommissioningWindowManager : public Messaging::UnsolicitedMessageHandler,

// For tests only, allow overriding the spec-defined minimum value of the
// commissioning window timeout.
void OverrideMinCommissioningTimeout(System::Clock::Seconds16 timeout) { mMinCommissioningTimeoutOverride.SetValue(timeout); }
void OverrideMinCommissioningTimeout(System::Clock::Seconds32 timeout) { mMinCommissioningTimeoutOverride.SetValue(timeout); }

private:
//////////// SessionDelegate Implementation ///////////////
Expand All @@ -146,7 +146,7 @@ class CommissioningWindowManager : public Messaging::UnsolicitedMessageHandler,

// Start a timer that will call HandleCommissioningWindowTimeout, and then
// start advertising and listen for PASE.
CHIP_ERROR OpenCommissioningWindow(System::Clock::Seconds16 commissioningTimeout);
CHIP_ERROR OpenCommissioningWindow(System::Clock::Seconds32 commissioningTimeout);

// Start advertising and listening for PASE connections. Should only be
// called when a commissioning window timeout timer is running.
Expand Down Expand Up @@ -219,7 +219,7 @@ class CommissioningWindowManager : public Messaging::UnsolicitedMessageHandler,

// For tests only, so that we can test the commissioning window timeout
// without having to wait 3 minutes.
Optional<System::Clock::Seconds16> mMinCommissioningTimeoutOverride;
Optional<System::Clock::Seconds32> mMinCommissioningTimeoutOverride;

// The PASE session we are using, so we can handle CloseSession properly.
SessionHolderWithDelegate mPASESession;
Expand Down
2 changes: 1 addition & 1 deletion src/app/tests/TestCommissionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ void CheckCommissioningWindowManagerWindowTimeoutTask(intptr_t context)
NL_TEST_ASSERT(suite, !sAdminVendorIdDirty);

CommissioningWindowManager & commissionMgr = Server::GetInstance().GetCommissioningWindowManager();
constexpr auto kTimeoutSeconds = chip::System::Clock::Seconds16(1);
constexpr auto kTimeoutSeconds = chip::System::Clock::Seconds32(1);
constexpr uint16_t kTimeoutMs = 1000;
constexpr unsigned kSleepPadding = 100;
commissionMgr.OverrideMinCommissioningTimeout(kTimeoutSeconds);
Expand Down
5 changes: 3 additions & 2 deletions src/include/platform/ConnectivityManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,9 @@ class ConnectivityManager

enum BLEAdvertisingMode
{
kFastAdvertising = 0,
kSlowAdvertising = 1,
kFastAdvertising = 0,
kSlowAdvertising = 1,
kExtendedAdvertising = 2,
};

enum class SEDIntervalMode
Expand Down
72 changes: 60 additions & 12 deletions src/platform/Zephyr/BLEManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,18 +252,39 @@ inline CHIP_ERROR BLEManagerImpl::PrepareAdvertisingRequest()
Encoding::LittleEndian::Put16(serviceData.uuid, UUID16_CHIPoBLEService.val);
ReturnErrorOnFailure(ConfigurationMgr().GetBLEDeviceIdentificationInfo(serviceData.deviceIdInfo));

#if CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING
if (mFlags.Has(Flags::kExtendedAdvertisingEnabled))
{
serviceData.deviceIdInfo.SetVendorId(DEVICE_HANDLE_NULL);
serviceData.deviceIdInfo.SetProductId(DEVICE_HANDLE_NULL);
serviceData.deviceIdInfo.SetExtendedAnnouncementFlag(true);
}
#endif

advertisingData[0] = BT_DATA(BT_DATA_FLAGS, &kAdvertisingFlags, sizeof(kAdvertisingFlags));
advertisingData[1] = BT_DATA(BT_DATA_SVC_DATA16, &serviceData, sizeof(serviceData));
scanResponseData[0] = BT_DATA(BT_DATA_NAME_COMPLETE, name, nameSize);

mAdvertisingRequest.priority = CHIP_DEVICE_BLE_ADVERTISING_PRIORITY;
mAdvertisingRequest.options = kAdvertisingOptions;
mAdvertisingRequest.minInterval = mFlags.Has(Flags::kFastAdvertisingEnabled)
? CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MIN
: CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MIN;
mAdvertisingRequest.maxInterval = mFlags.Has(Flags::kFastAdvertisingEnabled)
? CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MAX
: CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX;
mAdvertisingRequest.priority = CHIP_DEVICE_BLE_ADVERTISING_PRIORITY;
mAdvertisingRequest.options = kAdvertisingOptions;

if (mFlags.Has(Flags::kFastAdvertisingEnabled))
{
mAdvertisingRequest.minInterval = CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MIN;
mAdvertisingRequest.maxInterval = CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MAX;
}
#if CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING
else if (mFlags.Has(Flags::kExtendedAdvertisingEnabled))
{
mAdvertisingRequest.minInterval = CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING_INTERVAL_MIN;
mAdvertisingRequest.maxInterval = CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING_INTERVAL_MAX;
}
#endif
else
{
mAdvertisingRequest.minInterval = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MIN;
mAdvertisingRequest.maxInterval = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX;
}
mAdvertisingRequest.advertisingData = Span<bt_data>(advertisingData);
mAdvertisingRequest.scanResponseData = nameSize ? Span<bt_data>(scanResponseData) : Span<bt_data>{};

Expand Down Expand Up @@ -322,10 +343,17 @@ CHIP_ERROR BLEManagerImpl::StartAdvertising()

if (mFlags.Has(Flags::kFastAdvertisingEnabled))
{
// Start timer to change advertising interval.
// Start timer to change advertising interval from fast to slow.
DeviceLayer::SystemLayer().StartTimer(
System::Clock::Milliseconds32(CHIP_DEVICE_CONFIG_BLE_ADVERTISING_INTERVAL_CHANGE_TIME),
HandleBLEAdvertisementIntervalChange, this);
HandleSlowBLEAdvertisementInterval, this);

#if CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING
// Start timer to schedule start of the extended advertising
DeviceLayer::SystemLayer().StartTimer(
System::Clock::Milliseconds32(CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING_INTERVAL_CHANGE_TIME_MS),
HandleExtendedBLEAdvertisementInterval, this);
#endif
}
}

Expand All @@ -342,6 +370,10 @@ CHIP_ERROR BLEManagerImpl::StopAdvertising()
mFlags.Clear(Flags::kAdvertising);
mFlags.Set(Flags::kFastAdvertisingEnabled, true);

#if CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING
mFlags.Clear(Flags::kExtendedAdvertisingEnabled);
#endif

ChipLogProgress(DeviceLayer, "CHIPoBLE advertising stopped");

// Post a CHIPoBLEAdvertisingChange(Stopped) event.
Expand All @@ -353,7 +385,8 @@ CHIP_ERROR BLEManagerImpl::StopAdvertising()
}

// Cancel timer event changing CHIPoBLE advertisement interval
DeviceLayer::SystemLayer().CancelTimer(HandleBLEAdvertisementIntervalChange, this);
DeviceLayer::SystemLayer().CancelTimer(HandleSlowBLEAdvertisementInterval, this);
DeviceLayer::SystemLayer().CancelTimer(HandleExtendedBLEAdvertisementInterval, this);
}

return CHIP_NO_ERROR;
Expand All @@ -366,6 +399,9 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val)
ChipLogDetail(DeviceLayer, "CHIPoBLE advertising set to %s", val ? "on" : "off");

mFlags.Set(Flags::kAdvertisingEnabled, val);
// Ensure that each enabling/disabling of the standard advertising clears
// the extended mode flag.
mFlags.Set(Flags::kExtendedAdvertisingEnabled, false);
PlatformMgr().ScheduleWork(DriveBLEState, 0);
}

Expand All @@ -378,8 +414,14 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode)
{
case BLEAdvertisingMode::kFastAdvertising:
mFlags.Set(Flags::kFastAdvertisingEnabled, true);
mFlags.Set(Flags::kExtendedAdvertisingEnabled, false);
break;
case BLEAdvertisingMode::kSlowAdvertising:
mFlags.Set(Flags::kFastAdvertisingEnabled, false);
mFlags.Set(Flags::kExtendedAdvertisingEnabled, false);
break;
case BLEAdvertisingMode::kExtendedAdvertising:
mFlags.Set(Flags::kExtendedAdvertisingEnabled, true);
mFlags.Set(Flags::kFastAdvertisingEnabled, false);
break;
default:
Expand Down Expand Up @@ -570,12 +612,18 @@ CHIP_ERROR BLEManagerImpl::PrepareC3CharData()
}
#endif

void BLEManagerImpl::HandleBLEAdvertisementIntervalChange(System::Layer * layer, void * param)
void BLEManagerImpl::HandleSlowBLEAdvertisementInterval(System::Layer * layer, void * param)
{
BLEMgr().SetAdvertisingMode(BLEAdvertisingMode::kSlowAdvertising);
ChipLogProgress(DeviceLayer, "CHIPoBLE advertising mode changed to slow");
}

void BLEManagerImpl::HandleExtendedBLEAdvertisementInterval(System::Layer * layer, void * param)
{
BLEMgr().SetAdvertisingMode(BLEAdvertisingMode::kExtendedAdvertising);
ChipLogProgress(DeviceLayer, "CHIPoBLE advertising mode changed to extended");
}

void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event)
{
CHIP_ERROR err = CHIP_NO_ERROR;
Expand Down
4 changes: 3 additions & 1 deletion src/platform/Zephyr/BLEManagerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePla
kAdvertisingRefreshNeeded =
0x0010, /**< The advertising state/configuration has changed, but the SoftDevice has yet to be updated. */
kChipoBleGattServiceRegister = 0x0020, /**< The system has currently CHIPoBLE GATT service registered. */
kExtendedAdvertisingEnabled = 0x0040, /**< The application has enabled extended advertising. */
};

struct ServiceData;
Expand Down Expand Up @@ -129,7 +130,8 @@ class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePla
static void HandleTXIndicated(bt_conn * conn, bt_gatt_indicate_params * attr, uint8_t err);
static void HandleConnect(bt_conn * conn, uint8_t err);
static void HandleDisconnect(bt_conn * conn, uint8_t reason);
static void HandleBLEAdvertisementIntervalChange(System::Layer * layer, void * param);
static void HandleSlowBLEAdvertisementInterval(System::Layer * layer, void * param);
static void HandleExtendedBLEAdvertisementInterval(System::Layer * layer, void * param);

// ===== Members for internal use by the following friends.

Expand Down
6 changes: 6 additions & 0 deletions src/platform/Zephyr/CHIPDevicePlatformConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,9 @@
#ifdef CONFIG_CHIP_EXTENDED_DISCOVERY
#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1
#endif // CONFIG_CHIP_EXTENDED_DISCOVERY

#ifdef CONFIG_CHIP_BLE_EXT_ADVERTISING
#define CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING 1
#endif // CONFIG_CHIP_BLE_EXT_ADVERTISING

#define CHIP_DEVICE_CONFIG_DISCOVERY_TIMEOUT_SECS (CONFIG_CHIP_BLE_ADVERTISING_DURATION * 60)
6 changes: 6 additions & 0 deletions src/platform/nrfconnect/CHIPDevicePlatformConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,12 @@
#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1
#endif // CONFIG_CHIP_EXTENDED_DISCOVERY

#ifdef CONFIG_CHIP_BLE_EXT_ADVERTISING
#define CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING 1
#endif // CONFIG_CHIP_BLE_EXT_ADVERTISING

#define CHIP_DEVICE_CONFIG_DISCOVERY_TIMEOUT_SECS (CONFIG_CHIP_BLE_ADVERTISING_DURATION * 60)

#ifndef CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID_LENGTH
#ifdef CONFIG_CHIP_FACTORY_DATA
// UID will be copied from the externally programmed factory data, so we don't know the actual length and we need to assume some max
Expand Down
Loading