diff --git a/.gitignore b/.gitignore index 9ed30d6a..1d22f629 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,5 @@ Source/playerinfo/player_info/player_info */*/*/*/*tests */*/generated */*/*/*/lib*.a +.cache +compile_commands.json diff --git a/CMakeLists.txt b/CMakeLists.txt index ace9de77..5f2dc90a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,8 @@ option(CDMI "Include OpenCDM interface." OFF) option(CRYPTOGRAPHY "Include the cryptography library." OFF) +option(POWERCONTROLLER + "Include the powermanager COMRPC abstraction library." OFF) option(INSTALL_TESTS "Install the test applications" OFF) diff --git a/NOTICE b/NOTICE index fd4f8ed1..f0bbef9d 100644 --- a/NOTICE +++ b/NOTICE @@ -31,4 +31,5 @@ Licensed under the MIT License Copyright (C) 2015,2019 Metrological Licensed under the BSD-2 License - +Copyright 2025 RDK Management +Licensed under the Apache License, Version 2.0 diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index af7578a5..4cc4cb1d 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -58,3 +58,7 @@ endif() if(LOCALTRACER) add_subdirectory(localtracer) endif() + +if(POWERCONTROLLER) + add_subdirectory(powercontroller) +endif() diff --git a/Source/powercontroller/CMakeLists.txt b/Source/powercontroller/CMakeLists.txt new file mode 100644 index 00000000..786bffc1 --- /dev/null +++ b/Source/powercontroller/CMakeLists.txt @@ -0,0 +1,79 @@ +# If not stated otherwise in this file or this component's LICENSE file the +# following copyright and licenses apply: +# +# Copyright 2025 RDK Management +# +# 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. + +cmake_minimum_required(VERSION 3.3) + +find_package(WPEFramework) + +project(PowerController) + +project_version(4.4.1) + +set(TARGET ${NAMESPACE}${PROJECT_NAME}) + +message("Setup ${TARGET} v${PROJECT_VERSION}") + +find_package(${NAMESPACE}Core REQUIRED) +find_package(${NAMESPACE}COM REQUIRED) +find_package(CompileSettingsDebug CONFIG REQUIRED) + +set(PUBLIC_HEADERS "power_controller.h") + +add_library(${TARGET} SHARED + Module.cpp + power_controller.cpp +) + +target_link_libraries(${TARGET} + PRIVATE + ${NAMESPACE}Core::${NAMESPACE}Core + ${NAMESPACE}COM::${NAMESPACE}COM + CompileSettingsDebug::CompileSettingsDebug + ) + +set_target_properties(${TARGET} PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES + FRAMEWORK FALSE + PUBLIC_HEADER "${PUBLIC_HEADERS}" # specify the public headers + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR} + ) + +target_include_directories( ${TARGET} + PUBLIC + $ + $ + ) + +install( + TARGETS ${TARGET} EXPORT ${TARGET}Targets # for downstream dependencies + ARCHIVE DESTINATION lib COMPONENT libs # static lib + LIBRARY DESTINATION lib COMPONENT libs # shared lib + RUNTIME DESTINATION bin COMPONENT libs # binaries + FRAMEWORK DESTINATION bin COMPONENT libs # for mac + PUBLIC_HEADER DESTINATION include/${NAMESPACE}/powercontroller COMPONENT devel # headers for mac (note the different component -> different package) + INCLUDES DESTINATION include/${NAMESPACE}/powercontroller # headers +) + +InstallCMakeConfig( + TARGETS ${TARGET}) + +InstallPackageConfig( + TARGETS ${TARGET} + DESCRIPTION "communications channel abstraction for powermanager plugin") + diff --git a/Source/powercontroller/Module.cpp b/Source/powercontroller/Module.cpp new file mode 100644 index 00000000..e924dc30 --- /dev/null +++ b/Source/powercontroller/Module.cpp @@ -0,0 +1,22 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2025 RDK Management + * + * 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 "Module.h" + +MODULE_NAME_DECLARATION(BUILD_REFERENCE) diff --git a/Source/powercontroller/Module.h b/Source/powercontroller/Module.h new file mode 100644 index 00000000..c9c13219 --- /dev/null +++ b/Source/powercontroller/Module.h @@ -0,0 +1,33 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2025 RDK Management + * + * 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 + +#ifndef MODULE_NAME +#define MODULE_NAME ClientLibrary_PowerManager +#endif + +#include +#include +#include + +#if defined(__WINDOWS__) && defined(POWERMANAGER_EXPORTS) +#undef EXTERNAL +#define EXTERNAL EXTERNAL_EXPORT +#endif diff --git a/Source/powercontroller/power_controller.cpp b/Source/powercontroller/power_controller.cpp new file mode 100644 index 00000000..ebadd21b --- /dev/null +++ b/Source/powercontroller/power_controller.cpp @@ -0,0 +1,1458 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2025 RDK Management + * + * 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. + */ + +// std includes +#include +#include +#include +#include + +// Thunder includes +#include +#include + +#include "power_controller.h" + +using namespace WPEFramework; +using PowerState = WPEFramework::Exchange::IPowerManager::PowerState; +using WakeupSrcType = WPEFramework::Exchange::IPowerManager::WakeupSrcType; +using WakeupReason = WPEFramework::Exchange::IPowerManager::WakeupReason; +using SystemMode = WPEFramework::Exchange::IPowerManager::SystemMode; +using ThermalTemperature = WPEFramework::Exchange::IPowerManager::ThermalTemperature; + +namespace /*unnamed*/ { + +const std::unordered_map& powerStateMap() +{ + static const std::unordered_map map = { + { PowerState::POWER_STATE_UNKNOWN, POWER_STATE_UNKNOWN }, + { PowerState::POWER_STATE_OFF, POWER_STATE_OFF }, + { PowerState::POWER_STATE_STANDBY, POWER_STATE_STANDBY }, + { PowerState::POWER_STATE_ON, POWER_STATE_ON }, + { PowerState::POWER_STATE_STANDBY_LIGHT_SLEEP, POWER_STATE_STANDBY_LIGHT_SLEEP }, + { PowerState::POWER_STATE_STANDBY_DEEP_SLEEP, POWER_STATE_STANDBY_DEEP_SLEEP }, + }; + + return map; +} + +PowerController_PowerState_t convert(const PowerState from) +{ + auto& map = powerStateMap(); + auto it = map.find(from); + return (it != map.end()) ? it->second : POWER_STATE_UNKNOWN; +} + +PowerState convert(const PowerController_PowerState_t from) +{ + auto& map = powerStateMap(); + + for (const auto& kv : map) { + if (kv.second == from) { + return kv.first; + } + } + return PowerState::POWER_STATE_UNKNOWN; +} + +const std::unordered_map& wakeupSrcTypeMap() +{ + static const std::unordered_map map = { + { WakeupSrcType::WAKEUP_SRC_UNKNOWN, WAKEUP_SRC_UNKNOWN }, + { WakeupSrcType::WAKEUP_SRC_VOICE, WAKEUP_SRC_VOICE }, + { WakeupSrcType::WAKEUP_SRC_PRESENCEDETECTED, WAKEUP_SRC_PRESENCEDETECTED }, + { WakeupSrcType::WAKEUP_SRC_BLUETOOTH, WAKEUP_SRC_BLUETOOTH }, + { WakeupSrcType::WAKEUP_SRC_RF4CE, WAKEUP_SRC_RF4CE }, + { WakeupSrcType::WAKEUP_SRC_WIFI, WAKEUP_SRC_WIFI }, + { WakeupSrcType::WAKEUP_SRC_IR, WAKEUP_SRC_IR }, + { WakeupSrcType::WAKEUP_SRC_POWERKEY, WAKEUP_SRC_POWERKEY }, + { WakeupSrcType::WAKEUP_SRC_TIMER, WAKEUP_SRC_TIMER }, + { WakeupSrcType::WAKEUP_SRC_CEC, WAKEUP_SRC_CEC }, + { WakeupSrcType::WAKEUP_SRC_LAN, WAKEUP_SRC_LAN }, + }; + return map; +} + +PowerController_WakeupSrcType_t convert(const WakeupSrcType from) +{ + auto& map = wakeupSrcTypeMap(); + auto it = map.find(from); + return (it != map.end()) ? it->second : WAKEUP_SRC_UNKNOWN; +} + +WakeupSrcType convert(const PowerController_WakeupSrcType_t from) +{ + auto& map = wakeupSrcTypeMap(); + + for (const auto& kv : map) { + if (kv.second == from) { + return kv.first; + } + } + return WakeupSrcType::WAKEUP_SRC_UNKNOWN; +} + +const std::unordered_map& wakeupReasonMap() +{ + static const std::unordered_map map = { + { WakeupReason::WAKEUP_REASON_UNKNOWN, WAKEUP_REASON_UNKNOWN }, + { WakeupReason::WAKEUP_REASON_IR, WAKEUP_REASON_IR }, + { WakeupReason::WAKEUP_REASON_BLUETOOTH, WAKEUP_REASON_BLUETOOTH }, + { WakeupReason::WAKEUP_REASON_RF4CE, WAKEUP_REASON_RF4CE }, + { WakeupReason::WAKEUP_REASON_GPIO, WAKEUP_REASON_GPIO }, + { WakeupReason::WAKEUP_REASON_LAN, WAKEUP_REASON_LAN }, + { WakeupReason::WAKEUP_REASON_WIFI, WAKEUP_REASON_WIFI }, + { WakeupReason::WAKEUP_REASON_TIMER, WAKEUP_REASON_TIMER }, + { WakeupReason::WAKEUP_REASON_FRONTPANEL, WAKEUP_REASON_FRONTPANEL }, + { WakeupReason::WAKEUP_REASON_WATCHDOG, WAKEUP_REASON_WATCHDOG }, + { WakeupReason::WAKEUP_REASON_SOFTWARERESET, WAKEUP_REASON_SOFTWARERESET }, + { WakeupReason::WAKEUP_REASON_THERMALRESET, WAKEUP_REASON_THERMALRESET }, + { WakeupReason::WAKEUP_REASON_WARMRESET, WAKEUP_REASON_WARMRESET }, + { WakeupReason::WAKEUP_REASON_COLDBOOT, WAKEUP_REASON_COLDBOOT }, + { WakeupReason::WAKEUP_REASON_STRAUTHFAIL, WAKEUP_REASON_STRAUTHFAIL }, + { WakeupReason::WAKEUP_REASON_CEC, WAKEUP_REASON_CEC }, + { WakeupReason::WAKEUP_REASON_PRESENCE, WAKEUP_REASON_PRESENCE }, + { WakeupReason::WAKEUP_REASON_VOICE, WAKEUP_REASON_VOICE }, + }; + return map; +} + +PowerController_WakeupReason_t convert(const WakeupReason from) +{ + auto& map = wakeupReasonMap(); + auto it = map.find(from); + return (it != map.end()) ? it->second : WAKEUP_REASON_UNKNOWN; +} + +WakeupReason convert(const PowerController_WakeupReason_t from) +{ + auto& map = wakeupReasonMap(); + + for (const auto& kv : map) { + if (kv.second == from) { + return kv.first; + } + } + return WakeupReason::WAKEUP_REASON_UNKNOWN; +} + +const std::unordered_map& systemModeMap() +{ + static const std::unordered_map map = { + { SYSTEM_MODE_UNKNOWN, SystemMode::SYSTEM_MODE_UNKNOWN }, + { SYSTEM_MODE_NORMAL, SystemMode::SYSTEM_MODE_NORMAL }, + { SYSTEM_MODE_EAS, SystemMode::SYSTEM_MODE_EAS }, + { SYSTEM_MODE_WAREHOUSE, SystemMode::SYSTEM_MODE_WAREHOUSE }, + }; + return map; +} + +SystemMode convert(const PowerController_SystemMode_t from) +{ + auto& map = systemModeMap(); + auto it = map.find(from); + return (it != map.end()) ? it->second : SystemMode::SYSTEM_MODE_UNKNOWN; +} + +const std::unordered_map& thermalTemperatureMap() +{ + static const std::unordered_map map = { + { ThermalTemperature::THERMAL_TEMPERATURE_UNKNOWN, THERMAL_TEMPERATURE_UNKNOWN }, + { ThermalTemperature::THERMAL_TEMPERATURE_NORMAL, THERMAL_TEMPERATURE_NORMAL }, + { ThermalTemperature::THERMAL_TEMPERATURE_HIGH, THERMAL_TEMPERATURE_HIGH }, + { ThermalTemperature::THERMAL_TEMPERATURE_CRITICAL, THERMAL_TEMPERATURE_CRITICAL }, + }; + return map; +} + +PowerController_ThermalTemperature_t convert(const ThermalTemperature from) +{ + auto& map = thermalTemperatureMap(); + auto it = map.find(from); + return (it != map.end()) ? it->second : THERMAL_TEMPERATURE_UNKNOWN; +} + +static constexpr const TCHAR callSign[] = _T("org.rdk.PowerManager"); + +// Templated Callback list avoid code duplication, for individual callback types +// This class expects mechanism to register / unregister for individual & unique notifications with PowerManager +// via RegisterNotificationLocked and UnregisterNotificationLocked methods. To be implemented in PowerController (i,e PARENT) +template +class CallbackList : public std::list { + PARENT& _parent; + bool _registered; + +public: + CallbackList(PARENT& parent) + : _parent(parent) + , _registered(false) + { + } + + // Locked method expected to be called from locked context + uint32_t RegisterCallbackLocked(typename CallbackType::Type callback, void* userdata) + { + uint32_t result = Core::ERROR_ALREADY_CONNECTED; + + auto it = std::find_if(this->begin(), this->end(), [&callback](const CallbackType& cb) { + return cb.callback == callback; + }); + + if (it == this->end()) { + this->emplace_back(callback, userdata); + result = Core::ERROR_NONE; + RegisterNotificationLocked(); + } + + return result; + } + + // Locked method expected to be called from locked context + uint32_t UnRegisterCallbackLocked(typename CallbackType::Type callback) + { + uint32_t result = Core::ERROR_ALREADY_RELEASED; + + auto it = std::find_if(this->begin(), this->end(), [&callback](const CallbackType& cb) { + return cb.callback == callback; + }); + + if (it != this->end()) { + this->erase(it); + result = Core::ERROR_NONE; + UnregisterNotificationLocked(false); + } + + return result; + } + + // Locked method expected to be called from locked context + inline void RegisterNotificationLocked() + { + if (!_registered && !this->empty() && _parent.IsActivatedLocked()) { + _registered = _parent.template RegisterNotificationLocked(); + } + } + + // Locked method expected to be called from locked context + // @param forced A boolean indicating whether to forcefully unregister from notification + // regardless of the callback list's state / unregister status. + // This is required to handle PowerManager restart scenarios. + inline void UnregisterNotificationLocked(const bool forced) + { + if (_registered && _parent.IsActivatedLocked() && (forced || this->empty())) { + bool unregistered = _parent.template UnregisterNotificationLocked(); + + // --------------------------------------- + // | forced | unregistered | _registered | + // |--------|--------------|-------------| + // | 0 | 0 | 1 | + // | 0 | 1 | 0 | + // | 1 | 0 | 0 | + // | 1 | 1 | 0 | + // --------------------------------------- + _registered = !forced && !unregistered; + } + } +}; + +struct OperationalStateChangeCb { + using Type = PowerController_OperationalStateChangeCb; + Type callback; + void* userdata; + + OperationalStateChangeCb(Type cb, void* ud) + : callback(cb) + , userdata(ud) + { + } +}; + +struct NetworkStandbyModeChangedCb { + using Type = PowerController_NetworkStandbyModeChangedCb; + Type callback; + void* userdata; + + NetworkStandbyModeChangedCb(Type cb, void* ud) + : callback(cb) + , userdata(ud) + { + } +}; + +struct PowerModePreChangedCb { + using Type = PowerController_PowerModePreChangeCb; + Type callback; + void* userdata; + + PowerModePreChangedCb(Type cb, void* ud) + : callback(cb) + , userdata(ud) + { + } +}; + +struct PowerModeChangedCb { + using Type = PowerController_PowerModeChangedCb; + Type callback; + void* userdata; + + PowerModeChangedCb(Type cb, void* ud) + : callback(cb) + , userdata(ud) + { + } +}; + +struct DeepSleepTimeoutCb { + using Type = PowerController_DeepSleepTimeoutCb; + Type callback; + void* userdata; + + DeepSleepTimeoutCb(Type cb, void* ud) + : callback(cb) + , userdata(ud) + { + } +}; + +struct ThermalModeChangedCb { + using Type = PowerController_ThermalModeChangedCb; + Type callback; + void* userdata; + + ThermalModeChangedCb(Type cb, void* ud) + : callback(cb) + , userdata(ud) + { + } +}; + +struct RebootBeginCb { + using Type = PowerController_RebootBeginCb; + Type callback; + void* userdata; + + RebootBeginCb(Type cb, void* ud) + : callback(cb) + , userdata(ud) + { + } +}; + +class PowerController : public RPC::SmartInterfaceType { +private: + using BaseClass = RPC::SmartInterfaceType; + using OperationalStateChangeCallbacks = CallbackList; + using PowerModePreChangeCallbacks = CallbackList; + using PowerModeChangedCallbacks = CallbackList; + using DeepSleepTimeoutCallbacks = CallbackList; + using NetworkStandbyModeChangedCallbacks = CallbackList; + using ThermalModeChangedCallbacks = CallbackList; + using RebootBeginCallbacks = CallbackList; + + class Notification : public Exchange::IPowerManager::IRebootNotification, + public Exchange::IPowerManager::IModeChangedNotification, + public Exchange::IPowerManager::IModePreChangeNotification, + public Exchange::IPowerManager::IDeepSleepTimeoutNotification, + public Exchange::IPowerManager::INetworkStandbyModeChangedNotification, + public Exchange::IPowerManager::IThermalModeChangedNotification { + private: + PowerController& _parent; + + public: + Notification(PowerController& parent) + : _parent(parent) + { + } + + Notification(const Notification&) = delete; // Delete copy constructor + Notification& operator=(const Notification&) = delete; // Delete copy assignment operator + + Notification(Notification&&) = delete; // Delete move constructor + Notification& operator=(Notification&&) = delete; // Delete move assignment operator + + virtual void OnPowerModeChanged(const PowerState& currentState, const PowerState& newState) override + { + _parent.NotifyPowerModeChanged(currentState, newState); + } + + virtual void OnPowerModePreChange(const PowerState& currentState, const PowerState& newState, const int transactionId, const int stateChangeAfter) override + { + _parent.NotifyPowerModePreChange(currentState, newState, transactionId, stateChangeAfter); + } + + virtual void OnDeepSleepTimeout(const int& wakeupTimeout) override + { + _parent.NotifyDeepSleepTimeout(wakeupTimeout); + } + + virtual void OnNetworkStandbyModeChanged(const bool& enabled) override + { + _parent.NotifyNetworkStandbyModeChanged(enabled); + } + + virtual void OnThermalModeChanged(const ThermalTemperature& currentThermalLevel, const ThermalTemperature& newThermalLevel, const float& currentTemperature) override + { + _parent.NotifyThermalModeChanged(currentThermalLevel, newThermalLevel, currentTemperature); + } + + virtual void OnRebootBegin(const string& rebootReasonCustom, const string& rebootReasonOther, const string& rebootRequestor) override + { + _parent.NotifyRebootBegin(rebootReasonCustom, rebootReasonOther, rebootRequestor); + } + + BEGIN_INTERFACE_MAP(Notification) + INTERFACE_ENTRY(Exchange::IPowerManager::IRebootNotification) + INTERFACE_ENTRY(Exchange::IPowerManager::IModePreChangeNotification) + INTERFACE_ENTRY(Exchange::IPowerManager::IModeChangedNotification) + INTERFACE_ENTRY(Exchange::IPowerManager::IDeepSleepTimeoutNotification) + INTERFACE_ENTRY(Exchange::IPowerManager::INetworkStandbyModeChangedNotification) + INTERFACE_ENTRY(Exchange::IPowerManager::IThermalModeChangedNotification) + END_INTERFACE_MAP + + template + inline T* baseInterface() + { + static_assert(std::is_base_of(), "base type mismatch"); + return static_cast(this); + } + }; + + PowerController() + : BaseClass() + , _powerManagerInterface(nullptr) + , _powerManagerNotification(*this) + , _operationalStateChangeCallbacks(*this) + , _powerModePreChangeCallbacks(*this) + , _powerModeChangedCallbacks(*this) + , _deepSleepTimeoutCallbacks(*this) + , _networkStandbyModeChangedCallbacks(*this) + , _thermalModeChangedCallbacks(*this) + , _rebootBeginCallbacks(*this) + , _shutdown(false) + { + (void)Connect(); + } + + ~PowerController() + { + _shutdown = true; + /* Close destroys _powerManagerInterface too */ + BaseClass::Close(Core::infinite); + } + + virtual void Operational(const bool upAndRunning) override + { + _apiLock.Lock(); + + // avoid misleading log during shutdown + if (!upAndRunning && _shutdown) { + std::cout << "PowerController::Operational (" << callSign << ") " << upAndRunning << std::endl; + } + + if (upAndRunning) { + // Communicatior opened && PowerManager is Activated + if (nullptr == _powerManagerInterface) { + _powerManagerInterface = BaseClass::Interface(); + if (_powerManagerInterface != nullptr) { + RegisterNotificationsLocked(); + std::cout << "PowerController successfully established COM-RPC connection with PowerManager plugin\n"; + } else { + // Internal error powerManager is running, but QueryInterface failed for it ? + std::cerr << "PowerController failed to establish COM-RPC connection with PowerManager plugin\n"; + } + } + } else { + // PowerManager is Deactivated || Communicator closed + if (nullptr != _powerManagerInterface) { + UnregisterNotificationsLocked(); + _powerManagerInterface->Release(); + _powerManagerInterface = nullptr; + } else { + std::cerr << "Unexpected, powerManager just deactivated, but interface already null ?\n"; + } + } + _apiLock.Unlock(); + + _callbackLock.Lock(); + // avoid notifying operational state changed if shuting down because of Term + if (!_shutdown) { + for (auto& cb : _operationalStateChangeCallbacks) { + cb.callback(upAndRunning, cb.userdata); + } + } + _callbackLock.Unlock(); + } + + // Locked method expected to be called from locked context + void RegisterNotificationsLocked() + { + _powerModeChangedCallbacks.RegisterNotificationLocked(); + _powerModePreChangeCallbacks.RegisterNotificationLocked(); + _deepSleepTimeoutCallbacks.RegisterNotificationLocked(); + _networkStandbyModeChangedCallbacks.RegisterNotificationLocked(); + _thermalModeChangedCallbacks.RegisterNotificationLocked(); + _rebootBeginCallbacks.RegisterNotificationLocked(); + } + + // Locked method expected to be called from locked context + void UnregisterNotificationsLocked() + { + _powerModeChangedCallbacks.UnregisterNotificationLocked(true); + _powerModePreChangeCallbacks.UnregisterNotificationLocked(true); + _deepSleepTimeoutCallbacks.UnregisterNotificationLocked(true); + _networkStandbyModeChangedCallbacks.UnregisterNotificationLocked(true); + _thermalModeChangedCallbacks.UnregisterNotificationLocked(true); + _rebootBeginCallbacks.UnregisterNotificationLocked(true); + } + + inline bool IsConnected() const + { + return (~0 != ConnectionId()); + } + +public: + // Locked method expected to be called from locked context + inline bool IsActivatedLocked() const + { + return (nullptr != _powerManagerInterface); + } + + uint32_t Connect() + { + uint32_t status = Core::ERROR_NONE; + std::string errMsg = ""; + + _apiLock.Lock(); + do { + if (!IsConnected()) { + uint32_t res = BaseClass::Open(RPC::CommunicationTimeOut, BaseClass::Connector(), callSign); + if (Core::ERROR_NONE != res) { + std::cerr << "COM-RPC channel open failed. Is Thunder running?\n"; + errMsg = "COM-RPC channel open failed"; + status = Core::ERROR_UNAVAILABLE; + break; + } + } + + if (nullptr == _powerManagerInterface) { + errMsg = "PowerManager plugin is not activated yet"; + status = Core::ERROR_NOT_EXIST; + } + } while (false); + + _apiLock.Unlock(); + + std::cout << "PowerController::Connect (" << callSign << ") status: " << status << ", errMsg: \"" << errMsg << "\"" << std::endl; + + return status; + } + + // Locked method expected to be called from locked context (take care in specializations too) + template + bool RegisterNotificationLocked() + { + // static_assert(std::false_type::value, "Specialization required for CallbackType"); + return false; + } + + // Locked method expected to be called from locked context (take care in specializations too) + template + bool UnregisterNotificationLocked() + { + // static_assert(std::false_type::value, "Specialization required for CallbackType"); + return false; + } + + static void Init() + { + _apiLock.Lock(); + if (nullptr == _instance) { + ASSERT(0 == _nClients); + _instance = new PowerController(); + } + _nClients++; + _apiLock.Unlock(); + } + + static void Term() + { + _apiLock.Lock(); + if (_nClients > 0) { + _nClients--; + } + if (0 == _nClients && nullptr != _instance) { + delete _instance; + _instance = nullptr; + } + _apiLock.Unlock(); + } + + static PowerController& Instance() + { + ASSERT(nullptr != _instance); + return *_instance; + } + + uint32_t GetPowerState(PowerController_PowerState_t* currentState, PowerController_PowerState_t* previousState) + { + uint32_t result = Core::ERROR_UNAVAILABLE; + + PowerState currentState_ = PowerState::POWER_STATE_UNKNOWN; + PowerState previousState_ = PowerState::POWER_STATE_UNKNOWN; + + _apiLock.Lock(); + + if (_powerManagerInterface) { + result = _powerManagerInterface->GetPowerState(currentState_, previousState_); + } + + _apiLock.Unlock(); + + if (Core::ERROR_NONE == result) { + *currentState = convert(currentState_); + *previousState = convert(previousState_); + } + + return result; + } + + uint32_t SetPowerState(const int keyCode, const PowerController_PowerState_t powerState, const char* reason) + { + uint32_t result = Core::ERROR_UNAVAILABLE; + + PowerState powerState_ = convert(powerState); + + _apiLock.Lock(); + + if (_powerManagerInterface) { + result = _powerManagerInterface->SetPowerState(keyCode, powerState_, reason); + } + + _apiLock.Unlock(); + + return result; + } + + uint32_t GetThermalState(float* currentTemperature) + { + uint32_t result = Core::ERROR_UNAVAILABLE; + + _apiLock.Lock(); + + if (_powerManagerInterface) { + result = _powerManagerInterface->GetThermalState(*currentTemperature); + } + + _apiLock.Unlock(); + + return result; + } + + uint32_t SetTemperatureThresholds(float high, float critical) + { + uint32_t result = Core::ERROR_UNAVAILABLE; + + _apiLock.Lock(); + + if (_powerManagerInterface) { + result = _powerManagerInterface->SetTemperatureThresholds(high, critical); + } + + _apiLock.Unlock(); + + return result; + } + + uint32_t GetTemperatureThresholds(float* high, float* critical) + { + uint32_t result = Core::ERROR_UNAVAILABLE; + + _apiLock.Lock(); + + if (_powerManagerInterface) { + result = _powerManagerInterface->GetTemperatureThresholds(*high, *critical); + } + + _apiLock.Unlock(); + + return result; + } + + uint32_t SetOvertempGraceInterval(const int graceInterval) + { + uint32_t result = Core::ERROR_UNAVAILABLE; + + _apiLock.Lock(); + + if (_powerManagerInterface) { + result = _powerManagerInterface->SetOvertempGraceInterval(graceInterval); + } + + _apiLock.Unlock(); + + return result; + } + + uint32_t GetOvertempGraceInterval(int* graceInterval) + { + uint32_t result = Core::ERROR_UNAVAILABLE; + + _apiLock.Lock(); + + if (_powerManagerInterface) { + result = _powerManagerInterface->GetOvertempGraceInterval(*graceInterval); + } + + _apiLock.Unlock(); + + return result; + } + + uint32_t SetDeepSleepTimer(const int timeOut) + { + uint32_t result = Core::ERROR_UNAVAILABLE; + + _apiLock.Lock(); + + if (_powerManagerInterface) { + result = _powerManagerInterface->SetDeepSleepTimer(timeOut); + } + + _apiLock.Unlock(); + + return result; + } + + uint32_t GetLastWakeupReason(PowerController_WakeupReason_t* wakeupReason) + { + uint32_t result = Core::ERROR_UNAVAILABLE; + WakeupReason wakeupReason_ = WakeupReason::WAKEUP_REASON_UNKNOWN; + + _apiLock.Lock(); + + if (_powerManagerInterface) { + result = _powerManagerInterface->GetLastWakeupReason(wakeupReason_); + } + + _apiLock.Unlock(); + + if (Core::ERROR_NONE == result) { + *wakeupReason = convert(wakeupReason_); + } + + return result; + } + + uint32_t GetLastWakeupKeyCode(int* keycode) + { + uint32_t result = Core::ERROR_UNAVAILABLE; + + _apiLock.Lock(); + + if (_powerManagerInterface) { + _powerManagerInterface->GetLastWakeupKeyCode(*keycode); + } + + _apiLock.Unlock(); + + return result; + } + + uint32_t Reboot(const char* rebootRequestor, const char* rebootReasonCustom, const char* rebootReasonOther) + { + uint32_t result = Core::ERROR_UNAVAILABLE; + + _apiLock.Lock(); + + if (_powerManagerInterface) { + result = _powerManagerInterface->Reboot(rebootRequestor, rebootReasonCustom, rebootReasonOther); + } + + _apiLock.Unlock(); + + return result; + } + + uint32_t SetNetworkStandbyMode(const bool standbyMode) + { + uint32_t result = Core::ERROR_UNAVAILABLE; + + _apiLock.Lock(); + + if (_powerManagerInterface) { + result = _powerManagerInterface->SetNetworkStandbyMode(standbyMode); + } + + _apiLock.Unlock(); + + return result; + } + uint32_t GetNetworkStandbyMode(bool* standbyMode) + { + uint32_t result = Core::ERROR_UNAVAILABLE; + + _apiLock.Lock(); + + if (_powerManagerInterface) { + result = _powerManagerInterface->GetNetworkStandbyMode(*standbyMode); + } + + _apiLock.Unlock(); + + return result; + } + + uint32_t SetWakeupSrcConfig(const int powerMode, const int wakeSrcType, int config) + { + uint32_t result = Core::ERROR_UNAVAILABLE; + + _apiLock.Lock(); + + if (_powerManagerInterface) { + result = _powerManagerInterface->SetWakeupSrcConfig(powerMode, wakeSrcType, config); + } + + _apiLock.Unlock(); + + return result; + } + + uint32_t GetWakeupSrcConfig(int& powerMode, int& srcType, int& config) + { + uint32_t result = Core::ERROR_UNAVAILABLE; + + _apiLock.Lock(); + + if (_powerManagerInterface) { + result = _powerManagerInterface->GetWakeupSrcConfig(powerMode, srcType, config); + } + + _apiLock.Unlock(); + + return result; + } + + uint32_t SetSystemMode(const PowerController_SystemMode_t currentMode, const PowerController_SystemMode_t newMode) + { + uint32_t result = Core::ERROR_UNAVAILABLE; + SystemMode currentMode_ = convert(currentMode); + SystemMode newMode_ = convert(newMode); + + _apiLock.Lock(); + + if (_powerManagerInterface) { + result = _powerManagerInterface->SetSystemMode(currentMode_, newMode_); + } + + _apiLock.Unlock(); + + return result; + } + + uint32_t GetPowerStateBeforeReboot(PowerController_PowerState_t* powerStateBeforeReboot) + { + uint32_t result = Core::ERROR_UNAVAILABLE; + PowerState powerStateBeforeReboot_ = PowerState::POWER_STATE_UNKNOWN; + + _apiLock.Lock(); + + if (_powerManagerInterface) { + result = _powerManagerInterface->GetPowerStateBeforeReboot(powerStateBeforeReboot_); + } + + _apiLock.Unlock(); + + if (Core::ERROR_NONE == result) { + *powerStateBeforeReboot = convert(powerStateBeforeReboot_); + } + + return result; + } + + uint32_t AddPowerModePreChangeClient(const std::string& clientName, uint32_t& clientId) + { + uint32_t result = Core::ERROR_UNAVAILABLE; + + _apiLock.Lock(); + + if (_powerManagerInterface) { + result = _powerManagerInterface->AddPowerModePreChangeClient(clientName, clientId); + } + + _apiLock.Unlock(); + + return result; + } + + uint32_t RemovePowerModePreChangeClient(const uint32_t clientId) + { + uint32_t result = Core::ERROR_UNAVAILABLE; + + _apiLock.Lock(); + + if (_powerManagerInterface) { + result = _powerManagerInterface->RemovePowerModePreChangeClient(clientId); + } + + _apiLock.Unlock(); + + return result; + } + + uint32_t DelayPowerModeChangeBy(const uint32_t clientId, const int transactionId, const int delay) + { + uint32_t result = Core::ERROR_UNAVAILABLE; + + _apiLock.Lock(); + + if (_powerManagerInterface) { + result = _powerManagerInterface->DelayPowerModeChangeBy(clientId, transactionId, delay); + } + + _apiLock.Unlock(); + + return result; + } + + uint32_t PowerModePreChangeComplete(const uint32_t clientId, const int transactionId) + { + uint32_t result = Core::ERROR_UNAVAILABLE; + + _apiLock.Lock(); + + if (_powerManagerInterface) { + result = _powerManagerInterface->PowerModePreChangeComplete(clientId, transactionId); + } + + _apiLock.Unlock(); + + return result; + } + + void NotifyPowerModeChanged(const PowerState& currentState, const PowerState& newState) + { + PowerController_PowerState_t currentState_ = convert(currentState); + PowerController_PowerState_t newState_ = convert(newState); + _callbackLock.Lock(); + + for (auto& cb : _powerModeChangedCallbacks) { + cb.callback(currentState_, newState_, cb.userdata); + } + + _callbackLock.Unlock(); + } + + void NotifyPowerModePreChange(const PowerState& currentState, const PowerState& newState, const int transactionId, const int stateChangeAfter) + { + PowerController_PowerState_t currentState_ = convert(currentState); + PowerController_PowerState_t newState_ = convert(newState); + _callbackLock.Lock(); + + for (auto& cb : _powerModePreChangeCallbacks) { + cb.callback(currentState_, newState_, transactionId, stateChangeAfter, cb.userdata); + } + + _callbackLock.Unlock(); + } + + void NotifyDeepSleepTimeout(const int& wakeupTimeout) + { + _callbackLock.Lock(); + + for (auto& cb : _deepSleepTimeoutCallbacks) { + cb.callback(wakeupTimeout, cb.userdata); + } + + _callbackLock.Unlock(); + } + + void NotifyNetworkStandbyModeChanged(const bool& enabled) + { + _callbackLock.Lock(); + + for (auto& cb : _networkStandbyModeChangedCallbacks) { + cb.callback(enabled, cb.userdata); + } + + _callbackLock.Unlock(); + } + + void NotifyThermalModeChanged(const ThermalTemperature& currentThermalLevel, const ThermalTemperature& newThermalLevel, const float& currentTemperature) + { + PowerController_ThermalTemperature_t currentThermalLevel_ = convert(currentThermalLevel); + PowerController_ThermalTemperature_t newThermalLevel_ = convert(newThermalLevel); + + _callbackLock.Lock(); + + for (auto& cb : _thermalModeChangedCallbacks) { + cb.callback(currentThermalLevel_, newThermalLevel_, currentTemperature, cb.userdata); + } + + _callbackLock.Unlock(); + } + + void NotifyRebootBegin(const string& rebootReasonCustom, const string& rebootReasonOther, const string& rebootRequestor) + { + _callbackLock.Lock(); + + for (auto& cb : _rebootBeginCallbacks) { + cb.callback(rebootReasonCustom.c_str(), rebootReasonOther.c_str(), rebootRequestor.c_str(), cb.userdata); + } + + _callbackLock.Unlock(); + } + + // Generic template function for callback register + template + uint32_t RegisterCallback(CallbackList& callbacklist, typename CallbackType::Type callback, void* userdata) + { + uint32_t result = Core::ERROR_INVALID_PARAMETER; + + ASSERT(nullptr != callback); + + if (nullptr != callback) { + _callbackLock.Lock(); + + result = callbacklist.RegisterCallbackLocked(callback, userdata); + + _callbackLock.Unlock(); + } + + return result; + } + + // Generic template function for callback unregister + template + uint32_t UnRegisterCallback(CallbackList& callbacklist, typename CallbackType::Type callback) + { + uint32_t result = Core::ERROR_INVALID_PARAMETER; + + ASSERT(nullptr != callback); + + if (nullptr != callback) { + _callbackLock.Lock(); + + result = callbacklist.UnRegisterCallbackLocked(callback); + + _callbackLock.Unlock(); + } + + return (result); + } + + uint32_t RegisterOperationalStateChangedCallback(PowerController_OperationalStateChangeCb callback, void* userdata) + { + return RegisterCallback(_operationalStateChangeCallbacks, callback, userdata); + } + + uint32_t UnRegisterOperationalStateChangedCallback(PowerController_OperationalStateChangeCb callback) + { + return UnRegisterCallback(_operationalStateChangeCallbacks, callback); + } + + uint32_t RegisterPowerModeChangedCallback(PowerController_PowerModeChangedCb callback, void* userdata) + { + return RegisterCallback(_powerModeChangedCallbacks, callback, userdata); + } + + uint32_t UnRegisterPowerModeChangedCallback(PowerController_PowerModeChangedCb callback) + { + return UnRegisterCallback(_powerModeChangedCallbacks, callback); + } + + uint32_t RegisterPowerModePreChangeCallback(PowerController_PowerModePreChangeCb callback, void* userdata) + { + return RegisterCallback(_powerModePreChangeCallbacks, callback, userdata); + } + + uint32_t UnRegisterPowerModePreChangeCallback(PowerController_PowerModePreChangeCb callback) + { + return UnRegisterCallback(_powerModePreChangeCallbacks, callback); + } + + uint32_t RegisterDeepSleepTimeoutCallback(PowerController_DeepSleepTimeoutCb callback, void* userdata) + { + return RegisterCallback(_deepSleepTimeoutCallbacks, callback, userdata); + } + + uint32_t UnRegisterDeepSleepTimeoutCallback(PowerController_DeepSleepTimeoutCb callback) + { + return UnRegisterCallback(_deepSleepTimeoutCallbacks, callback); + } + + uint32_t RegisterNetworkStandbyModeChangedCallback(PowerController_NetworkStandbyModeChangedCb callback, void* userdata) + { + return RegisterCallback(_networkStandbyModeChangedCallbacks, callback, userdata); + } + + uint32_t UnRegisterNetworkStandbyModeChangedCallback(PowerController_NetworkStandbyModeChangedCb callback) + { + return UnRegisterCallback(_networkStandbyModeChangedCallbacks, callback); + } + + uint32_t RegisterThermalModeChangedCallback(PowerController_ThermalModeChangedCb callback, void* userdata) + { + return RegisterCallback(_thermalModeChangedCallbacks, callback, userdata); + } + + uint32_t UnRegisterThermalModeChangedCallback(PowerController_ThermalModeChangedCb callback) + { + return UnRegisterCallback(_thermalModeChangedCallbacks, callback); + } + + uint32_t RegisterRebootBeginCallback(PowerController_RebootBeginCb callback, void* userdata) + { + return RegisterCallback(_rebootBeginCallbacks, callback, userdata); + } + + uint32_t UnRegisterRebootBeginCallback(PowerController_RebootBeginCb callback) + { + return UnRegisterCallback(_rebootBeginCallbacks, callback); + } + +private: + static int _nClients; // Init() count + static PowerController* _instance; + static Core::CriticalSection _apiLock; + static Core::CriticalSection _callbackLock; + + Exchange::IPowerManager* _powerManagerInterface; // remote PowerManager plugin interface + Core::Sink _powerManagerNotification; + + // containers for notification registertion + OperationalStateChangeCallbacks _operationalStateChangeCallbacks; + PowerModeChangedCallbacks _powerModeChangedCallbacks; + PowerModePreChangeCallbacks _powerModePreChangeCallbacks; + DeepSleepTimeoutCallbacks _deepSleepTimeoutCallbacks; + NetworkStandbyModeChangedCallbacks _networkStandbyModeChangedCallbacks; + ThermalModeChangedCallbacks _thermalModeChangedCallbacks; + RebootBeginCallbacks _rebootBeginCallbacks; + + bool _shutdown; +}; +template <> +bool PowerController::RegisterNotificationLocked() +{ + // Operational state change notification is managed by SmartInterfaceType + return true; +} + +template <> +bool PowerController::RegisterNotificationLocked() +{ + return Core::ERROR_NONE == _powerManagerInterface->Register(_powerManagerNotification.baseInterface()); +} + +template <> +bool PowerController::RegisterNotificationLocked() +{ + return Core::ERROR_NONE == _powerManagerInterface->Register(_powerManagerNotification.baseInterface()); +} + +template <> +bool PowerController::RegisterNotificationLocked() +{ + return Core::ERROR_NONE == _powerManagerInterface->Register(_powerManagerNotification.baseInterface()); +} + +template <> +bool PowerController::RegisterNotificationLocked() +{ + return Core::ERROR_NONE == _powerManagerInterface->Register(_powerManagerNotification.baseInterface()); +} + +template <> +bool PowerController::RegisterNotificationLocked() +{ + return Core::ERROR_NONE == _powerManagerInterface->Register(_powerManagerNotification.baseInterface()); +} + +template <> +bool PowerController::RegisterNotificationLocked() +{ + return Core::ERROR_NONE == _powerManagerInterface->Register(_powerManagerNotification.baseInterface()); +} + +template <> +bool PowerController::UnregisterNotificationLocked() +{ + // Operational state change notification is managed by SmartInterfaceType + return true; +} + +template <> +bool PowerController::UnregisterNotificationLocked() +{ + return Core::ERROR_NONE == _powerManagerInterface->Unregister(_powerManagerNotification.baseInterface()); +} + +template <> +bool PowerController::UnregisterNotificationLocked() +{ + return Core::ERROR_NONE == _powerManagerInterface->Unregister(_powerManagerNotification.baseInterface()); +} + +template <> +bool PowerController::UnregisterNotificationLocked() +{ + return Core::ERROR_NONE == _powerManagerInterface->Unregister(_powerManagerNotification.baseInterface()); +} + +template <> +bool PowerController::UnregisterNotificationLocked() +{ + return Core::ERROR_NONE == _powerManagerInterface->Unregister(_powerManagerNotification.baseInterface()); +} + +template <> +bool PowerController::UnregisterNotificationLocked() +{ + return Core::ERROR_NONE == _powerManagerInterface->Unregister(_powerManagerNotification.baseInterface()); +} + +template <> +bool PowerController::UnregisterNotificationLocked() +{ + return Core::ERROR_NONE == _powerManagerInterface->Unregister(_powerManagerNotification.baseInterface()); +} + +} // nameless namespace + +/* static */ PowerController* PowerController::_instance = nullptr; +/* static */ int PowerController::_nClients = 0; +/* static */ Core::CriticalSection PowerController::_apiLock; +/* static */ Core::CriticalSection PowerController::_callbackLock; + +extern "C" { + +void PowerController_Init() +{ + PowerController::Init(); +} + +void PowerController_Term() +{ + PowerController::Term(); +} + +uint32_t PowerController_Connect() +{ + return PowerController::Instance().Connect(); +} + +bool PowerController_IsOperational() +{ + return PowerController::Instance().IsOperational(); +} + +uint32_t PowerController_GetPowerState(PowerController_PowerState_t* currentState, PowerController_PowerState_t* previousState) +{ + ASSERT(nullptr != currentState); + ASSERT(nullptr != previousState); + return PowerController::Instance().GetPowerState(currentState, previousState); +} + +uint32_t PowerController_SetPowerState(const int keyCode, const PowerController_PowerState_t powerstate, const char* reason) +{ + return PowerController::Instance().SetPowerState(keyCode, powerstate, reason); +} + +uint32_t PowerController_GetThermalState(float* currentTemperature) +{ + ASSERT(nullptr != currentTemperature); + return PowerController::Instance().GetThermalState(currentTemperature); +} + +uint32_t PowerController_SetTemperatureThresholds(float high, float critical) +{ + return PowerController::Instance().SetTemperatureThresholds(high, critical); +} + +uint32_t PowerController_GetTemperatureThresholds(float* high, float* critical) +{ + ASSERT(nullptr != high); + ASSERT(nullptr != critical); + return PowerController::Instance().GetTemperatureThresholds(high, critical); +} + +uint32_t PowerController_SetOvertempGraceInterval(const int graceInterval) +{ + return PowerController::Instance().SetOvertempGraceInterval(graceInterval); +} + +uint32_t PowerController_GetOvertempGraceInterval(int* graceInterval /* @out */) +{ + ASSERT(nullptr != graceInterval); + return PowerController::Instance().GetOvertempGraceInterval(graceInterval); +} + +uint32_t PowerController_SetDeepSleepTimer(const int timeOut) +{ + return PowerController::Instance().SetDeepSleepTimer(timeOut); +} + +uint32_t PowerController_GetLastWakeupReason(PowerController_WakeupReason_t* wakeupReason) +{ + ASSERT(nullptr != wakeupReason); + return PowerController::Instance().GetLastWakeupReason(wakeupReason); +} + +uint32_t PowerController_GetLastWakeupKeyCode(int* keycode) +{ + ASSERT(nullptr != keycode); + return PowerController::Instance().GetLastWakeupKeyCode(keycode); +} + +uint32_t PowerController_Reboot(const char* rebootRequestor, const char* rebootReasonCustom, const char* rebootReasonOther) +{ + ASSERT(nullptr != rebootRequestor); + ASSERT(nullptr != rebootReasonCustom); + ASSERT(nullptr != rebootReasonOther); + return PowerController::Instance().Reboot(rebootRequestor, rebootReasonCustom, rebootReasonOther); +} + +uint32_t PowerController_SetNetworkStandbyMode(const bool standbyMode) +{ + return PowerController::Instance().SetNetworkStandbyMode(standbyMode); +} + +uint32_t PowerController_GetNetworkStandbyMode(bool* standbyMode) +{ + ASSERT(standbyMode != nullptr); + return PowerController::Instance().GetNetworkStandbyMode(standbyMode); +} + +uint32_t PowerController_SetWakeupSrcConfig(const int powerMode, const int wakeSrcType, int config) +{ + return PowerController::Instance().SetWakeupSrcConfig(powerMode, wakeSrcType, config); +} + +uint32_t PowerController_GetWakeupSrcConfig(int* powerMode, int* srcType, int* config) +{ + ASSERT(nullptr != powerMode); + ASSERT(nullptr != srcType); + ASSERT(nullptr != config); + return PowerController::Instance().GetWakeupSrcConfig(*powerMode, *srcType, *config); +} + +uint32_t PowerController_SetSystemMode(const PowerController_SystemMode_t currentMode, const PowerController_SystemMode_t newMode) +{ + return PowerController::Instance().SetSystemMode(currentMode, newMode); +} + +uint32_t PowerController_GetPowerStateBeforeReboot(PowerController_PowerState_t* powerStateBeforeReboot) +{ + ASSERT(nullptr != powerStateBeforeReboot); + return PowerController::Instance().GetPowerStateBeforeReboot(powerStateBeforeReboot); +} + +uint32_t PowerController_AddPowerModePreChangeClient(const char* clientName, uint32_t* clientId) +{ + ASSERT(nullptr != clientName); + ASSERT(nullptr != clientId); + return PowerController::Instance().AddPowerModePreChangeClient(clientName, *clientId); +} + +uint32_t PowerController_RemovePowerModePreChangeClient(const uint32_t clientId) +{ + return PowerController::Instance().RemovePowerModePreChangeClient(clientId); +} + +uint32_t PowerController_DelayPowerModeChangeBy(const uint32_t clientId, const int transactionId, const int delayPeriod) +{ + return PowerController::Instance().DelayPowerModeChangeBy(clientId, transactionId, delayPeriod); +} + +uint32_t PowerController_PowerModePreChangeComplete(const uint32_t clientId, const int transactionId) +{ + return PowerController::Instance().PowerModePreChangeComplete(clientId, transactionId); +} + +uint32_t PowerController_RegisterOperationalStateChangeCallback(PowerController_OperationalStateChangeCb callback, void* userdata) +{ + return PowerController::Instance().RegisterOperationalStateChangedCallback(callback, userdata); +} + +uint32_t PowerController_UnRegisterOperationalStateChangeCallback(PowerController_OperationalStateChangeCb callback) +{ + return PowerController::Instance().UnRegisterOperationalStateChangedCallback(callback); +} + +uint32_t PowerController_RegisterPowerModeChangedCallback(PowerController_PowerModeChangedCb callback, void* userdata) +{ + return PowerController::Instance().RegisterPowerModeChangedCallback(callback, userdata); +} + +uint32_t PowerController_UnRegisterPowerModeChangedCallback(PowerController_PowerModeChangedCb callback) +{ + return PowerController::Instance().UnRegisterPowerModeChangedCallback(callback); +} + +uint32_t PowerController_RegisterPowerModePreChangeCallback(PowerController_PowerModePreChangeCb callback, void* userdata) +{ + return PowerController::Instance().RegisterPowerModePreChangeCallback(callback, userdata); +} + +uint32_t PowerController_UnRegisterPowerModePreChangeCallback(PowerController_PowerModePreChangeCb callback) +{ + return PowerController::Instance().UnRegisterPowerModePreChangeCallback(callback); +} + +uint32_t PowerController_RegisterDeepSleepTimeoutCallback(PowerController_DeepSleepTimeoutCb callback, void* userdata) +{ + return PowerController::Instance().RegisterDeepSleepTimeoutCallback(callback, userdata); +} + +uint32_t PowerController_UnRegisterDeepSleepTimeoutCallback(PowerController_DeepSleepTimeoutCb callback) +{ + return PowerController::Instance().UnRegisterDeepSleepTimeoutCallback(callback); +} + +uint32_t PowerController_RegisterNetworkStandbyModeChangedCallback(PowerController_NetworkStandbyModeChangedCb callback, void* userdata) +{ + return PowerController::Instance().RegisterNetworkStandbyModeChangedCallback(callback, userdata); +} + +uint32_t PowerController_UnRegisterNetworkStandbyModeChangedCallback(PowerController_NetworkStandbyModeChangedCb callback) +{ + return PowerController::Instance().UnRegisterNetworkStandbyModeChangedCallback(callback); +} + +uint32_t PowerController_RegisterThermalModeChangedCallback(PowerController_ThermalModeChangedCb callback, void* userdata) +{ + return PowerController::Instance().RegisterThermalModeChangedCallback(callback, userdata); +} + +uint32_t PowerController_UnRegisterThermalModeChangedCallback(PowerController_ThermalModeChangedCb callback) +{ + return PowerController::Instance().UnRegisterThermalModeChangedCallback(callback); +} + +uint32_t PowerController_RegisterRebootBeginCallback(PowerController_RebootBeginCb callback, void* userdata) +{ + return PowerController::Instance().RegisterRebootBeginCallback(callback, userdata); +} + +uint32_t PowerController_UnRegisterRebootBeginCallback(PowerController_RebootBeginCb callback) +{ + return PowerController::Instance().UnRegisterRebootBeginCallback(callback); +} + +} // extern "C" diff --git a/Source/powercontroller/power_controller.h b/Source/powercontroller/power_controller.h new file mode 100644 index 00000000..6bc23382 --- /dev/null +++ b/Source/powercontroller/power_controller.h @@ -0,0 +1,414 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2025 RDK Management + * + * 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. + */ +#ifndef POWERMANAGER_CLIENT_H +#define POWERMANAGER_CLIENT_H + +#include +#include + +#undef EXTERNAL +#if defined(WIN32) || defined(_WINDOWS) || defined (__CYGWIN__) || defined(_WIN64) +#ifdef DEVICEINFO_EXPORTS +#define EXTERNAL __declspec(dllexport) +#else +#define EXTERNAL __declspec(dllimport) +#pragma comment(lib, "deviceinfo.lib") +#endif +#else +#define EXTERNAL __attribute__((visibility("default"))) +#endif +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum PowerController_PowerState { + POWER_STATE_UNKNOWN = 0 /* UNKNOWN */, + POWER_STATE_OFF = 1 /* OFF */, + POWER_STATE_STANDBY = 2 /* STANDBY */, + POWER_STATE_ON = 3 /* ON */, + POWER_STATE_STANDBY_LIGHT_SLEEP = 4 /* LIGHT_SLEEP */, + POWER_STATE_STANDBY_DEEP_SLEEP = 5 /* DEEP_SLEEP */ +} PowerController_PowerState_t; + +typedef enum PowerController_ThermalTemperature { + THERMAL_TEMPERATURE_UNKNOWN = 0 /* UNKNOWN Thermal Temperature */, + THERMAL_TEMPERATURE_NORMAL = 1 /* Normal Thermal Temperature */, + THERMAL_TEMPERATURE_HIGH = 2 /* High Thermal Temperature */, + THERMAL_TEMPERATURE_CRITICAL = 4 /* Critial Thermal Temperature */ +} PowerController_ThermalTemperature_t; + +typedef enum PowerController_WakeupSrcType { + WAKEUP_SRC_UNKNOWN = 0 /* UNKNOWN */, + WAKEUP_SRC_VOICE = 1 /* VOICE */, + WAKEUP_SRC_PRESENCEDETECTED = 2 /* PRESENCEDETECTED */, + WAKEUP_SRC_BLUETOOTH = 3 /* BLUETOOTH */, + WAKEUP_SRC_WIFI = 4 /* WIFI */, + WAKEUP_SRC_IR = 5 /* IR */, + WAKEUP_SRC_POWERKEY = 6 /* POWERKEY */, + WAKEUP_SRC_TIMER = 7 /* TIMER */, + WAKEUP_SRC_CEC = 8 /* CEC */, + WAKEUP_SRC_LAN = 9 /* LAN */, + WAKEUP_SRC_RF4CE = 10 /* RF4CE */ +} PowerController_WakeupSrcType_t; + +typedef enum PowerController_WakeupReason { + WAKEUP_REASON_UNKNOWN = 0 /* UNKNOWN */, + WAKEUP_REASON_IR = 1 /* IR */, + WAKEUP_REASON_BLUETOOTH = 2 /* BLUETOOTH */, + WAKEUP_REASON_RF4CE = 3 /* RF4CE */, + WAKEUP_REASON_GPIO = 4 /* GPIO */, + WAKEUP_REASON_LAN = 5 /* LAN */, + WAKEUP_REASON_WIFI = 6 /* WIFI */, + WAKEUP_REASON_TIMER = 7 /* TIMER */, + WAKEUP_REASON_FRONTPANEL = 8 /* FRONTPANEL */, + WAKEUP_REASON_WATCHDOG = 9 /* WATCHDOG */, + WAKEUP_REASON_SOFTWARERESET = 10 /* SOFTWARERESET */, + WAKEUP_REASON_THERMALRESET = 11 /* THERMALRESET */, + WAKEUP_REASON_WARMRESET = 12 /* WARMRESET */, + WAKEUP_REASON_COLDBOOT = 13 /* COLDBOOT */, + WAKEUP_REASON_STRAUTHFAIL = 14 /* STR_AUTH_FAIL */, + WAKEUP_REASON_CEC = 15 /* CEC */, + WAKEUP_REASON_PRESENCE = 16 /* PRESENCE */, + WAKEUP_REASON_VOICE = 17 /* VOICE */ +} PowerController_WakeupReason_t; + +typedef enum PowerController_SystemMode { + SYSTEM_MODE_UNKNOWN = 0 /* UNKNOWN */, + SYSTEM_MODE_NORMAL = 1 /* NORMAL */, + SYSTEM_MODE_EAS = 2 /* EAS */, + SYSTEM_MODE_WAREHOUSE = 3 /* WAREHOUSE */ +} PowerController_SystemMode_t; + +#define POWER_CONTROLLER_ERROR_NONE 0 +#define POWER_CONTROLLER_ERROR_GENERAL 1 +#define POWER_CONTROLLER_ERROR_UNAVAILABLE 2 +#define POWER_CONTROLLER_ERROR_NOT_EXIST 43 + +/** + * @brief Initializes the Power Controller. + * + * This function creates an instance of the PowerManager plugin client interface and increments the client instance count. + * + * @details + * - If the Power Controller instance does not already exist, it will be created. + * - The instance count is incremented each time this function is called. + * - After Init, & before making any PowerController request client needs to ensure + * - Power Manager plugin is activated and operational via `PowerController_IsOperational`. + * - If not operational, clients can use this Connect API to establish COM-RPC connection with the Power Manager plugin. + * - If there us any failure in Connect all PowerController requests will fail with `POWER_CONTROLLER_ERROR_UNAVAILABLE` (Except for callback register / unregister APIs). + * + * @see PowerController_Term + */ +EXTERNAL void PowerController_Init(); + +/** + * @brief PowerController attempts to connect to the Power Manager plugin. + * + * This function connects to the Power Manager plugin. + * + * @details + * - This function is used to connect to the Power Manager plugin. + * - Before making any PowerController request client needs to ensure + * - Power Manager plugin is activated and operational via `PowerController_IsOperational`. + * - If not operational, clients can use this Connect API to establish COM-RPC connection with the Power Manager plugin. + * - If there us any failure in Connect all PowerController requests will fail with `POWER_CONTROLLER_ERROR_UNAVAILABLE` (Except for callback register / unregister APIs). + * - In case of failure this API should be called again with brief delay. + * + * @return `POWER_CONTROLLER_ERROR_NONE` on success. + * @return `POWER_CONTROLLER_ERROR_UNAVAILABLE` if Thunder RPC server is not running / error establishing RPC communication channel. + * @return `POWER_CONTROLLER_ERROR_NOT_EXIST` if the PowerManager plugin is not activated yet. + */ +EXTERNAL uint32_t PowerController_Connect(); + +/** + * @brief Terminates the Power Controller. + * + * This function decrements client instance count attempts to delete Power Controller instance + * + * @details + * - If the controller reference count is greater than one, this function only decrements the count. + * - When the reference count reaches zero, the controller instance is destroyed, and all associated resources are released (PowerManager plugin client instance). + * - Ensure that this function is called once for every call to `PowerController_Init`. + * + * @see PowerController_Init + */ +EXTERNAL void PowerController_Term(); + +/** + * @brief Checks if the Power Manager plugin is active & operational + * + * This function determines whether the Power Manager interface is operational and ready to handle requests. + * It can be used to verify the availability of the Power Manager client before initiating operations that depend on it. + * + * IMPORTANT - This is the first function that should be called after `PowerController_Init`. + * + * @return `true` if the Power Manager interface is active and operational, otherwise `false`. + * + * @details + * - Use this function to confirm the operational status of the Power Manager plugin. + * - Calling this function is NOT MANDATORY but optional + * - Clients can register for notifications about state changes using `PowerController_RegisterOperationalStateChangeCallback`. + * - If the Power Manager interface is not active, subsequent Power Manager operations will fail with the error `POWER_CONTROLLER_ERROR_UNAVAILABLE`. + * - Therefore in failure cases, clients can use `PowerController_Connect` to establish COM-RPC connection with the Power Manager plugin. + * + * @see PowerController_RegisterOperationalStateChangeCallback + */ +EXTERNAL bool PowerController_IsOperational(); + +/** Gets the Power State.*/ +// @text getPowerState +// @brief Get Power State +// @param powerState: Get current power state +EXTERNAL uint32_t PowerController_GetPowerState(PowerController_PowerState_t* currentState /* @out */, PowerController_PowerState_t* previousState /* @out */); + +/** Sets Power State . */ +// @text setPowerState +// @brief Set Power State +// @param keyCode: NA for most platfroms, to be depricated +// @param powerState: Set power to this state +// @param reason: null terminated string stating reason for for state change +EXTERNAL uint32_t PowerController_SetPowerState(const int keyCode /* @in */, const PowerController_PowerState_t powerstate /* @in */, const char* reason /* @in */); + +/** Gets the current Thermal state.*/ +// @text getThermalState +// @brief Get Current Thermal State (temperature) +// @param currentTemperature: current temperature +EXTERNAL uint32_t PowerController_GetThermalState(float* currentTemperature /* @out */); + +/** Sets the Temperature Thresholds.*/ +// @text setTemperatureThresholds +// @brief Set Temperature Thresholds +// @param high: high threshold +// @param critical : critical threshold +EXTERNAL uint32_t PowerController_SetTemperatureThresholds(float high /* @in */, float critical /* @in */); + +/** Gets the current Temperature Thresholds.*/ +// @text getTemperatureThresholds +// @brief Get Temperature Thresholds +// @param high: high threshold +// @param critical : critical threshold +EXTERNAL uint32_t PowerController_GetTemperatureThresholds(float* high /* @out */, float* critical /* @out */); + +/** Sets the current Temperature Grace interval.*/ +// @property +// @text PowerController_SetOvertempGraceInterval +// @brief Set Temperature Thresholds +// @param graceInterval: interval in secs? +EXTERNAL uint32_t PowerController_SetOvertempGraceInterval(const int graceInterval /* @in */); + +/** Gets the grace interval for over-temperature.*/ +// @property +// @text PowerController_GetOvertempGraceInterval +// @brief Get Temperature Grace interval +// @param graceInterval: interval in secs? +EXTERNAL uint32_t PowerController_GetOvertempGraceInterval(int* graceInterval /* @out */); + +/** Set Deep Sleep Timer for later wakeup */ +// @property +// @text setDeepSleepTimer +// @brief Set Deep sleep timer for timeOut period +// @param timeOut: deep sleep timeout +EXTERNAL uint32_t PowerController_SetDeepSleepTimer(const int timeOut /* @in */); + +/** Get Last Wakeup reason */ +// @property +// @text getLastWakeupReason +// @brief Get Last Wake up reason +// @param wakeupReason: wake up reason +EXTERNAL uint32_t PowerController_GetLastWakeupReason(PowerController_WakeupReason_t* wakeupReason /* @out */); + +/** Get Last Wakeup key code */ +// @property +// @text getLastWakeupKeyCode +// @brief Get the key code that can be used for wakeup +// @param keycode: Key code for wakeup +EXTERNAL uint32_t PowerController_GetLastWakeupKeyCode(int* keycode /* @out */); + +/** Request Reboot with PowerManager */ +// @text reboot +// @brief Reboot device +// @param rebootRequestor: null terminated string identifier for the entity requesting the reboot. +// @param rebootReasonCustom: custom-defined reason for the reboot, provided as a null terminated string. +// @param rebootReasonOther: null terminated string describing any other reasons for the reboot. +EXTERNAL uint32_t PowerController_Reboot(const char* rebootRequestor /* @in */, const char* rebootReasonCustom /* @in */, const char* rebootReasonOther /* @in */); + +/** Set Network Standby Mode */ +// @property +// @text setNetworkStandbyMode +// @brief Set the standby mode for Network +// @param standbyMode: Network standby mode +EXTERNAL uint32_t PowerController_SetNetworkStandbyMode(const bool standbyMode /* @in */); + +/** Get Network Standby Mode */ +// @text getNetworkStandbyMode +// @brief Get the standby mode for Network +// @param standbyMode: Network standby mode +EXTERNAL uint32_t PowerController_GetNetworkStandbyMode(bool* standbyMode /* @out */); + +/** Set Wakeup source configuration */ +// @text setWakeupSrcConfig +// @brief Set the source configuration for device wakeup +// @param powerMode: power mode +// @param wakeSrcType: source type +// @param config: config +EXTERNAL uint32_t PowerController_SetWakeupSrcConfig(const int powerMode /* @in */, const int wakeSrcType /* @in */, int config /* @in */); + +/** Get Wakeup source configuration */ +// @text getWakeupSrcConfig +// @brief Get the source configuration for device wakeup +// @param powerMode: power mode +// @param srcType: source type +// @param config: config +EXTERNAL uint32_t PowerController_GetWakeupSrcConfig(int* powerMode /* @out */, int* srcType /* @out */, int* config /* @out */); + +/** Initiate System mode change */ +// @text PowerController_SetSystemMode +// @brief System mode change +// @param oldMode: current mode +// @param newMode: new mode +EXTERNAL uint32_t PowerController_SetSystemMode(const PowerController_SystemMode_t currentMode /* @in */, const PowerController_SystemMode_t newMode /* @in */); + +/** Get Power State before last reboot */ +// @text PowerController_GetPowerStateBeforeReboot +// @brief Get Power state before last reboot +// @param powerStateBeforeReboot: power state +EXTERNAL uint32_t PowerController_GetPowerStateBeforeReboot(PowerController_PowerState_t* powerStateBeforeReboot /* @out */); + +/** Engage a client in power mode change operation. */ +// @text PowerController_AddPowerModePreChangeClient +// @brief - Register a client to engage in power mode state changes. +// - When `PowerModePreChange` event is received, then added client should call either +// - `PowerModePreChangeComplete` API to inform power manager that this client has completed its pre-change operation. +// - Or `DelayPowerModeChangeBy` API to delay the power mode change. +// - If the client does not call `PowerModePreChangeComplete` API, the power mode change will complete +// after the maximum delay `stateChangeAfter` seconds (as received in `OnPowerModePreChange` event). +// - Clients are required to re-register if the PowerManager plugin restarts. Therefore, it is essential for clients to register +// for operational state changes using `PowerController_RegisterOperationalStateChangeCallback`. +// +// IMPORTANT: ** IT'S A BUG IF CLIENT `Unregister` FROM `IModePreChangeNotification` BEFORE DISENGAGING ITSELF ** +// always make sure to call `RemovePowerModePreChangeClient` before calling `Unregister` from `IModePreChangeNotification`. +// +// @param clientName: Name of the client as null terminated string +// @param clientId: Unique identifier for the client to be used while acknowledging the pre-change operation (`PowerModePreChangeComplete`) +// or to delay the power mode change (`DelayPowerModeChangeBy`) +EXTERNAL uint32_t PowerController_AddPowerModePreChangeClient(const char *clientName /* @in */, uint32_t* clientId /* @out */); + +/** Disengage a client from the power mode change operation. */ +// @text PowerController_RemovePowerModePreChangeClient +// @brief Removes a registered client from participating in power mode pre-change operations. +// NOTE client will still continue to receive pre-change notifications. +// @param clientId: Unique identifier for the client. See `AddPowerModePreChangeClient` +EXTERNAL uint32_t PowerController_RemovePowerModePreChangeClient(const uint32_t clientId /* @in */); + +/** Power prechange activity completed */ +// @text PowerController_PowerModePreChangeComplete +// @brief Pre power mode handling complete for given client and transation id +// @param clientId: Unique identifier for the client, as received in AddPowerModePreChangeClient +// @param transactionId: transaction id as received in OnPowerModePreChange +EXTERNAL uint32_t PowerController_PowerModePreChangeComplete(const uint32_t clientId /* @in */, const int transactionId /* @in */); + +/** Delay Powermode change by given time */ +// @text PowerController_DelayPowerModeChangeBy +// @brief Delay Powermode change by given time. If different clients provide different values of delay, then the maximum of these values is used. +// @param clientId: Unique identifier for the client, as received in AddPowerModePreChangeClient +// @param transactionId: transaction id as received in OnPowerModePreChange +// @param delayPeriod: delay in seconds +EXTERNAL uint32_t PowerController_DelayPowerModeChangeBy(const uint32_t clientId /* @in */, const int transactionId /* @in */, const int delayPeriod /* @in */); + +/* Callback data types for event notifications from power manager plugin */ +// @brief Operational state changed event +// @param isOperational: true if PowerManager plugin is activated, false otherwise +// @param userdata: opaque data, client can use it to have context to callbacks +typedef void (*PowerController_OperationalStateChangeCb)(bool isOperational, void* userdata); + +// @brief Power mode changed +// @param currentState: Current Power State +// @param newState: New Power State +// @param userdata: opaque data, client can use it to have context to callbacks +typedef void (*PowerController_PowerModeChangedCb)(const PowerController_PowerState_t currentState, const PowerController_PowerState_t newState, void* userdata); + +// @brief Power mode Pre-change event +// @param currentState: Current Power State +// @param newState: Changing power state to this New Power State +// @param transactionId: transactionId to be used when invoking prePowerChangeComplete() / delayPowerModeChangeBy API +// @param stateChangeAfter: seconds after which the actual power mode will be applied. +// @param userdata: opaque data, client can use it to have context to callbacks +typedef void (*PowerController_PowerModePreChangeCb)(const PowerController_PowerState_t currentState, const PowerController_PowerState_t newState, const int transactionId, const int stateChangeAfter, void* userdata); + +// @brief Deep sleep timeout event +// @param wakeupTimeout: Deep sleep wakeup timeout in seconds +// @param userdata: opaque data, client can use it to have context to callbacks +typedef void (*PowerController_DeepSleepTimeoutCb)(const int wakeupTimeout, void* userdata); + +// @brief Network Standby Mode changed event - only on XIone +// @param enabled: network standby enabled or disabled +// @param userdata: opaque data, client can use it to have context to callbacks +typedef void (*PowerController_NetworkStandbyModeChangedCb)(const bool enabled, void* userdata); + +// @brief Thermal Mode changed event +// @param currentThermalLevel: current thermal level +// @param newThermalLevel: new thermal level +// @param currentTemperature: current temperature +// @param userdata: opaque data, client can use it to have context to callbacks +typedef void (*PowerController_ThermalModeChangedCb)(const PowerController_ThermalTemperature_t currentThermalLevel, const PowerController_ThermalTemperature_t newThermalLevel, const float currentTemperature, void* userdata); + +// @brief Reboot begin event +// @param rebootReasonCustom: Reboot reason custom +// @param rebootReasonOther: Reboot reason other +// @param rebootRequestor: Reboot requested by +// @param userdata: opaque data, client can use it to have context to callbacks +typedef void (*PowerController_RebootBeginCb)(const char* rebootReasonCustom, const char* rebootReasonOther, const char* rebootRequestor, void* userdata); + +/* Type defines for callbacks / notifications */ +/* userdata in all callbacks are opaque, clients can use it to have context to callbacks */ + +/** Register for PowerManager plugin operational state change event callback, for initial state use `PowerController_IsOperational` call */ +EXTERNAL uint32_t PowerController_RegisterOperationalStateChangeCallback(PowerController_OperationalStateChangeCb callback, void* userdata); +/** UnRegister (previously registered) PowerManager plugin operational state change event callback */ +EXTERNAL uint32_t PowerController_UnRegisterOperationalStateChangeCallback(PowerController_OperationalStateChangeCb callback); +/** Register for PowerMode changed callback */ +EXTERNAL uint32_t PowerController_RegisterPowerModeChangedCallback(PowerController_PowerModeChangedCb callback, void* userdata); +/** UnRegister (previously registered) PowerMode changed callback */ +EXTERNAL uint32_t PowerController_UnRegisterPowerModeChangedCallback(PowerController_PowerModeChangedCb callback); +/** Register for PowerMode pre-change callback */ +EXTERNAL uint32_t PowerController_RegisterPowerModePreChangeCallback(PowerController_PowerModePreChangeCb callback, void* userdata); +/** UnRegister (previously registered) PowerMode pre-change callback */ +EXTERNAL uint32_t PowerController_UnRegisterPowerModePreChangeCallback(PowerController_PowerModePreChangeCb callback); +/** Register for PowerMode pre-change callback */ +EXTERNAL uint32_t PowerController_RegisterDeepSleepTimeoutCallback(PowerController_DeepSleepTimeoutCb callback, void* userdata); +/** UnRegister (previously registered) DeepSleep Timeout callback */ +EXTERNAL uint32_t PowerController_UnRegisterDeepSleepTimeoutCallback(PowerController_DeepSleepTimeoutCb callback); +/** Register for Network Standby Mode changed event - only on XIone */ +EXTERNAL uint32_t PowerController_RegisterNetworkStandbyModeChangedCallback(PowerController_NetworkStandbyModeChangedCb callback, void* userdata); +/** UnRegister (previously registered) Network Standby Mode changed callback */ +EXTERNAL uint32_t PowerController_UnRegisterNetworkStandbyModeChangedCallback(PowerController_NetworkStandbyModeChangedCb callback); +/** Register for Thermal Mode changed event callback */ +EXTERNAL uint32_t PowerController_RegisterThermalModeChangedCallback(PowerController_ThermalModeChangedCb callback, void* userdata); +/** UnRegister (previously registered) Thermal Mode changed event callback */ +EXTERNAL uint32_t PowerController_UnRegisterThermalModeChangedCallback(PowerController_ThermalModeChangedCb callback); +/** Register for reboot start event callback */ +EXTERNAL uint32_t PowerController_RegisterRebootBeginCallback(PowerController_RebootBeginCb callback, void* userdata); +/** UnRegister (previously registered) reboot start event callback */ +EXTERNAL uint32_t PowerController_UnRegisterRebootBeginCallback(PowerController_RebootBeginCb callback); + +#ifdef __cplusplus +}; // extern "C" +#endif + +#endif // POWERMANAGER_CLIENT_H