Skip to content

Commit 8f4c8b5

Browse files
authored
[Linux] Do not report BLE scan error if BlueZ is gone (project-chip#32586)
* [Linux] Do not report BLE scan error if BlueZ is gone * Wrap GDBusObjectManager with GAutoPtr * Wrap glib callbacks with lambda * Wrap start/stop implementations with lambda * Fix signal handler type
1 parent 1ef9228 commit 8f4c8b5

File tree

2 files changed

+74
-63
lines changed

2 files changed

+74
-63
lines changed

src/platform/Linux/bluez/ChipDeviceScanner.cpp

+63-52
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,11 @@ CHIP_ERROR ChipDeviceScanner::Init(BluezAdapter1 * adapter, ChipDeviceScannerDel
6969
VerifyOrDie(g_main_context_get_thread_default() != nullptr);
7070

7171
GAutoPtr<GError> err;
72-
self->mManager = g_dbus_object_manager_client_new_for_bus_sync(
72+
self->mManager.reset(g_dbus_object_manager_client_new_for_bus_sync(
7373
G_BUS_TYPE_SYSTEM, G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, BLUEZ_INTERFACE, "/",
7474
bluez_object_manager_client_get_proxy_type, nullptr /* unused user data in the Proxy Type Func */,
75-
nullptr /* destroy notify */, nullptr /* cancellable */, &err.GetReceiver());
76-
VerifyOrReturnError(self->mManager != nullptr, CHIP_ERROR_INTERNAL,
75+
nullptr /* destroy notify */, nullptr /* cancellable */, &err.GetReceiver()));
76+
VerifyOrReturnError(self->mManager, CHIP_ERROR_INTERNAL,
7777
ChipLogError(Ble, "Failed to get D-Bus object manager for device scanning: %s", err->message));
7878
return CHIP_NO_ERROR;
7979
},
@@ -95,8 +95,7 @@ void ChipDeviceScanner::Shutdown()
9595
// released during a D-Bus signal being processed.
9696
PlatformMgrImpl().GLibMatterContextInvokeSync(
9797
+[](ChipDeviceScanner * self) {
98-
if (self->mManager != nullptr)
99-
g_object_unref(self->mManager);
98+
self->mManager.reset();
10099
self->mAdapter.reset();
101100
return CHIP_NO_ERROR;
102101
},
@@ -112,7 +111,8 @@ CHIP_ERROR ChipDeviceScanner::StartScan(System::Clock::Timeout timeout)
112111
VerifyOrReturnError(mTimerState == ScannerTimerState::TIMER_CANCELED, CHIP_ERROR_INCORRECT_STATE);
113112

114113
mCancellable.reset(g_cancellable_new());
115-
CHIP_ERROR err = PlatformMgrImpl().GLibMatterContextInvokeSync(MainLoopStartScan, this);
114+
CHIP_ERROR err = PlatformMgrImpl().GLibMatterContextInvokeSync(
115+
+[](ChipDeviceScanner * self) { return self->StartScanImpl(); }, this);
116116
if (err != CHIP_NO_ERROR)
117117
{
118118
ChipLogError(Ble, "Failed to initiate BLE scan start: %" CHIP_ERROR_FORMAT, err.Format());
@@ -153,7 +153,8 @@ CHIP_ERROR ChipDeviceScanner::StopScan()
153153
assertChipStackLockedByCurrentThread();
154154
VerifyOrReturnError(mScannerState == ChipDeviceScannerState::SCANNER_SCANNING, CHIP_NO_ERROR);
155155

156-
CHIP_ERROR err = PlatformMgrImpl().GLibMatterContextInvokeSync(MainLoopStopScan, this);
156+
CHIP_ERROR err = PlatformMgrImpl().GLibMatterContextInvokeSync(
157+
+[](ChipDeviceScanner * self) { return self->StopScanImpl(); }, this);
157158
if (err != CHIP_NO_ERROR)
158159
{
159160
ChipLogError(Ble, "Failed to initiate BLE scan stop: %" CHIP_ERROR_FORMAT, err.Format());
@@ -178,59 +179,63 @@ CHIP_ERROR ChipDeviceScanner::StopScan()
178179
return CHIP_NO_ERROR;
179180
}
180181

181-
CHIP_ERROR ChipDeviceScanner::MainLoopStopScan(ChipDeviceScanner * self)
182+
CHIP_ERROR ChipDeviceScanner::StopScanImpl()
182183
{
183-
GAutoPtr<GError> error;
184184

185185
// In case we are currently running a scan
186-
g_cancellable_cancel(self->mCancellable.get());
187-
self->mCancellable.reset();
186+
g_cancellable_cancel(mCancellable.get());
187+
mCancellable.reset();
188188

189-
if (self->mObjectAddedSignal)
189+
if (mObjectAddedSignal)
190190
{
191-
g_signal_handler_disconnect(self->mManager, self->mObjectAddedSignal);
192-
self->mObjectAddedSignal = 0;
191+
g_signal_handler_disconnect(mManager.get(), mObjectAddedSignal);
192+
mObjectAddedSignal = 0;
193193
}
194194

195-
if (self->mInterfaceChangedSignal)
195+
if (mPropertiesChangedSignal)
196196
{
197-
g_signal_handler_disconnect(self->mManager, self->mInterfaceChangedSignal);
198-
self->mInterfaceChangedSignal = 0;
197+
g_signal_handler_disconnect(mManager.get(), mPropertiesChangedSignal);
198+
mPropertiesChangedSignal = 0;
199199
}
200200

201-
if (!bluez_adapter1_call_stop_discovery_sync(self->mAdapter.get(), nullptr /* not cancellable */, &error.GetReceiver()))
201+
GAutoPtr<GError> error;
202+
if (!bluez_adapter1_call_stop_discovery_sync(mAdapter.get(), nullptr /* not cancellable */, &error.GetReceiver()))
202203
{
203-
ChipLogError(Ble, "Failed to stop discovery %s", error->message);
204-
return CHIP_ERROR_INTERNAL;
204+
// Do not report error if BlueZ service is not available on the bus (service unknown) or
205+
// the requested BLE adapter is not available (unknown object). In both cases the scan is
206+
// already stopped.
207+
if (error->code != G_DBUS_ERROR_SERVICE_UNKNOWN && error->code != G_DBUS_ERROR_UNKNOWN_OBJECT)
208+
{
209+
ChipLogError(Ble, "Failed to stop discovery: %s", error->message);
210+
return CHIP_ERROR_INTERNAL;
211+
}
205212
}
206213

207214
return CHIP_NO_ERROR;
208215
}
209216

210-
void ChipDeviceScanner::SignalObjectAdded(GDBusObjectManager * manager, GDBusObject * object, ChipDeviceScanner * self)
217+
void ChipDeviceScanner::SignalObjectAdded(GDBusObjectManager * aManager, GDBusObject * aObject)
211218
{
212-
GAutoPtr<BluezDevice1> device(bluez_object_get_device1(reinterpret_cast<BluezObject *>(object)));
213-
VerifyOrReturn(device.get() != nullptr);
219+
GAutoPtr<BluezDevice1> device(bluez_object_get_device1(reinterpret_cast<BluezObject *>(aObject)));
220+
VerifyOrReturn(device);
214221

215-
self->ReportDevice(*device.get());
222+
ReportDevice(*device.get());
216223
}
217224

218-
void ChipDeviceScanner::SignalInterfaceChanged(GDBusObjectManagerClient * manager, GDBusObjectProxy * object,
219-
GDBusProxy * aInterface, GVariant * aChangedProperties,
220-
const gchar * const * aInvalidatedProps, ChipDeviceScanner * self)
225+
void ChipDeviceScanner::SignalInterfacePropertiesChanged(GDBusObjectManagerClient * aManager, GDBusObjectProxy * aObject,
226+
GDBusProxy * aInterface, GVariant * aChangedProperties,
227+
const char * const * aInvalidatedProps)
221228
{
222-
GAutoPtr<BluezDevice1> device(bluez_object_get_device1(reinterpret_cast<BluezObject *>(object)));
223-
VerifyOrReturn(device.get() != nullptr);
229+
GAutoPtr<BluezDevice1> device(bluez_object_get_device1(reinterpret_cast<BluezObject *>(aObject)));
230+
VerifyOrReturn(device);
224231

225-
self->ReportDevice(*device.get());
232+
ReportDevice(*device.get());
226233
}
227234

228235
void ChipDeviceScanner::ReportDevice(BluezDevice1 & device)
229236
{
230-
if (strcmp(bluez_device1_get_adapter(&device), g_dbus_proxy_get_object_path(G_DBUS_PROXY(mAdapter.get()))) != 0)
231-
{
232-
return;
233-
}
237+
VerifyOrReturn(strcmp(bluez_device1_get_adapter(&device),
238+
g_dbus_proxy_get_object_path(reinterpret_cast<GDBusProxy *>(mAdapter.get()))) == 0);
234239

235240
chip::Ble::ChipBLEDeviceIdentificationInfo deviceInfo;
236241

@@ -245,10 +250,8 @@ void ChipDeviceScanner::ReportDevice(BluezDevice1 & device)
245250

246251
void ChipDeviceScanner::RemoveDevice(BluezDevice1 & device)
247252
{
248-
if (strcmp(bluez_device1_get_adapter(&device), g_dbus_proxy_get_object_path(G_DBUS_PROXY(mAdapter.get()))) != 0)
249-
{
250-
return;
251-
}
253+
VerifyOrReturn(strcmp(bluez_device1_get_adapter(&device),
254+
g_dbus_proxy_get_object_path(reinterpret_cast<GDBusProxy *>(mAdapter.get()))) == 0);
252255

253256
chip::Ble::ChipBLEDeviceIdentificationInfo deviceInfo;
254257

@@ -257,30 +260,39 @@ void ChipDeviceScanner::RemoveDevice(BluezDevice1 & device)
257260
return;
258261
}
259262

260-
const auto devicePath = g_dbus_proxy_get_object_path(G_DBUS_PROXY(&device));
261263
GAutoPtr<GError> error;
262-
264+
const auto devicePath = g_dbus_proxy_get_object_path(reinterpret_cast<GDBusProxy *>(&device));
263265
if (!bluez_adapter1_call_remove_device_sync(mAdapter.get(), devicePath, nullptr, &error.GetReceiver()))
264266
{
265267
ChipLogDetail(Ble, "Failed to remove device %s: %s", StringOrNullMarker(devicePath), error->message);
266268
}
267269
}
268270

269-
CHIP_ERROR ChipDeviceScanner::MainLoopStartScan(ChipDeviceScanner * self)
271+
CHIP_ERROR ChipDeviceScanner::StartScanImpl()
270272
{
271273
GAutoPtr<GError> error;
272274

273-
self->mObjectAddedSignal = g_signal_connect(self->mManager, "object-added", G_CALLBACK(SignalObjectAdded), self);
274-
self->mInterfaceChangedSignal =
275-
g_signal_connect(self->mManager, "interface-proxy-properties-changed", G_CALLBACK(SignalInterfaceChanged), self);
275+
mObjectAddedSignal = g_signal_connect(mManager.get(), "object-added",
276+
G_CALLBACK(+[](GDBusObjectManager * aMgr, GDBusObject * aObj, ChipDeviceScanner * self) {
277+
return self->SignalObjectAdded(aMgr, aObj);
278+
}),
279+
this);
280+
281+
mPropertiesChangedSignal = g_signal_connect(
282+
mManager.get(), "interface-proxy-properties-changed",
283+
G_CALLBACK(+[](GDBusObjectManagerClient * aMgr, GDBusObjectProxy * aObj, GDBusProxy * aIface, GVariant * aChangedProps,
284+
const char * const * aInvalidatedProps, ChipDeviceScanner * self) {
285+
return self->SignalInterfacePropertiesChanged(aMgr, aObj, aIface, aChangedProps, aInvalidatedProps);
286+
}),
287+
this);
276288

277-
ChipLogProgress(Ble, "BLE removing known devices.");
278-
for (BluezObject & object : BluezObjectList(self->mManager))
289+
ChipLogProgress(Ble, "BLE removing known devices");
290+
for (BluezObject & object : BluezObjectList(mManager.get()))
279291
{
280292
GAutoPtr<BluezDevice1> device(bluez_object_get_device1(&object));
281-
if (device.get() != nullptr)
293+
if (device)
282294
{
283-
self->RemoveDevice(*device.get());
295+
RemoveDevice(*device.get());
284296
}
285297
}
286298

@@ -295,16 +307,15 @@ CHIP_ERROR ChipDeviceScanner::MainLoopStartScan(ChipDeviceScanner * self)
295307
g_variant_builder_add(&filterBuilder, "{sv}", "Transport", g_variant_new_string("le"));
296308
GVariant * filter = g_variant_builder_end(&filterBuilder);
297309

298-
if (!bluez_adapter1_call_set_discovery_filter_sync(self->mAdapter.get(), filter, self->mCancellable.get(),
299-
&error.GetReceiver()))
310+
if (!bluez_adapter1_call_set_discovery_filter_sync(mAdapter.get(), filter, mCancellable.get(), &error.GetReceiver()))
300311
{
301312
// Not critical: ignore if fails
302313
ChipLogError(Ble, "Failed to set discovery filters: %s", error->message);
303314
error.reset();
304315
}
305316

306-
ChipLogProgress(Ble, "BLE initiating scan.");
307-
if (!bluez_adapter1_call_start_discovery_sync(self->mAdapter.get(), self->mCancellable.get(), &error.GetReceiver()))
317+
ChipLogProgress(Ble, "BLE initiating scan");
318+
if (!bluez_adapter1_call_start_discovery_sync(mAdapter.get(), mCancellable.get(), &error.GetReceiver()))
308319
{
309320
ChipLogError(Ble, "Failed to start discovery: %s", error->message);
310321
return CHIP_ERROR_INTERNAL;

src/platform/Linux/bluez/ChipDeviceScanner.h

+11-11
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,13 @@ class ChipDeviceScanner
9292
TIMER_EXPIRED
9393
};
9494

95+
CHIP_ERROR StartScanImpl();
96+
CHIP_ERROR StopScanImpl();
9597
static void TimerExpiredCallback(chip::System::Layer * layer, void * appState);
96-
static CHIP_ERROR MainLoopStartScan(ChipDeviceScanner * self);
97-
static CHIP_ERROR MainLoopStopScan(ChipDeviceScanner * self);
98-
static void SignalObjectAdded(GDBusObjectManager * manager, GDBusObject * object, ChipDeviceScanner * self);
99-
static void SignalInterfaceChanged(GDBusObjectManagerClient * manager, GDBusObjectProxy * object, GDBusProxy * aInterface,
100-
GVariant * aChangedProperties, const gchar * const * aInvalidatedProps,
101-
ChipDeviceScanner * self);
98+
99+
void SignalObjectAdded(GDBusObjectManager * aManager, GDBusObject * aObject);
100+
void SignalInterfacePropertiesChanged(GDBusObjectManagerClient * aManager, GDBusObjectProxy * aObject, GDBusProxy * aInterface,
101+
GVariant * aChangedProperties, const char * const * aInvalidatedProps);
102102

103103
/// Check if a given device is a CHIP device and if yes, report it as discovered
104104
void ReportDevice(BluezDevice1 & device);
@@ -107,12 +107,12 @@ class ChipDeviceScanner
107107
/// so that it can be re-discovered if it's still advertising.
108108
void RemoveDevice(BluezDevice1 & device);
109109

110-
GDBusObjectManager * mManager = nullptr;
110+
GAutoPtr<GDBusObjectManager> mManager;
111111
GAutoPtr<BluezAdapter1> mAdapter;
112-
ChipDeviceScannerDelegate * mDelegate = nullptr;
113-
gulong mObjectAddedSignal = 0;
114-
gulong mInterfaceChangedSignal = 0;
115-
ChipDeviceScannerState mScannerState = ChipDeviceScannerState::SCANNER_UNINITIALIZED;
112+
ChipDeviceScannerDelegate * mDelegate = nullptr;
113+
unsigned long mObjectAddedSignal = 0;
114+
unsigned long mPropertiesChangedSignal = 0;
115+
ChipDeviceScannerState mScannerState = ChipDeviceScannerState::SCANNER_UNINITIALIZED;
116116
/// Used to track if timer has already expired and doesn't need to be canceled.
117117
ScannerTimerState mTimerState = ScannerTimerState::TIMER_CANCELED;
118118
GAutoPtr<GCancellable> mCancellable;

0 commit comments

Comments
 (0)