From 92050f6ea8071ad99bc6e9c5764047f767dcfab1 Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Fri, 14 Apr 2023 19:35:33 +0200 Subject: [PATCH] [Tizen] Run single thread for processing all GLib sources (#25762) * Remove unused timeout in MainLoop::AsyncRequest() * Create dedicated glib thread during Matter stack initialization * Use GLibMatterContextInvoke in BLE manager * Use GLibMatterContextInvoke in device scanner * Use GLibMatterContextInvoke in DNS-SD manager * Use GLibMatterContextInvoke in WiFi manager * Remove MainLoop class * Use better name for synchronous invoke * Verify that thread default glib context is set * Type safety for GLibMatterContextInvokeSynchronous * Cleanup * Align sync function name with convention * Wait for Matter glib event loop to start running --- src/platform/Tizen/BLEManagerImpl.cpp | 49 +++--- src/platform/Tizen/BLEManagerImpl.h | 6 +- src/platform/Tizen/BUILD.gn | 2 - src/platform/Tizen/ChipDeviceScanner.cpp | 39 ++--- src/platform/Tizen/ChipDeviceScanner.h | 5 +- src/platform/Tizen/DnssdImpl.cpp | 68 +++------ src/platform/Tizen/DnssdImpl.h | 5 +- src/platform/Tizen/MainLoop.cpp | 159 -------------------- src/platform/Tizen/MainLoop.h | 69 --------- src/platform/Tizen/PlatformManagerImpl.cpp | 98 ++++++++++++ src/platform/Tizen/PlatformManagerImpl.h | 40 ++++- src/platform/Tizen/WiFiManager.cpp | 165 +++++++-------------- src/platform/Tizen/WiFiManager.h | 10 +- 13 files changed, 251 insertions(+), 464 deletions(-) delete mode 100644 src/platform/Tizen/MainLoop.cpp delete mode 100644 src/platform/Tizen/MainLoop.h diff --git a/src/platform/Tizen/BLEManagerImpl.cpp b/src/platform/Tizen/BLEManagerImpl.cpp index 29cd066d7144eb..8b55c11ea61cf2 100644 --- a/src/platform/Tizen/BLEManagerImpl.cpp +++ b/src/platform/Tizen/BLEManagerImpl.cpp @@ -65,7 +65,6 @@ #include "CHIPDevicePlatformEvent.h" #include "ChipDeviceScanner.h" -#include "MainLoop.h" namespace chip { namespace DeviceLayer { @@ -118,14 +117,14 @@ void BLEManagerImpl::GattConnectionStateChangedCb(int result, bool connected, co } } -gboolean BLEManagerImpl::_BleInitialize(void * userData) +CHIP_ERROR BLEManagerImpl::_BleInitialize(void * userData) { int ret; if (sInstance.mFlags.Has(Flags::kTizenBLELayerInitialized)) { ChipLogProgress(DeviceLayer, "BLE Already Initialized"); - return true; + return CHIP_NO_ERROR; } ret = bt_initialize(); @@ -144,11 +143,10 @@ gboolean BLEManagerImpl::_BleInitialize(void * userData) sInstance.mFlags.Set(Flags::kTizenBLELayerInitialized); ChipLogProgress(DeviceLayer, "BLE Initialized"); - sInstance.mMainContext = g_main_context_get_thread_default(); - return true; + return CHIP_NO_ERROR; exit: - return false; + return CHIP_ERROR_INTERNAL; } static int __GetAttInfo(bt_gatt_h gattHandle, char ** uuid, bt_gatt_type_e * type) @@ -447,37 +445,27 @@ void BLEManagerImpl::HandleConnectionTimeout(System::Layer * layer, void * data) sInstance.NotifyHandleConnectFailed(CHIP_ERROR_TIMEOUT); } -gboolean BLEManagerImpl::ConnectChipThing(gpointer userData) +CHIP_ERROR BLEManagerImpl::ConnectChipThing(const char * address) { - int ret = BT_ERROR_NONE; + CHIP_ERROR err = CHIP_NO_ERROR; + int ret; - char * address = reinterpret_cast(userData); ChipLogProgress(DeviceLayer, "ConnectRequest: Addr [%s]", StringOrNullMarker(address)); ret = bt_gatt_client_create(address, &sInstance.mGattClient); - VerifyOrExit(ret == BT_ERROR_NONE, ChipLogError(DeviceLayer, "Failed to create GATT client. ret [%d]", ret)); + VerifyOrExit(ret == BT_ERROR_NONE, ChipLogError(DeviceLayer, "Failed to create GATT client. ret [%d]", ret); + err = CHIP_ERROR_INTERNAL); ret = bt_gatt_connect(address, false); - VerifyOrExit(ret == BT_ERROR_NONE, ChipLogError(DeviceLayer, "Failed to issue GATT connect request. ret [%d]", ret)); + VerifyOrExit(ret == BT_ERROR_NONE, ChipLogError(DeviceLayer, "Failed to issue GATT connect request. ret [%d]", ret); + err = CHIP_ERROR_INTERNAL); ChipLogProgress(DeviceLayer, "GATT Connect Issued"); -exit: - if (ret != BT_ERROR_NONE) - sInstance.NotifyHandleConnectFailed(CHIP_ERROR_INTERNAL); - g_free(address); - return G_SOURCE_REMOVE; -} - -void BLEManagerImpl::ConnectHandler(const char * address) -{ - GSource * idleSource; - - idleSource = g_idle_source_new(); - g_source_set_callback(idleSource, ConnectChipThing, g_strdup(address), nullptr); - g_source_set_priority(idleSource, G_PRIORITY_HIGH_IDLE); - g_source_attach(idleSource, sInstance.mMainContext); - g_source_unref(idleSource); +exit: + if (err != CHIP_NO_ERROR) + sInstance.NotifyHandleConnectFailed(err); + return err; } void BLEManagerImpl::OnChipDeviceScanned(void * device, const Ble::ChipBLEDeviceIdentificationInfo & info) @@ -515,7 +503,7 @@ void BLEManagerImpl::OnChipDeviceScanned(void * device, const Ble::ChipBLEDevice mDeviceScanner->StopChipScan(); /* Initiate Connect */ - ConnectHandler(deviceInfo->remote_address); + PlatformMgrImpl().GLibMatterContextInvokeSync(ConnectChipThing, const_cast(deviceInfo->remote_address)); } void BLEManagerImpl::OnScanComplete() @@ -960,7 +948,6 @@ void BLEManagerImpl::DriveBLEState(intptr_t arg) CHIP_ERROR BLEManagerImpl::_Init() { CHIP_ERROR err; - bool ret; err = BleLayer::Init(this, this, this, &DeviceLayer::SystemLayer()); SuccessOrExit(err); @@ -968,8 +955,8 @@ CHIP_ERROR BLEManagerImpl::_Init() mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled; ChipLogProgress(DeviceLayer, "Initialize BLE"); - ret = MainLoop::Instance().Init(_BleInitialize); - VerifyOrExit(ret != false, err = CHIP_ERROR_INTERNAL); + err = PlatformMgrImpl().GLibMatterContextInvokeSync(_BleInitialize, static_cast(nullptr)); + SuccessOrExit(err); PlatformMgr().ScheduleWork(DriveBLEState, 0); diff --git a/src/platform/Tizen/BLEManagerImpl.h b/src/platform/Tizen/BLEManagerImpl.h index 629d7208a88c26..af5e37b56a5ed8 100644 --- a/src/platform/Tizen/BLEManagerImpl.h +++ b/src/platform/Tizen/BLEManagerImpl.h @@ -164,7 +164,7 @@ class BLEManagerImpl final : public BLEManager, kAdvertisingRefreshNeeded = 0x0200, /**< The advertising configuration/state in BLE layer needs to be updated. */ }; - static gboolean _BleInitialize(void * userData); + static CHIP_ERROR _BleInitialize(void * userData); void DriveBLEState(); static void DriveBLEState(intptr_t arg); @@ -207,8 +207,7 @@ class BLEManagerImpl final : public BLEManager, void NotifyBLEWriteReceived(System::PacketBufferHandle & buf, BLE_CONNECTION_OBJECT conId); // ==== Connection. - void ConnectHandler(const char * address); - static gboolean ConnectChipThing(gpointer userData); + static CHIP_ERROR ConnectChipThing(const char * userData); void NotifyBLEConnectionEstablished(BLE_CONNECTION_OBJECT conId, CHIP_ERROR error); void NotifyBLEDisconnection(BLE_CONNECTION_OBJECT conId, CHIP_ERROR error); void NotifyHandleNewConnection(BLE_CONNECTION_OBJECT conId); @@ -235,7 +234,6 @@ class BLEManagerImpl final : public BLEManager, BLEScanConfig mBLEScanConfig; std::unique_ptr mDeviceScanner; - GMainContext * mMainContext = nullptr; bt_gatt_client_h mGattClient = nullptr; }; diff --git a/src/platform/Tizen/BUILD.gn b/src/platform/Tizen/BUILD.gn index 4b4043fb934576..9a6d42f050dc08 100644 --- a/src/platform/Tizen/BUILD.gn +++ b/src/platform/Tizen/BUILD.gn @@ -51,8 +51,6 @@ static_library("Tizen") { "KeyValueStoreManagerImpl.cpp", "KeyValueStoreManagerImpl.h", "Logging.cpp", - "MainLoop.cpp", - "MainLoop.h", "NetworkCommissioningDriver.h", "NetworkCommissioningEthernetDriver.cpp", "PlatformManagerImpl.cpp", diff --git a/src/platform/Tizen/ChipDeviceScanner.cpp b/src/platform/Tizen/ChipDeviceScanner.cpp index 2cee8ed1aa6eb1..5dcf154f13b984 100644 --- a/src/platform/Tizen/ChipDeviceScanner.cpp +++ b/src/platform/Tizen/ChipDeviceScanner.cpp @@ -33,8 +33,7 @@ #include #include #include - -#include "MainLoop.h" +#include namespace chip { namespace DeviceLayer { @@ -144,29 +143,27 @@ gboolean ChipDeviceScanner::TimerExpiredCb(gpointer userData) return G_SOURCE_REMOVE; } -gboolean ChipDeviceScanner::TriggerScan(GMainLoop * mainLoop, gpointer userData) +CHIP_ERROR ChipDeviceScanner::TriggerScan(ChipDeviceScanner * self) { - auto self = reinterpret_cast(userData); - int ret = BT_ERROR_NONE; + CHIP_ERROR err = CHIP_NO_ERROR; GSource * idleSource; + int ret; - self->mAsyncLoop = mainLoop; - - // All set, trigger LE Scan - ret = bt_adapter_le_start_scan(LeScanResultCb, userData); - VerifyOrExit(ret == BT_ERROR_NONE, ChipLogError(DeviceLayer, "bt_adapter_le_start_scan() failed: %s", get_error_message(ret))); - ChipLogProgress(DeviceLayer, "Scan started"); + // Trigger LE Scan + ret = bt_adapter_le_start_scan(LeScanResultCb, self); + VerifyOrExit(ret == BT_ERROR_NONE, ChipLogError(DeviceLayer, "bt_adapter_le_start_scan() failed: %s", get_error_message(ret)); + err = CHIP_ERROR_INTERNAL); + self->mIsScanning = true; - // Start Timer + // Setup timer for scan timeout idleSource = g_timeout_source_new(self->mScanTimeoutMs); - g_source_set_callback(idleSource, TimerExpiredCb, userData, nullptr); + g_source_set_callback(idleSource, TimerExpiredCb, self, nullptr); g_source_set_priority(idleSource, G_PRIORITY_HIGH_IDLE); - g_source_attach(idleSource, g_main_loop_get_context(self->mAsyncLoop)); + g_source_attach(idleSource, g_main_context_get_thread_default()); g_source_unref(idleSource); - return true; exit: - return false; + return err; } static bool __IsScanFilterSupported() @@ -212,14 +209,9 @@ CHIP_ERROR ChipDeviceScanner::StartChipScan(System::Clock::Timeout timeout, Scan // All set to trigger LE Scan ChipLogProgress(DeviceLayer, "Start CHIP BLE scan: timeout=%ums", mScanTimeoutMs); - if (MainLoop::Instance().AsyncRequest(TriggerScan, this) == false) - { - ChipLogError(DeviceLayer, "Failed to trigger Scan..."); - err = CHIP_ERROR_INTERNAL; - goto exit; - } + err = PlatformMgrImpl().GLibMatterContextInvokeSync(TriggerScan, this); + SuccessOrExit(err); - mIsScanning = true; // optimistic, to allow all callbacks to check this return CHIP_NO_ERROR; exit: @@ -240,7 +232,6 @@ CHIP_ERROR ChipDeviceScanner::StopChipScan() ChipLogError(DeviceLayer, "bt_adapter_le_stop_scan() failed: %s", get_error_message(ret)); } - g_main_loop_quit(mAsyncLoop); ChipLogProgress(DeviceLayer, "CHIP Scanner Async Thread Quit Done..Wait for Thread Windup...!"); UnRegisterScanFilter(); diff --git a/src/platform/Tizen/ChipDeviceScanner.h b/src/platform/Tizen/ChipDeviceScanner.h index fedfba500d95ad..b7220fb55a7db9 100644 --- a/src/platform/Tizen/ChipDeviceScanner.h +++ b/src/platform/Tizen/ChipDeviceScanner.h @@ -96,18 +96,17 @@ class ChipDeviceScanner static std::unique_ptr Create(ChipDeviceScannerDelegate * delegate); private: - static gboolean TriggerScan(GMainLoop * mainLoop, gpointer userData); static void LeScanResultCb(int result, bt_adapter_le_device_scan_result_info_s * info, void * userData); + static gboolean TimerExpiredCb(gpointer user_data); + static CHIP_ERROR TriggerScan(ChipDeviceScanner * userData); void CheckScanFilter(ScanFilterType filterType, ScanFilterData & filterData); int RegisterScanFilter(ScanFilterType filterType, ScanFilterData & filterData); void UnRegisterScanFilter(void); int CreateLEScanFilter(ScanFilterType filterType, ScanFilterData & filterData); - static gboolean TimerExpiredCb(gpointer user_data); ChipDeviceScannerDelegate * mDelegate = nullptr; bool mIsScanning = false; bool mIsStopping = false; - GMainLoop * mAsyncLoop = nullptr; unsigned int mScanTimeoutMs = 10000; bt_scan_filter_h mScanFilter = nullptr; }; diff --git a/src/platform/Tizen/DnssdImpl.cpp b/src/platform/Tizen/DnssdImpl.cpp index abdfc110831f6b..0c68bd67694a03 100644 --- a/src/platform/Tizen/DnssdImpl.cpp +++ b/src/platform/Tizen/DnssdImpl.cpp @@ -40,8 +40,6 @@ #include #include -#include "MainLoop.h" - #if CHIP_DEVICE_CONFIG_ENABLE_THREAD #include #endif @@ -98,8 +96,6 @@ void OnRegister(dnssd_error_e result, dnssd_service_h service, void * data) ChipLogDetail(DeviceLayer, "DNSsd %s: name: %s, type: %s, port: %u, interfaceId: %u", __func__, rCtx->mName, rCtx->mType, rCtx->mPort, rCtx->mInterfaceId); - rCtx->MainLoopQuit(); - if (result != DNSSD_ERROR_NONE) { ChipLogError(DeviceLayer, "DNSsd %s: Error: %d", __func__, result); @@ -112,19 +108,16 @@ void OnRegister(dnssd_error_e result, dnssd_service_h service, void * data) rCtx->mCallback(rCtx->mCbContext, rCtx->mType, rCtx->mName, CHIP_NO_ERROR); } -gboolean RegisterAsync(GMainLoop * mainLoop, gpointer userData) +CHIP_ERROR RegisterAsync(chip::Dnssd::RegisterContext * rCtx) { ChipLogDetail(DeviceLayer, "DNSsd %s", __func__); - auto rCtx = reinterpret_cast(userData); - rCtx->mMainLoop = mainLoop; - int ret = dnssd_register_local_service(rCtx->mServiceHandle, OnRegister, rCtx); - VerifyOrReturnValue(ret == DNSSD_ERROR_NONE, false, + VerifyOrReturnValue(ret == DNSSD_ERROR_NONE, GetChipError(ret), ChipLogError(DeviceLayer, "dnssd_register_local_service() failed. ret: %d", ret)); rCtx->mIsRegistered = true; - return true; + return CHIP_NO_ERROR; } gboolean OnBrowseTimeout(void * userData) @@ -133,14 +126,13 @@ gboolean OnBrowseTimeout(void * userData) auto * bCtx = reinterpret_cast(userData); - bCtx->MainLoopQuit(); bCtx->mCallback(bCtx->mCbContext, bCtx->mServices.data(), bCtx->mServices.size(), true, CHIP_NO_ERROR); // After this point the context might be no longer valid bCtx->mInstance->RemoveContext(bCtx); // This is a one-shot timer - return FALSE; + return G_SOURCE_REMOVE; } void OnBrowseAdd(chip::Dnssd::BrowseContext * context, const char * type, const char * name, uint32_t interfaceId) @@ -237,13 +229,11 @@ void OnBrowse(dnssd_service_state_e state, dnssd_service_h service, void * data) g_free(ifaceName); } -gboolean BrowseAsync(GMainLoop * mainLoop, gpointer userData) +CHIP_ERROR BrowseAsync(chip::Dnssd::BrowseContext * bCtx) { ChipLogDetail(DeviceLayer, "DNSsd %s", __func__); - auto * bCtx = reinterpret_cast(userData); auto interfaceId = bCtx->mInterfaceId; - bCtx->mMainLoop = mainLoop; int ret; if (interfaceId == 0) @@ -253,19 +243,16 @@ gboolean BrowseAsync(GMainLoop * mainLoop, gpointer userData) else { char iface[IF_NAMESIZE + 1] = ""; - VerifyOrReturnValue(if_indextoname(interfaceId, iface) != nullptr, false, + VerifyOrReturnValue(if_indextoname(interfaceId, iface) != nullptr, CHIP_ERROR_INTERNAL, ChipLogError(DeviceLayer, "if_indextoname() failed. errno: %d", errno)); ret = dnssd_browse_service(bCtx->mType, iface, &bCtx->mBrowserHandle, OnBrowse, bCtx); } - if (ret != DNSSD_ERROR_NONE) - { - ChipLogError(DeviceLayer, "dnssd_browse_service() failed. ret: %d", ret); - return false; - } + VerifyOrReturnValue(ret == DNSSD_ERROR_NONE, GetChipError(ret), + ChipLogError(DeviceLayer, "dnssd_browse_service() failed. ret: %d", ret)); bCtx->mIsBrowsing = true; - return true; + return CHIP_NO_ERROR; } void GetTextEntries(unsigned short txtLen, uint8_t * txtRecord, std::vector & textEntries) @@ -307,8 +294,6 @@ gboolean OnResolveFinalize(gpointer userData) ChipLogDetail(DeviceLayer, "DNSsd %s", __func__); auto rCtx = reinterpret_cast(userData); - rCtx->MainLoopQuit(); - { // Lock the stack mutex when calling the callback function, so that the callback // function could safely perform message exchange (e.g. PASE session pairing). @@ -395,30 +380,29 @@ void OnResolve(dnssd_error_e result, dnssd_service_h service, void * userData) // the Resolve() itself is called with the stack mutex locked. auto * sourceIdle = g_idle_source_new(); g_source_set_callback(sourceIdle, OnResolveFinalize, rCtx, NULL); - g_source_attach(sourceIdle, g_main_loop_get_context(rCtx->mMainLoop)); + g_source_attach(sourceIdle, g_main_context_get_thread_default()); + g_source_unref(sourceIdle); } return; exit: - rCtx->MainLoopQuit(); rCtx->Finalize(ret != DNSSD_ERROR_NONE ? GetChipError(ret) : err); rCtx->mInstance->RemoveContext(rCtx); } -gboolean ResolveAsync(GMainLoop * mainLoop, gpointer userData) +CHIP_ERROR ResolveAsync(chip::Dnssd::ResolveContext * rCtx) { ChipLogDetail(DeviceLayer, "DNSsd %s", __func__); - auto * rCtx = reinterpret_cast(userData); - rCtx->mMainLoop = mainLoop; - int ret = dnssd_resolve_service(rCtx->mServiceHandle, OnResolve, rCtx); - VerifyOrReturnValue(ret == DNSSD_ERROR_NONE, false, ChipLogError(DeviceLayer, "dnssd_resolve_service() failed. ret: %d", ret)); + VerifyOrReturnValue(ret == DNSSD_ERROR_NONE, GetChipError(ret), + ChipLogError(DeviceLayer, "dnssd_resolve_service() failed. ret: %d", ret)); rCtx->mIsResolving = true; - return true; + return CHIP_NO_ERROR; } + } // namespace namespace chip { @@ -426,12 +410,6 @@ namespace Dnssd { DnssdTizen DnssdTizen::sInstance; -void GenericContext::MainLoopQuit() -{ - VerifyOrReturn(mMainLoop != nullptr, ); - g_main_loop_quit(std::exchange(mMainLoop, nullptr)); -} - RegisterContext::RegisterContext(DnssdTizen * instance, const char * type, const DnssdService & service, DnssdPublishCallback callback, void * context) : GenericContext(ContextType::Register, instance) @@ -535,7 +513,6 @@ CHIP_ERROR DnssdTizen::RegisterService(const DnssdService & service, DnssdPublis std::string fullType = GetFullType(service.mType, service.mProtocol); auto interfaceId = service.mInterface.GetPlatformInterface(); CHIP_ERROR err = CHIP_NO_ERROR; - bool ok = false; ChipLogProgress(DeviceLayer, "DNSsd %s: name: %s, type: %s, interfaceId: %u, port: %u", __func__, service.mName, fullType.c_str(), interfaceId, service.mPort); @@ -607,8 +584,8 @@ CHIP_ERROR DnssdTizen::RegisterService(const DnssdService & service, DnssdPublis err = GetChipError(ret)); } - ok = DeviceLayer::Internal::MainLoop::Instance().AsyncRequest(RegisterAsync, serviceCtx); - VerifyOrExit(ok, err = CHIP_ERROR_INTERNAL); + err = DeviceLayer::PlatformMgrImpl().GLibMatterContextInvokeSync(RegisterAsync, serviceCtx); + SuccessOrExit(err); exit: if (err != CHIP_NO_ERROR) @@ -646,8 +623,8 @@ CHIP_ERROR DnssdTizen::Browse(const char * type, Dnssd::DnssdServiceProtocol pro auto browseCtx = CreateBrowseContext(fullType.c_str(), protocol, interfaceId, callback, context); - bool ok = DeviceLayer::Internal::MainLoop::Instance().AsyncRequest(BrowseAsync, browseCtx); - VerifyOrExit(ok, err = CHIP_ERROR_INTERNAL); + err = DeviceLayer::PlatformMgrImpl().GLibMatterContextInvokeSync(BrowseAsync, browseCtx); + SuccessOrExit(err); exit: if (err != CHIP_NO_ERROR) @@ -664,7 +641,6 @@ CHIP_ERROR DnssdTizen::Resolve(const DnssdService & browseResult, chip::Inet::In std::string fullType = GetFullType(browseResult.mType, browseResult.mProtocol); auto interfaceId = interface.GetPlatformInterface(); CHIP_ERROR err = CHIP_NO_ERROR; - bool ok = false; int ret; ChipLogDetail(DeviceLayer, "DNSsd %s: name: %s, type: %s, interfaceId: %u", __func__, browseResult.mName, fullType.c_str(), @@ -688,8 +664,8 @@ CHIP_ERROR DnssdTizen::Resolve(const DnssdService & browseResult, chip::Inet::In VerifyOrExit(ret == DNSSD_ERROR_NONE, ChipLogError(DeviceLayer, "dnssd_create_remote_service() failed. ret: %d", ret); err = GetChipError(ret)); - ok = DeviceLayer::Internal::MainLoop::Instance().AsyncRequest(ResolveAsync, resolveCtx); - VerifyOrExit(ok, err = CHIP_ERROR_INTERNAL); + err = DeviceLayer::PlatformMgrImpl().GLibMatterContextInvokeSync(ResolveAsync, resolveCtx); + SuccessOrExit(err); exit: if (err != CHIP_NO_ERROR) diff --git a/src/platform/Tizen/DnssdImpl.h b/src/platform/Tizen/DnssdImpl.h index bfa34e7dab242f..50ff42b5c9e764 100644 --- a/src/platform/Tizen/DnssdImpl.h +++ b/src/platform/Tizen/DnssdImpl.h @@ -49,12 +49,9 @@ struct GenericContext { ContextType mContextType; DnssdTizen * mInstance; - GMainLoop * mMainLoop = nullptr; GenericContext(ContextType contextType, DnssdTizen * instance) : mContextType(contextType), mInstance(instance) {} - virtual ~GenericContext() { MainLoopQuit(); }; - - void MainLoopQuit(); + virtual ~GenericContext() = default; }; struct RegisterContext : public GenericContext diff --git a/src/platform/Tizen/MainLoop.cpp b/src/platform/Tizen/MainLoop.cpp deleted file mode 100644 index 56b5f28af87934..00000000000000 --- a/src/platform/Tizen/MainLoop.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2021 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "MainLoop.h" - -#include -#include -#include - -#include -#include - -namespace chip { -namespace DeviceLayer { -namespace Internal { - -LoopData::LoopData() -{ - mMainContext = g_main_context_new(); - mMainLoop = g_main_loop_new(mMainContext, FALSE); -} - -LoopData::~LoopData() -{ - if (mThread.joinable()) - { - mThread.join(); - } - if (mMainContext != nullptr) - { - g_main_context_unref(mMainContext); - } - if (mMainLoop != nullptr) - { - g_main_loop_unref(mMainLoop); - } -} - -gboolean MainLoop::ThreadTimeout(gpointer userData) -{ - LoopData * loopData = reinterpret_cast(userData); - - VerifyOrReturnError(loopData != nullptr, G_SOURCE_REMOVE); - - ChipLogDetail(DeviceLayer, "[TIMEOUT] glib main loop [%p]", loopData->mMainLoop); - - if (loopData->mTimeoutFn) - { - ChipLogDetail(DeviceLayer, "Running thread timeout function"); - loopData->mTimeoutFn(loopData->mTimeoutUserData); - } - - g_main_loop_quit(loopData->mMainLoop); - - return G_SOURCE_REMOVE; -} - -void MainLoop::ThreadHandler(std::shared_ptr loopData) -{ - g_main_context_push_thread_default(loopData->mMainContext); - ChipLogDetail(DeviceLayer, "[PUSH] thread default context [%p]", loopData->mMainContext); - - ChipLogDetail(DeviceLayer, "[RUN] glib main loop [%p]", loopData->mMainLoop); - g_main_loop_run(loopData->mMainLoop); - ChipLogDetail(DeviceLayer, "[QUIT] glib main loop [%p]", loopData->mMainLoop); - - g_main_context_pop_thread_default(loopData->mMainContext); - ChipLogDetail(DeviceLayer, "[POP] thread default context [%p]", loopData->mMainContext); -} - -bool MainLoop::Init(initFn_t initFn, gpointer userData) -{ - auto loopData = std::make_shared(); - bool result = false; - - VerifyOrReturnError(loopData, false); - - g_main_context_push_thread_default(loopData->mMainContext); - ChipLogDetail(DeviceLayer, "[PUSH] thread default context [%p]", loopData->mMainContext); - - result = initFn(userData); - - g_main_context_pop_thread_default(loopData->mMainContext); - ChipLogDetail(DeviceLayer, "[POP] thread default context [%p]", loopData->mMainContext); - - VerifyOrReturnError(result, false); - - loopData->mThread = std::thread(ThreadHandler, loopData); - mLoopData.push_back(loopData); - - return true; -} - -void MainLoop::Deinit() -{ - for (auto & loopData : mLoopData) - { - g_main_loop_quit(loopData->mMainLoop); - } - mLoopData.clear(); -} - -bool MainLoop::AsyncRequest(asyncFn_t asyncFn, gpointer asyncUserData, guint timeoutInterval, timeoutFn_t timeoutFn, - gpointer timeoutUserData) -{ - auto loopData = std::make_shared(); - bool result = false; - - VerifyOrReturnError(loopData, false); - - loopData->mTimeoutFn = timeoutFn; - loopData->mTimeoutUserData = timeoutUserData; - - g_main_context_push_thread_default(loopData->mMainContext); - ChipLogDetail(DeviceLayer, "[PUSH] thread default context [%p]", loopData->mMainContext); - - result = asyncFn(loopData->mMainLoop, asyncUserData); - - g_main_context_pop_thread_default(loopData->mMainContext); - ChipLogDetail(DeviceLayer, "[POP] thread default context [%p]", loopData->mMainContext); - - VerifyOrReturnError(result, false); - - loopData->mThread = std::thread(ThreadHandler, loopData); - loopData->mThread.detach(); - - if (timeoutInterval) - { - GSource * source = g_timeout_source_new_seconds(timeoutInterval); - g_source_set_callback(source, ThreadTimeout, loopData.get(), nullptr); - g_source_attach(source, loopData->mMainContext); - g_source_unref(source); - } - - return true; -} - -MainLoop & MainLoop::Instance() -{ - static MainLoop sMainLoop; - return sMainLoop; -} - -} // namespace Internal -} // namespace DeviceLayer -} // namespace chip diff --git a/src/platform/Tizen/MainLoop.h b/src/platform/Tizen/MainLoop.h deleted file mode 100644 index 618d45aebe9803..00000000000000 --- a/src/platform/Tizen/MainLoop.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2021 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include -#include - -#include - -namespace chip { -namespace DeviceLayer { -namespace Internal { - -typedef gboolean (*initFn_t)(gpointer userData); -typedef gboolean (*asyncFn_t)(GMainLoop * mainLoop, gpointer userData); -typedef void (*timeoutFn_t)(gpointer userData); - -class LoopData -{ -public: - LoopData(); - ~LoopData(); - - // Thread which governs glib main event loop - std::thread mThread; - // Objects for running glib main event loop - GMainContext * mMainContext = nullptr; - GMainLoop * mMainLoop = nullptr; - // Optional timeout function - timeoutFn_t mTimeoutFn = nullptr; - gpointer mTimeoutUserData = nullptr; -}; - -class MainLoop -{ -public: - bool Init(initFn_t initFn, gpointer userData = nullptr); - void Deinit(void); - bool AsyncRequest(asyncFn_t asyncFn, gpointer asyncUserData = nullptr, guint timeoutInterval = 0, - timeoutFn_t timeoutFn = nullptr, gpointer timeoutUserData = nullptr); - static MainLoop & Instance(void); - -private: - MainLoop() = default; - - static gboolean ThreadTimeout(gpointer userData); - static void ThreadHandler(std::shared_ptr loopData); - - std::vector> mLoopData; -}; - -} // namespace Internal -} // namespace DeviceLayer -} // namespace chip diff --git a/src/platform/Tizen/PlatformManagerImpl.cpp b/src/platform/Tizen/PlatformManagerImpl.cpp index f893eb94ec4f5a..d0f62901a61bbe 100644 --- a/src/platform/Tizen/PlatformManagerImpl.cpp +++ b/src/platform/Tizen/PlatformManagerImpl.cpp @@ -29,6 +29,11 @@ * class. */ #include +#include +#include + +#include + #include #include #include @@ -45,8 +50,65 @@ namespace DeviceLayer { PlatformManagerImpl PlatformManagerImpl::sInstance; +namespace { + +struct GLibMatterContextInvokeData +{ + CHIP_ERROR (*mFunc)(void *); + void * mFuncUserData; + CHIP_ERROR mFuncResult; + // Sync primitives to wait for the function to be executed + std::mutex mDoneMutex; + std::condition_variable mDoneCond; + bool mDone = false; +}; + +void * GLibMainLoopThread(void * userData) +{ + GMainLoop * loop = static_cast(userData); + GMainContext * context = g_main_loop_get_context(loop); + + g_main_context_push_thread_default(context); + g_main_loop_run(loop); + + return nullptr; +} + +} // namespace + CHIP_ERROR PlatformManagerImpl::_InitChipStack() { + auto * context = g_main_context_new(); + mGLibMainLoop = g_main_loop_new(context, FALSE); + mGLibMainLoopThread = g_thread_new("gmain-matter", GLibMainLoopThread, mGLibMainLoop); + g_main_context_unref(context); + + { + // Wait for the GLib main loop to start. It is required that the GLib Matter + // context is acquired by the g_main_loop_run() before any other GLib function + // is called. Otherwise, the GLibMatterContextInvokeSync() might run callback + // functions on the wrong thread. + + GLibMatterContextInvokeData invokeData{}; + + auto * idleSource = g_idle_source_new(); + g_source_set_callback( + idleSource, + [](void * userData_) { + auto * data = reinterpret_cast(userData_); + std::unique_lock lock(data->mDoneMutex); + data->mDone = true; + data->mDoneCond.notify_one(); + return G_SOURCE_REMOVE; + }, + &invokeData, nullptr); + g_source_attach(idleSource, g_main_loop_get_context(mGLibMainLoop)); + g_source_unref(idleSource); + + std::unique_lock lock(invokeData.mDoneMutex); + invokeData.mDoneCond.wait(lock, [&invokeData]() { return invokeData.mDone; }); + } + ReturnErrorOnFailure(Internal::PosixConfig::Init()); ReturnErrorOnFailure(Internal::GenericPlatformManagerImpl_POSIX::_InitChipStack()); @@ -58,5 +120,41 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack() return CHIP_NO_ERROR; } +void PlatformManagerImpl::_Shutdown() +{ + Internal::GenericPlatformManagerImpl_POSIX::_Shutdown(); + + g_main_loop_quit(mGLibMainLoop); + g_main_loop_unref(mGLibMainLoop); + g_thread_join(mGLibMainLoopThread); +} + +CHIP_ERROR PlatformManagerImpl::_GLibMatterContextInvokeSync(CHIP_ERROR (*func)(void *), void * userData) +{ + GLibMatterContextInvokeData invokeData{ func, userData }; + + g_main_context_invoke_full( + g_main_loop_get_context(mGLibMainLoop), G_PRIORITY_HIGH_IDLE, + [](void * userData_) { + auto * data = reinterpret_cast(userData_); + VerifyOrExit(g_main_context_get_thread_default() != nullptr, + ChipLogError(DeviceLayer, "GLib thread default main context is not set"); + data->mFuncResult = CHIP_ERROR_INCORRECT_STATE); + data->mFuncResult = data->mFunc(data->mFuncUserData); + exit: + data->mDoneMutex.lock(); + data->mDone = true; + data->mDoneMutex.unlock(); + data->mDoneCond.notify_one(); + return G_SOURCE_REMOVE; + }, + &invokeData, nullptr); + + std::unique_lock lock(invokeData.mDoneMutex); + invokeData.mDoneCond.wait(lock, [&invokeData]() { return invokeData.mDone; }); + + return invokeData.mFuncResult; +} + } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/Tizen/PlatformManagerImpl.h b/src/platform/Tizen/PlatformManagerImpl.h index 1c8cfd5502c623..04ad1c02864705 100644 --- a/src/platform/Tizen/PlatformManagerImpl.h +++ b/src/platform/Tizen/PlatformManagerImpl.h @@ -23,6 +23,8 @@ #pragma once +#include + #include #include @@ -49,18 +51,46 @@ class PlatformManagerImpl final : public PlatformManager, public Internal::Gener public: // ===== Platform-specific members that may be accessed directly by the application. + /** + * @brief Invoke a function on the Matter GLib context. + * + * If execution of the function will have to be scheduled on other thread, + * this call will block the current thread until the function is executed. + * + * @param[in] function The function to call. + * @param[in] userData User data to pass to the function. + * @returns The result of the function. + */ + template + CHIP_ERROR GLibMatterContextInvokeSync(CHIP_ERROR (*func)(T *), T * userData) + { + return _GLibMatterContextInvokeSync((CHIP_ERROR(*)(void *)) func, (void *) userData); + } + private: // ===== Methods that implement the PlatformManager abstract interface. - CHIP_ERROR _InitChipStack(void); + CHIP_ERROR _InitChipStack(); + void _Shutdown(); // ===== Members for internal use by the following friends. - friend PlatformManager & PlatformMgr(void); - friend PlatformManagerImpl & PlatformMgrImpl(void); + friend PlatformManager & PlatformMgr(); + friend PlatformManagerImpl & PlatformMgrImpl(); friend class Internal::BLEManagerImpl; static PlatformManagerImpl sInstance; + + /** + * @brief Invoke a function on the Matter GLib context. + * + * @note This function does not provide type safety for the user data. Please, + * use the GLibMatterContextInvokeSync() template function instead. + */ + CHIP_ERROR _GLibMatterContextInvokeSync(CHIP_ERROR (*func)(void *), void * userData); + + GMainLoop * mGLibMainLoop; + GThread * mGLibMainLoopThread; }; /** @@ -69,7 +99,7 @@ class PlatformManagerImpl final : public PlatformManager, public Internal::Gener * Chip applications should use this to access features of the PlatformManager object * that are common to all platforms. */ -inline PlatformManager & PlatformMgr(void) +inline PlatformManager & PlatformMgr() { return PlatformManagerImpl::sInstance; } @@ -80,7 +110,7 @@ inline PlatformManager & PlatformMgr(void) * Chip applications can use this to gain access to features of the PlatformManager * that are specific to Tizen platform. */ -inline PlatformManagerImpl & PlatformMgrImpl(void) +inline PlatformManagerImpl & PlatformMgrImpl() { return PlatformManagerImpl::sInstance; } diff --git a/src/platform/Tizen/WiFiManager.cpp b/src/platform/Tizen/WiFiManager.cpp index 13c27dd541576e..b45e34bda450c8 100644 --- a/src/platform/Tizen/WiFiManager.cpp +++ b/src/platform/Tizen/WiFiManager.cpp @@ -31,8 +31,6 @@ #include #include -#include "MainLoop.h" - namespace { static constexpr const char * __WiFiDeviceStateToStr(wifi_manager_device_state_e state) { @@ -179,8 +177,6 @@ void WiFiManager::_IPConflictCb(char * mac, wifi_manager_ip_conflict_state_e ipC void WiFiManager::_ActivateCb(wifi_manager_error_e wifiErr, void * userData) { - auto loop = reinterpret_cast(userData); - if (wifiErr == WIFI_MANAGER_ERROR_NONE) { ChipLogProgress(DeviceLayer, "WiFi is activated"); @@ -189,14 +185,10 @@ void WiFiManager::_ActivateCb(wifi_manager_error_e wifiErr, void * userData) { ChipLogError(DeviceLayer, "FAIL: activate WiFi [%s]", get_error_message(wifiErr)); } - - g_main_loop_quit(loop); } void WiFiManager::_DeactivateCb(wifi_manager_error_e wifiErr, void * userData) { - auto loop = reinterpret_cast(userData); - if (wifiErr == WIFI_MANAGER_ERROR_NONE) { ChipLogProgress(DeviceLayer, "WiFi is deactivated"); @@ -205,13 +197,10 @@ void WiFiManager::_DeactivateCb(wifi_manager_error_e wifiErr, void * userData) { ChipLogError(DeviceLayer, "FAIL: deactivate WiFi [%s]", get_error_message(wifiErr)); } - - g_main_loop_quit(loop); } void WiFiManager::_ScanFinishedCb(wifi_manager_error_e wifiErr, void * userData) { - auto loop = reinterpret_cast(userData); wifi_manager_ap_h foundAp = nullptr; if (wifiErr == WIFI_MANAGER_ERROR_NONE) @@ -221,15 +210,13 @@ void WiFiManager::_ScanFinishedCb(wifi_manager_error_e wifiErr, void * userData) foundAp = sInstance._WiFiGetFoundAP(); if (foundAp != nullptr) { - MainLoop::Instance().AsyncRequest(_WiFiConnect, static_cast(foundAp)); + PlatformMgrImpl().GLibMatterContextInvokeSync(_WiFiConnect, foundAp); } } else { ChipLogError(DeviceLayer, "FAIL: scan WiFi [%s]", get_error_message(wifiErr)); } - - g_main_loop_quit(loop); } bool WiFiManager::_FoundAPCb(wifi_manager_ap_h ap, void * userData) @@ -271,8 +258,6 @@ bool WiFiManager::_FoundAPCb(wifi_manager_ap_h ap, void * userData) void WiFiManager::_ConnectedCb(wifi_manager_error_e wifiErr, void * userData) { - auto loop = reinterpret_cast(userData); - if (wifiErr == WIFI_MANAGER_ERROR_NONE || wifiErr == WIFI_MANAGER_ERROR_ALREADY_EXISTS) { ChipLogProgress(DeviceLayer, "WiFi is connected"); @@ -295,8 +280,6 @@ void WiFiManager::_ConnectedCb(wifi_manager_error_e wifiErr, void * userData) chip::DeviceLayer::PlatformMgr().UnlockChipStack(); } } - - g_main_loop_quit(loop); } bool WiFiManager::_ConfigListCb(const wifi_manager_config_h config, void * userData) @@ -322,24 +305,20 @@ bool WiFiManager::_ConfigListCb(const wifi_manager_config_h config, void * userD return true; } -gboolean WiFiManager::_WiFiInitialize(gpointer userData) +CHIP_ERROR WiFiManager::_WiFiInitialize(gpointer userData) { - int wifiErr = WIFI_MANAGER_ERROR_NONE; + int wifiErr; - wifiErr = wifi_manager_initialize(&(sInstance.mWiFiManagerHandle)); - if (wifiErr == WIFI_MANAGER_ERROR_NONE) - { - ChipLogProgress(DeviceLayer, "WiFi is initialized"); - sInstance._WiFiSetStates(); - sInstance._WiFiSetCallbacks(); - } - else - { - ChipLogError(DeviceLayer, "FAIL: initialize WiFi [%s]", get_error_message(wifiErr)); - return false; - } + wifiErr = wifi_manager_initialize(&sInstance.mWiFiManagerHandle); + VerifyOrReturnError(wifiErr == WIFI_MANAGER_ERROR_NONE, CHIP_ERROR_INTERNAL, + ChipLogError(DeviceLayer, "FAIL: initialize WiFi [%s]", get_error_message(wifiErr))); - return true; + ChipLogProgress(DeviceLayer, "WiFi is initialized"); + + sInstance._WiFiSetStates(); + sInstance._WiFiSetCallbacks(); + + return CHIP_NO_ERROR; } void WiFiManager::_WiFiDeinitialize() @@ -359,79 +338,57 @@ void WiFiManager::_WiFiDeinitialize() } } -gboolean WiFiManager::_WiFiActivate(GMainLoop * mainLoop, gpointer userData) +CHIP_ERROR WiFiManager::_WiFiActivate(gpointer userData) { - int wifiErr = WIFI_MANAGER_ERROR_NONE; + int wifiErr; - wifiErr = wifi_manager_activate(sInstance.mWiFiManagerHandle, _ActivateCb, mainLoop); - if (wifiErr == WIFI_MANAGER_ERROR_NONE) - { - ChipLogProgress(DeviceLayer, "WiFi activation is requested"); - } - else - { - ChipLogError(DeviceLayer, "FAIL: request WiFi activation [%s]", get_error_message(wifiErr)); - return false; - } + wifiErr = wifi_manager_activate(sInstance.mWiFiManagerHandle, _ActivateCb, nullptr); + VerifyOrReturnError(wifiErr == WIFI_MANAGER_ERROR_NONE, CHIP_ERROR_INTERNAL, + ChipLogError(DeviceLayer, "FAIL: request WiFi activation [%s]", get_error_message(wifiErr))); - return true; + ChipLogProgress(DeviceLayer, "WiFi activation is requested"); + return CHIP_NO_ERROR; } -gboolean WiFiManager::_WiFiDeactivate(GMainLoop * mainLoop, gpointer userData) +CHIP_ERROR WiFiManager::_WiFiDeactivate(gpointer userData) { - int wifiErr = WIFI_MANAGER_ERROR_NONE; + int wifiErr; - wifiErr = wifi_manager_deactivate(sInstance.mWiFiManagerHandle, _DeactivateCb, mainLoop); - if (wifiErr == WIFI_MANAGER_ERROR_NONE) - { - ChipLogProgress(DeviceLayer, "WiFi deactivation is requested"); - } - else - { - ChipLogError(DeviceLayer, "FAIL: request WiFi deactivation [%s]", get_error_message(wifiErr)); - return false; - } + wifiErr = wifi_manager_deactivate(sInstance.mWiFiManagerHandle, _DeactivateCb, nullptr); + VerifyOrReturnError(wifiErr == WIFI_MANAGER_ERROR_NONE, CHIP_ERROR_INTERNAL, + ChipLogError(DeviceLayer, "FAIL: request WiFi deactivation [%s]", get_error_message(wifiErr))); - return true; + ChipLogProgress(DeviceLayer, "WiFi deactivation is requested"); + return CHIP_NO_ERROR; } -gboolean WiFiManager::_WiFiScan(GMainLoop * mainLoop, gpointer userData) +CHIP_ERROR WiFiManager::_WiFiScan(gpointer userData) { - int wifiErr = WIFI_MANAGER_ERROR_NONE; + int wifiErr; - wifiErr = wifi_manager_scan(sInstance.mWiFiManagerHandle, _ScanFinishedCb, mainLoop); - if (wifiErr == WIFI_MANAGER_ERROR_NONE) - { - ChipLogProgress(DeviceLayer, "WiFi scan is requested"); - } - else - { - ChipLogError(DeviceLayer, "FAIL: request WiFi scan [%s]", get_error_message(wifiErr)); - return false; - } + wifiErr = wifi_manager_scan(sInstance.mWiFiManagerHandle, _ScanFinishedCb, nullptr); + VerifyOrReturnError(wifiErr == WIFI_MANAGER_ERROR_NONE, CHIP_ERROR_INTERNAL, + ChipLogError(DeviceLayer, "FAIL: request WiFi scan [%s]", get_error_message(wifiErr))); - return true; + ChipLogProgress(DeviceLayer, "WiFi scan is requested"); + return CHIP_NO_ERROR; } -gboolean WiFiManager::_WiFiConnect(GMainLoop * mainLoop, gpointer userData) +CHIP_ERROR WiFiManager::_WiFiConnect(wifi_manager_ap_h ap) { - int wifiErr = WIFI_MANAGER_ERROR_NONE; - wifi_manager_ap_h ap = static_cast(userData); + CHIP_ERROR err = CHIP_NO_ERROR; + int wifiErr; - wifiErr = wifi_manager_connect(sInstance.mWiFiManagerHandle, ap, _ConnectedCb, mainLoop); - if (wifiErr == WIFI_MANAGER_ERROR_NONE) - { - ChipLogProgress(DeviceLayer, "WiFi connect is requested"); - } - else - { - ChipLogError(DeviceLayer, "FAIL: request WiFi connect [%s]", get_error_message(wifiErr)); - wifi_manager_ap_destroy(ap); - return false; - } + wifiErr = wifi_manager_connect(sInstance.mWiFiManagerHandle, ap, _ConnectedCb, nullptr); + VerifyOrExit(wifiErr == WIFI_MANAGER_ERROR_NONE, + ChipLogError(DeviceLayer, "FAIL: request WiFi connect [%s]", get_error_message(wifiErr)); + err = CHIP_ERROR_INTERNAL); + + ChipLogProgress(DeviceLayer, "WiFi connect is requested"); +exit: wifi_manager_ap_destroy(ap); - return true; + return err; } void WiFiManager::_WiFiSetStates() @@ -595,13 +552,12 @@ void WiFiManager::Init() sInstance.mModuleState = WIFI_MANAGER_MODULE_STATE_DETACHED; sInstance.mConnectionState = WIFI_MANAGER_CONNECTION_STATE_DISCONNECTED; - MainLoop::Instance().Init(_WiFiInitialize); + PlatformMgrImpl().GLibMatterContextInvokeSync(_WiFiInitialize, static_cast(nullptr)); } void WiFiManager::Deinit() { sInstance._WiFiDeinitialize(); - MainLoop::Instance().Deinit(); } CHIP_ERROR WiFiManager::IsActivated(bool * isWiFiActivated) @@ -616,16 +572,12 @@ CHIP_ERROR WiFiManager::Activate() { CHIP_ERROR err = CHIP_NO_ERROR; bool isWiFiActivated = false; - bool dbusAsyncErr = false; VerifyOrExit((err = IsActivated(&isWiFiActivated)) == CHIP_NO_ERROR, ); VerifyOrExit(isWiFiActivated == false, ChipLogProgress(DeviceLayer, "WiFi is already activated")); - dbusAsyncErr = MainLoop::Instance().AsyncRequest(_WiFiActivate); - VerifyOrExit(dbusAsyncErr == true, { - ChipLogError(DeviceLayer, "FAIL: Async request: Activate WiFi"); - err = CHIP_ERROR_INTERNAL; - }); + err = PlatformMgrImpl().GLibMatterContextInvokeSync(_WiFiActivate, static_cast(nullptr)); + SuccessOrExit(err); exit: return err; @@ -635,16 +587,12 @@ CHIP_ERROR WiFiManager::Deactivate() { CHIP_ERROR err = CHIP_NO_ERROR; bool isWiFiActivated = false; - bool dbusAsyncErr = false; VerifyOrExit((err = IsActivated(&isWiFiActivated)) == CHIP_NO_ERROR, ); VerifyOrExit(isWiFiActivated == true, ChipLogProgress(DeviceLayer, "WiFi is already deactivated")); - dbusAsyncErr = MainLoop::Instance().AsyncRequest(_WiFiDeactivate); - VerifyOrExit(dbusAsyncErr == true, { - ChipLogError(DeviceLayer, "FAIL: Async request: Deactivate WiFi"); - err = CHIP_ERROR_INTERNAL; - }); + err = PlatformMgrImpl().GLibMatterContextInvokeSync(_WiFiDeactivate, static_cast(nullptr)); + SuccessOrExit(err); exit: return err; @@ -655,7 +603,6 @@ CHIP_ERROR WiFiManager::Connect(const char * ssid, const char * key, { CHIP_ERROR err = CHIP_NO_ERROR; bool isWiFiActivated = false; - bool dbusAsyncErr = false; wifi_manager_ap_h foundAp = nullptr; g_strlcpy(sInstance.mWiFiSSID, ssid, sizeof(sInstance.mWiFiSSID)); @@ -672,19 +619,13 @@ CHIP_ERROR WiFiManager::Connect(const char * ssid, const char * key, foundAp = sInstance._WiFiGetFoundAP(); if (foundAp != nullptr) { - dbusAsyncErr = MainLoop::Instance().AsyncRequest(_WiFiConnect, foundAp); - VerifyOrExit(dbusAsyncErr == true, { - ChipLogError(DeviceLayer, "FAIL: Async request: Connect WiFi"); - err = CHIP_ERROR_INTERNAL; - }); + err = PlatformMgrImpl().GLibMatterContextInvokeSync(_WiFiConnect, foundAp); + SuccessOrExit(err); } else { - dbusAsyncErr = MainLoop::Instance().AsyncRequest(_WiFiScan); - VerifyOrExit(dbusAsyncErr == true, { - ChipLogError(DeviceLayer, "FAIL: Async request: Scan WiFi"); - err = CHIP_ERROR_INTERNAL; - }); + err = PlatformMgrImpl().GLibMatterContextInvokeSync(_WiFiScan, static_cast(nullptr)); + SuccessOrExit(err); } exit: diff --git a/src/platform/Tizen/WiFiManager.h b/src/platform/Tizen/WiFiManager.h index 87da73aafc16a9..6304642ed07f51 100644 --- a/src/platform/Tizen/WiFiManager.h +++ b/src/platform/Tizen/WiFiManager.h @@ -69,11 +69,11 @@ class WiFiManager static void _ConnectedCb(wifi_manager_error_e wifiErr, void * userData); static bool _ConfigListCb(const wifi_manager_config_h config, void * userData); - static gboolean _WiFiInitialize(gpointer userData); - static gboolean _WiFiActivate(GMainLoop * mainLoop, gpointer userData); - static gboolean _WiFiDeactivate(GMainLoop * mainLoop, gpointer userData); - static gboolean _WiFiScan(GMainLoop * mainLoop, gpointer userData); - static gboolean _WiFiConnect(GMainLoop * mainLoop, gpointer userData); + static CHIP_ERROR _WiFiInitialize(gpointer userData); + static CHIP_ERROR _WiFiActivate(gpointer userData); + static CHIP_ERROR _WiFiDeactivate(gpointer userData); + static CHIP_ERROR _WiFiScan(gpointer userData); + static CHIP_ERROR _WiFiConnect(wifi_manager_ap_h ap); void _WiFiDeinitialize(); void _WiFiSetStates();