Skip to content

Commit 0b0d116

Browse files
[zephyr] Added Bluetooth LE Extended Advertisement option (#33005)
This commit implements platform solution for a Bluetooth LE extended advertising. Additionally, for the CommissioningWindowManager types were changed from Seconds16 to Seconds32, because the current implementation overflows for 48h duration. Co-authored-by: Patryk Lipinski <patryk.lipinski@nordicsemi.no>
1 parent 35ced57 commit 0b0d116

9 files changed

+112
-31
lines changed

config/zephyr/Kconfig

+18
Original file line numberDiff line numberDiff line change
@@ -533,4 +533,22 @@ config CHIP_OTA_IMAGE_EXTRA_ARGS
533533

534534
endif
535535

536+
config CHIP_BLE_EXT_ADVERTISING
537+
bool "Bluetooth LE extended advertising"
538+
help
539+
Enable Bluetooth LE extended advertising, which allows the device to advertise
540+
Matter service over Bluetooth LE for a period of time longer than 15 minutes.
541+
If this config is true,
542+
CHIP_DEVICE_CONFIG_DISCOVERY_TIMEOUT_SECS define can be set up to 172800 seconds (48h).
543+
544+
config CHIP_BLE_ADVERTISING_DURATION
545+
int "Bluetooth LE advertising duration in minutes"
546+
range 15 2880 if CHIP_BLE_EXT_ADVERTISING
547+
range 0 15
548+
default 15
549+
help
550+
Specify how long the device will advertise Matter service over Bluetooth LE in minutes.
551+
If CHIP_BLE_EXT_ADVERTISING is set to false, the maximum duration time is 15 minutes,
552+
else the maximum duration time can be extended to 2880 minutes (48h).
553+
536554
endif

src/app/server/CommissioningWindowManager.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ void CommissioningWindowManager::OnSessionEstablished(const SessionHandle & sess
228228
}
229229
}
230230

231-
CHIP_ERROR CommissioningWindowManager::OpenCommissioningWindow(Seconds16 commissioningTimeout)
231+
CHIP_ERROR CommissioningWindowManager::OpenCommissioningWindow(Seconds32 commissioningTimeout)
232232
{
233233
VerifyOrReturnError(commissioningTimeout <= MaxCommissioningTimeout() && commissioningTimeout >= MinCommissioningTimeout(),
234234
CHIP_ERROR_INVALID_ARGUMENT);
@@ -288,7 +288,7 @@ CHIP_ERROR CommissioningWindowManager::AdvertiseAndListenForPASE()
288288
return CHIP_NO_ERROR;
289289
}
290290

291-
CHIP_ERROR CommissioningWindowManager::OpenBasicCommissioningWindow(Seconds16 commissioningTimeout,
291+
CHIP_ERROR CommissioningWindowManager::OpenBasicCommissioningWindow(Seconds32 commissioningTimeout,
292292
CommissioningWindowAdvertisement advertisementMode)
293293
{
294294
RestoreDiscriminator();
@@ -316,7 +316,7 @@ CHIP_ERROR CommissioningWindowManager::OpenBasicCommissioningWindow(Seconds16 co
316316

317317
CHIP_ERROR
318318
CommissioningWindowManager::OpenBasicCommissioningWindowForAdministratorCommissioningCluster(
319-
System::Clock::Seconds16 commissioningTimeout, FabricIndex fabricIndex, VendorId vendorId)
319+
System::Clock::Seconds32 commissioningTimeout, FabricIndex fabricIndex, VendorId vendorId)
320320
{
321321
ReturnErrorOnFailure(OpenBasicCommissioningWindow(commissioningTimeout, CommissioningWindowAdvertisement::kDnssdOnly));
322322

@@ -326,7 +326,7 @@ CommissioningWindowManager::OpenBasicCommissioningWindowForAdministratorCommissi
326326
return CHIP_NO_ERROR;
327327
}
328328

329-
CHIP_ERROR CommissioningWindowManager::OpenEnhancedCommissioningWindow(Seconds16 commissioningTimeout, uint16_t discriminator,
329+
CHIP_ERROR CommissioningWindowManager::OpenEnhancedCommissioningWindow(Seconds32 commissioningTimeout, uint16_t discriminator,
330330
Spake2pVerifier & verifier, uint32_t iterations,
331331
ByteSpan salt, FabricIndex fabricIndex, VendorId vendorId)
332332
{

src/app/server/CommissioningWindowManager.h

+11-11
Original file line numberDiff line numberDiff line change
@@ -58,21 +58,21 @@ class CommissioningWindowManager : public Messaging::UnsolicitedMessageHandler,
5858
return CHIP_NO_ERROR;
5959
}
6060

61-
static constexpr System::Clock::Seconds16 MaxCommissioningTimeout()
61+
static constexpr System::Clock::Seconds32 MaxCommissioningTimeout()
6262
{
6363
#if CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING
6464
// Specification section 2.3.1 - Extended Announcement Duration up to 48h
65-
return System::Clock::Seconds16(60 * 60 * 48);
65+
return System::Clock::Seconds32(60 * 60 * 48);
6666
#else
6767
// Specification section 5.4.2.3. Announcement Duration says 15 minutes.
68-
return System::Clock::Seconds16(15 * 60);
68+
return System::Clock::Seconds32(15 * 60);
6969
#endif
7070
}
7171

72-
System::Clock::Seconds16 MinCommissioningTimeout() const
72+
System::Clock::Seconds32 MinCommissioningTimeout() const
7373
{
7474
// Specification section 5.4.2.3. Announcement Duration says 3 minutes.
75-
return mMinCommissioningTimeoutOverride.ValueOr(System::Clock::Seconds16(3 * 60));
75+
return mMinCommissioningTimeoutOverride.ValueOr(System::Clock::Seconds32(3 * 60));
7676
}
7777

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

8888
/**
8989
* Open the pairing window using default configured parameters, triggered by
9090
* the Administrator Commmissioning cluster implementation.
9191
*/
9292
CHIP_ERROR
93-
OpenBasicCommissioningWindowForAdministratorCommissioningCluster(System::Clock::Seconds16 commissioningTimeout,
93+
OpenBasicCommissioningWindowForAdministratorCommissioningCluster(System::Clock::Seconds32 commissioningTimeout,
9494
FabricIndex fabricIndex, VendorId vendorId);
9595

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

@@ -128,7 +128,7 @@ class CommissioningWindowManager : public Messaging::UnsolicitedMessageHandler,
128128

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

133133
private:
134134
//////////// SessionDelegate Implementation ///////////////
@@ -146,7 +146,7 @@ class CommissioningWindowManager : public Messaging::UnsolicitedMessageHandler,
146146

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

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

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

224224
// The PASE session we are using, so we can handle CloseSession properly.
225225
SessionHolderWithDelegate mPASESession;

src/app/tests/TestCommissionManager.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ void CheckCommissioningWindowManagerWindowTimeoutTask(intptr_t context)
239239
NL_TEST_ASSERT(suite, !sAdminVendorIdDirty);
240240

241241
CommissioningWindowManager & commissionMgr = Server::GetInstance().GetCommissioningWindowManager();
242-
constexpr auto kTimeoutSeconds = chip::System::Clock::Seconds16(1);
242+
constexpr auto kTimeoutSeconds = chip::System::Clock::Seconds32(1);
243243
constexpr uint16_t kTimeoutMs = 1000;
244244
constexpr unsigned kSleepPadding = 100;
245245
commissionMgr.OverrideMinCommissioningTimeout(kTimeoutSeconds);

src/include/platform/ConnectivityManager.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,9 @@ class ConnectivityManager
138138

139139
enum BLEAdvertisingMode
140140
{
141-
kFastAdvertising = 0,
142-
kSlowAdvertising = 1,
141+
kFastAdvertising = 0,
142+
kSlowAdvertising = 1,
143+
kExtendedAdvertising = 2,
143144
};
144145

145146
enum class SEDIntervalMode

src/platform/Zephyr/BLEManagerImpl.cpp

+60-12
Original file line numberDiff line numberDiff line change
@@ -252,18 +252,39 @@ inline CHIP_ERROR BLEManagerImpl::PrepareAdvertisingRequest()
252252
Encoding::LittleEndian::Put16(serviceData.uuid, UUID16_CHIPoBLEService.val);
253253
ReturnErrorOnFailure(ConfigurationMgr().GetBLEDeviceIdentificationInfo(serviceData.deviceIdInfo));
254254

255+
#if CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING
256+
if (mFlags.Has(Flags::kExtendedAdvertisingEnabled))
257+
{
258+
serviceData.deviceIdInfo.SetVendorId(DEVICE_HANDLE_NULL);
259+
serviceData.deviceIdInfo.SetProductId(DEVICE_HANDLE_NULL);
260+
serviceData.deviceIdInfo.SetExtendedAnnouncementFlag(true);
261+
}
262+
#endif
263+
255264
advertisingData[0] = BT_DATA(BT_DATA_FLAGS, &kAdvertisingFlags, sizeof(kAdvertisingFlags));
256265
advertisingData[1] = BT_DATA(BT_DATA_SVC_DATA16, &serviceData, sizeof(serviceData));
257266
scanResponseData[0] = BT_DATA(BT_DATA_NAME_COMPLETE, name, nameSize);
258267

259-
mAdvertisingRequest.priority = CHIP_DEVICE_BLE_ADVERTISING_PRIORITY;
260-
mAdvertisingRequest.options = kAdvertisingOptions;
261-
mAdvertisingRequest.minInterval = mFlags.Has(Flags::kFastAdvertisingEnabled)
262-
? CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MIN
263-
: CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MIN;
264-
mAdvertisingRequest.maxInterval = mFlags.Has(Flags::kFastAdvertisingEnabled)
265-
? CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MAX
266-
: CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX;
268+
mAdvertisingRequest.priority = CHIP_DEVICE_BLE_ADVERTISING_PRIORITY;
269+
mAdvertisingRequest.options = kAdvertisingOptions;
270+
271+
if (mFlags.Has(Flags::kFastAdvertisingEnabled))
272+
{
273+
mAdvertisingRequest.minInterval = CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MIN;
274+
mAdvertisingRequest.maxInterval = CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MAX;
275+
}
276+
#if CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING
277+
else if (mFlags.Has(Flags::kExtendedAdvertisingEnabled))
278+
{
279+
mAdvertisingRequest.minInterval = CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING_INTERVAL_MIN;
280+
mAdvertisingRequest.maxInterval = CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING_INTERVAL_MAX;
281+
}
282+
#endif
283+
else
284+
{
285+
mAdvertisingRequest.minInterval = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MIN;
286+
mAdvertisingRequest.maxInterval = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX;
287+
}
267288
mAdvertisingRequest.advertisingData = Span<bt_data>(advertisingData);
268289
mAdvertisingRequest.scanResponseData = nameSize ? Span<bt_data>(scanResponseData) : Span<bt_data>{};
269290

@@ -322,10 +343,17 @@ CHIP_ERROR BLEManagerImpl::StartAdvertising()
322343

323344
if (mFlags.Has(Flags::kFastAdvertisingEnabled))
324345
{
325-
// Start timer to change advertising interval.
346+
// Start timer to change advertising interval from fast to slow.
326347
DeviceLayer::SystemLayer().StartTimer(
327348
System::Clock::Milliseconds32(CHIP_DEVICE_CONFIG_BLE_ADVERTISING_INTERVAL_CHANGE_TIME),
328-
HandleBLEAdvertisementIntervalChange, this);
349+
HandleSlowBLEAdvertisementInterval, this);
350+
351+
#if CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING
352+
// Start timer to schedule start of the extended advertising
353+
DeviceLayer::SystemLayer().StartTimer(
354+
System::Clock::Milliseconds32(CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING_INTERVAL_CHANGE_TIME_MS),
355+
HandleExtendedBLEAdvertisementInterval, this);
356+
#endif
329357
}
330358
}
331359

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

373+
#if CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING
374+
mFlags.Clear(Flags::kExtendedAdvertisingEnabled);
375+
#endif
376+
345377
ChipLogProgress(DeviceLayer, "CHIPoBLE advertising stopped");
346378

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

355387
// Cancel timer event changing CHIPoBLE advertisement interval
356-
DeviceLayer::SystemLayer().CancelTimer(HandleBLEAdvertisementIntervalChange, this);
388+
DeviceLayer::SystemLayer().CancelTimer(HandleSlowBLEAdvertisementInterval, this);
389+
DeviceLayer::SystemLayer().CancelTimer(HandleExtendedBLEAdvertisementInterval, this);
357390
}
358391

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

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

@@ -378,8 +414,14 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode)
378414
{
379415
case BLEAdvertisingMode::kFastAdvertising:
380416
mFlags.Set(Flags::kFastAdvertisingEnabled, true);
417+
mFlags.Set(Flags::kExtendedAdvertisingEnabled, false);
381418
break;
382419
case BLEAdvertisingMode::kSlowAdvertising:
420+
mFlags.Set(Flags::kFastAdvertisingEnabled, false);
421+
mFlags.Set(Flags::kExtendedAdvertisingEnabled, false);
422+
break;
423+
case BLEAdvertisingMode::kExtendedAdvertising:
424+
mFlags.Set(Flags::kExtendedAdvertisingEnabled, true);
383425
mFlags.Set(Flags::kFastAdvertisingEnabled, false);
384426
break;
385427
default:
@@ -570,12 +612,18 @@ CHIP_ERROR BLEManagerImpl::PrepareC3CharData()
570612
}
571613
#endif
572614

573-
void BLEManagerImpl::HandleBLEAdvertisementIntervalChange(System::Layer * layer, void * param)
615+
void BLEManagerImpl::HandleSlowBLEAdvertisementInterval(System::Layer * layer, void * param)
574616
{
575617
BLEMgr().SetAdvertisingMode(BLEAdvertisingMode::kSlowAdvertising);
576618
ChipLogProgress(DeviceLayer, "CHIPoBLE advertising mode changed to slow");
577619
}
578620

621+
void BLEManagerImpl::HandleExtendedBLEAdvertisementInterval(System::Layer * layer, void * param)
622+
{
623+
BLEMgr().SetAdvertisingMode(BLEAdvertisingMode::kExtendedAdvertising);
624+
ChipLogProgress(DeviceLayer, "CHIPoBLE advertising mode changed to extended");
625+
}
626+
579627
void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event)
580628
{
581629
CHIP_ERROR err = CHIP_NO_ERROR;

src/platform/Zephyr/BLEManagerImpl.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePla
9191
kAdvertisingRefreshNeeded =
9292
0x0010, /**< The advertising state/configuration has changed, but the SoftDevice has yet to be updated. */
9393
kChipoBleGattServiceRegister = 0x0020, /**< The system has currently CHIPoBLE GATT service registered. */
94+
kExtendedAdvertisingEnabled = 0x0040, /**< The application has enabled extended advertising. */
9495
};
9596

9697
struct ServiceData;
@@ -129,7 +130,8 @@ class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePla
129130
static void HandleTXIndicated(bt_conn * conn, bt_gatt_indicate_params * attr, uint8_t err);
130131
static void HandleConnect(bt_conn * conn, uint8_t err);
131132
static void HandleDisconnect(bt_conn * conn, uint8_t reason);
132-
static void HandleBLEAdvertisementIntervalChange(System::Layer * layer, void * param);
133+
static void HandleSlowBLEAdvertisementInterval(System::Layer * layer, void * param);
134+
static void HandleExtendedBLEAdvertisementInterval(System::Layer * layer, void * param);
133135

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

src/platform/Zephyr/CHIPDevicePlatformConfig.h

+6
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,9 @@
130130
#ifdef CONFIG_CHIP_EXTENDED_DISCOVERY
131131
#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1
132132
#endif // CONFIG_CHIP_EXTENDED_DISCOVERY
133+
134+
#ifdef CONFIG_CHIP_BLE_EXT_ADVERTISING
135+
#define CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING 1
136+
#endif // CONFIG_CHIP_BLE_EXT_ADVERTISING
137+
138+
#define CHIP_DEVICE_CONFIG_DISCOVERY_TIMEOUT_SECS (CONFIG_CHIP_BLE_ADVERTISING_DURATION * 60)

src/platform/nrfconnect/CHIPDevicePlatformConfig.h

+6
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,12 @@
212212
#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1
213213
#endif // CONFIG_CHIP_EXTENDED_DISCOVERY
214214

215+
#ifdef CONFIG_CHIP_BLE_EXT_ADVERTISING
216+
#define CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING 1
217+
#endif // CONFIG_CHIP_BLE_EXT_ADVERTISING
218+
219+
#define CHIP_DEVICE_CONFIG_DISCOVERY_TIMEOUT_SECS (CONFIG_CHIP_BLE_ADVERTISING_DURATION * 60)
220+
215221
#ifndef CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID_LENGTH
216222
#ifdef CONFIG_CHIP_FACTORY_DATA
217223
// 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

0 commit comments

Comments
 (0)