24
24
#include < glib-object.h>
25
25
#include < glib.h>
26
26
27
+ #include < ble/BleError.h>
27
28
#include < lib/support/CodeUtils.h>
28
29
#include < lib/support/logging/CHIPLogging.h>
29
30
#include < platform/ConfigurationManager.h>
@@ -109,15 +110,13 @@ CHIP_ERROR BluezAdvertisement::InitImpl()
109
110
110
111
CHIP_ERROR BluezAdvertisement::Init (const BluezEndpoint & aEndpoint, const char * aAdvUUID, const char * aAdvName)
111
112
{
112
- GAutoPtr<char > rootPath;
113
- CHIP_ERROR err;
114
-
115
- VerifyOrExit (!mAdv , err = CHIP_ERROR_INCORRECT_STATE;
116
- ChipLogError (DeviceLayer, " FAIL: BLE advertisement already initialized in %s" , __func__));
113
+ VerifyOrReturnError (!mAdv , CHIP_ERROR_INCORRECT_STATE,
114
+ ChipLogError (DeviceLayer, " FAIL: BLE advertisement already initialized in %s" , __func__));
117
115
118
116
mRoot .reset (reinterpret_cast <GDBusObjectManagerServer *>(g_object_ref (aEndpoint.GetGattApplicationObjectManager ())));
119
117
mAdapter .reset (reinterpret_cast <BluezAdapter1 *>(g_object_ref (aEndpoint.GetAdapter ())));
120
118
119
+ GAutoPtr<char > rootPath;
121
120
g_object_get (G_OBJECT (mRoot .get ()), " object-path" , &rootPath.GetReceiver (), nullptr );
122
121
g_snprintf (mAdvPath , sizeof (mAdvPath ), " %s/advertising" , rootPath.get ());
123
122
g_strlcpy (mAdvUUID , aAdvUUID, sizeof (mAdvUUID ));
@@ -132,15 +131,13 @@ CHIP_ERROR BluezAdvertisement::Init(const BluezEndpoint & aEndpoint, const char
132
131
g_snprintf (mAdvName , sizeof (mAdvName ), " %s%04x" , CHIP_DEVICE_CONFIG_BLE_DEVICE_NAME_PREFIX, getpid () & 0xffff );
133
132
}
134
133
135
- err = PlatformMgrImpl ().GLibMatterContextInvokeSync (
134
+ CHIP_ERROR err = PlatformMgrImpl ().GLibMatterContextInvokeSync (
136
135
+[](BluezAdvertisement * self) { return self->InitImpl (); }, this );
137
- VerifyOrReturnError (err == CHIP_NO_ERROR, CHIP_ERROR_INCORRECT_STATE ,
136
+ VerifyOrReturnError (err == CHIP_NO_ERROR, err ,
138
137
ChipLogError (Ble, " Failed to schedule BLE advertisement Init() on CHIPoBluez thread" ));
139
138
140
139
mIsInitialized = true ;
141
-
142
- exit :
143
- return err;
140
+ return CHIP_NO_ERROR;
144
141
}
145
142
146
143
CHIP_ERROR BluezAdvertisement::SetIntervals (AdvertisingIntervals aAdvIntervals)
@@ -224,39 +221,49 @@ void BluezAdvertisement::Shutdown()
224
221
225
222
void BluezAdvertisement::StartDone (GObject * aObject, GAsyncResult * aResult)
226
223
{
227
- auto * advMgr = reinterpret_cast <BluezLEAdvertisingManager1 *>(aObject);
228
224
GAutoPtr<GError> error;
229
- gboolean success = FALSE ;
230
-
231
- success = bluez_leadvertising_manager1_call_register_advertisement_finish (advMgr, aResult, &error.GetReceiver ());
232
- VerifyOrExit (success == TRUE , ChipLogError (DeviceLayer, " FAIL: RegisterAdvertisement : %s" , error->message ));
225
+ if (!bluez_leadvertising_manager1_call_register_advertisement_finish (reinterpret_cast <BluezLEAdvertisingManager1 *>(aObject),
226
+ aResult, &error.GetReceiver ()))
227
+ {
228
+ ChipLogError (DeviceLayer, " FAIL: RegisterAdvertisement: %s" , error->message );
229
+ switch (error->code )
230
+ {
231
+ case G_DBUS_ERROR_NO_REPLY: // BlueZ crashed or the D-Bus connection is broken
232
+ case G_DBUS_ERROR_SERVICE_UNKNOWN: // BlueZ service is not available on the bus
233
+ case G_DBUS_ERROR_UNKNOWN_OBJECT: // Requested BLE adapter is not available
234
+ BLEManagerImpl::NotifyBLEPeripheralAdvStartComplete (BLE_ERROR_ADAPTER_UNAVAILABLE);
235
+ break ;
236
+ default :
237
+ BLEManagerImpl::NotifyBLEPeripheralAdvStartComplete (CHIP_ERROR_INTERNAL);
238
+ }
239
+ return ;
240
+ }
233
241
234
242
mIsAdvertising = true ;
235
243
236
- ChipLogDetail (DeviceLayer, " RegisterAdvertisement complete" );
237
-
238
- exit :
239
- BLEManagerImpl::NotifyBLEPeripheralAdvStartComplete (success == TRUE );
244
+ ChipLogDetail (DeviceLayer, " BLE advertisement started successfully" );
245
+ BLEManagerImpl::NotifyBLEPeripheralAdvStartComplete (CHIP_NO_ERROR);
240
246
}
241
247
242
248
CHIP_ERROR BluezAdvertisement::StartImpl ()
243
249
{
244
- GDBusObject * adapterObject;
245
- GAutoPtr<BluezLEAdvertisingManager1> advMgr;
246
- GVariantBuilder optionsBuilder;
247
- GVariant * options;
250
+ VerifyOrReturnError (mAdapter , CHIP_ERROR_UNINITIALIZED);
248
251
249
- VerifyOrExit (!mIsAdvertising , ChipLogError (DeviceLayer, " FAIL: Advertising has already been enabled in %s" , __func__));
250
- VerifyOrExit (mAdapter , ChipLogError (DeviceLayer, " FAIL: NULL mAdapter in %s" , __func__));
252
+ // If the adapter configured in the Init() was unplugged, the g_dbus_interface_get_object()
253
+ // or bluez_object_get_leadvertising_manager1() might return nullptr (depending on the timing,
254
+ // since the D-Bus communication is handled on a separate thread). In such case, we should not
255
+ // report internal error, but adapter unavailable, so the application can handle the situation
256
+ // properly.
251
257
252
- adapterObject = g_dbus_interface_get_object (G_DBUS_INTERFACE (mAdapter .get ()));
253
- VerifyOrExit (adapterObject != nullptr , ChipLogError (DeviceLayer, " FAIL: NULL adapterObject in %s " , __func__) );
254
-
255
- advMgr. reset ( bluez_object_get_leadvertising_manager1 (reinterpret_cast <BluezObject *>(adapterObject)));
256
- VerifyOrExit (advMgr, ChipLogError (DeviceLayer, " FAIL: NULL advMgr in %s " , __func__) );
258
+ GDBusObject * adapterObject = g_dbus_interface_get_object (reinterpret_cast <GDBusInterface *> (mAdapter .get ()));
259
+ VerifyOrReturnError (adapterObject != nullptr , BLE_ERROR_ADAPTER_UNAVAILABLE );
260
+ GAutoPtr<BluezLEAdvertisingManager1> advMgr (
261
+ bluez_object_get_leadvertising_manager1 (reinterpret_cast <BluezObject *>(adapterObject)));
262
+ VerifyOrReturnError (advMgr, BLE_ERROR_ADAPTER_UNAVAILABLE );
257
263
264
+ GVariantBuilder optionsBuilder;
258
265
g_variant_builder_init (&optionsBuilder, G_VARIANT_TYPE (" a{sv}" ));
259
- options = g_variant_builder_end (&optionsBuilder);
266
+ GVariant * options = g_variant_builder_end (&optionsBuilder);
260
267
261
268
bluez_leadvertising_manager1_call_register_advertisement (
262
269
advMgr.get (), mAdvPath , options, nullptr ,
@@ -265,51 +272,58 @@ CHIP_ERROR BluezAdvertisement::StartImpl()
265
272
},
266
273
this );
267
274
268
- exit :
269
275
return CHIP_NO_ERROR;
270
276
}
271
277
272
278
CHIP_ERROR BluezAdvertisement::Start ()
273
279
{
274
280
VerifyOrReturnError (mIsInitialized , CHIP_ERROR_INCORRECT_STATE);
275
-
276
- CHIP_ERROR err = PlatformMgrImpl ().GLibMatterContextInvokeSync (
281
+ VerifyOrReturnValue (! mIsAdvertising , CHIP_NO_ERROR, ChipLogDetail (DeviceLayer, " BLE advertising already started " ));
282
+ return PlatformMgrImpl ().GLibMatterContextInvokeSync (
277
283
+[](BluezAdvertisement * self) { return self->StartImpl (); }, this );
278
- VerifyOrReturnError (err == CHIP_NO_ERROR, CHIP_ERROR_INCORRECT_STATE,
279
- ChipLogError (Ble, " Failed to schedule BLE advertisement Start() on CHIPoBluez thread" ));
280
- return err;
281
284
}
282
285
283
286
void BluezAdvertisement::StopDone (GObject * aObject, GAsyncResult * aResult)
284
287
{
285
- auto * advMgr = reinterpret_cast <BluezLEAdvertisingManager1 *>(aObject);
286
288
GAutoPtr<GError> error;
287
- gboolean success = FALSE ;
288
-
289
- success = bluez_leadvertising_manager1_call_unregister_advertisement_finish (advMgr, aResult, &error.GetReceiver ());
290
- VerifyOrExit (success == TRUE , ChipLogError (DeviceLayer, " FAIL: UnregisterAdvertisement: %s" , error->message ));
289
+ if (!bluez_leadvertising_manager1_call_unregister_advertisement_finish (reinterpret_cast <BluezLEAdvertisingManager1 *>(aObject),
290
+ aResult, &error.GetReceiver ()))
291
+ {
292
+ ChipLogError (DeviceLayer, " FAIL: UnregisterAdvertisement: %s" , error->message );
293
+ switch (error->code )
294
+ {
295
+ case G_DBUS_ERROR_NO_REPLY: // BlueZ crashed or the D-Bus connection is broken
296
+ case G_DBUS_ERROR_SERVICE_UNKNOWN: // BlueZ service is not available on the bus
297
+ case G_DBUS_ERROR_UNKNOWN_OBJECT: // Requested BLE adapter is not available
298
+ BLEManagerImpl::NotifyBLEPeripheralAdvStopComplete (BLE_ERROR_ADAPTER_UNAVAILABLE);
299
+ break ;
300
+ default :
301
+ BLEManagerImpl::NotifyBLEPeripheralAdvStopComplete (CHIP_ERROR_INTERNAL);
302
+ }
303
+ return ;
304
+ }
291
305
292
306
mIsAdvertising = false ;
293
307
294
- ChipLogDetail (DeviceLayer, " UnregisterAdvertisement complete" );
295
-
296
- exit :
297
- BLEManagerImpl::NotifyBLEPeripheralAdvStopComplete (success == TRUE );
308
+ ChipLogDetail (DeviceLayer, " BLE advertisement stopped successfully" );
309
+ BLEManagerImpl::NotifyBLEPeripheralAdvStopComplete (CHIP_NO_ERROR);
298
310
}
299
311
300
312
CHIP_ERROR BluezAdvertisement::StopImpl ()
301
313
{
302
- GDBusObject * adapterObject;
303
- GAutoPtr<BluezLEAdvertisingManager1> advMgr;
314
+ VerifyOrReturnError (mAdapter , CHIP_ERROR_UNINITIALIZED);
304
315
305
- VerifyOrExit (mIsAdvertising , ChipLogError (DeviceLayer, " FAIL: Advertising has already been disabled in %s" , __func__));
306
- VerifyOrExit (mAdapter , ChipLogError (DeviceLayer, " FAIL: NULL mAdapter in %s" , __func__));
316
+ // If the adapter configured in the Init() was unplugged, the g_dbus_interface_get_object()
317
+ // or bluez_object_get_leadvertising_manager1() might return nullptr (depending on the timing,
318
+ // since the D-Bus communication is handled on a separate thread). In such case, we should not
319
+ // report internal error, but adapter unavailable, so the application can handle the situation
320
+ // properly.
307
321
308
- adapterObject = g_dbus_interface_get_object (G_DBUS_INTERFACE (mAdapter .get ()));
309
- VerifyOrExit (adapterObject != nullptr , ChipLogError (DeviceLayer, " FAIL: NULL adapterObject in %s " , __func__) );
310
-
311
- advMgr. reset ( bluez_object_get_leadvertising_manager1 (reinterpret_cast <BluezObject *>(adapterObject)));
312
- VerifyOrExit (advMgr, ChipLogError (DeviceLayer, " FAIL: NULL advMgr in %s " , __func__) );
322
+ GDBusObject * adapterObject = g_dbus_interface_get_object (reinterpret_cast <GDBusInterface *> (mAdapter .get ()));
323
+ VerifyOrReturnError (adapterObject != nullptr , BLE_ERROR_ADAPTER_UNAVAILABLE );
324
+ GAutoPtr<BluezLEAdvertisingManager1> advMgr (
325
+ bluez_object_get_leadvertising_manager1 (reinterpret_cast <BluezObject *>(adapterObject)));
326
+ VerifyOrReturnError (advMgr, BLE_ERROR_ADAPTER_UNAVAILABLE );
313
327
314
328
bluez_leadvertising_manager1_call_unregister_advertisement (
315
329
advMgr.get (), mAdvPath , nullptr ,
@@ -318,19 +332,15 @@ CHIP_ERROR BluezAdvertisement::StopImpl()
318
332
},
319
333
this );
320
334
321
- exit :
322
335
return CHIP_NO_ERROR;
323
336
}
324
337
325
338
CHIP_ERROR BluezAdvertisement::Stop ()
326
339
{
327
340
VerifyOrReturnError (mIsInitialized , CHIP_ERROR_INCORRECT_STATE);
328
-
329
- CHIP_ERROR err = PlatformMgrImpl ().GLibMatterContextInvokeSync (
341
+ VerifyOrReturnValue ( mIsAdvertising , CHIP_NO_ERROR, ChipLogDetail (DeviceLayer, " BLE advertising already stopped " ));
342
+ return PlatformMgrImpl ().GLibMatterContextInvokeSync (
330
343
+[](BluezAdvertisement * self) { return self->StopImpl (); }, this );
331
- VerifyOrReturnError (err == CHIP_NO_ERROR, CHIP_ERROR_INCORRECT_STATE,
332
- ChipLogError (Ble, " Failed to schedule BLE advertisement Stop() on CHIPoBluez thread" ));
333
- return err;
334
344
}
335
345
336
346
} // namespace Internal
0 commit comments