Skip to content
This repository was archived by the owner on Dec 20, 2023. It is now read-only.

Commit 8b97118

Browse files
author
Jay Logue
committed
BLEManager changes
-- Introduced a new WoBLEAdvertisingChange device event that gets generated whenever the BLEManager starts and stops WoBLE advertising. -- Added method to ConnectivityManager to determine whether WoBLE advertising is currently active. -- Fixed logic bugs in the transition between fast and slow WoBLE advertising. The system will now properly transition between the two modes when the device’s provisioning state changes, or when expressly asked to by the application. -- Eliminated subtle race condition on Nordic platforms where WoBLE would be disabled entirely due to an unexpected error from the SoftDevice if a connection arrived just as the BLEManager was updating the advertising configuration. -- Renamed BLEManager internal flag values and added documentation to make their meaning clearer.
1 parent 7691a8e commit 8b97118

File tree

8 files changed

+208
-68
lines changed

8 files changed

+208
-68
lines changed

src/adaptations/device-layer/ESP32/BLEManagerImpl.cpp

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -242,21 +242,26 @@ void BLEManagerImpl::_OnPlatformEvent(const WeaveDeviceEvent * event)
242242
HandleConnectionError(event->WoBLEConnectionError.ConId, event->WoBLEConnectionError.Reason);
243243
break;
244244

245-
// If WOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED is enabled, and there is a change to the
246-
// device's provisioning state, then automatically disable WoBLE advertising if the device
247-
// is now fully provisioned.
248-
#if WEAVE_DEVICE_CONFIG_WOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED
249245
case DeviceEventType::kFabricMembershipChange:
250246
case DeviceEventType::kServiceProvisioningChange:
251247
case DeviceEventType::kAccountPairingChange:
248+
249+
// If WOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED is enabled, and there is a change to the
250+
// device's provisioning state, then automatically disable WoBLE advertising if the device
251+
// is now fully provisioned.
252+
#if WEAVE_DEVICE_CONFIG_WOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED
252253
if (ConfigurationMgr().IsFullyProvisioned())
253254
{
254-
SetAdvertisingEnabled(false);
255+
ClearFlag(mFlags, kFlag_AdvertisingEnabled);
255256
WeaveLogProgress(DeviceLayer, "WoBLE advertising disabled because device is fully provisioned");
256257
}
257-
break;
258258
#endif // WEAVE_DEVICE_CONFIG_WOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED
259259

260+
// Force the advertising configuration to be refreshed to reflect new provisioning state.
261+
ClearFlag(mFlags, kFlag_AdvertisingConfigured);
262+
263+
DriveBLEState();
264+
260265
default:
261266
break;
262267
}
@@ -450,7 +455,7 @@ void BLEManagerImpl::DriveBLEState(void)
450455
}
451456

452457
// Start advertising if needed.
453-
if (!GetFlag(mFlags, kFlag_Advertising))
458+
if (!GetFlag(mFlags, kFlag_Advertising) || GetFlag(mFlags, kFlag_AdvertisingRefreshNeeded))
454459
{
455460
err = StartAdvertising();
456461
ExitNow();
@@ -694,9 +699,10 @@ WEAVE_ERROR BLEManagerImpl::StartAdvertising(void)
694699
bool connectable = (numCons < kMaxConnections);
695700
advertParams.adv_type = connectable ? ADV_TYPE_IND : ADV_TYPE_NONCONN_IND;
696701

697-
// Advertise in fast mode if not paired to an account and there are no WoBLE connections.
702+
// Advertise in fast mode if not fully provisioned and there are no WoBLE connections, or
703+
// if the application has expressly requested fast advertising.
698704
advertParams.adv_int_min = advertParams.adv_int_max =
699-
(numCons == 0 && !ConfigurationMgr().IsPairedToAccount())
705+
((numCons == 0 && !ConfigurationMgr().IsFullyProvisioned()) || GetFlag(mFlags, kFlag_FastAdvertisingEnabled))
700706
? WEAVE_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL
701707
: WEAVE_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL;
702708

@@ -839,8 +845,10 @@ void BLEManagerImpl::HandleGATTCommEvent(esp_gatts_cb_event_t event, esp_gatt_if
839845
// Allocate a connection state record for the new connection.
840846
GetConnectionState(param->mtu.conn_id, true);
841847

842-
// Receiving a connection stops the advertising processes, so update the advertising state accordingly.
843-
ClearFlag(mFlags, kFlag_Advertising);
848+
// Receiving a connection stops the advertising processes. So record that the advertising state
849+
// in the ESP BLE layer needs to be refreshed. If advertising should to be re-enabled, this will
850+
// be handled in DriveBLEState() the next time it runs.
851+
SetFlag(mFlags, kFlag_AdvertisingRefreshNeeded);
844852

845853
// Re-evaluate the advertising state in light of the new connection.
846854
PlatformMgr().ScheduleWork(DriveBLEState, 0);
@@ -1211,11 +1219,24 @@ void BLEManagerImpl::HandleGAPEvent(esp_gap_ble_cb_event_t event, esp_ble_gap_cb
12111219
ExitNow(err = ESP_ERR_INVALID_RESPONSE);
12121220
}
12131221

1214-
WeaveLogProgress(DeviceLayer, "WoBLE advertising started");
1215-
1216-
SetFlag(sInstance.mFlags, kFlag_Advertising);
12171222
ClearFlag(sInstance.mFlags, kFlag_ControlOpInProgress);
12181223

1224+
// Transition to the Advertising state...
1225+
if (!GetFlag(sInstance.mFlags, kFlag_Advertising))
1226+
{
1227+
WeaveLogProgress(DeviceLayer, "WoBLE advertising started");
1228+
1229+
SetFlag(sInstance.mFlags, kFlag_Advertising);
1230+
1231+
// Post a WoBLEAdvertisingChange(Started) event.
1232+
{
1233+
WeaveDeviceEvent advChange;
1234+
advChange.Type = DeviceEventType::kWoBLEAdvertisingChange;
1235+
advChange.WoBLEAdvertisingChange.Result = kActivity_Started;
1236+
PlatformMgr().PostEvent(&advChange);
1237+
}
1238+
}
1239+
12191240
break;
12201241

12211242
case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
@@ -1226,16 +1247,29 @@ void BLEManagerImpl::HandleGAPEvent(esp_gap_ble_cb_event_t event, esp_ble_gap_cb
12261247
ExitNow(err = ESP_ERR_INVALID_RESPONSE);
12271248
}
12281249

1229-
ClearFlag(sInstance.mFlags, kFlag_Advertising);
12301250
ClearFlag(sInstance.mFlags, kFlag_ControlOpInProgress);
12311251

1232-
WeaveLogProgress(DeviceLayer, "WoBLE advertising stopped");
1252+
// Transition to the not Advertising state...
1253+
if (GetFlag(sInstance.mFlags, kFlag_Advertising))
1254+
{
1255+
ClearFlag(sInstance.mFlags, kFlag_Advertising);
12331256

1234-
// Inform the ThreadStackManager that WoBLE advertising has stopped.
1257+
WeaveLogProgress(DeviceLayer, "WoBLE advertising stopped");
1258+
1259+
// Directly inform the ThreadStackManager that WoBLE advertising has stopped.
12351260
#if WEAVE_DEVICE_CONFIG_ENABLE_THREAD
1236-
ThreadStackMgr().OnWoBLEAdvertisingStop();
1261+
ThreadStackMgr().OnWoBLEAdvertisingStop();
12371262
#endif // WEAVE_DEVICE_CONFIG_ENABLE_THREAD
12381263

1264+
// Post a WoBLEAdvertisingChange(Stopped) event.
1265+
{
1266+
WeaveDeviceEvent advChange;
1267+
advChange.Type = DeviceEventType::kWoBLEAdvertisingChange;
1268+
advChange.WoBLEAdvertisingChange.Result = kActivity_Stopped;
1269+
PlatformMgr().PostEvent(&advChange);
1270+
}
1271+
}
1272+
12391273
break;
12401274

12411275
default:

src/adaptations/device-layer/include/Weave/DeviceLayer/ConnectivityManager.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ class ConnectivityManager
157157
WEAVE_ERROR SetBLEAdvertisingEnabled(bool val);
158158
bool IsBLEFastAdvertisingEnabled(void);
159159
WEAVE_ERROR SetBLEFastAdvertisingEnabled(bool val);
160+
bool IsBLEAdvertising(void);
160161
WEAVE_ERROR GetBLEDeviceName(char * buf, size_t bufSize);
161162
WEAVE_ERROR SetBLEDeviceName(const char * deviceName);
162163
uint16_t NumBLEConnections(void);
@@ -479,6 +480,11 @@ inline WEAVE_ERROR ConnectivityManager::SetBLEFastAdvertisingEnabled(bool val)
479480
return static_cast<ImplClass*>(this)->_SetBLEFastAdvertisingEnabled(val);
480481
}
481482

483+
inline bool ConnectivityManager::IsBLEAdvertising(void)
484+
{
485+
return static_cast<ImplClass*>(this)->_IsBLEAdvertising();
486+
}
487+
482488
inline WEAVE_ERROR ConnectivityManager::GetBLEDeviceName(char * buf, size_t bufSize)
483489
{
484490
return static_cast<ImplClass*>(this)->_GetBLEDeviceName(buf, bufSize);

src/adaptations/device-layer/include/Weave/DeviceLayer/ESP32/BLEManagerImpl.h

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class BLEManagerImpl final
5858
WEAVE_ERROR _SetAdvertisingEnabled(bool val);
5959
bool _IsFastAdvertisingEnabled(void);
6060
WEAVE_ERROR _SetFastAdvertisingEnabled(bool val);
61+
bool _IsAdvertising(void);
6162
WEAVE_ERROR _GetDeviceName(char * buf, size_t bufSize);
6263
WEAVE_ERROR _SetDeviceName(const char * deviceName);
6364
uint16_t _NumConnections(void);
@@ -90,18 +91,18 @@ class BLEManagerImpl final
9091

9192
enum
9293
{
93-
kFlag_AsyncInitCompleted = 0x0001,
94-
kFlag_ESPBLELayerInitialized = 0x0002,
95-
kFlag_AppRegistered = 0x0004,
96-
kFlag_AttrsRegistered = 0x0008,
97-
kFlag_GATTServiceStarted = 0x0010,
98-
kFlag_AdvertisingConfigured = 0x0020,
99-
kFlag_Advertising = 0x0040,
100-
kFlag_ControlOpInProgress = 0x0080,
101-
102-
kFlag_AdvertisingEnabled = 0x0100,
103-
kFlag_FastAdvertisingEnabled = 0x0200,
104-
kFlag_UseCustomDeviceName = 0x0400,
94+
kFlag_AsyncInitCompleted = 0x0001, /**< One-time asynchronous initialization actions have been performed. */
95+
kFlag_ESPBLELayerInitialized = 0x0002, /**< The ESP BLE layer has been initialized. */
96+
kFlag_AppRegistered = 0x0004, /**< The WoBLE application has been registered with the ESP BLE layer. */
97+
kFlag_AttrsRegistered = 0x0008, /**< The WoBLE GATT attributes have been registered with the ESP BLE layer. */
98+
kFlag_GATTServiceStarted = 0x0010, /**< The WoBLE GATT service has been started. */
99+
kFlag_AdvertisingConfigured = 0x0020, /**< WoBLE advertising has been configured in the ESP BLE layer. */
100+
kFlag_Advertising = 0x0040, /**< The system is currently WoBLE advertising. */
101+
kFlag_ControlOpInProgress = 0x0080, /**< An async control operation has been issued to the ESP BLE layer. */
102+
kFlag_AdvertisingEnabled = 0x0100, /**< The application has enabled WoBLE advertising. */
103+
kFlag_FastAdvertisingEnabled = 0x0200, /**< The application has enabled fast advertising. */
104+
kFlag_UseCustomDeviceName = 0x0400, /**< The application has configured a custom BLE device name. */
105+
kFlag_AdvertisingRefreshNeeded = 0x0800, /**< The advertising state in ESP BLE layer needs to be updated. */
105106
};
106107

107108
enum
@@ -192,6 +193,11 @@ inline bool BLEManagerImpl::_IsFastAdvertisingEnabled(void)
192193
return GetFlag(mFlags, kFlag_FastAdvertisingEnabled);
193194
}
194195

196+
inline bool BLEManagerImpl::_IsAdvertising(void)
197+
{
198+
return GetFlag(mFlags, kFlag_Advertising);
199+
}
200+
195201
} // namespace Internal
196202
} // namespace DeviceLayer
197203
} // namespace Weave

src/adaptations/device-layer/include/Weave/DeviceLayer/WeaveDeviceEvent.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,13 @@ enum PublicEventTypes
189189
* Signals that the state of the Thread network interface has changed.
190190
*/
191191
kThreadInterfaceStateChange,
192+
193+
/**
194+
* Weave-over-BLE (WoBLE) Advertising Change
195+
*
196+
* Signals that the state of WoBLE advertising has changed.
197+
*/
198+
kWoBLEAdvertisingChange,
192199
};
193200

194201
/**
@@ -226,6 +233,18 @@ enum ConnectivityChange
226233
kConnectivity_Lost = -1
227234
};
228235

236+
/**
237+
* Activity Change
238+
*
239+
* Describes a change in some activity associated with a Weave device.
240+
*/
241+
enum ActivityChange
242+
{
243+
kActivity_NoChange = 0,
244+
kActivity_Started = 1,
245+
kActivity_Stopped = -1,
246+
};
247+
229248
inline ConnectivityChange GetConnectivityChange(bool prevState, bool newState)
230249
{
231250
if (prevState == newState)
@@ -374,6 +393,10 @@ struct WeaveDeviceEvent final
374393
uint32_t Flags;
375394
} OpenThread;
376395
} ThreadStateChange;
396+
struct
397+
{
398+
ActivityChange Result;
399+
} WoBLEAdvertisingChange;
377400
};
378401

379402
void Clear() { memset(this, 0, sizeof(*this)); }

src/adaptations/device-layer/include/Weave/DeviceLayer/internal/BLEManager.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class BLEManager
5959
WEAVE_ERROR SetAdvertisingEnabled(bool val);
6060
bool IsFastAdvertisingEnabled(void);
6161
WEAVE_ERROR SetFastAdvertisingEnabled(bool val);
62+
bool IsAdvertising(void);
6263
WEAVE_ERROR GetDeviceName(char * buf, size_t bufSize);
6364
WEAVE_ERROR SetDeviceName(const char * deviceName);
6465
uint16_t NumConnections(void);
@@ -148,6 +149,11 @@ inline WEAVE_ERROR BLEManager::SetFastAdvertisingEnabled(bool val)
148149
return static_cast<ImplClass*>(this)->_SetFastAdvertisingEnabled(val);
149150
}
150151

152+
inline bool BLEManager::IsAdvertising(void)
153+
{
154+
return static_cast<ImplClass*>(this)->_IsAdvertising();
155+
}
156+
151157
inline WEAVE_ERROR BLEManager::GetDeviceName(char * buf, size_t bufSize)
152158
{
153159
return static_cast<ImplClass*>(this)->_GetDeviceName(buf, bufSize);

src/adaptations/device-layer/include/Weave/DeviceLayer/internal/GenericConnectivityManagerImpl_BLE.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class GenericConnectivityManagerImpl_BLE
6161
WEAVE_ERROR _SetBLEAdvertisingEnabled(bool val);
6262
bool _IsBLEFastAdvertisingEnabled(void);
6363
WEAVE_ERROR _SetBLEFastAdvertisingEnabled(bool val);
64+
bool _IsBLEAdvertising(void);
6465
WEAVE_ERROR _GetBLEDeviceName(char * buf, size_t bufSize);
6566
WEAVE_ERROR _SetBLEDeviceName(const char * deviceName);
6667
uint16_t _NumBLEConnections(void);
@@ -110,6 +111,12 @@ inline WEAVE_ERROR GenericConnectivityManagerImpl_BLE<ImplClass>::_SetBLEFastAdv
110111
return BLEMgr().SetFastAdvertisingEnabled(val);
111112
}
112113

114+
template<class ImplClass>
115+
inline bool GenericConnectivityManagerImpl_BLE<ImplClass>::_IsBLEAdvertising(void)
116+
{
117+
return BLEMgr().IsAdvertising();
118+
}
119+
113120
template<class ImplClass>
114121
inline WEAVE_ERROR GenericConnectivityManagerImpl_BLE<ImplClass>::_GetBLEDeviceName(char * buf, size_t bufSize)
115122
{

src/adaptations/device-layer/include/Weave/DeviceLayer/nRF5/BLEManagerImpl.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class BLEManagerImpl final
5757
WEAVE_ERROR _SetAdvertisingEnabled(bool val);
5858
bool _IsFastAdvertisingEnabled(void);
5959
WEAVE_ERROR _SetFastAdvertisingEnabled(bool val);
60+
bool _IsAdvertising(void);
6061
WEAVE_ERROR _GetDeviceName(char * buf, size_t bufSize);
6162
WEAVE_ERROR _SetDeviceName(const char * deviceName);
6263
uint16_t _NumConnections(void);
@@ -89,11 +90,11 @@ class BLEManagerImpl final
8990

9091
enum
9192
{
92-
kFlag_AsyncInitCompleted = 0x0001,
93-
kFlag_AdvertisingEnabled = 0x0002,
94-
kFlag_FastAdvertisingEnabled = 0x0004,
95-
kFlag_Advertising = 0x0008,
96-
kFlag_AdvertisingConfigChangePending = 0x0010,
93+
kFlag_AsyncInitCompleted = 0x0001, /**< One-time asynchronous initialization actions have been performed. */
94+
kFlag_AdvertisingEnabled = 0x0002, /**< The application has enabled WoBLE advertising. */
95+
kFlag_FastAdvertisingEnabled = 0x0004, /**< The application has enabled fast advertising. */
96+
kFlag_Advertising = 0x0008, /**< The system is currently WoBLE advertising. */
97+
kFlag_AdvertisingRefreshNeeded = 0x0010, /**< The advertising state/configuration has changed, but the SoftDevice has yet to be updated. */
9798
};
9899

99100
enum
@@ -174,6 +175,11 @@ inline bool BLEManagerImpl::_IsFastAdvertisingEnabled(void)
174175
return GetFlag(mFlags, kFlag_FastAdvertisingEnabled);
175176
}
176177

178+
inline bool BLEManagerImpl::_IsAdvertising(void)
179+
{
180+
return GetFlag(mFlags, kFlag_Advertising);
181+
}
182+
177183
} // namespace Internal
178184
} // namespace DeviceLayer
179185
} // namespace Weave

0 commit comments

Comments
 (0)