From 3324427cea6207b88d5278ef792c92f8c5436379 Mon Sep 17 00:00:00 2001 From: Manimaran Renganathan Date: Tue, 27 Jan 2026 18:23:26 +0000 Subject: [PATCH 01/16] RDKEMW-9659 Implement DeviceSettings client library for FPD in rpc/cli --- configure.ac | 13 + rpc/cli/Makefile | 20 +- rpc/cli/Makefile.am | 13 +- rpc/cli/dsFPD-com.cpp | 758 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 802 insertions(+), 2 deletions(-) create mode 100644 rpc/cli/dsFPD-com.cpp diff --git a/configure.ac b/configure.ac index 081cb2be..7445ffc2 100644 --- a/configure.ac +++ b/configure.ac @@ -50,6 +50,19 @@ PKG_CHECK_MODULES([DBUS], [dbus-1]) AC_CHECK_LIB(gthread-2.0, g_thread_init) +# Thunder COM-RPC plugin support +AC_ARG_ENABLE([thunder-plugin], + AS_HELP_STRING([--enable-thunder-plugin], [Enable Thunder COM-RPC plugin support (default: no)]), + [enable_thunder_plugin=$enableval], + [enable_thunder_plugin=no]) + +AM_CONDITIONAL([USE_THUNDER_PLUGIN], [test "x$enable_thunder_plugin" = "xyes"]) + +AS_IF([test "x$enable_thunder_plugin" = "xyes"], + [AC_DEFINE([USE_WPE_THUNDER_PLUGIN], [1], [Define to 1 to enable Thunder COM-RPC plugin support]) + AC_MSG_NOTICE([Thunder COM-RPC plugin support enabled])], + [AC_MSG_NOTICE([Thunder COM-RPC plugin support disabled])]) + # Checks for typedefs, structures, and compiler characteristics. AC_TYPE_PID_T AC_TYPE_SIZE_T diff --git a/rpc/cli/Makefile b/rpc/cli/Makefile index ab24c14f..06f2b963 100644 --- a/rpc/cli/Makefile +++ b/rpc/cli/Makefile @@ -21,6 +21,18 @@ CFLAGS += -g -fPIC -D_REENTRANT -Wall LIBNAME := dshalcli LIBNAMEFULL := lib$(LIBNAME).so INSTALL := $(PWD)/install + +# Conditional compilation: Thunder vs IARM +ifdef USE_WPE_THUNDER_PLUGIN + # Thunder mode - use dsFPD-com.cpp, exclude dsFPD.c + OBJS := $(patsubst %.cpp,%.o,$(wildcard *.cpp)) + OBJS += $(patsubst %.c,%.o,$(filter-out dsFPD.c,$(wildcard *.c))) +else + # IARM mode - use dsFPD.c, exclude dsFPD-com.cpp + OBJS := $(patsubst %.cpp,%.o,$(filter-out dsFPD-com.cpp,$(wildcard *.cpp))) + OBJS += $(patsubst %.c,%.o,$(wildcard *.c)) +endif + OBJS := $(patsubst %.cpp,%.o,$(wildcard *.cpp)) OBJS += $(patsubst %.c,%.o,$(wildcard *.c)) INCLUDE := -I$(PWD) \ @@ -31,13 +43,19 @@ INCLUDE += $(HAL_INCLUDE) CFLAGS += $(INCLUDE) +# Conditional linking flags +ifdef USE_WPE_THUNDER_PLUGIN + LDLIBS := -lWPEFrameworkCore -lWPEFrameworkCOM +else + LDLIBS := -lIARMBus +endif all: install @echo "Build Finished...." library: $(OBJS) @echo "Building $(LIBNAMEFULL) ...." - $(CXX) $(OBJS) $(CFLAGS) -lIARMBus -shared -o $(LIBNAMEFULL) + $(CXX) $(OBJS) $(CFLAGS) $(LDLIBS) -shared -o $(LIBNAMEFULL) %.o: %.cpp @echo "Building $@ ...." diff --git a/rpc/cli/Makefile.am b/rpc/cli/Makefile.am index fe48bb37..27f50c1b 100644 --- a/rpc/cli/Makefile.am +++ b/rpc/cli/Makefile.am @@ -28,4 +28,15 @@ INCLUDE_FILES = -I=$(includedir)/rdk/halif/ds-hal \ lib_LTLIBRARIES = libdshalcli.la libdshalcli_la_CPPFLAGS = $(INCLUDE_FILES) libdshalcli_la_CFLAGS = -g -fPIC -D_REENTRANT -Wall -libdshalcli_la_SOURCES = dsAudio.c dsclientlogger.c dsDisplay.c dsFPD.c dsHost.cpp dsVideoDevice.c dsVideoPort.c + +# Conditional compilation for Thunder COM-RPC +if USE_THUNDER_PLUGIN + FPD_SOURCE = dsFPD-com.cpp + THUNDER_LIBS = -lWPEFrameworkCore -lWPEFrameworkCOM +else + FPD_SOURCE = dsFPD.c + THUNDER_LIBS = +endif + +libdshalcli_la_SOURCES = dsAudio.c dsclientlogger.c dsDisplay.c $(FPD_SOURCE) dsHost.cpp dsVideoDevice.c dsVideoPort.c +libdshalcli_la_LIBADD = $(THUNDER_LIBS) diff --git a/rpc/cli/dsFPD-com.cpp b/rpc/cli/dsFPD-com.cpp new file mode 100644 index 00000000..3f7f5183 --- /dev/null +++ b/rpc/cli/dsFPD-com.cpp @@ -0,0 +1,758 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2016 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. +*/ + +/** +* @defgroup devicesettings +* @{ +* @defgroup rpc +* @{ +**/ + +#ifdef USE_WPE_THUNDER_PLUGIN + +#include +#include +#include +#include + +#include "dsFPD.h" +#include "dsError.h" +#include "dsclientlogger.h" + +// Thunder COM-RPC includes +#ifndef MODULE_NAME +#define MODULE_NAME DeviceSettings_FPD_Client +#endif + +#include +#include +#include +#include + +using namespace WPEFramework; + +// Thunder callsign for DeviceSettingsManager plugin +static constexpr const TCHAR callSign[] = _T("org.rdk.DeviceSettingsManager"); + +/** + * @brief DeviceSettingsFPD class manages Thunder COM-RPC connection for FPD + */ +class DeviceSettingsFPD : public RPC::SmartInterfaceType { +private: + using BaseClass = RPC::SmartInterfaceType; + + Exchange::IDeviceSettingsManagerFPD* _fpdInterface; + + static DeviceSettingsFPD* _instance; + static Core::CriticalSection _apiLock; + + bool _connected; + bool _shutdown; + + DeviceSettingsFPD() + : BaseClass() + , _fpdInterface(nullptr) + , _connected(false) + , _shutdown(false) + { + (void)Connect(); + } + + ~DeviceSettingsFPD() + { + _shutdown = true; + BaseClass::Close(Core::infinite); + } + + virtual void Operational(const bool upAndRunning) override + { + _apiLock.Lock(); + + if (upAndRunning) { + // Communicator opened && DeviceSettingsManager is Activated + if (nullptr == _fpdInterface) { + _fpdInterface = BaseClass::Interface(); + if (_fpdInterface != nullptr) { + printf("[dsFPD-com] Successfully established COM-RPC connection with DeviceSettingsManager plugin\n"); + } else { + fprintf(stderr, "[dsFPD-com] Failed to get interface - plugin implementation may have failed to load\n"); + } + } + } else { + // DeviceSettingsManager is Deactivated || Communicator closed + if (nullptr != _fpdInterface) { + _fpdInterface->Release(); + _fpdInterface = nullptr; + } + } + _apiLock.Unlock(); + } + + inline bool IsActivatedLocked() const + { + return (nullptr != _fpdInterface); + } + + inline bool isConnected() const + { + return _connected; + } + +public: + bool IsOperational() const + { + _apiLock.Lock(); + bool result = (isConnected() && (nullptr != _fpdInterface)); + _apiLock.Unlock(); + return result; + } + + bool WaitForOperational(uint32_t timeoutMs = 5000) const + { + const uint32_t pollIntervalMs = 100; + uint32_t elapsedMs = 0; + + while (elapsedMs < timeoutMs) { + if (IsOperational()) { + return true; + } + std::this_thread::sleep_for(std::chrono::milliseconds(pollIntervalMs)); + elapsedMs += pollIntervalMs; + } + return false; + } + + uint32_t Connect() + { + uint32_t status = Core::ERROR_NONE; + + _apiLock.Lock(); + + if (!isConnected()) { + printf("[dsFPD-com] Attempting to connect to Thunder with callsign: %s\n", callSign); + uint32_t res = BaseClass::Open(RPC::CommunicationTimeOut, BaseClass::Connector(), callSign); + if (Core::ERROR_NONE == res) { + _connected = true; + printf("[dsFPD-com] Successfully opened RPC connection to Thunder\n"); + } else { + fprintf(stderr, "[dsFPD-com] Failed to open RPC connection, error: %u. Is Thunder running?\n", res); + status = Core::ERROR_UNAVAILABLE; + } + } + + if (nullptr == _fpdInterface) { + status = Core::ERROR_NOT_EXIST; + printf("[dsFPD-com] DeviceSettingsManager plugin not yet operational\n"); + } + + _apiLock.Unlock(); + + return status; + } + + uint32_t Disconnect() + { + uint32_t status = Core::ERROR_GENERAL; + bool close = false; + + _apiLock.Lock(); + + if (isConnected()) { + close = true; + _connected = false; + } + + _apiLock.Unlock(); + + if (close) { + status = BaseClass::Close(Core::infinite); + } + + return status; + } + + static void Init() + { + _apiLock.Lock(); + if (nullptr == _instance) { + _instance = new DeviceSettingsFPD(); + } + _apiLock.Unlock(); + } + + static void Term() + { + _apiLock.Lock(); + if (nullptr != _instance) { + delete _instance; + _instance = nullptr; + } + _apiLock.Unlock(); + } + + static DeviceSettingsFPD* Instance() + { + return _instance; + } + + // FPD API implementations + // Note: Thunder interface doesn't have FPDInit/FPDTerm/SetFPDText methods + + Core::hresult SetFPDTime(const Exchange::IDeviceSettingsManagerFPD::FPDTimeFormat timeFormat, + const uint32_t hour, const uint32_t minutes) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->SetFPDTime(timeFormat, hour, minutes); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult SetFPDScroll(const uint32_t scrollHoldOnDur, const uint32_t horzScrollIterations, + const uint32_t vertScrollIterations) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->SetFPDScroll(scrollHoldOnDur, horzScrollIterations, vertScrollIterations); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult SetFPDBlink(const Exchange::IDeviceSettingsManagerFPD::FPDIndicator indicator, + const uint32_t blinkDuration, const uint32_t blinkIterations) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->SetFPDBlink(indicator, blinkDuration, blinkIterations); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult GetFPDBrightness(const Exchange::IDeviceSettingsManagerFPD::FPDIndicator indicator, + uint32_t& brightness) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->GetFPDBrightness(indicator, brightness); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult SetFPDBrightness(const Exchange::IDeviceSettingsManagerFPD::FPDIndicator indicator, + const uint32_t brightness, const bool persist) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->SetFPDBrightness(indicator, brightness, persist); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult GetFPDTextBrightness(const Exchange::IDeviceSettingsManagerFPD::FPDTextDisplay indicator, + uint32_t& brightness) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->GetFPDTextBrightness(indicator, brightness); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult SetFPDTextBrightness(const Exchange::IDeviceSettingsManagerFPD::FPDTextDisplay indicator, + const uint32_t brightness) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->SetFPDTextBrightness(indicator, brightness); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult GetFPDColor(const Exchange::IDeviceSettingsManagerFPD::FPDIndicator indicator, + uint32_t& color) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->GetFPDColor(indicator, color); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult SetFPDColor(const Exchange::IDeviceSettingsManagerFPD::FPDIndicator indicator, + const uint32_t color) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->SetFPDColor(indicator, color); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult EnableFPDClockDisplay(const bool enable) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->EnableFPDClockDisplay(enable); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult SetFPDState(const Exchange::IDeviceSettingsManagerFPD::FPDIndicator indicator, + const Exchange::IDeviceSettingsManagerFPD::FPDState state) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->SetFPDState(indicator, state); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult GetFPDState(const Exchange::IDeviceSettingsManagerFPD::FPDIndicator indicator, + Exchange::IDeviceSettingsManagerFPD::FPDState& state) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->GetFPDState(indicator, state); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult GetFPDTimeFormat(Exchange::IDeviceSettingsManagerFPD::FPDTimeFormat& timeFormat) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->GetFPDTimeFormat(timeFormat); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult SetFPDTimeFormat(const Exchange::IDeviceSettingsManagerFPD::FPDTimeFormat timeFormat) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->SetFPDTimeFormat(timeFormat); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult SetFPDMode(const Exchange::IDeviceSettingsManagerFPD::FPDMode mode) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->SetFPDMode(mode); + } + _apiLock.Unlock(); + return result; + } +}; + +// Static member initialization +DeviceSettingsFPD* DeviceSettingsFPD::_instance = nullptr; +Core::CriticalSection DeviceSettingsFPD::_apiLock; + +/** + * @brief Convert Thunder error code to dsError_t + */ +static dsError_t ConvertThunderError(uint32_t thunderError) +{ + if (thunderError == Core::ERROR_NONE) { + return dsERR_NONE; + } else if (thunderError == Core::ERROR_UNAVAILABLE) { + return dsERR_OPERATION_NOT_SUPPORTED; + } else if (thunderError == Core::ERROR_BAD_REQUEST) { + return dsERR_INVALID_PARAM; + } else { + return dsERR_GENERAL; + } +} + +// C API implementations using Thunder COM-RPC + +extern "C" { + +// Forward declarations +dsError_t dsSetFPDBrightness(dsFPDIndicator_t eIndicator, dsFPDBrightness_t eBrightness, bool toPersist); +dsError_t dsSetFPDColor(dsFPDIndicator_t eIndicator, dsFPDColor_t eColor, bool toPersist); + +dsError_t dsFPInit(void) +{ + printf("<<<<< Front Panel is initialized in Thunder Mode >>>>>>>>\r\n"); + + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance) { + DeviceSettingsFPD::Init(); + instance = DeviceSettingsFPD::Instance(); + } + + if (!instance) { + fprintf(stderr, "[dsFPD-com] Failed to create DeviceSettingsFPD instance\n"); + return dsERR_GENERAL; + } + + // Wait for plugin to become operational + if (!instance->WaitForOperational(5000)) { + fprintf(stderr, "[dsFPD-com] DeviceSettingsManager plugin not operational after 5 seconds\n"); + return dsERR_GENERAL; + } + + // Thunder interface doesn't have explicit Init method - connection is sufficient + return dsERR_NONE; +} + +dsError_t dsFPTerm(void) +{ + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance) { + return dsERR_GENERAL; + } + + // Thunder interface doesn't have explicit Term method + // Terminate instance + DeviceSettingsFPD::Term(); + + return dsERR_NONE; +} + +dsError_t dsSetFPText(const char* pszChars) +{ + if (pszChars == NULL) { + fprintf(stderr, "[dsFPD-com] Invalid parameter: pszChars is NULL\n"); + return dsERR_INVALID_PARAM; + } + + // Thunder interface doesn't support text display + fprintf(stderr, "[dsFPD-com] SetFPText not supported in Thunder mode\n"); + return dsERR_OPERATION_NOT_SUPPORTED; +} + +dsError_t dsSetFPTime(dsFPDTimeFormat_t eTime, const unsigned int uHour, const unsigned int uMinutes) +{ + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsManagerFPD::FPDTimeFormat timeFormat = + static_cast(eTime); + + uint32_t result = instance->SetFPDTime(timeFormat, uHour, uMinutes); + return ConvertThunderError(result); +} + +dsError_t dsSetFPScroll(unsigned int nScrollHoldOnDur, unsigned int nHorzScrollIterations, unsigned int nVertScrollIterations) +{ + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { + return dsERR_GENERAL; + } + + uint32_t result = instance->SetFPDScroll(nScrollHoldOnDur, nHorzScrollIterations, nVertScrollIterations); + return ConvertThunderError(result); +} + +dsError_t dsSetFPBlink(dsFPDIndicator_t eIndicator, unsigned int nBlinkDuration, unsigned int nBlinkIterations) +{ + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsManagerFPD::FPDIndicator indicator = + static_cast(eIndicator); + + uint32_t result = instance->SetFPDBlink(indicator, nBlinkDuration, nBlinkIterations); + return ConvertThunderError(result); +} + +dsError_t dsGetFPBrightness(dsFPDIndicator_t eIndicator, dsFPDBrightness_t *pBrightness) +{ + if (pBrightness == NULL) { + fprintf(stderr, "[dsFPD-com] Invalid parameter: pBrightness is NULL\n"); + return dsERR_INVALID_PARAM; + } + + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsManagerFPD::FPDIndicator indicator = + static_cast(eIndicator); + + uint32_t brightness = 0; + uint32_t result = instance->GetFPDBrightness(indicator, brightness); + + if (result == Core::ERROR_NONE) { + *pBrightness = static_cast(brightness); + } + + return ConvertThunderError(result); +} + +dsError_t dsGetFPDBrightness(dsFPDIndicator_t eIndicator, dsFPDBrightness_t *pBrightness, bool persist) +{ + // Note: persist parameter may not be used in GET operation for Thunder + return dsGetFPBrightness(eIndicator, pBrightness); +} + +dsError_t dsSetFPBrightness(dsFPDIndicator_t eIndicator, dsFPDBrightness_t eBrightness) +{ + return dsSetFPDBrightness(eIndicator, eBrightness, true); +} + +dsError_t dsSetFPDBrightness(dsFPDIndicator_t eIndicator, dsFPDBrightness_t eBrightness, bool toPersist) +{ + if (eIndicator >= dsFPD_INDICATOR_MAX || eBrightness > 100) { + fprintf(stderr, "[dsFPD-com] Invalid parameter\n"); + return dsERR_INVALID_PARAM; + } + + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsManagerFPD::FPDIndicator indicator = + static_cast(eIndicator); + + uint32_t result = instance->SetFPDBrightness(indicator, static_cast(eBrightness), toPersist); + return ConvertThunderError(result); +} + +dsError_t dsGetFPTextBrightness(dsFPDTextDisplay_t eIndicator, dsFPDBrightness_t *pBrightness) +{ + if (pBrightness == NULL) { + fprintf(stderr, "[dsFPD-com] Invalid parameter: pBrightness is NULL\n"); + return dsERR_INVALID_PARAM; + } + + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsManagerFPD::FPDTextDisplay indicator = + static_cast(eIndicator); + + uint32_t brightness = 0; + uint32_t result = instance->GetFPDTextBrightness(indicator, brightness); + + if (result == Core::ERROR_NONE) { + *pBrightness = static_cast(brightness); + } + + return ConvertThunderError(result); +} + +dsError_t dsSetFPTextBrightness(dsFPDTextDisplay_t eIndicator, dsFPDBrightness_t eBrightness) +{ + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsManagerFPD::FPDTextDisplay indicator = + static_cast(eIndicator); + + uint32_t result = instance->SetFPDTextBrightness(indicator, static_cast(eBrightness)); + return ConvertThunderError(result); +} + +dsError_t dsGetFPColor(dsFPDIndicator_t eIndicator, dsFPDColor_t *pColor) +{ + if (pColor == NULL) { + fprintf(stderr, "[dsFPD-com] Invalid parameter: pColor is NULL\n"); + return dsERR_INVALID_PARAM; + } + + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsManagerFPD::FPDIndicator indicator = + static_cast(eIndicator); + + uint32_t color = 0; + uint32_t result = instance->GetFPDColor(indicator, color); + + if (result == Core::ERROR_NONE) { + *pColor = static_cast(color); + } + + return ConvertThunderError(result); +} + +dsError_t dsSetFPColor(dsFPDIndicator_t eIndicator, dsFPDColor_t eColor) +{ + return dsSetFPDColor(eIndicator, eColor, true); +} + +dsError_t dsSetFPDColor(dsFPDIndicator_t eIndicator, dsFPDColor_t eColor, bool toPersist) +{ + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsManagerFPD::FPDIndicator indicator = + static_cast(eIndicator); + + // Thunder interface doesn't support persist flag - ignore it + uint32_t result = instance->SetFPDColor(indicator, static_cast(eColor)); + return ConvertThunderError(result); +} + +dsError_t dsFPEnableCLockDisplay(int enable) +{ + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { + return dsERR_GENERAL; + } + + uint32_t result = instance->EnableFPDClockDisplay(enable != 0); + return ConvertThunderError(result); +} + +dsError_t dsSetFPState(dsFPDIndicator_t eIndicator, dsFPDState_t state) +{ + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsManagerFPD::FPDIndicator indicator = + static_cast(eIndicator); + Exchange::IDeviceSettingsManagerFPD::FPDState fpdState = + static_cast(state); + + uint32_t result = instance->SetFPDState(indicator, fpdState); + return ConvertThunderError(result); +} + +dsError_t dsGetFPState(dsFPDIndicator_t eIndicator, dsFPDState_t* state) +{ + if (state == NULL) { + fprintf(stderr, "[dsFPD-com] Invalid parameter: state is NULL\n"); + return dsERR_INVALID_PARAM; + } + + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsManagerFPD::FPDIndicator indicator = + static_cast(eIndicator); + + Exchange::IDeviceSettingsManagerFPD::FPDState fpdState; + uint32_t result = instance->GetFPDState(indicator, fpdState); + + if (result == Core::ERROR_NONE) { + *state = static_cast(fpdState); + } + + return ConvertThunderError(result); +} + +dsError_t dsGetFPTimeFormat(dsFPDTimeFormat_t *pTimeFormat) +{ + if (pTimeFormat == NULL) { + fprintf(stderr, "[dsFPD-com] Invalid parameter: pTimeFormat is NULL\n"); + return dsERR_INVALID_PARAM; + } + + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsManagerFPD::FPDTimeFormat timeFormat; + uint32_t result = instance->GetFPDTimeFormat(timeFormat); + + if (result == Core::ERROR_NONE) { + *pTimeFormat = static_cast(timeFormat); + } + + return ConvertThunderError(result); +} + +dsError_t dsSetFPTimeFormat(dsFPDTimeFormat_t eTimeFormat) +{ + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsManagerFPD::FPDTimeFormat timeFormat = + static_cast(eTimeFormat); + + uint32_t result = instance->SetFPDTimeFormat(timeFormat); + return ConvertThunderError(result); +} + +dsError_t dsSetFPDMode(dsFPDMode_t eMode) +{ + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsManagerFPD::FPDMode mode = + static_cast(eMode); + + uint32_t result = instance->SetFPDMode(mode); + return ConvertThunderError(result); +} + +} // extern "C" + +#endif // USE_WPE_THUNDER_PLUGIN + +/** @} */ +/** @} */ From b6e760cf82ebf3486298a6b5ca2364978207532d Mon Sep 17 00:00:00 2001 From: Manimaran Renganathan Date: Fri, 30 Jan 2026 16:50:14 +0000 Subject: [PATCH 02/16] Modified the dsFPD-com.cpp code based on latest DeviceSettings plugin and Interface changes --- rpc/cli/dsFPD-com.cpp | 114 +++++++++++++++++++++--------------------- 1 file changed, 58 insertions(+), 56 deletions(-) diff --git a/rpc/cli/dsFPD-com.cpp b/rpc/cli/dsFPD-com.cpp index 3f7f5183..53631e05 100644 --- a/rpc/cli/dsFPD-com.cpp +++ b/rpc/cli/dsFPD-com.cpp @@ -43,21 +43,21 @@ #include #include #include -#include +#include using namespace WPEFramework; -// Thunder callsign for DeviceSettingsManager plugin -static constexpr const TCHAR callSign[] = _T("org.rdk.DeviceSettingsManager"); +// Thunder callsign for DeviceSettings plugin +static constexpr const TCHAR callSign[] = _T("org.rdk.DeviceSettings"); /** * @brief DeviceSettingsFPD class manages Thunder COM-RPC connection for FPD */ -class DeviceSettingsFPD : public RPC::SmartInterfaceType { +class DeviceSettingsFPD : public RPC::SmartInterfaceType { private: - using BaseClass = RPC::SmartInterfaceType; + using BaseClass = RPC::SmartInterfaceType; - Exchange::IDeviceSettingsManagerFPD* _fpdInterface; + Exchange::IDeviceSettingsFPD* _fpdInterface; static DeviceSettingsFPD* _instance; static Core::CriticalSection _apiLock; @@ -85,17 +85,17 @@ class DeviceSettingsFPD : public RPC::SmartInterfaceTypeRelease(); _fpdInterface = nullptr; @@ -158,7 +158,7 @@ class DeviceSettingsFPD : public RPC::SmartInterfaceTypeSetFPDTime(timeFormat, hour, minutes); + result = _fpdInterface->SetFPDTime(timeFormat, minutes, seconds); } _apiLock.Unlock(); return result; @@ -238,7 +238,7 @@ class DeviceSettingsFPD : public RPC::SmartInterfaceTypeWaitForOperational(5000)) { - fprintf(stderr, "[dsFPD-com] DeviceSettingsManager plugin not operational after 5 seconds\n"); + fprintf(stderr, "[dsFPD-com] DeviceSettings plugin not operational after 5 seconds\n"); return dsERR_GENERAL; } @@ -477,9 +477,11 @@ dsError_t dsSetFPTime(dsFPDTimeFormat_t eTime, const unsigned int uHour, const u return dsERR_GENERAL; } - Exchange::IDeviceSettingsManagerFPD::FPDTimeFormat timeFormat = - static_cast(eTime); + Exchange::IDeviceSettingsFPD::FPDTimeFormat timeFormat = + static_cast(eTime); + // Note: Interface expects minutes and seconds, but API provides hour and minutes + // Converting: treating uMinutes as seconds for interface compatibility uint32_t result = instance->SetFPDTime(timeFormat, uHour, uMinutes); return ConvertThunderError(result); } @@ -502,8 +504,8 @@ dsError_t dsSetFPBlink(dsFPDIndicator_t eIndicator, unsigned int nBlinkDuration, return dsERR_GENERAL; } - Exchange::IDeviceSettingsManagerFPD::FPDIndicator indicator = - static_cast(eIndicator); + Exchange::IDeviceSettingsFPD::FPDIndicator indicator = + static_cast(eIndicator); uint32_t result = instance->SetFPDBlink(indicator, nBlinkDuration, nBlinkIterations); return ConvertThunderError(result); @@ -521,8 +523,8 @@ dsError_t dsGetFPBrightness(dsFPDIndicator_t eIndicator, dsFPDBrightness_t *pBri return dsERR_GENERAL; } - Exchange::IDeviceSettingsManagerFPD::FPDIndicator indicator = - static_cast(eIndicator); + Exchange::IDeviceSettingsFPD::FPDIndicator indicator = + static_cast(eIndicator); uint32_t brightness = 0; uint32_t result = instance->GetFPDBrightness(indicator, brightness); @@ -557,8 +559,8 @@ dsError_t dsSetFPDBrightness(dsFPDIndicator_t eIndicator, dsFPDBrightness_t eBri return dsERR_GENERAL; } - Exchange::IDeviceSettingsManagerFPD::FPDIndicator indicator = - static_cast(eIndicator); + Exchange::IDeviceSettingsFPD::FPDIndicator indicator = + static_cast(eIndicator); uint32_t result = instance->SetFPDBrightness(indicator, static_cast(eBrightness), toPersist); return ConvertThunderError(result); @@ -576,8 +578,8 @@ dsError_t dsGetFPTextBrightness(dsFPDTextDisplay_t eIndicator, dsFPDBrightness_t return dsERR_GENERAL; } - Exchange::IDeviceSettingsManagerFPD::FPDTextDisplay indicator = - static_cast(eIndicator); + Exchange::IDeviceSettingsFPD::FPDTextDisplay indicator = + static_cast(eIndicator); uint32_t brightness = 0; uint32_t result = instance->GetFPDTextBrightness(indicator, brightness); @@ -596,8 +598,8 @@ dsError_t dsSetFPTextBrightness(dsFPDTextDisplay_t eIndicator, dsFPDBrightness_t return dsERR_GENERAL; } - Exchange::IDeviceSettingsManagerFPD::FPDTextDisplay indicator = - static_cast(eIndicator); + Exchange::IDeviceSettingsFPD::FPDTextDisplay indicator = + static_cast(eIndicator); uint32_t result = instance->SetFPDTextBrightness(indicator, static_cast(eBrightness)); return ConvertThunderError(result); @@ -615,8 +617,8 @@ dsError_t dsGetFPColor(dsFPDIndicator_t eIndicator, dsFPDColor_t *pColor) return dsERR_GENERAL; } - Exchange::IDeviceSettingsManagerFPD::FPDIndicator indicator = - static_cast(eIndicator); + Exchange::IDeviceSettingsFPD::FPDIndicator indicator = + static_cast(eIndicator); uint32_t color = 0; uint32_t result = instance->GetFPDColor(indicator, color); @@ -640,8 +642,8 @@ dsError_t dsSetFPDColor(dsFPDIndicator_t eIndicator, dsFPDColor_t eColor, bool t return dsERR_GENERAL; } - Exchange::IDeviceSettingsManagerFPD::FPDIndicator indicator = - static_cast(eIndicator); + Exchange::IDeviceSettingsFPD::FPDIndicator indicator = + static_cast(eIndicator); // Thunder interface doesn't support persist flag - ignore it uint32_t result = instance->SetFPDColor(indicator, static_cast(eColor)); @@ -666,10 +668,10 @@ dsError_t dsSetFPState(dsFPDIndicator_t eIndicator, dsFPDState_t state) return dsERR_GENERAL; } - Exchange::IDeviceSettingsManagerFPD::FPDIndicator indicator = - static_cast(eIndicator); - Exchange::IDeviceSettingsManagerFPD::FPDState fpdState = - static_cast(state); + Exchange::IDeviceSettingsFPD::FPDIndicator indicator = + static_cast(eIndicator); + Exchange::IDeviceSettingsFPD::FPDState fpdState = + static_cast(state); uint32_t result = instance->SetFPDState(indicator, fpdState); return ConvertThunderError(result); @@ -687,10 +689,10 @@ dsError_t dsGetFPState(dsFPDIndicator_t eIndicator, dsFPDState_t* state) return dsERR_GENERAL; } - Exchange::IDeviceSettingsManagerFPD::FPDIndicator indicator = - static_cast(eIndicator); + Exchange::IDeviceSettingsFPD::FPDIndicator indicator = + static_cast(eIndicator); - Exchange::IDeviceSettingsManagerFPD::FPDState fpdState; + Exchange::IDeviceSettingsFPD::FPDState fpdState; uint32_t result = instance->GetFPDState(indicator, fpdState); if (result == Core::ERROR_NONE) { @@ -712,7 +714,7 @@ dsError_t dsGetFPTimeFormat(dsFPDTimeFormat_t *pTimeFormat) return dsERR_GENERAL; } - Exchange::IDeviceSettingsManagerFPD::FPDTimeFormat timeFormat; + Exchange::IDeviceSettingsFPD::FPDTimeFormat timeFormat; uint32_t result = instance->GetFPDTimeFormat(timeFormat); if (result == Core::ERROR_NONE) { @@ -729,8 +731,8 @@ dsError_t dsSetFPTimeFormat(dsFPDTimeFormat_t eTimeFormat) return dsERR_GENERAL; } - Exchange::IDeviceSettingsManagerFPD::FPDTimeFormat timeFormat = - static_cast(eTimeFormat); + Exchange::IDeviceSettingsFPD::FPDTimeFormat timeFormat = + static_cast(eTimeFormat); uint32_t result = instance->SetFPDTimeFormat(timeFormat); return ConvertThunderError(result); @@ -743,8 +745,8 @@ dsError_t dsSetFPDMode(dsFPDMode_t eMode) return dsERR_GENERAL; } - Exchange::IDeviceSettingsManagerFPD::FPDMode mode = - static_cast(eMode); + Exchange::IDeviceSettingsFPD::FPDMode mode = + static_cast(eMode); uint32_t result = instance->SetFPDMode(mode); return ConvertThunderError(result); From fdc41051567c374991e65d68683865aed78d75fb Mon Sep 17 00:00:00 2001 From: Manimaran Renganathan Date: Mon, 2 Feb 2026 11:27:44 +0000 Subject: [PATCH 03/16] Modified the rpc/cliMakefile with conditionally exclude dsFPD.c when Thunder is enabled. --- rpc/cli/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpc/cli/Makefile b/rpc/cli/Makefile index 06f2b963..7b2575ee 100644 --- a/rpc/cli/Makefile +++ b/rpc/cli/Makefile @@ -33,8 +33,8 @@ else OBJS += $(patsubst %.c,%.o,$(wildcard *.c)) endif -OBJS := $(patsubst %.cpp,%.o,$(wildcard *.cpp)) -OBJS += $(patsubst %.c,%.o,$(wildcard *.c)) +#OBJS := $(patsubst %.cpp,%.o,$(wildcard *.cpp)) +#OBJS += $(patsubst %.c,%.o,$(wildcard *.c)) INCLUDE := -I$(PWD) \ -I$(PWD)/hal/include \ -I$(PWD)/rpc/include From 034e5db7c0a293816ddf68a64ca891a496d4d8ef Mon Sep 17 00:00:00 2001 From: Manimaran Renganathan Date: Wed, 4 Feb 2026 08:18:32 +0000 Subject: [PATCH 04/16] Added export USE_WPE_THUNDER_PLUGIN=y in cov_build.sh --- cov_build.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cov_build.sh b/cov_build.sh index 22e8d7d4..1f1a6463 100644 --- a/cov_build.sh +++ b/cov_build.sh @@ -66,8 +66,10 @@ cd ${RDK_SOURCE_PATH} export STANDALONE_BUILD_ENABLED=y export DS_MGRS=$WORKDIR +export USE_WPE_THUNDER_PLUGIN=y + find $WORKDIR -iname "*.o" -exec rm -v {} \; find $WORKDIR -iname "*.so*" -exec rm -v {} \; echo "##### Triggering make" -make CFLAGS+='-fPIC -DDSMGR_LOGGER_ENABLED=ON -DRDK_DSHAL_NAME=\"libdshal.so\" -I${DS_IF_PATH}/include -I${DS_HAL_PATH} -I${DS_MGRS}/stubs -I${IARMBUS_PATH}/core -I${IARMBUS_PATH}/core/include -I${IARM_MGRS}/sysmgr/include -I${DS_MGRS}/ds/include -I${DS_MGRS}/rpc/include -I${POWER_IF_PATH}/include/ -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I${IARM_MGRS}/mfr/include/ -I${IARM_MGRS}/mfr/common -I${DEEPSLEEP_IF_PATH}/include -I${IARM_MGRS}/hal/include -I${IARM_MGRS}/power -I${IARM_MGRS}/power/include' LDFLAGS="-L/usr/lib/x86_64-linux-gnu/ -L/usr/local/include -lglib-2.0 -lIARMBus -lWPEFrameworkPowerController -ldshal" \ No newline at end of file +make CFLAGS+='-fPIC -DDSMGR_LOGGER_ENABLED=ON -DRDK_DSHAL_NAME=\"libdshal.so\" -I${DS_IF_PATH}/include -I${DS_HAL_PATH} -I${DS_MGRS}/stubs -I${IARMBUS_PATH}/core -I${IARMBUS_PATH}/core/include -I${IARM_MGRS}/sysmgr/include -I${DS_MGRS}/ds/include -I${DS_MGRS}/rpc/include -I${POWER_IF_PATH}/include/ -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I${IARM_MGRS}/mfr/include/ -I${IARM_MGRS}/mfr/common -I${DEEPSLEEP_IF_PATH}/include -I${IARM_MGRS}/hal/include -I${IARM_MGRS}/power -I${IARM_MGRS}/power/include' LDFLAGS="-L/usr/lib/x86_64-linux-gnu/ -L/usr/local/include -lglib-2.0 -lIARMBus -lWPEFrameworkPowerController -ldshal" From d220f98621f74970843eda26879da2ca536e188d Mon Sep 17 00:00:00 2001 From: Manimaran Renganathan Date: Wed, 4 Feb 2026 16:39:07 +0000 Subject: [PATCH 05/16] Modified the code 1. Created the dsConnectionManager.cpp, dsConnectionManager.h and dsHdmiIn-com.cpp files 2. Modified the dsFPD-com.cpp file with SmartInterfaceType to get the common interface from FPD and using QueryInterface to get the interface handle for other component like HdmiIn, CompositeIn, etc., --- rpc/cli/dsConnectionManager.cpp | 239 ++++++++++++ rpc/cli/dsConnectionManager.h | 138 +++++++ rpc/cli/dsFPD-com.cpp | 605 +++++++++-------------------- rpc/cli/dsHdmiIn-com.cpp | 651 ++++++++++++++++++++++++++++++++ 4 files changed, 1209 insertions(+), 424 deletions(-) create mode 100644 rpc/cli/dsConnectionManager.cpp create mode 100644 rpc/cli/dsConnectionManager.h create mode 100644 rpc/cli/dsHdmiIn-com.cpp diff --git a/rpc/cli/dsConnectionManager.cpp b/rpc/cli/dsConnectionManager.cpp new file mode 100644 index 00000000..df5170c9 --- /dev/null +++ b/rpc/cli/dsConnectionManager.cpp @@ -0,0 +1,239 @@ +/* + * 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. +*/ + +#ifdef USE_WPE_THUNDER_PLUGIN + +#include +#include +#include +#include "dsConnectionManager.h" + +using namespace WPEFramework; + +namespace DeviceSettingsClient { + +// Thunder callsign for DeviceSettings plugin +static constexpr const TCHAR callSign[] = _T("org.rdk.DeviceSettings"); + +// Static member initialization +ConnectionManager* ConnectionManager::_instance = nullptr; +Core::CriticalSection ConnectionManager::_dsConnectionManagerlock; + +ConnectionManager::ConnectionManager() + : BaseClass() + , _fpdInterface(nullptr) + , _hdmiInInterface(nullptr) + , _connected(false) + , _shutdown(false) +{ + printf("[dsConnectionManager] Initializing centralized connection manager\n"); + (void)Connect(); +} + +ConnectionManager::~ConnectionManager() +{ + printf("[dsConnectionManager] Destroying connection manager\n"); + _shutdown = true; + + // Release all component interfaces before closing base connection + if (_hdmiInInterface) { + _hdmiInInterface->Release(); + _hdmiInInterface = nullptr; + } + + if (_fpdInterface) { + _fpdInterface->Release(); + _fpdInterface = nullptr; + } + + BaseClass::Close(Core::infinite); +} + +void ConnectionManager::Operational(const bool upAndRunning) +{ + _dsConnectionManagerlock.Lock(); + + if (!_shutdown) { + printf("[dsConnectionManager] Operational callback: %s\n", upAndRunning ? "UP" : "DOWN"); + } + + if (upAndRunning) { + // Communicator opened && DeviceSettings is Activated + if (nullptr == _fpdInterface) { + printf("[dsConnectionManager] Plugin activated, acquiring primary FPD interface\n"); + _fpdInterface = BaseClass::Interface(); + + if (_fpdInterface != nullptr) { + printf("[dsConnectionManager] Successfully established COM-RPC connection with DeviceSettings plugin\n"); + + // Acquire secondary interfaces via QueryInterface + if (nullptr == _hdmiInInterface) { + _hdmiInInterface = _fpdInterface->QueryInterface(); + if (_hdmiInInterface != nullptr) { + printf("[dsConnectionManager] Successfully acquired HDMIIn interface via QueryInterface\n"); + } else { + fprintf(stderr, "[dsConnectionManager] Failed to acquire HDMIIn interface via QueryInterface\n"); + } + } + + // Add more component interfaces here as needed: + // if (nullptr == _compositeInInterface) { + // _compositeInInterface = _fpdInterface->QueryInterface(); + // } + + } else { + fprintf(stderr, "[dsConnectionManager] Failed to get FPD interface - plugin implementation may have failed to load\n"); + } + } + } else { + // DeviceSettings is Deactivated || Communicator closed + printf("[dsConnectionManager] Plugin deactivated, releasing all interfaces\n"); + + if (_hdmiInInterface != nullptr) { + _hdmiInInterface->Release(); + _hdmiInInterface = nullptr; + } + + if (_fpdInterface != nullptr) { + _fpdInterface->Release(); + _fpdInterface = nullptr; + } + } + + _dsConnectionManagerlock.Unlock(); +} + +void ConnectionManager::Init() +{ + _dsConnectionManagerlock.Lock(); + if (nullptr == _instance) { + _instance = new ConnectionManager(); + } + _dsConnectionManagerlock.Unlock(); +} + +void ConnectionManager::Term() +{ + _dsConnectionManagerlock.Lock(); + if (nullptr != _instance) { + delete _instance; + _instance = nullptr; + } + _dsConnectionManagerlock.Unlock(); +} + +ConnectionManager* ConnectionManager::Instance() +{ + return _instance; +} + +bool ConnectionManager::IsOperational() const +{ + _dsConnectionManagerlock.Lock(); + bool result = (isConnected() && (nullptr != _fpdInterface)); + _dsConnectionManagerlock.Unlock(); + return result; +} + +bool ConnectionManager::WaitForOperational(uint32_t timeoutMs) const +{ + const uint32_t pollIntervalMs = 100; + uint32_t elapsedMs = 0; + + while (elapsedMs < timeoutMs) { + if (IsOperational()) { + return true; + } + std::this_thread::sleep_for(std::chrono::milliseconds(pollIntervalMs)); + elapsedMs += pollIntervalMs; + } + return false; +} + +uint32_t ConnectionManager::Connect() +{ + uint32_t status = Core::ERROR_NONE; + + _dsConnectionManagerlock.Lock(); + + if (!isConnected()) { + printf("[dsConnectionManager] Attempting to connect to Thunder with callsign: %s\n", callSign); + uint32_t res = BaseClass::Open(RPC::CommunicationTimeOut, BaseClass::Connector(), callSign); + if (Core::ERROR_NONE == res) { + _connected = true; + printf("[dsConnectionManager] Successfully opened RPC connection to Thunder\n"); + } else { + fprintf(stderr, "[dsConnectionManager] Failed to open RPC connection, error: %u. Is Thunder running?\n", res); + status = Core::ERROR_UNAVAILABLE; + } + } else { + printf("[dsConnectionManager] Already connected\n"); + } + + if (nullptr == _fpdInterface) { + status = Core::ERROR_NOT_EXIST; + printf("[dsConnectionManager] DeviceSettings plugin not yet operational, waiting for Operational() callback\n"); + } + + _dsConnectionManagerlock.Unlock(); + + return status; +} + +uint32_t ConnectionManager::Disconnect() +{ + uint32_t status = Core::ERROR_GENERAL; + bool close = false; + + _dsConnectionManagerlock.Lock(); + + if (isConnected()) { + close = true; + _connected = false; + } + + _dsConnectionManagerlock.Unlock(); + + if (close) { + status = BaseClass::Close(Core::infinite); + printf("[dsConnectionManager] Disconnected from Thunder\n"); + } + + return status; +} + +Exchange::IDeviceSettingsFPD* ConnectionManager::GetFPDInterface() +{ + _dsConnectionManagerlock.Lock(); + Exchange::IDeviceSettingsFPD* interface = _fpdInterface; + _dsConnectionManagerlock.Unlock(); + return interface; +} + +Exchange::IDeviceSettingsHDMIIn* ConnectionManager::GetHDMIInInterface() +{ + _dsConnectionManagerlock.Lock(); + Exchange::IDeviceSettingsHDMIIn* interface = _hdmiInInterface; + _dsConnectionManagerlock.Unlock(); + return interface; +} + +} // namespace DeviceSettingsClient + +#endif // USE_WPE_THUNDER_PLUGIN diff --git a/rpc/cli/dsConnectionManager.h b/rpc/cli/dsConnectionManager.h new file mode 100644 index 00000000..eed60bf4 --- /dev/null +++ b/rpc/cli/dsConnectionManager.h @@ -0,0 +1,138 @@ +/* + * 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 __DS_CONNECTION_MANAGER_H__ +#define __DS_CONNECTION_MANAGER_H__ + +#ifdef USE_WPE_THUNDER_PLUGIN + +#include +#include +#include +#include +#include + +namespace DeviceSettingsClient { + +/** + * @brief Centralized Connection Manager for DeviceSettings plugin + * + * This class manages a single Thunder COM-RPC connection to the DeviceSettings plugin + * and provides access to multiple component interfaces (FPD, HDMIIn, etc.) through + * QueryInterface pattern. + */ +class ConnectionManager : public WPEFramework::RPC::SmartInterfaceType { +private: + using BaseClass = WPEFramework::RPC::SmartInterfaceType; + + // Component interfaces obtained via QueryInterface + WPEFramework::Exchange::IDeviceSettingsFPD* _fpdInterface; + WPEFramework::Exchange::IDeviceSettingsHDMIIn* _hdmiInInterface; + // Add more component interfaces here as needed + // WPEFramework::Exchange::IDeviceSettingsCompositeIn* _compositeInInterface; + // WPEFramework::Exchange::IDeviceSettingsHost* _hostInterface; + + static ConnectionManager* _instance; + static WPEFramework::Core::CriticalSection _dsConnectionManagerlock; + + bool _connected; + bool _shutdown; + + // Private constructor for singleton + ConnectionManager(); + + // Private destructor + ~ConnectionManager(); + + // Operational callback from Thunder + virtual void Operational(const bool upAndRunning) override; + + inline bool isConnected() const { return _connected; } + inline bool IsActivatedLocked() const { return (nullptr != _fpdInterface); } + +public: + // Delete copy/move constructors and assignment operators + ConnectionManager(const ConnectionManager&) = delete; + ConnectionManager& operator=(const ConnectionManager&) = delete; + ConnectionManager(ConnectionManager&&) = delete; + ConnectionManager& operator=(ConnectionManager&&) = delete; + + /** + * @brief Initialize the connection manager singleton + */ + static void Init(); + + /** + * @brief Terminate the connection manager singleton + */ + static void Term(); + + /** + * @brief Get the singleton instance + */ + static ConnectionManager* Instance(); + + /** + * @brief Check if plugin is operational (connected and activated) + */ + bool IsOperational() const; + + /** + * @brief Wait for plugin to become operational with timeout + */ + bool WaitForOperational(uint32_t timeoutMs = 5000) const; + + /** + * @brief Connect to Thunder DeviceSettings plugin + */ + uint32_t Connect(); + + /** + * @brief Disconnect from Thunder DeviceSettings plugin + */ + uint32_t Disconnect(); + + /** + * @brief Get FPD interface pointer + * @return FPD interface or nullptr if not available + */ + WPEFramework::Exchange::IDeviceSettingsFPD* GetFPDInterface(); + + /** + * @brief Get HDMIIn interface pointer + * @return HDMIIn interface or nullptr if not available + */ + WPEFramework::Exchange::IDeviceSettingsHDMIIn* GetHDMIInInterface(); + + /** + * @brief Lock the API mutex for thread-safe operations + */ + static void Lock() { _dsConnectionManagerlock.Lock(); } + + /** + * @brief Unlock the API mutex + */ + static void Unlock() { _dsConnectionManagerlock.Unlock(); } +}; + +} // namespace DeviceSettingsClient + +#endif // USE_WPE_THUNDER_PLUGIN + +#endif // __DS_CONNECTION_MANAGER_H__ diff --git a/rpc/cli/dsFPD-com.cpp b/rpc/cli/dsFPD-com.cpp index 53631e05..69b89f1a 100644 --- a/rpc/cli/dsFPD-com.cpp +++ b/rpc/cli/dsFPD-com.cpp @@ -28,390 +28,39 @@ #include #include -#include -#include #include "dsFPD.h" #include "dsError.h" #include "dsclientlogger.h" +#include "dsConnectionManager.h" // Thunder COM-RPC includes #ifndef MODULE_NAME #define MODULE_NAME DeviceSettings_FPD_Client #endif -#include -#include -#include #include using namespace WPEFramework; - -// Thunder callsign for DeviceSettings plugin -static constexpr const TCHAR callSign[] = _T("org.rdk.DeviceSettings"); - -/** - * @brief DeviceSettingsFPD class manages Thunder COM-RPC connection for FPD - */ -class DeviceSettingsFPD : public RPC::SmartInterfaceType { -private: - using BaseClass = RPC::SmartInterfaceType; - - Exchange::IDeviceSettingsFPD* _fpdInterface; - - static DeviceSettingsFPD* _instance; - static Core::CriticalSection _apiLock; - - bool _connected; - bool _shutdown; - - DeviceSettingsFPD() - : BaseClass() - , _fpdInterface(nullptr) - , _connected(false) - , _shutdown(false) - { - (void)Connect(); - } - - ~DeviceSettingsFPD() - { - _shutdown = true; - BaseClass::Close(Core::infinite); - } - - virtual void Operational(const bool upAndRunning) override - { - _apiLock.Lock(); - - if (upAndRunning) { - // Communicator opened && DeviceSettings is Activated - if (nullptr == _fpdInterface) { - _fpdInterface = BaseClass::Interface(); - if (_fpdInterface != nullptr) { - printf("[dsFPD-com] Successfully established COM-RPC connection with DeviceSettings plugin\n"); - } else { - fprintf(stderr, "[dsFPD-com] Failed to get interface - plugin implementation may have failed to load\n"); - } - } - } else { - // DeviceSettings is Deactivated || Communicator closed - if (nullptr != _fpdInterface) { - _fpdInterface->Release(); - _fpdInterface = nullptr; - } - } - _apiLock.Unlock(); - } - - inline bool IsActivatedLocked() const - { - return (nullptr != _fpdInterface); - } - - inline bool isConnected() const - { - return _connected; - } - -public: - bool IsOperational() const - { - _apiLock.Lock(); - bool result = (isConnected() && (nullptr != _fpdInterface)); - _apiLock.Unlock(); - return result; - } - - bool WaitForOperational(uint32_t timeoutMs = 5000) const - { - const uint32_t pollIntervalMs = 100; - uint32_t elapsedMs = 0; - - while (elapsedMs < timeoutMs) { - if (IsOperational()) { - return true; - } - std::this_thread::sleep_for(std::chrono::milliseconds(pollIntervalMs)); - elapsedMs += pollIntervalMs; - } - return false; - } - - uint32_t Connect() - { - uint32_t status = Core::ERROR_NONE; - - _apiLock.Lock(); - - if (!isConnected()) { - printf("[dsFPD-com] Attempting to connect to Thunder with callsign: %s\n", callSign); - uint32_t res = BaseClass::Open(RPC::CommunicationTimeOut, BaseClass::Connector(), callSign); - if (Core::ERROR_NONE == res) { - _connected = true; - printf("[dsFPD-com] Successfully opened RPC connection to Thunder\n"); - } else { - fprintf(stderr, "[dsFPD-com] Failed to open RPC connection, error: %u. Is Thunder running?\n", res); - status = Core::ERROR_UNAVAILABLE; - } - } - - if (nullptr == _fpdInterface) { - status = Core::ERROR_NOT_EXIST; - printf("[dsFPD-com] DeviceSettings plugin not yet operational\n"); - } - - _apiLock.Unlock(); - - return status; - } - - uint32_t Disconnect() - { - uint32_t status = Core::ERROR_GENERAL; - bool close = false; - - _apiLock.Lock(); - - if (isConnected()) { - close = true; - _connected = false; - } - - _apiLock.Unlock(); - - if (close) { - status = BaseClass::Close(Core::infinite); - } - - return status; - } - - static void Init() - { - _apiLock.Lock(); - if (nullptr == _instance) { - _instance = new DeviceSettingsFPD(); - } - _apiLock.Unlock(); - } - - static void Term() - { - _apiLock.Lock(); - if (nullptr != _instance) { - delete _instance; - _instance = nullptr; - } - _apiLock.Unlock(); - } - - static DeviceSettingsFPD* Instance() - { - return _instance; - } - - // FPD API implementations - // Note: Thunder interface doesn't have FPDInit/FPDTerm/SetFPDText methods - - Core::hresult SetFPDTime(const Exchange::IDeviceSettingsFPD::FPDTimeFormat timeFormat, - const uint32_t minutes, const uint32_t seconds) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->SetFPDTime(timeFormat, minutes, seconds); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult SetFPDScroll(const uint32_t scrollHoldOnDur, const uint32_t horzScrollIterations, - const uint32_t vertScrollIterations) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->SetFPDScroll(scrollHoldOnDur, horzScrollIterations, vertScrollIterations); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult SetFPDBlink(const Exchange::IDeviceSettingsFPD::FPDIndicator indicator, - const uint32_t blinkDuration, const uint32_t blinkIterations) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->SetFPDBlink(indicator, blinkDuration, blinkIterations); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult GetFPDBrightness(const Exchange::IDeviceSettingsFPD::FPDIndicator indicator, - uint32_t& brightness) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->GetFPDBrightness(indicator, brightness); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult SetFPDBrightness(const Exchange::IDeviceSettingsFPD::FPDIndicator indicator, - const uint32_t brightness, const bool persist) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->SetFPDBrightness(indicator, brightness, persist); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult GetFPDTextBrightness(const Exchange::IDeviceSettingsFPD::FPDTextDisplay indicator, - uint32_t& brightness) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->GetFPDTextBrightness(indicator, brightness); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult SetFPDTextBrightness(const Exchange::IDeviceSettingsFPD::FPDTextDisplay indicator, - const uint32_t brightness) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->SetFPDTextBrightness(indicator, brightness); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult GetFPDColor(const Exchange::IDeviceSettingsFPD::FPDIndicator indicator, - uint32_t& color) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->GetFPDColor(indicator, color); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult SetFPDColor(const Exchange::IDeviceSettingsFPD::FPDIndicator indicator, - const uint32_t color) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->SetFPDColor(indicator, color); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult EnableFPDClockDisplay(const bool enable) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->EnableFPDClockDisplay(enable); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult SetFPDState(const Exchange::IDeviceSettingsFPD::FPDIndicator indicator, - const Exchange::IDeviceSettingsFPD::FPDState state) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->SetFPDState(indicator, state); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult GetFPDState(const Exchange::IDeviceSettingsFPD::FPDIndicator indicator, - Exchange::IDeviceSettingsFPD::FPDState& state) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->GetFPDState(indicator, state); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult GetFPDTimeFormat(Exchange::IDeviceSettingsFPD::FPDTimeFormat& timeFormat) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->GetFPDTimeFormat(timeFormat); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult SetFPDTimeFormat(const Exchange::IDeviceSettingsFPD::FPDTimeFormat timeFormat) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->SetFPDTimeFormat(timeFormat); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult SetFPDMode(const Exchange::IDeviceSettingsFPD::FPDMode mode) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->SetFPDMode(mode); - } - _apiLock.Unlock(); - return result; - } -}; - -// Static member initialization -DeviceSettingsFPD* DeviceSettingsFPD::_instance = nullptr; -Core::CriticalSection DeviceSettingsFPD::_apiLock; +using namespace DeviceSettingsClient; /** * @brief Convert Thunder error code to dsError_t */ static dsError_t ConvertThunderError(uint32_t thunderError) { - if (thunderError == Core::ERROR_NONE) { + if (thunderError == WPEFramework::Core::ERROR_NONE) { return dsERR_NONE; - } else if (thunderError == Core::ERROR_UNAVAILABLE) { + } else if (thunderError == WPEFramework::Core::ERROR_UNAVAILABLE) { return dsERR_OPERATION_NOT_SUPPORTED; - } else if (thunderError == Core::ERROR_BAD_REQUEST) { + } else if (thunderError == WPEFramework::Core::ERROR_BAD_REQUEST) { return dsERR_INVALID_PARAM; } else { return dsERR_GENERAL; } } -// C API implementations using Thunder COM-RPC +// C API implementations using Thunder COM-RPC via ConnectionManager extern "C" { @@ -421,21 +70,21 @@ dsError_t dsSetFPDColor(dsFPDIndicator_t eIndicator, dsFPDColor_t eColor, bool t dsError_t dsFPInit(void) { - printf("<<<<< Front Panel is initialized in Thunder Mode >>>>>>>>\r\n"); + printf("<<<<< Front Panel is initialized in Thunder Mode (using ConnectionManager) >>>>>>>>\r\n"); - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance) { - DeviceSettingsFPD::Init(); - instance = DeviceSettingsFPD::Instance(); + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr) { + ConnectionManager::Init(); + connMgr = ConnectionManager::Instance(); } - if (!instance) { - fprintf(stderr, "[dsFPD-com] Failed to create DeviceSettingsFPD instance\n"); + if (!connMgr) { + fprintf(stderr, "[dsFPD-com] Failed to create ConnectionManager instance\n"); return dsERR_GENERAL; } // Wait for plugin to become operational - if (!instance->WaitForOperational(5000)) { + if (!connMgr->WaitForOperational(5000)) { fprintf(stderr, "[dsFPD-com] DeviceSettings plugin not operational after 5 seconds\n"); return dsERR_GENERAL; } @@ -446,15 +95,8 @@ dsError_t dsFPInit(void) dsError_t dsFPTerm(void) { - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance) { - return dsERR_GENERAL; - } - - // Thunder interface doesn't have explicit Term method - // Terminate instance - DeviceSettingsFPD::Term(); - + // Note: Don't terminate ConnectionManager here as other components may be using it + // ConnectionManager will be terminated by dsConnectionTerm() or at process exit return dsERR_NONE; } @@ -472,42 +114,66 @@ dsError_t dsSetFPText(const char* pszChars) dsError_t dsSetFPTime(dsFPDTimeFormat_t eTime, const unsigned int uHour, const unsigned int uMinutes) { - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } Exchange::IDeviceSettingsFPD::FPDTimeFormat timeFormat = static_cast(eTime); + ConnectionManager::Lock(); // Note: Interface expects minutes and seconds, but API provides hour and minutes // Converting: treating uMinutes as seconds for interface compatibility - uint32_t result = instance->SetFPDTime(timeFormat, uHour, uMinutes); + uint32_t result = fpdInterface->SetFPDTime(timeFormat, uHour, uMinutes); + ConnectionManager::Unlock(); + return ConvertThunderError(result); } dsError_t dsSetFPScroll(unsigned int nScrollHoldOnDur, unsigned int nHorzScrollIterations, unsigned int nVertScrollIterations) { - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } - uint32_t result = instance->SetFPDScroll(nScrollHoldOnDur, nHorzScrollIterations, nVertScrollIterations); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->SetFPDScroll(nScrollHoldOnDur, nHorzScrollIterations, nVertScrollIterations); + ConnectionManager::Unlock(); + return ConvertThunderError(result); } dsError_t dsSetFPBlink(dsFPDIndicator_t eIndicator, unsigned int nBlinkDuration, unsigned int nBlinkIterations) { - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } Exchange::IDeviceSettingsFPD::FPDIndicator indicator = static_cast(eIndicator); - uint32_t result = instance->SetFPDBlink(indicator, nBlinkDuration, nBlinkIterations); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->SetFPDBlink(indicator, nBlinkDuration, nBlinkIterations); + ConnectionManager::Unlock(); + return ConvertThunderError(result); } @@ -518,8 +184,13 @@ dsError_t dsGetFPBrightness(dsFPDIndicator_t eIndicator, dsFPDBrightness_t *pBri return dsERR_INVALID_PARAM; } - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } @@ -527,9 +198,11 @@ dsError_t dsGetFPBrightness(dsFPDIndicator_t eIndicator, dsFPDBrightness_t *pBri static_cast(eIndicator); uint32_t brightness = 0; - uint32_t result = instance->GetFPDBrightness(indicator, brightness); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->GetFPDBrightness(indicator, brightness); + ConnectionManager::Unlock(); - if (result == Core::ERROR_NONE) { + if (result == WPEFramework::Core::ERROR_NONE) { *pBrightness = static_cast(brightness); } @@ -554,15 +227,23 @@ dsError_t dsSetFPDBrightness(dsFPDIndicator_t eIndicator, dsFPDBrightness_t eBri return dsERR_INVALID_PARAM; } - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } Exchange::IDeviceSettingsFPD::FPDIndicator indicator = static_cast(eIndicator); - uint32_t result = instance->SetFPDBrightness(indicator, static_cast(eBrightness), toPersist); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->SetFPDBrightness(indicator, static_cast(eBrightness), toPersist); + ConnectionManager::Unlock(); + return ConvertThunderError(result); } @@ -573,8 +254,13 @@ dsError_t dsGetFPTextBrightness(dsFPDTextDisplay_t eIndicator, dsFPDBrightness_t return dsERR_INVALID_PARAM; } - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } @@ -582,9 +268,11 @@ dsError_t dsGetFPTextBrightness(dsFPDTextDisplay_t eIndicator, dsFPDBrightness_t static_cast(eIndicator); uint32_t brightness = 0; - uint32_t result = instance->GetFPDTextBrightness(indicator, brightness); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->GetFPDTextBrightness(indicator, brightness); + ConnectionManager::Unlock(); - if (result == Core::ERROR_NONE) { + if (result == WPEFramework::Core::ERROR_NONE) { *pBrightness = static_cast(brightness); } @@ -593,15 +281,23 @@ dsError_t dsGetFPTextBrightness(dsFPDTextDisplay_t eIndicator, dsFPDBrightness_t dsError_t dsSetFPTextBrightness(dsFPDTextDisplay_t eIndicator, dsFPDBrightness_t eBrightness) { - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } Exchange::IDeviceSettingsFPD::FPDTextDisplay indicator = static_cast(eIndicator); - uint32_t result = instance->SetFPDTextBrightness(indicator, static_cast(eBrightness)); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->SetFPDTextBrightness(indicator, static_cast(eBrightness)); + ConnectionManager::Unlock(); + return ConvertThunderError(result); } @@ -612,8 +308,13 @@ dsError_t dsGetFPColor(dsFPDIndicator_t eIndicator, dsFPDColor_t *pColor) return dsERR_INVALID_PARAM; } - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } @@ -621,9 +322,11 @@ dsError_t dsGetFPColor(dsFPDIndicator_t eIndicator, dsFPDColor_t *pColor) static_cast(eIndicator); uint32_t color = 0; - uint32_t result = instance->GetFPDColor(indicator, color); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->GetFPDColor(indicator, color); + ConnectionManager::Unlock(); - if (result == Core::ERROR_NONE) { + if (result == WPEFramework::Core::ERROR_NONE) { *pColor = static_cast(color); } @@ -637,8 +340,13 @@ dsError_t dsSetFPColor(dsFPDIndicator_t eIndicator, dsFPDColor_t eColor) dsError_t dsSetFPDColor(dsFPDIndicator_t eIndicator, dsFPDColor_t eColor, bool toPersist) { - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } @@ -646,25 +354,41 @@ dsError_t dsSetFPDColor(dsFPDIndicator_t eIndicator, dsFPDColor_t eColor, bool t static_cast(eIndicator); // Thunder interface doesn't support persist flag - ignore it - uint32_t result = instance->SetFPDColor(indicator, static_cast(eColor)); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->SetFPDColor(indicator, static_cast(eColor)); + ConnectionManager::Unlock(); + return ConvertThunderError(result); } dsError_t dsFPEnableCLockDisplay(int enable) { - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } - uint32_t result = instance->EnableFPDClockDisplay(enable != 0); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->EnableFPDClockDisplay(enable != 0); + ConnectionManager::Unlock(); + return ConvertThunderError(result); } dsError_t dsSetFPState(dsFPDIndicator_t eIndicator, dsFPDState_t state) { - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } @@ -673,7 +397,10 @@ dsError_t dsSetFPState(dsFPDIndicator_t eIndicator, dsFPDState_t state) Exchange::IDeviceSettingsFPD::FPDState fpdState = static_cast(state); - uint32_t result = instance->SetFPDState(indicator, fpdState); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->SetFPDState(indicator, fpdState); + ConnectionManager::Unlock(); + return ConvertThunderError(result); } @@ -684,8 +411,13 @@ dsError_t dsGetFPState(dsFPDIndicator_t eIndicator, dsFPDState_t* state) return dsERR_INVALID_PARAM; } - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } @@ -693,9 +425,11 @@ dsError_t dsGetFPState(dsFPDIndicator_t eIndicator, dsFPDState_t* state) static_cast(eIndicator); Exchange::IDeviceSettingsFPD::FPDState fpdState; - uint32_t result = instance->GetFPDState(indicator, fpdState); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->GetFPDState(indicator, fpdState); + ConnectionManager::Unlock(); - if (result == Core::ERROR_NONE) { + if (result == WPEFramework::Core::ERROR_NONE) { *state = static_cast(fpdState); } @@ -709,15 +443,22 @@ dsError_t dsGetFPTimeFormat(dsFPDTimeFormat_t *pTimeFormat) return dsERR_INVALID_PARAM; } - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } Exchange::IDeviceSettingsFPD::FPDTimeFormat timeFormat; - uint32_t result = instance->GetFPDTimeFormat(timeFormat); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->GetFPDTimeFormat(timeFormat); + ConnectionManager::Unlock(); - if (result == Core::ERROR_NONE) { + if (result == WPEFramework::Core::ERROR_NONE) { *pTimeFormat = static_cast(timeFormat); } @@ -726,29 +467,45 @@ dsError_t dsGetFPTimeFormat(dsFPDTimeFormat_t *pTimeFormat) dsError_t dsSetFPTimeFormat(dsFPDTimeFormat_t eTimeFormat) { - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } Exchange::IDeviceSettingsFPD::FPDTimeFormat timeFormat = static_cast(eTimeFormat); - uint32_t result = instance->SetFPDTimeFormat(timeFormat); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->SetFPDTimeFormat(timeFormat); + ConnectionManager::Unlock(); + return ConvertThunderError(result); } dsError_t dsSetFPDMode(dsFPDMode_t eMode) { - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } Exchange::IDeviceSettingsFPD::FPDMode mode = static_cast(eMode); - uint32_t result = instance->SetFPDMode(mode); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->SetFPDMode(mode); + ConnectionManager::Unlock(); + return ConvertThunderError(result); } diff --git a/rpc/cli/dsHdmiIn-com.cpp b/rpc/cli/dsHdmiIn-com.cpp new file mode 100644 index 00000000..8a28acbc --- /dev/null +++ b/rpc/cli/dsHdmiIn-com.cpp @@ -0,0 +1,651 @@ +/* + * 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. +*/ + +/** +* @defgroup devicesettings +* @{ +* @defgroup rpc +* @{ +**/ + +#ifdef USE_WPE_THUNDER_PLUGIN + +#include +#include + +#include "dsHdmiIn.h" +#include "dsError.h" +#include "dsclientlogger.h" +#include "dsConnectionManager.h" + +// Thunder COM-RPC includes +#ifndef MODULE_NAME +#define MODULE_NAME DeviceSettings_HDMIIn_Client +#endif + +#include + +using namespace WPEFramework; +using namespace DeviceSettingsClient; + +/** + * @brief Convert Thunder error code to dsError_t + */ +static dsError_t ConvertThunderError(uint32_t thunderError) +{ + if (thunderError == WPEFramework::Core::ERROR_NONE) { + return dsERR_NONE; + } else if (thunderError == WPEFramework::Core::ERROR_UNAVAILABLE) { + return dsERR_OPERATION_NOT_SUPPORTED; + } else if (thunderError == WPEFramework::Core::ERROR_BAD_REQUEST) { + return dsERR_INVALID_PARAM; + } else { + return dsERR_GENERAL; + } +} + +// C API implementations using Thunder COM-RPC via ConnectionManager + +extern "C" { + +dsError_t dsHdmiInInit(void) +{ + printf("<<<<< HDMI In is initialized in Thunder Mode (using ConnectionManager) >>>>>>>>\r\n"); + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr) { + ConnectionManager::Init(); + connMgr = ConnectionManager::Instance(); + } + + if (!connMgr) { + fprintf(stderr, "[dsHdmiIn-com] Failed to create ConnectionManager instance\n"); + return dsERR_GENERAL; + } + + // Wait for plugin to become operational + if (!connMgr->WaitForOperational(5000)) { + fprintf(stderr, "[dsHdmiIn-com] DeviceSettings plugin not operational after 5 seconds\n"); + return dsERR_GENERAL; + } + + return dsERR_NONE; +} + +dsError_t dsHdmiInTerm(void) +{ + // Note: Don't terminate ConnectionManager here as other components may be using it + // ConnectionManager will be terminated by dsConnectionTerm() or at process exit + return dsERR_NONE; +} + +dsError_t dsHdmiInGetNumberOfInputs(uint8_t* pNumberOfInputs) +{ + if (pNumberOfInputs == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: pNumberOfInputs is NULL\n"); + return dsERR_INVALID_PARAM; + } + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + int32_t count = 0; + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->GetHDMIInNumbefOfInputs(count); + ConnectionManager::Unlock(); + + if (result == WPEFramework::Core::ERROR_NONE) { + *pNumberOfInputs = static_cast(count); + } + + return ConvertThunderError(result); +} + +dsError_t dsHdmiInGetStatus(dsHdmiInStatus_t* pStatus) +{ + if (pStatus == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: pStatus is NULL\n"); + return dsERR_INVALID_PARAM; + } + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInStatus hdmiStatus; + Exchange::IDeviceSettingsHDMIIn::IHDMIInPortConnectionStatusIterator* portConnectionStatus = nullptr; + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->GetHDMIInStatus(hdmiStatus, portConnectionStatus); + ConnectionManager::Unlock(); + + if (result == WPEFramework::Core::ERROR_NONE) { + pStatus->isPresented = hdmiStatus.isPresented; + pStatus->activePort = static_cast(hdmiStatus.activePort); + + // TODO: Handle portConnectionStatus iterator if needed + if (portConnectionStatus) { + portConnectionStatus->Release(); + } + } + + return ConvertThunderError(result); +} + +dsError_t dsHdmiInSelectPort(dsHdmiInPort_t ePort, bool audioMix, dsVideoPlaneType_t videoPlaneType, bool topMost) +{ + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = + static_cast(ePort); + Exchange::IDeviceSettingsHDMIIn::HDMIVideoPlaneType planeType = + static_cast(videoPlaneType); + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->SelectHDMIInPort(port, audioMix, topMost, planeType); + ConnectionManager::Unlock(); + + return ConvertThunderError(result); +} + +dsError_t dsHdmiInScaleVideo(int32_t x, int32_t y, int32_t width, int32_t height) +{ + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInVideoRectangle videoPosition; + videoPosition.x = x; + videoPosition.y = y; + videoPosition.width = width; + videoPosition.height = height; + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->ScaleHDMIInVideo(videoPosition); + ConnectionManager::Unlock(); + + return ConvertThunderError(result); +} + +dsError_t dsHdmiInSelectZoomMode(dsVideoZoom_t zoomMode) +{ + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInVideoZoom zoom = + static_cast(zoomMode); + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->SelectHDMIZoomMode(zoom); + ConnectionManager::Unlock(); + + return ConvertThunderError(result); +} + +dsError_t dsHdmiInGetCurrentVideoMode(dsVideoPortResolution_t* resolution) +{ + if (resolution == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: resolution is NULL\n"); + return dsERR_INVALID_PARAM; + } + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIVideoPortResolution videoPortResolution; + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->GetHDMIVideoMode(videoPortResolution); + ConnectionManager::Unlock(); + + if (result == WPEFramework::Core::ERROR_NONE) { + strncpy(resolution->name, videoPortResolution.name.c_str(), sizeof(resolution->name) - 1); + resolution->name[sizeof(resolution->name) - 1] = '\0'; + resolution->pixelResolution = static_cast(videoPortResolution.pixelResolution); + resolution->aspectRatio = static_cast(videoPortResolution.aspectRatio); + resolution->stereoScopicMode = static_cast(videoPortResolution.stereoScopicMode); + resolution->frameRate = static_cast(videoPortResolution.frameRate); + resolution->interlaced = videoPortResolution.interlaced; + } + + return ConvertThunderError(result); +} + +dsError_t dsGetEDIDBytesInfo(int iHdmiPort, unsigned char* edid, int* length) +{ + if (edid == NULL || length == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter\n"); + return dsERR_INVALID_PARAM; + } + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = + static_cast(iHdmiPort); + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->GetEdidBytes(port, static_cast(*length), edid); + ConnectionManager::Unlock(); + + return ConvertThunderError(result); +} + +dsError_t dsGetHDMISPDInfo(int iHdmiPort, unsigned char* data) +{ + if (data == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: data is NULL\n"); + return dsERR_INVALID_PARAM; + } + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = + static_cast(iHdmiPort); + + // Assuming SPD info frame size (adjust as needed) + const uint16_t spdBytesLength = 32; + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->GetHDMISPDInformation(port, spdBytesLength, data); + ConnectionManager::Unlock(); + + return ConvertThunderError(result); +} + +dsError_t dsGetEdidVersion(int iHdmiPort, int* edidVersion) +{ + if (edidVersion == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: edidVersion is NULL\n"); + return dsERR_INVALID_PARAM; + } + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = + static_cast(iHdmiPort); + Exchange::IDeviceSettingsHDMIIn::HDMIInEdidVersion version; + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->GetHDMIEdidVersion(port, version); + ConnectionManager::Unlock(); + + if (result == WPEFramework::Core::ERROR_NONE) { + *edidVersion = static_cast(version); + } + + return ConvertThunderError(result); +} + +dsError_t dsSetEdidVersion(int iHdmiPort, int edidVersion) +{ + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = + static_cast(iHdmiPort); + Exchange::IDeviceSettingsHDMIIn::HDMIInEdidVersion version = + static_cast(edidVersion); + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->SetHDMIEdidVersion(port, version); + ConnectionManager::Unlock(); + + return ConvertThunderError(result); +} + +dsError_t dsGetAllmStatus(dsHdmiInPort_t iHdmiPort, bool* allmStatus) +{ + if (allmStatus == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: allmStatus is NULL\n"); + return dsERR_INVALID_PARAM; + } + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = + static_cast(iHdmiPort); + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->GetHDMIInAllmStatus(port, *allmStatus); + ConnectionManager::Unlock(); + + return ConvertThunderError(result); +} + +dsError_t dsGetEdid2AllmSupport(dsHdmiInPort_t iHdmiPort, bool* allmSupport) +{ + if (allmSupport == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: allmSupport is NULL\n"); + return dsERR_INVALID_PARAM; + } + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = + static_cast(iHdmiPort); + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->GetHDMIInEdid2AllmSupport(port, *allmSupport); + ConnectionManager::Unlock(); + + return ConvertThunderError(result); +} + +dsError_t dsSetEdid2AllmSupport(dsHdmiInPort_t iHdmiPort, bool allmSupport) +{ + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = + static_cast(iHdmiPort); + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->SetHDMIInEdid2AllmSupport(port, allmSupport); + ConnectionManager::Unlock(); + + return ConvertThunderError(result); +} + +dsError_t dsGetAVLatency(int* audio_latency, int* video_latency) +{ + if (audio_latency == NULL || video_latency == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter\n"); + return dsERR_INVALID_PARAM; + } + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + uint32_t videoLatency = 0; + uint32_t audioLatency = 0; + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->GetHDMIInAVLatency(videoLatency, audioLatency); + ConnectionManager::Unlock(); + + if (result == WPEFramework::Core::ERROR_NONE) { + *audio_latency = static_cast(audioLatency); + *video_latency = static_cast(videoLatency); + } + + return ConvertThunderError(result); +} + +dsError_t dsGetHdmiVersion(dsHdmiInPort_t iHdmiPort, dsHdmiVersion_t* capversion) +{ + if (capversion == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: capversion is NULL\n"); + return dsERR_INVALID_PARAM; + } + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = + static_cast(iHdmiPort); + Exchange::IDeviceSettingsHDMIIn::HDMIInCapabilityVersion capabilityVersion; + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->GetHDMIVersion(port, capabilityVersion); + ConnectionManager::Unlock(); + + if (result == WPEFramework::Core::ERROR_NONE) { + *capversion = static_cast(capabilityVersion); + } + + return ConvertThunderError(result); +} + +dsError_t dsSetVRRSupport(dsHdmiInPort_t iHdmiPort, bool vrrSupport) +{ + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = + static_cast(iHdmiPort); + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->SetVRRSupport(port, vrrSupport); + ConnectionManager::Unlock(); + + return ConvertThunderError(result); +} + +dsError_t dsGetVRRSupport(dsHdmiInPort_t iHdmiPort, bool* vrrSupport) +{ + if (vrrSupport == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: vrrSupport is NULL\n"); + return dsERR_INVALID_PARAM; + } + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = + static_cast(iHdmiPort); + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->GetVRRSupport(port, *vrrSupport); + ConnectionManager::Unlock(); + + return ConvertThunderError(result); +} + +dsError_t dsHdmiInGetVRRStatus(dsHdmiInPort_t iHdmiPort, dsHdmiInVrrStatus_t* vrrStatus) +{ + if (vrrStatus == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: vrrStatus is NULL\n"); + return dsERR_INVALID_PARAM; + } + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = + static_cast(iHdmiPort); + Exchange::IDeviceSettingsHDMIIn::HDMIInVRRStatus status; + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->GetVRRStatus(port, status); + ConnectionManager::Unlock(); + + if (result == WPEFramework::Core::ERROR_NONE) { + vrrStatus->vrrType = static_cast(status.vrrType); + vrrStatus->vrrFreeSyncFramerateHz = status.vrrFreeSyncFramerateHz; + } + + return ConvertThunderError(result); +} + +// Placeholder for unsupported APIs in Thunder mode +dsError_t dsHdmiInRegisterConnectCB(dsHdmiInConnectCB_t CBFunc) +{ + fprintf(stderr, "[dsHdmiIn-com] dsHdmiInRegisterConnectCB not supported in Thunder mode\n"); + return dsERR_OPERATION_NOT_SUPPORTED; +} + +dsError_t dsHdmiInRegisterSignalChangeCB(dsHdmiInSignalChangeCB_t CBFunc) +{ + fprintf(stderr, "[dsHdmiIn-com] dsHdmiInRegisterSignalChangeCB not supported in Thunder mode\n"); + return dsERR_OPERATION_NOT_SUPPORTED; +} + +dsError_t dsHdmiInRegisterStatusChangeCB(dsHdmiInStatusChangeCB_t CBFunc) +{ + fprintf(stderr, "[dsHdmiIn-com] dsHdmiInRegisterStatusChangeCB not supported in Thunder mode\n"); + return dsERR_OPERATION_NOT_SUPPORTED; +} + +dsError_t dsHdmiInRegisterVideoModeUpdateCB(dsHdmiInVideoModeUpdateCB_t CBFunc) +{ + fprintf(stderr, "[dsHdmiIn-com] dsHdmiInRegisterVideoModeUpdateCB not supported in Thunder mode\n"); + return dsERR_OPERATION_NOT_SUPPORTED; +} + +dsError_t dsHdmiInRegisterAllmChangeCB(dsHdmiInAllmChangeCB_t CBFunc) +{ + fprintf(stderr, "[dsHdmiIn-com] dsHdmiInRegisterAllmChangeCB not supported in Thunder mode\n"); + return dsERR_OPERATION_NOT_SUPPORTED; +} + +dsError_t dsHdmiInRegisterAVLatencyChangeCB(dsAVLatencyChangeCB_t CBFunc) +{ + fprintf(stderr, "[dsHdmiIn-com] dsHdmiInRegisterAVLatencyChangeCB not supported in Thunder mode\n"); + return dsERR_OPERATION_NOT_SUPPORTED; +} + +dsError_t dsHdmiInRegisterAviContentTypeChangeCB(dsAviContentTypeChangeCB_t CBFunc) +{ + fprintf(stderr, "[dsHdmiIn-com] dsHdmiInRegisterAviContentTypeChangeCB not supported in Thunder mode\n"); + return dsERR_OPERATION_NOT_SUPPORTED; +} + +} // extern "C" + +#endif // USE_WPE_THUNDER_PLUGIN + +/** @} */ +/** @} */ From 94475ecdfca006f0537dda94a1b1aa9d6abba86a Mon Sep 17 00:00:00 2001 From: Manimaran Renganathan Date: Thu, 5 Feb 2026 05:10:53 +0000 Subject: [PATCH 06/16] Resolved compilation errors --- rpc/cli/dsConnectionManager.h | 4 ++++ rpc/cli/dsHdmiIn-com.cpp | 18 +++++++++--------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/rpc/cli/dsConnectionManager.h b/rpc/cli/dsConnectionManager.h index eed60bf4..e553fab6 100644 --- a/rpc/cli/dsConnectionManager.h +++ b/rpc/cli/dsConnectionManager.h @@ -22,6 +22,10 @@ #ifdef USE_WPE_THUNDER_PLUGIN +#ifndef MODULE_NAME +#define MODULE_NAME DeviceSettings_ConnectionManager +#endif + #include #include #include diff --git a/rpc/cli/dsHdmiIn-com.cpp b/rpc/cli/dsHdmiIn-com.cpp index 8a28acbc..5d51eee0 100644 --- a/rpc/cli/dsHdmiIn-com.cpp +++ b/rpc/cli/dsHdmiIn-com.cpp @@ -267,7 +267,7 @@ dsError_t dsHdmiInGetCurrentVideoMode(dsVideoPortResolution_t* resolution) return ConvertThunderError(result); } -dsError_t dsGetEDIDBytesInfo(int iHdmiPort, unsigned char* edid, int* length) +dsError_t dsGetEDIDBytesInfo(dsHdmiInPort_t iHdmiPort, unsigned char* edid, int* length) { if (edid == NULL || length == NULL) { fprintf(stderr, "[dsHdmiIn-com] Invalid parameter\n"); @@ -294,7 +294,7 @@ dsError_t dsGetEDIDBytesInfo(int iHdmiPort, unsigned char* edid, int* length) return ConvertThunderError(result); } -dsError_t dsGetHDMISPDInfo(int iHdmiPort, unsigned char* data) +dsError_t dsGetHDMISPDInfo(dsHdmiInPort_t iHdmiPort, unsigned char* data) { if (data == NULL) { fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: data is NULL\n"); @@ -323,7 +323,7 @@ dsError_t dsGetHDMISPDInfo(int iHdmiPort, unsigned char* data) return ConvertThunderError(result); } -dsError_t dsGetEdidVersion(int iHdmiPort, int* edidVersion) +dsError_t dsGetEdidVersion(dsHdmiInPort_t iHdmiPort, tv_hdmi_edid_version_t* edidVersion) { if (edidVersion == NULL) { fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: edidVersion is NULL\n"); @@ -349,13 +349,13 @@ dsError_t dsGetEdidVersion(int iHdmiPort, int* edidVersion) ConnectionManager::Unlock(); if (result == WPEFramework::Core::ERROR_NONE) { - *edidVersion = static_cast(version); + *edidVersion = static_cast(version); } return ConvertThunderError(result); } -dsError_t dsSetEdidVersion(int iHdmiPort, int edidVersion) +dsError_t dsSetEdidVersion(dsHdmiInPort_t iHdmiPort, tv_hdmi_edid_version_t edidVersion) { ConnectionManager* connMgr = ConnectionManager::Instance(); if (!connMgr || !connMgr->IsOperational()) { @@ -486,7 +486,7 @@ dsError_t dsGetAVLatency(int* audio_latency, int* video_latency) return ConvertThunderError(result); } -dsError_t dsGetHdmiVersion(dsHdmiInPort_t iHdmiPort, dsHdmiVersion_t* capversion) +dsError_t dsGetHdmiVersion(dsHdmiInPort_t iHdmiPort, dsHdmiMaxCapabilityVersion_t* capversion) { if (capversion == NULL) { fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: capversion is NULL\n"); @@ -512,7 +512,7 @@ dsError_t dsGetHdmiVersion(dsHdmiInPort_t iHdmiPort, dsHdmiVersion_t* capversion ConnectionManager::Unlock(); if (result == WPEFramework::Core::ERROR_NONE) { - *capversion = static_cast(capabilityVersion); + *capversion = static_cast(capabilityVersion); } return ConvertThunderError(result); @@ -594,7 +594,7 @@ dsError_t dsHdmiInGetVRRStatus(dsHdmiInPort_t iHdmiPort, dsHdmiInVrrStatus_t* vr if (result == WPEFramework::Core::ERROR_NONE) { vrrStatus->vrrType = static_cast(status.vrrType); - vrrStatus->vrrFreeSyncFramerateHz = status.vrrFreeSyncFramerateHz; + vrrStatus->vrrAmdfreesyncFramerate_Hz = status.vrrFreeSyncFramerateHz; } return ConvertThunderError(result); @@ -637,7 +637,7 @@ dsError_t dsHdmiInRegisterAVLatencyChangeCB(dsAVLatencyChangeCB_t CBFunc) return dsERR_OPERATION_NOT_SUPPORTED; } -dsError_t dsHdmiInRegisterAviContentTypeChangeCB(dsAviContentTypeChangeCB_t CBFunc) +dsError_t dsHdmiInRegisterAviContentTypeChangeCB(dsHdmiInAviContentTypeChangeCB_t CBFunc) { fprintf(stderr, "[dsHdmiIn-com] dsHdmiInRegisterAviContentTypeChangeCB not supported in Thunder mode\n"); return dsERR_OPERATION_NOT_SUPPORTED; From 402f9bffbdb3083ac62130497231cacc8f55d6aa Mon Sep 17 00:00:00 2001 From: Manimaran Renganathan Date: Thu, 5 Feb 2026 05:49:15 +0000 Subject: [PATCH 07/16] Added the Makefile and Makefile.am changes in devicesettings /rpc/cli --- rpc/cli/Makefile | 8 ++++---- rpc/cli/Makefile.am | 8 +++++++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/rpc/cli/Makefile b/rpc/cli/Makefile index 7b2575ee..a10f6551 100644 --- a/rpc/cli/Makefile +++ b/rpc/cli/Makefile @@ -24,12 +24,12 @@ INSTALL := $(PWD)/install # Conditional compilation: Thunder vs IARM ifdef USE_WPE_THUNDER_PLUGIN - # Thunder mode - use dsFPD-com.cpp, exclude dsFPD.c + # Thunder mode - use *-com.cpp files, exclude legacy .c implementations OBJS := $(patsubst %.cpp,%.o,$(wildcard *.cpp)) - OBJS += $(patsubst %.c,%.o,$(filter-out dsFPD.c,$(wildcard *.c))) + OBJS += $(patsubst %.c,%.o,$(filter-out dsFPD.c dsHdmiIn.c,$(wildcard *.c))) else - # IARM mode - use dsFPD.c, exclude dsFPD-com.cpp - OBJS := $(patsubst %.cpp,%.o,$(filter-out dsFPD-com.cpp,$(wildcard *.cpp))) + # IARM mode - use legacy .c files, exclude Thunder -com.cpp implementations + OBJS := $(patsubst %.cpp,%.o,$(filter-out dsFPD-com.cpp dsHdmiIn-com.cpp dsConnectionManager.cpp,$(wildcard *.cpp))) OBJS += $(patsubst %.c,%.o,$(wildcard *.c)) endif diff --git a/rpc/cli/Makefile.am b/rpc/cli/Makefile.am index 27f50c1b..0b98e994 100644 --- a/rpc/cli/Makefile.am +++ b/rpc/cli/Makefile.am @@ -32,11 +32,17 @@ libdshalcli_la_CFLAGS = -g -fPIC -D_REENTRANT -Wall # Conditional compilation for Thunder COM-RPC if USE_THUNDER_PLUGIN FPD_SOURCE = dsFPD-com.cpp + HDMIIN_SOURCE = dsHdmiIn-com.cpp + COMPOSITEIN_SOURCE = + THUNDER_SOURCES = dsConnectionManager.cpp THUNDER_LIBS = -lWPEFrameworkCore -lWPEFrameworkCOM else FPD_SOURCE = dsFPD.c + HDMIIN_SOURCE = dsHdmiIn.c + COMPOSITEIN_SOURCE = dsCompositeIn.c + THUNDER_SOURCES = THUNDER_LIBS = endif -libdshalcli_la_SOURCES = dsAudio.c dsclientlogger.c dsDisplay.c $(FPD_SOURCE) dsHost.cpp dsVideoDevice.c dsVideoPort.c +libdshalcli_la_SOURCES = dsAudio.c dsclientlogger.c dsDisplay.c $(FPD_SOURCE) $(HDMIIN_SOURCE) $(COMPOSITEIN_SOURCE) $(THUNDER_SOURCES) dsHost.cpp dsVideoDevice.c dsVideoPort.c libdshalcli_la_LIBADD = $(THUNDER_LIBS) From 70a09eb5c1a60f8cd1044e326ce8c2b36b9ff738 Mon Sep 17 00:00:00 2001 From: Manimaran Renganathan Date: Thu, 5 Feb 2026 07:43:22 +0000 Subject: [PATCH 08/16] Resolved undefined reference error in dsHdmiIn-com.cpp file --- rpc/cli/dsHdmiIn-com.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/rpc/cli/dsHdmiIn-com.cpp b/rpc/cli/dsHdmiIn-com.cpp index 5d51eee0..aee2ce4f 100644 --- a/rpc/cli/dsHdmiIn-com.cpp +++ b/rpc/cli/dsHdmiIn-com.cpp @@ -518,7 +518,7 @@ dsError_t dsGetHdmiVersion(dsHdmiInPort_t iHdmiPort, dsHdmiMaxCapabilityVersion_ return ConvertThunderError(result); } -dsError_t dsSetVRRSupport(dsHdmiInPort_t iHdmiPort, bool vrrSupport) +dsError_t dsHdmiInSetVRRSupport(dsHdmiInPort_t iHdmiPort, bool vrrSupport) { ConnectionManager* connMgr = ConnectionManager::Instance(); if (!connMgr || !connMgr->IsOperational()) { @@ -540,7 +540,7 @@ dsError_t dsSetVRRSupport(dsHdmiInPort_t iHdmiPort, bool vrrSupport) return ConvertThunderError(result); } -dsError_t dsGetVRRSupport(dsHdmiInPort_t iHdmiPort, bool* vrrSupport) +dsError_t dsHdmiInGetVRRSupport(dsHdmiInPort_t iHdmiPort, bool* vrrSupport) { if (vrrSupport == NULL) { fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: vrrSupport is NULL\n"); @@ -600,6 +600,21 @@ dsError_t dsHdmiInGetVRRStatus(dsHdmiInPort_t iHdmiPort, dsHdmiInVrrStatus_t* vr return ConvertThunderError(result); } +dsError_t dsGetSupportedGameFeaturesList(dsSupportedGameFeatureList_t* feature) +{ + if (feature == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: feature is NULL\n"); + return dsERR_INVALID_PARAM; + } + + // This function is not yet implemented in Thunder COM-RPC mode + // For now, return empty list + feature->gameFeatureCount = 0; + feature->gameFeatureList[0] = '\0'; + fprintf(stderr, "[dsHdmiIn-com] dsGetSupportedGameFeaturesList not fully implemented in Thunder mode\n"); + return dsERR_OPERATION_NOT_SUPPORTED; +} + // Placeholder for unsupported APIs in Thunder mode dsError_t dsHdmiInRegisterConnectCB(dsHdmiInConnectCB_t CBFunc) { From 3944baf409fa950dc2f5e3b7d7f7c922883dafdb Mon Sep 17 00:00:00 2001 From: mravi105 Date: Thu, 5 Feb 2026 08:23:20 +0000 Subject: [PATCH 09/16] Revert "Resolved undefined reference error in dsHdmiIn-com.cpp file" This reverts commit 70a09eb5c1a60f8cd1044e326ce8c2b36b9ff738. --- rpc/cli/dsHdmiIn-com.cpp | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/rpc/cli/dsHdmiIn-com.cpp b/rpc/cli/dsHdmiIn-com.cpp index aee2ce4f..5d51eee0 100644 --- a/rpc/cli/dsHdmiIn-com.cpp +++ b/rpc/cli/dsHdmiIn-com.cpp @@ -518,7 +518,7 @@ dsError_t dsGetHdmiVersion(dsHdmiInPort_t iHdmiPort, dsHdmiMaxCapabilityVersion_ return ConvertThunderError(result); } -dsError_t dsHdmiInSetVRRSupport(dsHdmiInPort_t iHdmiPort, bool vrrSupport) +dsError_t dsSetVRRSupport(dsHdmiInPort_t iHdmiPort, bool vrrSupport) { ConnectionManager* connMgr = ConnectionManager::Instance(); if (!connMgr || !connMgr->IsOperational()) { @@ -540,7 +540,7 @@ dsError_t dsHdmiInSetVRRSupport(dsHdmiInPort_t iHdmiPort, bool vrrSupport) return ConvertThunderError(result); } -dsError_t dsHdmiInGetVRRSupport(dsHdmiInPort_t iHdmiPort, bool* vrrSupport) +dsError_t dsGetVRRSupport(dsHdmiInPort_t iHdmiPort, bool* vrrSupport) { if (vrrSupport == NULL) { fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: vrrSupport is NULL\n"); @@ -600,21 +600,6 @@ dsError_t dsHdmiInGetVRRStatus(dsHdmiInPort_t iHdmiPort, dsHdmiInVrrStatus_t* vr return ConvertThunderError(result); } -dsError_t dsGetSupportedGameFeaturesList(dsSupportedGameFeatureList_t* feature) -{ - if (feature == NULL) { - fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: feature is NULL\n"); - return dsERR_INVALID_PARAM; - } - - // This function is not yet implemented in Thunder COM-RPC mode - // For now, return empty list - feature->gameFeatureCount = 0; - feature->gameFeatureList[0] = '\0'; - fprintf(stderr, "[dsHdmiIn-com] dsGetSupportedGameFeaturesList not fully implemented in Thunder mode\n"); - return dsERR_OPERATION_NOT_SUPPORTED; -} - // Placeholder for unsupported APIs in Thunder mode dsError_t dsHdmiInRegisterConnectCB(dsHdmiInConnectCB_t CBFunc) { From 7e25fcc9390e6fb027bed2a6573b53bea15658bc Mon Sep 17 00:00:00 2001 From: mravi105 Date: Thu, 5 Feb 2026 08:23:22 +0000 Subject: [PATCH 10/16] Revert "Added the Makefile and Makefile.am changes in devicesettings /rpc/cli" This reverts commit 402f9bffbdb3083ac62130497231cacc8f55d6aa. --- rpc/cli/Makefile | 8 ++++---- rpc/cli/Makefile.am | 8 +------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/rpc/cli/Makefile b/rpc/cli/Makefile index a10f6551..7b2575ee 100644 --- a/rpc/cli/Makefile +++ b/rpc/cli/Makefile @@ -24,12 +24,12 @@ INSTALL := $(PWD)/install # Conditional compilation: Thunder vs IARM ifdef USE_WPE_THUNDER_PLUGIN - # Thunder mode - use *-com.cpp files, exclude legacy .c implementations + # Thunder mode - use dsFPD-com.cpp, exclude dsFPD.c OBJS := $(patsubst %.cpp,%.o,$(wildcard *.cpp)) - OBJS += $(patsubst %.c,%.o,$(filter-out dsFPD.c dsHdmiIn.c,$(wildcard *.c))) + OBJS += $(patsubst %.c,%.o,$(filter-out dsFPD.c,$(wildcard *.c))) else - # IARM mode - use legacy .c files, exclude Thunder -com.cpp implementations - OBJS := $(patsubst %.cpp,%.o,$(filter-out dsFPD-com.cpp dsHdmiIn-com.cpp dsConnectionManager.cpp,$(wildcard *.cpp))) + # IARM mode - use dsFPD.c, exclude dsFPD-com.cpp + OBJS := $(patsubst %.cpp,%.o,$(filter-out dsFPD-com.cpp,$(wildcard *.cpp))) OBJS += $(patsubst %.c,%.o,$(wildcard *.c)) endif diff --git a/rpc/cli/Makefile.am b/rpc/cli/Makefile.am index 0b98e994..27f50c1b 100644 --- a/rpc/cli/Makefile.am +++ b/rpc/cli/Makefile.am @@ -32,17 +32,11 @@ libdshalcli_la_CFLAGS = -g -fPIC -D_REENTRANT -Wall # Conditional compilation for Thunder COM-RPC if USE_THUNDER_PLUGIN FPD_SOURCE = dsFPD-com.cpp - HDMIIN_SOURCE = dsHdmiIn-com.cpp - COMPOSITEIN_SOURCE = - THUNDER_SOURCES = dsConnectionManager.cpp THUNDER_LIBS = -lWPEFrameworkCore -lWPEFrameworkCOM else FPD_SOURCE = dsFPD.c - HDMIIN_SOURCE = dsHdmiIn.c - COMPOSITEIN_SOURCE = dsCompositeIn.c - THUNDER_SOURCES = THUNDER_LIBS = endif -libdshalcli_la_SOURCES = dsAudio.c dsclientlogger.c dsDisplay.c $(FPD_SOURCE) $(HDMIIN_SOURCE) $(COMPOSITEIN_SOURCE) $(THUNDER_SOURCES) dsHost.cpp dsVideoDevice.c dsVideoPort.c +libdshalcli_la_SOURCES = dsAudio.c dsclientlogger.c dsDisplay.c $(FPD_SOURCE) dsHost.cpp dsVideoDevice.c dsVideoPort.c libdshalcli_la_LIBADD = $(THUNDER_LIBS) From 8c15bc0fd60fa4151c765d215253f01380a68e46 Mon Sep 17 00:00:00 2001 From: mravi105 Date: Thu, 5 Feb 2026 08:23:23 +0000 Subject: [PATCH 11/16] Revert "Resolved compilation errors" This reverts commit 94475ecdfca006f0537dda94a1b1aa9d6abba86a. --- rpc/cli/dsConnectionManager.h | 4 ---- rpc/cli/dsHdmiIn-com.cpp | 18 +++++++++--------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/rpc/cli/dsConnectionManager.h b/rpc/cli/dsConnectionManager.h index e553fab6..eed60bf4 100644 --- a/rpc/cli/dsConnectionManager.h +++ b/rpc/cli/dsConnectionManager.h @@ -22,10 +22,6 @@ #ifdef USE_WPE_THUNDER_PLUGIN -#ifndef MODULE_NAME -#define MODULE_NAME DeviceSettings_ConnectionManager -#endif - #include #include #include diff --git a/rpc/cli/dsHdmiIn-com.cpp b/rpc/cli/dsHdmiIn-com.cpp index 5d51eee0..8a28acbc 100644 --- a/rpc/cli/dsHdmiIn-com.cpp +++ b/rpc/cli/dsHdmiIn-com.cpp @@ -267,7 +267,7 @@ dsError_t dsHdmiInGetCurrentVideoMode(dsVideoPortResolution_t* resolution) return ConvertThunderError(result); } -dsError_t dsGetEDIDBytesInfo(dsHdmiInPort_t iHdmiPort, unsigned char* edid, int* length) +dsError_t dsGetEDIDBytesInfo(int iHdmiPort, unsigned char* edid, int* length) { if (edid == NULL || length == NULL) { fprintf(stderr, "[dsHdmiIn-com] Invalid parameter\n"); @@ -294,7 +294,7 @@ dsError_t dsGetEDIDBytesInfo(dsHdmiInPort_t iHdmiPort, unsigned char* edid, int* return ConvertThunderError(result); } -dsError_t dsGetHDMISPDInfo(dsHdmiInPort_t iHdmiPort, unsigned char* data) +dsError_t dsGetHDMISPDInfo(int iHdmiPort, unsigned char* data) { if (data == NULL) { fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: data is NULL\n"); @@ -323,7 +323,7 @@ dsError_t dsGetHDMISPDInfo(dsHdmiInPort_t iHdmiPort, unsigned char* data) return ConvertThunderError(result); } -dsError_t dsGetEdidVersion(dsHdmiInPort_t iHdmiPort, tv_hdmi_edid_version_t* edidVersion) +dsError_t dsGetEdidVersion(int iHdmiPort, int* edidVersion) { if (edidVersion == NULL) { fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: edidVersion is NULL\n"); @@ -349,13 +349,13 @@ dsError_t dsGetEdidVersion(dsHdmiInPort_t iHdmiPort, tv_hdmi_edid_version_t* edi ConnectionManager::Unlock(); if (result == WPEFramework::Core::ERROR_NONE) { - *edidVersion = static_cast(version); + *edidVersion = static_cast(version); } return ConvertThunderError(result); } -dsError_t dsSetEdidVersion(dsHdmiInPort_t iHdmiPort, tv_hdmi_edid_version_t edidVersion) +dsError_t dsSetEdidVersion(int iHdmiPort, int edidVersion) { ConnectionManager* connMgr = ConnectionManager::Instance(); if (!connMgr || !connMgr->IsOperational()) { @@ -486,7 +486,7 @@ dsError_t dsGetAVLatency(int* audio_latency, int* video_latency) return ConvertThunderError(result); } -dsError_t dsGetHdmiVersion(dsHdmiInPort_t iHdmiPort, dsHdmiMaxCapabilityVersion_t* capversion) +dsError_t dsGetHdmiVersion(dsHdmiInPort_t iHdmiPort, dsHdmiVersion_t* capversion) { if (capversion == NULL) { fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: capversion is NULL\n"); @@ -512,7 +512,7 @@ dsError_t dsGetHdmiVersion(dsHdmiInPort_t iHdmiPort, dsHdmiMaxCapabilityVersion_ ConnectionManager::Unlock(); if (result == WPEFramework::Core::ERROR_NONE) { - *capversion = static_cast(capabilityVersion); + *capversion = static_cast(capabilityVersion); } return ConvertThunderError(result); @@ -594,7 +594,7 @@ dsError_t dsHdmiInGetVRRStatus(dsHdmiInPort_t iHdmiPort, dsHdmiInVrrStatus_t* vr if (result == WPEFramework::Core::ERROR_NONE) { vrrStatus->vrrType = static_cast(status.vrrType); - vrrStatus->vrrAmdfreesyncFramerate_Hz = status.vrrFreeSyncFramerateHz; + vrrStatus->vrrFreeSyncFramerateHz = status.vrrFreeSyncFramerateHz; } return ConvertThunderError(result); @@ -637,7 +637,7 @@ dsError_t dsHdmiInRegisterAVLatencyChangeCB(dsAVLatencyChangeCB_t CBFunc) return dsERR_OPERATION_NOT_SUPPORTED; } -dsError_t dsHdmiInRegisterAviContentTypeChangeCB(dsHdmiInAviContentTypeChangeCB_t CBFunc) +dsError_t dsHdmiInRegisterAviContentTypeChangeCB(dsAviContentTypeChangeCB_t CBFunc) { fprintf(stderr, "[dsHdmiIn-com] dsHdmiInRegisterAviContentTypeChangeCB not supported in Thunder mode\n"); return dsERR_OPERATION_NOT_SUPPORTED; From 59ccd0850cd8fe54988f9688137207602f0cdff8 Mon Sep 17 00:00:00 2001 From: mravi105 Date: Thu, 5 Feb 2026 08:23:24 +0000 Subject: [PATCH 12/16] Revert "Modified the code" This reverts commit d220f98621f74970843eda26879da2ca536e188d. --- rpc/cli/dsConnectionManager.cpp | 239 ------------ rpc/cli/dsConnectionManager.h | 138 ------- rpc/cli/dsFPD-com.cpp | 605 ++++++++++++++++++++--------- rpc/cli/dsHdmiIn-com.cpp | 651 -------------------------------- 4 files changed, 424 insertions(+), 1209 deletions(-) delete mode 100644 rpc/cli/dsConnectionManager.cpp delete mode 100644 rpc/cli/dsConnectionManager.h delete mode 100644 rpc/cli/dsHdmiIn-com.cpp diff --git a/rpc/cli/dsConnectionManager.cpp b/rpc/cli/dsConnectionManager.cpp deleted file mode 100644 index df5170c9..00000000 --- a/rpc/cli/dsConnectionManager.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* - * 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. -*/ - -#ifdef USE_WPE_THUNDER_PLUGIN - -#include -#include -#include -#include "dsConnectionManager.h" - -using namespace WPEFramework; - -namespace DeviceSettingsClient { - -// Thunder callsign for DeviceSettings plugin -static constexpr const TCHAR callSign[] = _T("org.rdk.DeviceSettings"); - -// Static member initialization -ConnectionManager* ConnectionManager::_instance = nullptr; -Core::CriticalSection ConnectionManager::_dsConnectionManagerlock; - -ConnectionManager::ConnectionManager() - : BaseClass() - , _fpdInterface(nullptr) - , _hdmiInInterface(nullptr) - , _connected(false) - , _shutdown(false) -{ - printf("[dsConnectionManager] Initializing centralized connection manager\n"); - (void)Connect(); -} - -ConnectionManager::~ConnectionManager() -{ - printf("[dsConnectionManager] Destroying connection manager\n"); - _shutdown = true; - - // Release all component interfaces before closing base connection - if (_hdmiInInterface) { - _hdmiInInterface->Release(); - _hdmiInInterface = nullptr; - } - - if (_fpdInterface) { - _fpdInterface->Release(); - _fpdInterface = nullptr; - } - - BaseClass::Close(Core::infinite); -} - -void ConnectionManager::Operational(const bool upAndRunning) -{ - _dsConnectionManagerlock.Lock(); - - if (!_shutdown) { - printf("[dsConnectionManager] Operational callback: %s\n", upAndRunning ? "UP" : "DOWN"); - } - - if (upAndRunning) { - // Communicator opened && DeviceSettings is Activated - if (nullptr == _fpdInterface) { - printf("[dsConnectionManager] Plugin activated, acquiring primary FPD interface\n"); - _fpdInterface = BaseClass::Interface(); - - if (_fpdInterface != nullptr) { - printf("[dsConnectionManager] Successfully established COM-RPC connection with DeviceSettings plugin\n"); - - // Acquire secondary interfaces via QueryInterface - if (nullptr == _hdmiInInterface) { - _hdmiInInterface = _fpdInterface->QueryInterface(); - if (_hdmiInInterface != nullptr) { - printf("[dsConnectionManager] Successfully acquired HDMIIn interface via QueryInterface\n"); - } else { - fprintf(stderr, "[dsConnectionManager] Failed to acquire HDMIIn interface via QueryInterface\n"); - } - } - - // Add more component interfaces here as needed: - // if (nullptr == _compositeInInterface) { - // _compositeInInterface = _fpdInterface->QueryInterface(); - // } - - } else { - fprintf(stderr, "[dsConnectionManager] Failed to get FPD interface - plugin implementation may have failed to load\n"); - } - } - } else { - // DeviceSettings is Deactivated || Communicator closed - printf("[dsConnectionManager] Plugin deactivated, releasing all interfaces\n"); - - if (_hdmiInInterface != nullptr) { - _hdmiInInterface->Release(); - _hdmiInInterface = nullptr; - } - - if (_fpdInterface != nullptr) { - _fpdInterface->Release(); - _fpdInterface = nullptr; - } - } - - _dsConnectionManagerlock.Unlock(); -} - -void ConnectionManager::Init() -{ - _dsConnectionManagerlock.Lock(); - if (nullptr == _instance) { - _instance = new ConnectionManager(); - } - _dsConnectionManagerlock.Unlock(); -} - -void ConnectionManager::Term() -{ - _dsConnectionManagerlock.Lock(); - if (nullptr != _instance) { - delete _instance; - _instance = nullptr; - } - _dsConnectionManagerlock.Unlock(); -} - -ConnectionManager* ConnectionManager::Instance() -{ - return _instance; -} - -bool ConnectionManager::IsOperational() const -{ - _dsConnectionManagerlock.Lock(); - bool result = (isConnected() && (nullptr != _fpdInterface)); - _dsConnectionManagerlock.Unlock(); - return result; -} - -bool ConnectionManager::WaitForOperational(uint32_t timeoutMs) const -{ - const uint32_t pollIntervalMs = 100; - uint32_t elapsedMs = 0; - - while (elapsedMs < timeoutMs) { - if (IsOperational()) { - return true; - } - std::this_thread::sleep_for(std::chrono::milliseconds(pollIntervalMs)); - elapsedMs += pollIntervalMs; - } - return false; -} - -uint32_t ConnectionManager::Connect() -{ - uint32_t status = Core::ERROR_NONE; - - _dsConnectionManagerlock.Lock(); - - if (!isConnected()) { - printf("[dsConnectionManager] Attempting to connect to Thunder with callsign: %s\n", callSign); - uint32_t res = BaseClass::Open(RPC::CommunicationTimeOut, BaseClass::Connector(), callSign); - if (Core::ERROR_NONE == res) { - _connected = true; - printf("[dsConnectionManager] Successfully opened RPC connection to Thunder\n"); - } else { - fprintf(stderr, "[dsConnectionManager] Failed to open RPC connection, error: %u. Is Thunder running?\n", res); - status = Core::ERROR_UNAVAILABLE; - } - } else { - printf("[dsConnectionManager] Already connected\n"); - } - - if (nullptr == _fpdInterface) { - status = Core::ERROR_NOT_EXIST; - printf("[dsConnectionManager] DeviceSettings plugin not yet operational, waiting for Operational() callback\n"); - } - - _dsConnectionManagerlock.Unlock(); - - return status; -} - -uint32_t ConnectionManager::Disconnect() -{ - uint32_t status = Core::ERROR_GENERAL; - bool close = false; - - _dsConnectionManagerlock.Lock(); - - if (isConnected()) { - close = true; - _connected = false; - } - - _dsConnectionManagerlock.Unlock(); - - if (close) { - status = BaseClass::Close(Core::infinite); - printf("[dsConnectionManager] Disconnected from Thunder\n"); - } - - return status; -} - -Exchange::IDeviceSettingsFPD* ConnectionManager::GetFPDInterface() -{ - _dsConnectionManagerlock.Lock(); - Exchange::IDeviceSettingsFPD* interface = _fpdInterface; - _dsConnectionManagerlock.Unlock(); - return interface; -} - -Exchange::IDeviceSettingsHDMIIn* ConnectionManager::GetHDMIInInterface() -{ - _dsConnectionManagerlock.Lock(); - Exchange::IDeviceSettingsHDMIIn* interface = _hdmiInInterface; - _dsConnectionManagerlock.Unlock(); - return interface; -} - -} // namespace DeviceSettingsClient - -#endif // USE_WPE_THUNDER_PLUGIN diff --git a/rpc/cli/dsConnectionManager.h b/rpc/cli/dsConnectionManager.h deleted file mode 100644 index eed60bf4..00000000 --- a/rpc/cli/dsConnectionManager.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * 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 __DS_CONNECTION_MANAGER_H__ -#define __DS_CONNECTION_MANAGER_H__ - -#ifdef USE_WPE_THUNDER_PLUGIN - -#include -#include -#include -#include -#include - -namespace DeviceSettingsClient { - -/** - * @brief Centralized Connection Manager for DeviceSettings plugin - * - * This class manages a single Thunder COM-RPC connection to the DeviceSettings plugin - * and provides access to multiple component interfaces (FPD, HDMIIn, etc.) through - * QueryInterface pattern. - */ -class ConnectionManager : public WPEFramework::RPC::SmartInterfaceType { -private: - using BaseClass = WPEFramework::RPC::SmartInterfaceType; - - // Component interfaces obtained via QueryInterface - WPEFramework::Exchange::IDeviceSettingsFPD* _fpdInterface; - WPEFramework::Exchange::IDeviceSettingsHDMIIn* _hdmiInInterface; - // Add more component interfaces here as needed - // WPEFramework::Exchange::IDeviceSettingsCompositeIn* _compositeInInterface; - // WPEFramework::Exchange::IDeviceSettingsHost* _hostInterface; - - static ConnectionManager* _instance; - static WPEFramework::Core::CriticalSection _dsConnectionManagerlock; - - bool _connected; - bool _shutdown; - - // Private constructor for singleton - ConnectionManager(); - - // Private destructor - ~ConnectionManager(); - - // Operational callback from Thunder - virtual void Operational(const bool upAndRunning) override; - - inline bool isConnected() const { return _connected; } - inline bool IsActivatedLocked() const { return (nullptr != _fpdInterface); } - -public: - // Delete copy/move constructors and assignment operators - ConnectionManager(const ConnectionManager&) = delete; - ConnectionManager& operator=(const ConnectionManager&) = delete; - ConnectionManager(ConnectionManager&&) = delete; - ConnectionManager& operator=(ConnectionManager&&) = delete; - - /** - * @brief Initialize the connection manager singleton - */ - static void Init(); - - /** - * @brief Terminate the connection manager singleton - */ - static void Term(); - - /** - * @brief Get the singleton instance - */ - static ConnectionManager* Instance(); - - /** - * @brief Check if plugin is operational (connected and activated) - */ - bool IsOperational() const; - - /** - * @brief Wait for plugin to become operational with timeout - */ - bool WaitForOperational(uint32_t timeoutMs = 5000) const; - - /** - * @brief Connect to Thunder DeviceSettings plugin - */ - uint32_t Connect(); - - /** - * @brief Disconnect from Thunder DeviceSettings plugin - */ - uint32_t Disconnect(); - - /** - * @brief Get FPD interface pointer - * @return FPD interface or nullptr if not available - */ - WPEFramework::Exchange::IDeviceSettingsFPD* GetFPDInterface(); - - /** - * @brief Get HDMIIn interface pointer - * @return HDMIIn interface or nullptr if not available - */ - WPEFramework::Exchange::IDeviceSettingsHDMIIn* GetHDMIInInterface(); - - /** - * @brief Lock the API mutex for thread-safe operations - */ - static void Lock() { _dsConnectionManagerlock.Lock(); } - - /** - * @brief Unlock the API mutex - */ - static void Unlock() { _dsConnectionManagerlock.Unlock(); } -}; - -} // namespace DeviceSettingsClient - -#endif // USE_WPE_THUNDER_PLUGIN - -#endif // __DS_CONNECTION_MANAGER_H__ diff --git a/rpc/cli/dsFPD-com.cpp b/rpc/cli/dsFPD-com.cpp index 69b89f1a..53631e05 100644 --- a/rpc/cli/dsFPD-com.cpp +++ b/rpc/cli/dsFPD-com.cpp @@ -28,39 +28,390 @@ #include #include +#include +#include #include "dsFPD.h" #include "dsError.h" #include "dsclientlogger.h" -#include "dsConnectionManager.h" // Thunder COM-RPC includes #ifndef MODULE_NAME #define MODULE_NAME DeviceSettings_FPD_Client #endif +#include +#include +#include #include using namespace WPEFramework; -using namespace DeviceSettingsClient; + +// Thunder callsign for DeviceSettings plugin +static constexpr const TCHAR callSign[] = _T("org.rdk.DeviceSettings"); + +/** + * @brief DeviceSettingsFPD class manages Thunder COM-RPC connection for FPD + */ +class DeviceSettingsFPD : public RPC::SmartInterfaceType { +private: + using BaseClass = RPC::SmartInterfaceType; + + Exchange::IDeviceSettingsFPD* _fpdInterface; + + static DeviceSettingsFPD* _instance; + static Core::CriticalSection _apiLock; + + bool _connected; + bool _shutdown; + + DeviceSettingsFPD() + : BaseClass() + , _fpdInterface(nullptr) + , _connected(false) + , _shutdown(false) + { + (void)Connect(); + } + + ~DeviceSettingsFPD() + { + _shutdown = true; + BaseClass::Close(Core::infinite); + } + + virtual void Operational(const bool upAndRunning) override + { + _apiLock.Lock(); + + if (upAndRunning) { + // Communicator opened && DeviceSettings is Activated + if (nullptr == _fpdInterface) { + _fpdInterface = BaseClass::Interface(); + if (_fpdInterface != nullptr) { + printf("[dsFPD-com] Successfully established COM-RPC connection with DeviceSettings plugin\n"); + } else { + fprintf(stderr, "[dsFPD-com] Failed to get interface - plugin implementation may have failed to load\n"); + } + } + } else { + // DeviceSettings is Deactivated || Communicator closed + if (nullptr != _fpdInterface) { + _fpdInterface->Release(); + _fpdInterface = nullptr; + } + } + _apiLock.Unlock(); + } + + inline bool IsActivatedLocked() const + { + return (nullptr != _fpdInterface); + } + + inline bool isConnected() const + { + return _connected; + } + +public: + bool IsOperational() const + { + _apiLock.Lock(); + bool result = (isConnected() && (nullptr != _fpdInterface)); + _apiLock.Unlock(); + return result; + } + + bool WaitForOperational(uint32_t timeoutMs = 5000) const + { + const uint32_t pollIntervalMs = 100; + uint32_t elapsedMs = 0; + + while (elapsedMs < timeoutMs) { + if (IsOperational()) { + return true; + } + std::this_thread::sleep_for(std::chrono::milliseconds(pollIntervalMs)); + elapsedMs += pollIntervalMs; + } + return false; + } + + uint32_t Connect() + { + uint32_t status = Core::ERROR_NONE; + + _apiLock.Lock(); + + if (!isConnected()) { + printf("[dsFPD-com] Attempting to connect to Thunder with callsign: %s\n", callSign); + uint32_t res = BaseClass::Open(RPC::CommunicationTimeOut, BaseClass::Connector(), callSign); + if (Core::ERROR_NONE == res) { + _connected = true; + printf("[dsFPD-com] Successfully opened RPC connection to Thunder\n"); + } else { + fprintf(stderr, "[dsFPD-com] Failed to open RPC connection, error: %u. Is Thunder running?\n", res); + status = Core::ERROR_UNAVAILABLE; + } + } + + if (nullptr == _fpdInterface) { + status = Core::ERROR_NOT_EXIST; + printf("[dsFPD-com] DeviceSettings plugin not yet operational\n"); + } + + _apiLock.Unlock(); + + return status; + } + + uint32_t Disconnect() + { + uint32_t status = Core::ERROR_GENERAL; + bool close = false; + + _apiLock.Lock(); + + if (isConnected()) { + close = true; + _connected = false; + } + + _apiLock.Unlock(); + + if (close) { + status = BaseClass::Close(Core::infinite); + } + + return status; + } + + static void Init() + { + _apiLock.Lock(); + if (nullptr == _instance) { + _instance = new DeviceSettingsFPD(); + } + _apiLock.Unlock(); + } + + static void Term() + { + _apiLock.Lock(); + if (nullptr != _instance) { + delete _instance; + _instance = nullptr; + } + _apiLock.Unlock(); + } + + static DeviceSettingsFPD* Instance() + { + return _instance; + } + + // FPD API implementations + // Note: Thunder interface doesn't have FPDInit/FPDTerm/SetFPDText methods + + Core::hresult SetFPDTime(const Exchange::IDeviceSettingsFPD::FPDTimeFormat timeFormat, + const uint32_t minutes, const uint32_t seconds) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->SetFPDTime(timeFormat, minutes, seconds); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult SetFPDScroll(const uint32_t scrollHoldOnDur, const uint32_t horzScrollIterations, + const uint32_t vertScrollIterations) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->SetFPDScroll(scrollHoldOnDur, horzScrollIterations, vertScrollIterations); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult SetFPDBlink(const Exchange::IDeviceSettingsFPD::FPDIndicator indicator, + const uint32_t blinkDuration, const uint32_t blinkIterations) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->SetFPDBlink(indicator, blinkDuration, blinkIterations); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult GetFPDBrightness(const Exchange::IDeviceSettingsFPD::FPDIndicator indicator, + uint32_t& brightness) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->GetFPDBrightness(indicator, brightness); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult SetFPDBrightness(const Exchange::IDeviceSettingsFPD::FPDIndicator indicator, + const uint32_t brightness, const bool persist) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->SetFPDBrightness(indicator, brightness, persist); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult GetFPDTextBrightness(const Exchange::IDeviceSettingsFPD::FPDTextDisplay indicator, + uint32_t& brightness) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->GetFPDTextBrightness(indicator, brightness); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult SetFPDTextBrightness(const Exchange::IDeviceSettingsFPD::FPDTextDisplay indicator, + const uint32_t brightness) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->SetFPDTextBrightness(indicator, brightness); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult GetFPDColor(const Exchange::IDeviceSettingsFPD::FPDIndicator indicator, + uint32_t& color) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->GetFPDColor(indicator, color); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult SetFPDColor(const Exchange::IDeviceSettingsFPD::FPDIndicator indicator, + const uint32_t color) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->SetFPDColor(indicator, color); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult EnableFPDClockDisplay(const bool enable) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->EnableFPDClockDisplay(enable); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult SetFPDState(const Exchange::IDeviceSettingsFPD::FPDIndicator indicator, + const Exchange::IDeviceSettingsFPD::FPDState state) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->SetFPDState(indicator, state); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult GetFPDState(const Exchange::IDeviceSettingsFPD::FPDIndicator indicator, + Exchange::IDeviceSettingsFPD::FPDState& state) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->GetFPDState(indicator, state); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult GetFPDTimeFormat(Exchange::IDeviceSettingsFPD::FPDTimeFormat& timeFormat) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->GetFPDTimeFormat(timeFormat); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult SetFPDTimeFormat(const Exchange::IDeviceSettingsFPD::FPDTimeFormat timeFormat) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->SetFPDTimeFormat(timeFormat); + } + _apiLock.Unlock(); + return result; + } + + Core::hresult SetFPDMode(const Exchange::IDeviceSettingsFPD::FPDMode mode) + { + Core::hresult result = Core::ERROR_UNAVAILABLE; + _apiLock.Lock(); + if (_fpdInterface) { + result = _fpdInterface->SetFPDMode(mode); + } + _apiLock.Unlock(); + return result; + } +}; + +// Static member initialization +DeviceSettingsFPD* DeviceSettingsFPD::_instance = nullptr; +Core::CriticalSection DeviceSettingsFPD::_apiLock; /** * @brief Convert Thunder error code to dsError_t */ static dsError_t ConvertThunderError(uint32_t thunderError) { - if (thunderError == WPEFramework::Core::ERROR_NONE) { + if (thunderError == Core::ERROR_NONE) { return dsERR_NONE; - } else if (thunderError == WPEFramework::Core::ERROR_UNAVAILABLE) { + } else if (thunderError == Core::ERROR_UNAVAILABLE) { return dsERR_OPERATION_NOT_SUPPORTED; - } else if (thunderError == WPEFramework::Core::ERROR_BAD_REQUEST) { + } else if (thunderError == Core::ERROR_BAD_REQUEST) { return dsERR_INVALID_PARAM; } else { return dsERR_GENERAL; } } -// C API implementations using Thunder COM-RPC via ConnectionManager +// C API implementations using Thunder COM-RPC extern "C" { @@ -70,21 +421,21 @@ dsError_t dsSetFPDColor(dsFPDIndicator_t eIndicator, dsFPDColor_t eColor, bool t dsError_t dsFPInit(void) { - printf("<<<<< Front Panel is initialized in Thunder Mode (using ConnectionManager) >>>>>>>>\r\n"); + printf("<<<<< Front Panel is initialized in Thunder Mode >>>>>>>>\r\n"); - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr) { - ConnectionManager::Init(); - connMgr = ConnectionManager::Instance(); + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance) { + DeviceSettingsFPD::Init(); + instance = DeviceSettingsFPD::Instance(); } - if (!connMgr) { - fprintf(stderr, "[dsFPD-com] Failed to create ConnectionManager instance\n"); + if (!instance) { + fprintf(stderr, "[dsFPD-com] Failed to create DeviceSettingsFPD instance\n"); return dsERR_GENERAL; } // Wait for plugin to become operational - if (!connMgr->WaitForOperational(5000)) { + if (!instance->WaitForOperational(5000)) { fprintf(stderr, "[dsFPD-com] DeviceSettings plugin not operational after 5 seconds\n"); return dsERR_GENERAL; } @@ -95,8 +446,15 @@ dsError_t dsFPInit(void) dsError_t dsFPTerm(void) { - // Note: Don't terminate ConnectionManager here as other components may be using it - // ConnectionManager will be terminated by dsConnectionTerm() or at process exit + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance) { + return dsERR_GENERAL; + } + + // Thunder interface doesn't have explicit Term method + // Terminate instance + DeviceSettingsFPD::Term(); + return dsERR_NONE; } @@ -114,66 +472,42 @@ dsError_t dsSetFPText(const char* pszChars) dsError_t dsSetFPTime(dsFPDTimeFormat_t eTime, const unsigned int uHour, const unsigned int uMinutes) { - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); - if (!fpdInterface) { + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { return dsERR_GENERAL; } Exchange::IDeviceSettingsFPD::FPDTimeFormat timeFormat = static_cast(eTime); - ConnectionManager::Lock(); // Note: Interface expects minutes and seconds, but API provides hour and minutes // Converting: treating uMinutes as seconds for interface compatibility - uint32_t result = fpdInterface->SetFPDTime(timeFormat, uHour, uMinutes); - ConnectionManager::Unlock(); - + uint32_t result = instance->SetFPDTime(timeFormat, uHour, uMinutes); return ConvertThunderError(result); } dsError_t dsSetFPScroll(unsigned int nScrollHoldOnDur, unsigned int nHorzScrollIterations, unsigned int nVertScrollIterations) { - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); - if (!fpdInterface) { + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { return dsERR_GENERAL; } - ConnectionManager::Lock(); - uint32_t result = fpdInterface->SetFPDScroll(nScrollHoldOnDur, nHorzScrollIterations, nVertScrollIterations); - ConnectionManager::Unlock(); - + uint32_t result = instance->SetFPDScroll(nScrollHoldOnDur, nHorzScrollIterations, nVertScrollIterations); return ConvertThunderError(result); } dsError_t dsSetFPBlink(dsFPDIndicator_t eIndicator, unsigned int nBlinkDuration, unsigned int nBlinkIterations) { - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); - if (!fpdInterface) { + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { return dsERR_GENERAL; } Exchange::IDeviceSettingsFPD::FPDIndicator indicator = static_cast(eIndicator); - ConnectionManager::Lock(); - uint32_t result = fpdInterface->SetFPDBlink(indicator, nBlinkDuration, nBlinkIterations); - ConnectionManager::Unlock(); - + uint32_t result = instance->SetFPDBlink(indicator, nBlinkDuration, nBlinkIterations); return ConvertThunderError(result); } @@ -184,13 +518,8 @@ dsError_t dsGetFPBrightness(dsFPDIndicator_t eIndicator, dsFPDBrightness_t *pBri return dsERR_INVALID_PARAM; } - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); - if (!fpdInterface) { + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { return dsERR_GENERAL; } @@ -198,11 +527,9 @@ dsError_t dsGetFPBrightness(dsFPDIndicator_t eIndicator, dsFPDBrightness_t *pBri static_cast(eIndicator); uint32_t brightness = 0; - ConnectionManager::Lock(); - uint32_t result = fpdInterface->GetFPDBrightness(indicator, brightness); - ConnectionManager::Unlock(); + uint32_t result = instance->GetFPDBrightness(indicator, brightness); - if (result == WPEFramework::Core::ERROR_NONE) { + if (result == Core::ERROR_NONE) { *pBrightness = static_cast(brightness); } @@ -227,23 +554,15 @@ dsError_t dsSetFPDBrightness(dsFPDIndicator_t eIndicator, dsFPDBrightness_t eBri return dsERR_INVALID_PARAM; } - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); - if (!fpdInterface) { + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { return dsERR_GENERAL; } Exchange::IDeviceSettingsFPD::FPDIndicator indicator = static_cast(eIndicator); - ConnectionManager::Lock(); - uint32_t result = fpdInterface->SetFPDBrightness(indicator, static_cast(eBrightness), toPersist); - ConnectionManager::Unlock(); - + uint32_t result = instance->SetFPDBrightness(indicator, static_cast(eBrightness), toPersist); return ConvertThunderError(result); } @@ -254,13 +573,8 @@ dsError_t dsGetFPTextBrightness(dsFPDTextDisplay_t eIndicator, dsFPDBrightness_t return dsERR_INVALID_PARAM; } - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); - if (!fpdInterface) { + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { return dsERR_GENERAL; } @@ -268,11 +582,9 @@ dsError_t dsGetFPTextBrightness(dsFPDTextDisplay_t eIndicator, dsFPDBrightness_t static_cast(eIndicator); uint32_t brightness = 0; - ConnectionManager::Lock(); - uint32_t result = fpdInterface->GetFPDTextBrightness(indicator, brightness); - ConnectionManager::Unlock(); + uint32_t result = instance->GetFPDTextBrightness(indicator, brightness); - if (result == WPEFramework::Core::ERROR_NONE) { + if (result == Core::ERROR_NONE) { *pBrightness = static_cast(brightness); } @@ -281,23 +593,15 @@ dsError_t dsGetFPTextBrightness(dsFPDTextDisplay_t eIndicator, dsFPDBrightness_t dsError_t dsSetFPTextBrightness(dsFPDTextDisplay_t eIndicator, dsFPDBrightness_t eBrightness) { - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); - if (!fpdInterface) { + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { return dsERR_GENERAL; } Exchange::IDeviceSettingsFPD::FPDTextDisplay indicator = static_cast(eIndicator); - ConnectionManager::Lock(); - uint32_t result = fpdInterface->SetFPDTextBrightness(indicator, static_cast(eBrightness)); - ConnectionManager::Unlock(); - + uint32_t result = instance->SetFPDTextBrightness(indicator, static_cast(eBrightness)); return ConvertThunderError(result); } @@ -308,13 +612,8 @@ dsError_t dsGetFPColor(dsFPDIndicator_t eIndicator, dsFPDColor_t *pColor) return dsERR_INVALID_PARAM; } - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); - if (!fpdInterface) { + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { return dsERR_GENERAL; } @@ -322,11 +621,9 @@ dsError_t dsGetFPColor(dsFPDIndicator_t eIndicator, dsFPDColor_t *pColor) static_cast(eIndicator); uint32_t color = 0; - ConnectionManager::Lock(); - uint32_t result = fpdInterface->GetFPDColor(indicator, color); - ConnectionManager::Unlock(); + uint32_t result = instance->GetFPDColor(indicator, color); - if (result == WPEFramework::Core::ERROR_NONE) { + if (result == Core::ERROR_NONE) { *pColor = static_cast(color); } @@ -340,13 +637,8 @@ dsError_t dsSetFPColor(dsFPDIndicator_t eIndicator, dsFPDColor_t eColor) dsError_t dsSetFPDColor(dsFPDIndicator_t eIndicator, dsFPDColor_t eColor, bool toPersist) { - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); - if (!fpdInterface) { + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { return dsERR_GENERAL; } @@ -354,41 +646,25 @@ dsError_t dsSetFPDColor(dsFPDIndicator_t eIndicator, dsFPDColor_t eColor, bool t static_cast(eIndicator); // Thunder interface doesn't support persist flag - ignore it - ConnectionManager::Lock(); - uint32_t result = fpdInterface->SetFPDColor(indicator, static_cast(eColor)); - ConnectionManager::Unlock(); - + uint32_t result = instance->SetFPDColor(indicator, static_cast(eColor)); return ConvertThunderError(result); } dsError_t dsFPEnableCLockDisplay(int enable) { - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); - if (!fpdInterface) { + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { return dsERR_GENERAL; } - ConnectionManager::Lock(); - uint32_t result = fpdInterface->EnableFPDClockDisplay(enable != 0); - ConnectionManager::Unlock(); - + uint32_t result = instance->EnableFPDClockDisplay(enable != 0); return ConvertThunderError(result); } dsError_t dsSetFPState(dsFPDIndicator_t eIndicator, dsFPDState_t state) { - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); - if (!fpdInterface) { + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { return dsERR_GENERAL; } @@ -397,10 +673,7 @@ dsError_t dsSetFPState(dsFPDIndicator_t eIndicator, dsFPDState_t state) Exchange::IDeviceSettingsFPD::FPDState fpdState = static_cast(state); - ConnectionManager::Lock(); - uint32_t result = fpdInterface->SetFPDState(indicator, fpdState); - ConnectionManager::Unlock(); - + uint32_t result = instance->SetFPDState(indicator, fpdState); return ConvertThunderError(result); } @@ -411,13 +684,8 @@ dsError_t dsGetFPState(dsFPDIndicator_t eIndicator, dsFPDState_t* state) return dsERR_INVALID_PARAM; } - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); - if (!fpdInterface) { + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { return dsERR_GENERAL; } @@ -425,11 +693,9 @@ dsError_t dsGetFPState(dsFPDIndicator_t eIndicator, dsFPDState_t* state) static_cast(eIndicator); Exchange::IDeviceSettingsFPD::FPDState fpdState; - ConnectionManager::Lock(); - uint32_t result = fpdInterface->GetFPDState(indicator, fpdState); - ConnectionManager::Unlock(); + uint32_t result = instance->GetFPDState(indicator, fpdState); - if (result == WPEFramework::Core::ERROR_NONE) { + if (result == Core::ERROR_NONE) { *state = static_cast(fpdState); } @@ -443,22 +709,15 @@ dsError_t dsGetFPTimeFormat(dsFPDTimeFormat_t *pTimeFormat) return dsERR_INVALID_PARAM; } - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); - if (!fpdInterface) { + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { return dsERR_GENERAL; } Exchange::IDeviceSettingsFPD::FPDTimeFormat timeFormat; - ConnectionManager::Lock(); - uint32_t result = fpdInterface->GetFPDTimeFormat(timeFormat); - ConnectionManager::Unlock(); + uint32_t result = instance->GetFPDTimeFormat(timeFormat); - if (result == WPEFramework::Core::ERROR_NONE) { + if (result == Core::ERROR_NONE) { *pTimeFormat = static_cast(timeFormat); } @@ -467,45 +726,29 @@ dsError_t dsGetFPTimeFormat(dsFPDTimeFormat_t *pTimeFormat) dsError_t dsSetFPTimeFormat(dsFPDTimeFormat_t eTimeFormat) { - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); - if (!fpdInterface) { + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { return dsERR_GENERAL; } Exchange::IDeviceSettingsFPD::FPDTimeFormat timeFormat = static_cast(eTimeFormat); - ConnectionManager::Lock(); - uint32_t result = fpdInterface->SetFPDTimeFormat(timeFormat); - ConnectionManager::Unlock(); - + uint32_t result = instance->SetFPDTimeFormat(timeFormat); return ConvertThunderError(result); } dsError_t dsSetFPDMode(dsFPDMode_t eMode) { - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); - if (!fpdInterface) { + DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); + if (!instance || !instance->IsOperational()) { return dsERR_GENERAL; } Exchange::IDeviceSettingsFPD::FPDMode mode = static_cast(eMode); - ConnectionManager::Lock(); - uint32_t result = fpdInterface->SetFPDMode(mode); - ConnectionManager::Unlock(); - + uint32_t result = instance->SetFPDMode(mode); return ConvertThunderError(result); } diff --git a/rpc/cli/dsHdmiIn-com.cpp b/rpc/cli/dsHdmiIn-com.cpp deleted file mode 100644 index 8a28acbc..00000000 --- a/rpc/cli/dsHdmiIn-com.cpp +++ /dev/null @@ -1,651 +0,0 @@ -/* - * 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. -*/ - -/** -* @defgroup devicesettings -* @{ -* @defgroup rpc -* @{ -**/ - -#ifdef USE_WPE_THUNDER_PLUGIN - -#include -#include - -#include "dsHdmiIn.h" -#include "dsError.h" -#include "dsclientlogger.h" -#include "dsConnectionManager.h" - -// Thunder COM-RPC includes -#ifndef MODULE_NAME -#define MODULE_NAME DeviceSettings_HDMIIn_Client -#endif - -#include - -using namespace WPEFramework; -using namespace DeviceSettingsClient; - -/** - * @brief Convert Thunder error code to dsError_t - */ -static dsError_t ConvertThunderError(uint32_t thunderError) -{ - if (thunderError == WPEFramework::Core::ERROR_NONE) { - return dsERR_NONE; - } else if (thunderError == WPEFramework::Core::ERROR_UNAVAILABLE) { - return dsERR_OPERATION_NOT_SUPPORTED; - } else if (thunderError == WPEFramework::Core::ERROR_BAD_REQUEST) { - return dsERR_INVALID_PARAM; - } else { - return dsERR_GENERAL; - } -} - -// C API implementations using Thunder COM-RPC via ConnectionManager - -extern "C" { - -dsError_t dsHdmiInInit(void) -{ - printf("<<<<< HDMI In is initialized in Thunder Mode (using ConnectionManager) >>>>>>>>\r\n"); - - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr) { - ConnectionManager::Init(); - connMgr = ConnectionManager::Instance(); - } - - if (!connMgr) { - fprintf(stderr, "[dsHdmiIn-com] Failed to create ConnectionManager instance\n"); - return dsERR_GENERAL; - } - - // Wait for plugin to become operational - if (!connMgr->WaitForOperational(5000)) { - fprintf(stderr, "[dsHdmiIn-com] DeviceSettings plugin not operational after 5 seconds\n"); - return dsERR_GENERAL; - } - - return dsERR_NONE; -} - -dsError_t dsHdmiInTerm(void) -{ - // Note: Don't terminate ConnectionManager here as other components may be using it - // ConnectionManager will be terminated by dsConnectionTerm() or at process exit - return dsERR_NONE; -} - -dsError_t dsHdmiInGetNumberOfInputs(uint8_t* pNumberOfInputs) -{ - if (pNumberOfInputs == NULL) { - fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: pNumberOfInputs is NULL\n"); - return dsERR_INVALID_PARAM; - } - - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); - if (!hdmiInInterface) { - return dsERR_GENERAL; - } - - int32_t count = 0; - ConnectionManager::Lock(); - uint32_t result = hdmiInInterface->GetHDMIInNumbefOfInputs(count); - ConnectionManager::Unlock(); - - if (result == WPEFramework::Core::ERROR_NONE) { - *pNumberOfInputs = static_cast(count); - } - - return ConvertThunderError(result); -} - -dsError_t dsHdmiInGetStatus(dsHdmiInStatus_t* pStatus) -{ - if (pStatus == NULL) { - fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: pStatus is NULL\n"); - return dsERR_INVALID_PARAM; - } - - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); - if (!hdmiInInterface) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn::HDMIInStatus hdmiStatus; - Exchange::IDeviceSettingsHDMIIn::IHDMIInPortConnectionStatusIterator* portConnectionStatus = nullptr; - - ConnectionManager::Lock(); - uint32_t result = hdmiInInterface->GetHDMIInStatus(hdmiStatus, portConnectionStatus); - ConnectionManager::Unlock(); - - if (result == WPEFramework::Core::ERROR_NONE) { - pStatus->isPresented = hdmiStatus.isPresented; - pStatus->activePort = static_cast(hdmiStatus.activePort); - - // TODO: Handle portConnectionStatus iterator if needed - if (portConnectionStatus) { - portConnectionStatus->Release(); - } - } - - return ConvertThunderError(result); -} - -dsError_t dsHdmiInSelectPort(dsHdmiInPort_t ePort, bool audioMix, dsVideoPlaneType_t videoPlaneType, bool topMost) -{ - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); - if (!hdmiInInterface) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = - static_cast(ePort); - Exchange::IDeviceSettingsHDMIIn::HDMIVideoPlaneType planeType = - static_cast(videoPlaneType); - - ConnectionManager::Lock(); - uint32_t result = hdmiInInterface->SelectHDMIInPort(port, audioMix, topMost, planeType); - ConnectionManager::Unlock(); - - return ConvertThunderError(result); -} - -dsError_t dsHdmiInScaleVideo(int32_t x, int32_t y, int32_t width, int32_t height) -{ - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); - if (!hdmiInInterface) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn::HDMIInVideoRectangle videoPosition; - videoPosition.x = x; - videoPosition.y = y; - videoPosition.width = width; - videoPosition.height = height; - - ConnectionManager::Lock(); - uint32_t result = hdmiInInterface->ScaleHDMIInVideo(videoPosition); - ConnectionManager::Unlock(); - - return ConvertThunderError(result); -} - -dsError_t dsHdmiInSelectZoomMode(dsVideoZoom_t zoomMode) -{ - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); - if (!hdmiInInterface) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn::HDMIInVideoZoom zoom = - static_cast(zoomMode); - - ConnectionManager::Lock(); - uint32_t result = hdmiInInterface->SelectHDMIZoomMode(zoom); - ConnectionManager::Unlock(); - - return ConvertThunderError(result); -} - -dsError_t dsHdmiInGetCurrentVideoMode(dsVideoPortResolution_t* resolution) -{ - if (resolution == NULL) { - fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: resolution is NULL\n"); - return dsERR_INVALID_PARAM; - } - - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); - if (!hdmiInInterface) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn::HDMIVideoPortResolution videoPortResolution; - ConnectionManager::Lock(); - uint32_t result = hdmiInInterface->GetHDMIVideoMode(videoPortResolution); - ConnectionManager::Unlock(); - - if (result == WPEFramework::Core::ERROR_NONE) { - strncpy(resolution->name, videoPortResolution.name.c_str(), sizeof(resolution->name) - 1); - resolution->name[sizeof(resolution->name) - 1] = '\0'; - resolution->pixelResolution = static_cast(videoPortResolution.pixelResolution); - resolution->aspectRatio = static_cast(videoPortResolution.aspectRatio); - resolution->stereoScopicMode = static_cast(videoPortResolution.stereoScopicMode); - resolution->frameRate = static_cast(videoPortResolution.frameRate); - resolution->interlaced = videoPortResolution.interlaced; - } - - return ConvertThunderError(result); -} - -dsError_t dsGetEDIDBytesInfo(int iHdmiPort, unsigned char* edid, int* length) -{ - if (edid == NULL || length == NULL) { - fprintf(stderr, "[dsHdmiIn-com] Invalid parameter\n"); - return dsERR_INVALID_PARAM; - } - - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); - if (!hdmiInInterface) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = - static_cast(iHdmiPort); - - ConnectionManager::Lock(); - uint32_t result = hdmiInInterface->GetEdidBytes(port, static_cast(*length), edid); - ConnectionManager::Unlock(); - - return ConvertThunderError(result); -} - -dsError_t dsGetHDMISPDInfo(int iHdmiPort, unsigned char* data) -{ - if (data == NULL) { - fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: data is NULL\n"); - return dsERR_INVALID_PARAM; - } - - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); - if (!hdmiInInterface) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = - static_cast(iHdmiPort); - - // Assuming SPD info frame size (adjust as needed) - const uint16_t spdBytesLength = 32; - ConnectionManager::Lock(); - uint32_t result = hdmiInInterface->GetHDMISPDInformation(port, spdBytesLength, data); - ConnectionManager::Unlock(); - - return ConvertThunderError(result); -} - -dsError_t dsGetEdidVersion(int iHdmiPort, int* edidVersion) -{ - if (edidVersion == NULL) { - fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: edidVersion is NULL\n"); - return dsERR_INVALID_PARAM; - } - - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); - if (!hdmiInInterface) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = - static_cast(iHdmiPort); - Exchange::IDeviceSettingsHDMIIn::HDMIInEdidVersion version; - - ConnectionManager::Lock(); - uint32_t result = hdmiInInterface->GetHDMIEdidVersion(port, version); - ConnectionManager::Unlock(); - - if (result == WPEFramework::Core::ERROR_NONE) { - *edidVersion = static_cast(version); - } - - return ConvertThunderError(result); -} - -dsError_t dsSetEdidVersion(int iHdmiPort, int edidVersion) -{ - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); - if (!hdmiInInterface) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = - static_cast(iHdmiPort); - Exchange::IDeviceSettingsHDMIIn::HDMIInEdidVersion version = - static_cast(edidVersion); - - ConnectionManager::Lock(); - uint32_t result = hdmiInInterface->SetHDMIEdidVersion(port, version); - ConnectionManager::Unlock(); - - return ConvertThunderError(result); -} - -dsError_t dsGetAllmStatus(dsHdmiInPort_t iHdmiPort, bool* allmStatus) -{ - if (allmStatus == NULL) { - fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: allmStatus is NULL\n"); - return dsERR_INVALID_PARAM; - } - - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); - if (!hdmiInInterface) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = - static_cast(iHdmiPort); - - ConnectionManager::Lock(); - uint32_t result = hdmiInInterface->GetHDMIInAllmStatus(port, *allmStatus); - ConnectionManager::Unlock(); - - return ConvertThunderError(result); -} - -dsError_t dsGetEdid2AllmSupport(dsHdmiInPort_t iHdmiPort, bool* allmSupport) -{ - if (allmSupport == NULL) { - fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: allmSupport is NULL\n"); - return dsERR_INVALID_PARAM; - } - - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); - if (!hdmiInInterface) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = - static_cast(iHdmiPort); - - ConnectionManager::Lock(); - uint32_t result = hdmiInInterface->GetHDMIInEdid2AllmSupport(port, *allmSupport); - ConnectionManager::Unlock(); - - return ConvertThunderError(result); -} - -dsError_t dsSetEdid2AllmSupport(dsHdmiInPort_t iHdmiPort, bool allmSupport) -{ - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); - if (!hdmiInInterface) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = - static_cast(iHdmiPort); - - ConnectionManager::Lock(); - uint32_t result = hdmiInInterface->SetHDMIInEdid2AllmSupport(port, allmSupport); - ConnectionManager::Unlock(); - - return ConvertThunderError(result); -} - -dsError_t dsGetAVLatency(int* audio_latency, int* video_latency) -{ - if (audio_latency == NULL || video_latency == NULL) { - fprintf(stderr, "[dsHdmiIn-com] Invalid parameter\n"); - return dsERR_INVALID_PARAM; - } - - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); - if (!hdmiInInterface) { - return dsERR_GENERAL; - } - - uint32_t videoLatency = 0; - uint32_t audioLatency = 0; - ConnectionManager::Lock(); - uint32_t result = hdmiInInterface->GetHDMIInAVLatency(videoLatency, audioLatency); - ConnectionManager::Unlock(); - - if (result == WPEFramework::Core::ERROR_NONE) { - *audio_latency = static_cast(audioLatency); - *video_latency = static_cast(videoLatency); - } - - return ConvertThunderError(result); -} - -dsError_t dsGetHdmiVersion(dsHdmiInPort_t iHdmiPort, dsHdmiVersion_t* capversion) -{ - if (capversion == NULL) { - fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: capversion is NULL\n"); - return dsERR_INVALID_PARAM; - } - - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); - if (!hdmiInInterface) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = - static_cast(iHdmiPort); - Exchange::IDeviceSettingsHDMIIn::HDMIInCapabilityVersion capabilityVersion; - - ConnectionManager::Lock(); - uint32_t result = hdmiInInterface->GetHDMIVersion(port, capabilityVersion); - ConnectionManager::Unlock(); - - if (result == WPEFramework::Core::ERROR_NONE) { - *capversion = static_cast(capabilityVersion); - } - - return ConvertThunderError(result); -} - -dsError_t dsSetVRRSupport(dsHdmiInPort_t iHdmiPort, bool vrrSupport) -{ - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); - if (!hdmiInInterface) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = - static_cast(iHdmiPort); - - ConnectionManager::Lock(); - uint32_t result = hdmiInInterface->SetVRRSupport(port, vrrSupport); - ConnectionManager::Unlock(); - - return ConvertThunderError(result); -} - -dsError_t dsGetVRRSupport(dsHdmiInPort_t iHdmiPort, bool* vrrSupport) -{ - if (vrrSupport == NULL) { - fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: vrrSupport is NULL\n"); - return dsERR_INVALID_PARAM; - } - - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); - if (!hdmiInInterface) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = - static_cast(iHdmiPort); - - ConnectionManager::Lock(); - uint32_t result = hdmiInInterface->GetVRRSupport(port, *vrrSupport); - ConnectionManager::Unlock(); - - return ConvertThunderError(result); -} - -dsError_t dsHdmiInGetVRRStatus(dsHdmiInPort_t iHdmiPort, dsHdmiInVrrStatus_t* vrrStatus) -{ - if (vrrStatus == NULL) { - fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: vrrStatus is NULL\n"); - return dsERR_INVALID_PARAM; - } - - ConnectionManager* connMgr = ConnectionManager::Instance(); - if (!connMgr || !connMgr->IsOperational()) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); - if (!hdmiInInterface) { - return dsERR_GENERAL; - } - - Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = - static_cast(iHdmiPort); - Exchange::IDeviceSettingsHDMIIn::HDMIInVRRStatus status; - - ConnectionManager::Lock(); - uint32_t result = hdmiInInterface->GetVRRStatus(port, status); - ConnectionManager::Unlock(); - - if (result == WPEFramework::Core::ERROR_NONE) { - vrrStatus->vrrType = static_cast(status.vrrType); - vrrStatus->vrrFreeSyncFramerateHz = status.vrrFreeSyncFramerateHz; - } - - return ConvertThunderError(result); -} - -// Placeholder for unsupported APIs in Thunder mode -dsError_t dsHdmiInRegisterConnectCB(dsHdmiInConnectCB_t CBFunc) -{ - fprintf(stderr, "[dsHdmiIn-com] dsHdmiInRegisterConnectCB not supported in Thunder mode\n"); - return dsERR_OPERATION_NOT_SUPPORTED; -} - -dsError_t dsHdmiInRegisterSignalChangeCB(dsHdmiInSignalChangeCB_t CBFunc) -{ - fprintf(stderr, "[dsHdmiIn-com] dsHdmiInRegisterSignalChangeCB not supported in Thunder mode\n"); - return dsERR_OPERATION_NOT_SUPPORTED; -} - -dsError_t dsHdmiInRegisterStatusChangeCB(dsHdmiInStatusChangeCB_t CBFunc) -{ - fprintf(stderr, "[dsHdmiIn-com] dsHdmiInRegisterStatusChangeCB not supported in Thunder mode\n"); - return dsERR_OPERATION_NOT_SUPPORTED; -} - -dsError_t dsHdmiInRegisterVideoModeUpdateCB(dsHdmiInVideoModeUpdateCB_t CBFunc) -{ - fprintf(stderr, "[dsHdmiIn-com] dsHdmiInRegisterVideoModeUpdateCB not supported in Thunder mode\n"); - return dsERR_OPERATION_NOT_SUPPORTED; -} - -dsError_t dsHdmiInRegisterAllmChangeCB(dsHdmiInAllmChangeCB_t CBFunc) -{ - fprintf(stderr, "[dsHdmiIn-com] dsHdmiInRegisterAllmChangeCB not supported in Thunder mode\n"); - return dsERR_OPERATION_NOT_SUPPORTED; -} - -dsError_t dsHdmiInRegisterAVLatencyChangeCB(dsAVLatencyChangeCB_t CBFunc) -{ - fprintf(stderr, "[dsHdmiIn-com] dsHdmiInRegisterAVLatencyChangeCB not supported in Thunder mode\n"); - return dsERR_OPERATION_NOT_SUPPORTED; -} - -dsError_t dsHdmiInRegisterAviContentTypeChangeCB(dsAviContentTypeChangeCB_t CBFunc) -{ - fprintf(stderr, "[dsHdmiIn-com] dsHdmiInRegisterAviContentTypeChangeCB not supported in Thunder mode\n"); - return dsERR_OPERATION_NOT_SUPPORTED; -} - -} // extern "C" - -#endif // USE_WPE_THUNDER_PLUGIN - -/** @} */ -/** @} */ From 69ef6ab3271688e1c1d0d3f3efe921b03ac65f24 Mon Sep 17 00:00:00 2001 From: Manimaran Renganathan Date: Thu, 5 Feb 2026 09:58:44 +0000 Subject: [PATCH 13/16] Revert "Revert "Modified the code"" This reverts commit 59ccd0850cd8fe54988f9688137207602f0cdff8. --- rpc/cli/dsConnectionManager.cpp | 239 ++++++++++++ rpc/cli/dsConnectionManager.h | 138 +++++++ rpc/cli/dsFPD-com.cpp | 605 +++++++++-------------------- rpc/cli/dsHdmiIn-com.cpp | 651 ++++++++++++++++++++++++++++++++ 4 files changed, 1209 insertions(+), 424 deletions(-) create mode 100644 rpc/cli/dsConnectionManager.cpp create mode 100644 rpc/cli/dsConnectionManager.h create mode 100644 rpc/cli/dsHdmiIn-com.cpp diff --git a/rpc/cli/dsConnectionManager.cpp b/rpc/cli/dsConnectionManager.cpp new file mode 100644 index 00000000..df5170c9 --- /dev/null +++ b/rpc/cli/dsConnectionManager.cpp @@ -0,0 +1,239 @@ +/* + * 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. +*/ + +#ifdef USE_WPE_THUNDER_PLUGIN + +#include +#include +#include +#include "dsConnectionManager.h" + +using namespace WPEFramework; + +namespace DeviceSettingsClient { + +// Thunder callsign for DeviceSettings plugin +static constexpr const TCHAR callSign[] = _T("org.rdk.DeviceSettings"); + +// Static member initialization +ConnectionManager* ConnectionManager::_instance = nullptr; +Core::CriticalSection ConnectionManager::_dsConnectionManagerlock; + +ConnectionManager::ConnectionManager() + : BaseClass() + , _fpdInterface(nullptr) + , _hdmiInInterface(nullptr) + , _connected(false) + , _shutdown(false) +{ + printf("[dsConnectionManager] Initializing centralized connection manager\n"); + (void)Connect(); +} + +ConnectionManager::~ConnectionManager() +{ + printf("[dsConnectionManager] Destroying connection manager\n"); + _shutdown = true; + + // Release all component interfaces before closing base connection + if (_hdmiInInterface) { + _hdmiInInterface->Release(); + _hdmiInInterface = nullptr; + } + + if (_fpdInterface) { + _fpdInterface->Release(); + _fpdInterface = nullptr; + } + + BaseClass::Close(Core::infinite); +} + +void ConnectionManager::Operational(const bool upAndRunning) +{ + _dsConnectionManagerlock.Lock(); + + if (!_shutdown) { + printf("[dsConnectionManager] Operational callback: %s\n", upAndRunning ? "UP" : "DOWN"); + } + + if (upAndRunning) { + // Communicator opened && DeviceSettings is Activated + if (nullptr == _fpdInterface) { + printf("[dsConnectionManager] Plugin activated, acquiring primary FPD interface\n"); + _fpdInterface = BaseClass::Interface(); + + if (_fpdInterface != nullptr) { + printf("[dsConnectionManager] Successfully established COM-RPC connection with DeviceSettings plugin\n"); + + // Acquire secondary interfaces via QueryInterface + if (nullptr == _hdmiInInterface) { + _hdmiInInterface = _fpdInterface->QueryInterface(); + if (_hdmiInInterface != nullptr) { + printf("[dsConnectionManager] Successfully acquired HDMIIn interface via QueryInterface\n"); + } else { + fprintf(stderr, "[dsConnectionManager] Failed to acquire HDMIIn interface via QueryInterface\n"); + } + } + + // Add more component interfaces here as needed: + // if (nullptr == _compositeInInterface) { + // _compositeInInterface = _fpdInterface->QueryInterface(); + // } + + } else { + fprintf(stderr, "[dsConnectionManager] Failed to get FPD interface - plugin implementation may have failed to load\n"); + } + } + } else { + // DeviceSettings is Deactivated || Communicator closed + printf("[dsConnectionManager] Plugin deactivated, releasing all interfaces\n"); + + if (_hdmiInInterface != nullptr) { + _hdmiInInterface->Release(); + _hdmiInInterface = nullptr; + } + + if (_fpdInterface != nullptr) { + _fpdInterface->Release(); + _fpdInterface = nullptr; + } + } + + _dsConnectionManagerlock.Unlock(); +} + +void ConnectionManager::Init() +{ + _dsConnectionManagerlock.Lock(); + if (nullptr == _instance) { + _instance = new ConnectionManager(); + } + _dsConnectionManagerlock.Unlock(); +} + +void ConnectionManager::Term() +{ + _dsConnectionManagerlock.Lock(); + if (nullptr != _instance) { + delete _instance; + _instance = nullptr; + } + _dsConnectionManagerlock.Unlock(); +} + +ConnectionManager* ConnectionManager::Instance() +{ + return _instance; +} + +bool ConnectionManager::IsOperational() const +{ + _dsConnectionManagerlock.Lock(); + bool result = (isConnected() && (nullptr != _fpdInterface)); + _dsConnectionManagerlock.Unlock(); + return result; +} + +bool ConnectionManager::WaitForOperational(uint32_t timeoutMs) const +{ + const uint32_t pollIntervalMs = 100; + uint32_t elapsedMs = 0; + + while (elapsedMs < timeoutMs) { + if (IsOperational()) { + return true; + } + std::this_thread::sleep_for(std::chrono::milliseconds(pollIntervalMs)); + elapsedMs += pollIntervalMs; + } + return false; +} + +uint32_t ConnectionManager::Connect() +{ + uint32_t status = Core::ERROR_NONE; + + _dsConnectionManagerlock.Lock(); + + if (!isConnected()) { + printf("[dsConnectionManager] Attempting to connect to Thunder with callsign: %s\n", callSign); + uint32_t res = BaseClass::Open(RPC::CommunicationTimeOut, BaseClass::Connector(), callSign); + if (Core::ERROR_NONE == res) { + _connected = true; + printf("[dsConnectionManager] Successfully opened RPC connection to Thunder\n"); + } else { + fprintf(stderr, "[dsConnectionManager] Failed to open RPC connection, error: %u. Is Thunder running?\n", res); + status = Core::ERROR_UNAVAILABLE; + } + } else { + printf("[dsConnectionManager] Already connected\n"); + } + + if (nullptr == _fpdInterface) { + status = Core::ERROR_NOT_EXIST; + printf("[dsConnectionManager] DeviceSettings plugin not yet operational, waiting for Operational() callback\n"); + } + + _dsConnectionManagerlock.Unlock(); + + return status; +} + +uint32_t ConnectionManager::Disconnect() +{ + uint32_t status = Core::ERROR_GENERAL; + bool close = false; + + _dsConnectionManagerlock.Lock(); + + if (isConnected()) { + close = true; + _connected = false; + } + + _dsConnectionManagerlock.Unlock(); + + if (close) { + status = BaseClass::Close(Core::infinite); + printf("[dsConnectionManager] Disconnected from Thunder\n"); + } + + return status; +} + +Exchange::IDeviceSettingsFPD* ConnectionManager::GetFPDInterface() +{ + _dsConnectionManagerlock.Lock(); + Exchange::IDeviceSettingsFPD* interface = _fpdInterface; + _dsConnectionManagerlock.Unlock(); + return interface; +} + +Exchange::IDeviceSettingsHDMIIn* ConnectionManager::GetHDMIInInterface() +{ + _dsConnectionManagerlock.Lock(); + Exchange::IDeviceSettingsHDMIIn* interface = _hdmiInInterface; + _dsConnectionManagerlock.Unlock(); + return interface; +} + +} // namespace DeviceSettingsClient + +#endif // USE_WPE_THUNDER_PLUGIN diff --git a/rpc/cli/dsConnectionManager.h b/rpc/cli/dsConnectionManager.h new file mode 100644 index 00000000..eed60bf4 --- /dev/null +++ b/rpc/cli/dsConnectionManager.h @@ -0,0 +1,138 @@ +/* + * 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 __DS_CONNECTION_MANAGER_H__ +#define __DS_CONNECTION_MANAGER_H__ + +#ifdef USE_WPE_THUNDER_PLUGIN + +#include +#include +#include +#include +#include + +namespace DeviceSettingsClient { + +/** + * @brief Centralized Connection Manager for DeviceSettings plugin + * + * This class manages a single Thunder COM-RPC connection to the DeviceSettings plugin + * and provides access to multiple component interfaces (FPD, HDMIIn, etc.) through + * QueryInterface pattern. + */ +class ConnectionManager : public WPEFramework::RPC::SmartInterfaceType { +private: + using BaseClass = WPEFramework::RPC::SmartInterfaceType; + + // Component interfaces obtained via QueryInterface + WPEFramework::Exchange::IDeviceSettingsFPD* _fpdInterface; + WPEFramework::Exchange::IDeviceSettingsHDMIIn* _hdmiInInterface; + // Add more component interfaces here as needed + // WPEFramework::Exchange::IDeviceSettingsCompositeIn* _compositeInInterface; + // WPEFramework::Exchange::IDeviceSettingsHost* _hostInterface; + + static ConnectionManager* _instance; + static WPEFramework::Core::CriticalSection _dsConnectionManagerlock; + + bool _connected; + bool _shutdown; + + // Private constructor for singleton + ConnectionManager(); + + // Private destructor + ~ConnectionManager(); + + // Operational callback from Thunder + virtual void Operational(const bool upAndRunning) override; + + inline bool isConnected() const { return _connected; } + inline bool IsActivatedLocked() const { return (nullptr != _fpdInterface); } + +public: + // Delete copy/move constructors and assignment operators + ConnectionManager(const ConnectionManager&) = delete; + ConnectionManager& operator=(const ConnectionManager&) = delete; + ConnectionManager(ConnectionManager&&) = delete; + ConnectionManager& operator=(ConnectionManager&&) = delete; + + /** + * @brief Initialize the connection manager singleton + */ + static void Init(); + + /** + * @brief Terminate the connection manager singleton + */ + static void Term(); + + /** + * @brief Get the singleton instance + */ + static ConnectionManager* Instance(); + + /** + * @brief Check if plugin is operational (connected and activated) + */ + bool IsOperational() const; + + /** + * @brief Wait for plugin to become operational with timeout + */ + bool WaitForOperational(uint32_t timeoutMs = 5000) const; + + /** + * @brief Connect to Thunder DeviceSettings plugin + */ + uint32_t Connect(); + + /** + * @brief Disconnect from Thunder DeviceSettings plugin + */ + uint32_t Disconnect(); + + /** + * @brief Get FPD interface pointer + * @return FPD interface or nullptr if not available + */ + WPEFramework::Exchange::IDeviceSettingsFPD* GetFPDInterface(); + + /** + * @brief Get HDMIIn interface pointer + * @return HDMIIn interface or nullptr if not available + */ + WPEFramework::Exchange::IDeviceSettingsHDMIIn* GetHDMIInInterface(); + + /** + * @brief Lock the API mutex for thread-safe operations + */ + static void Lock() { _dsConnectionManagerlock.Lock(); } + + /** + * @brief Unlock the API mutex + */ + static void Unlock() { _dsConnectionManagerlock.Unlock(); } +}; + +} // namespace DeviceSettingsClient + +#endif // USE_WPE_THUNDER_PLUGIN + +#endif // __DS_CONNECTION_MANAGER_H__ diff --git a/rpc/cli/dsFPD-com.cpp b/rpc/cli/dsFPD-com.cpp index 53631e05..69b89f1a 100644 --- a/rpc/cli/dsFPD-com.cpp +++ b/rpc/cli/dsFPD-com.cpp @@ -28,390 +28,39 @@ #include #include -#include -#include #include "dsFPD.h" #include "dsError.h" #include "dsclientlogger.h" +#include "dsConnectionManager.h" // Thunder COM-RPC includes #ifndef MODULE_NAME #define MODULE_NAME DeviceSettings_FPD_Client #endif -#include -#include -#include #include using namespace WPEFramework; - -// Thunder callsign for DeviceSettings plugin -static constexpr const TCHAR callSign[] = _T("org.rdk.DeviceSettings"); - -/** - * @brief DeviceSettingsFPD class manages Thunder COM-RPC connection for FPD - */ -class DeviceSettingsFPD : public RPC::SmartInterfaceType { -private: - using BaseClass = RPC::SmartInterfaceType; - - Exchange::IDeviceSettingsFPD* _fpdInterface; - - static DeviceSettingsFPD* _instance; - static Core::CriticalSection _apiLock; - - bool _connected; - bool _shutdown; - - DeviceSettingsFPD() - : BaseClass() - , _fpdInterface(nullptr) - , _connected(false) - , _shutdown(false) - { - (void)Connect(); - } - - ~DeviceSettingsFPD() - { - _shutdown = true; - BaseClass::Close(Core::infinite); - } - - virtual void Operational(const bool upAndRunning) override - { - _apiLock.Lock(); - - if (upAndRunning) { - // Communicator opened && DeviceSettings is Activated - if (nullptr == _fpdInterface) { - _fpdInterface = BaseClass::Interface(); - if (_fpdInterface != nullptr) { - printf("[dsFPD-com] Successfully established COM-RPC connection with DeviceSettings plugin\n"); - } else { - fprintf(stderr, "[dsFPD-com] Failed to get interface - plugin implementation may have failed to load\n"); - } - } - } else { - // DeviceSettings is Deactivated || Communicator closed - if (nullptr != _fpdInterface) { - _fpdInterface->Release(); - _fpdInterface = nullptr; - } - } - _apiLock.Unlock(); - } - - inline bool IsActivatedLocked() const - { - return (nullptr != _fpdInterface); - } - - inline bool isConnected() const - { - return _connected; - } - -public: - bool IsOperational() const - { - _apiLock.Lock(); - bool result = (isConnected() && (nullptr != _fpdInterface)); - _apiLock.Unlock(); - return result; - } - - bool WaitForOperational(uint32_t timeoutMs = 5000) const - { - const uint32_t pollIntervalMs = 100; - uint32_t elapsedMs = 0; - - while (elapsedMs < timeoutMs) { - if (IsOperational()) { - return true; - } - std::this_thread::sleep_for(std::chrono::milliseconds(pollIntervalMs)); - elapsedMs += pollIntervalMs; - } - return false; - } - - uint32_t Connect() - { - uint32_t status = Core::ERROR_NONE; - - _apiLock.Lock(); - - if (!isConnected()) { - printf("[dsFPD-com] Attempting to connect to Thunder with callsign: %s\n", callSign); - uint32_t res = BaseClass::Open(RPC::CommunicationTimeOut, BaseClass::Connector(), callSign); - if (Core::ERROR_NONE == res) { - _connected = true; - printf("[dsFPD-com] Successfully opened RPC connection to Thunder\n"); - } else { - fprintf(stderr, "[dsFPD-com] Failed to open RPC connection, error: %u. Is Thunder running?\n", res); - status = Core::ERROR_UNAVAILABLE; - } - } - - if (nullptr == _fpdInterface) { - status = Core::ERROR_NOT_EXIST; - printf("[dsFPD-com] DeviceSettings plugin not yet operational\n"); - } - - _apiLock.Unlock(); - - return status; - } - - uint32_t Disconnect() - { - uint32_t status = Core::ERROR_GENERAL; - bool close = false; - - _apiLock.Lock(); - - if (isConnected()) { - close = true; - _connected = false; - } - - _apiLock.Unlock(); - - if (close) { - status = BaseClass::Close(Core::infinite); - } - - return status; - } - - static void Init() - { - _apiLock.Lock(); - if (nullptr == _instance) { - _instance = new DeviceSettingsFPD(); - } - _apiLock.Unlock(); - } - - static void Term() - { - _apiLock.Lock(); - if (nullptr != _instance) { - delete _instance; - _instance = nullptr; - } - _apiLock.Unlock(); - } - - static DeviceSettingsFPD* Instance() - { - return _instance; - } - - // FPD API implementations - // Note: Thunder interface doesn't have FPDInit/FPDTerm/SetFPDText methods - - Core::hresult SetFPDTime(const Exchange::IDeviceSettingsFPD::FPDTimeFormat timeFormat, - const uint32_t minutes, const uint32_t seconds) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->SetFPDTime(timeFormat, minutes, seconds); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult SetFPDScroll(const uint32_t scrollHoldOnDur, const uint32_t horzScrollIterations, - const uint32_t vertScrollIterations) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->SetFPDScroll(scrollHoldOnDur, horzScrollIterations, vertScrollIterations); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult SetFPDBlink(const Exchange::IDeviceSettingsFPD::FPDIndicator indicator, - const uint32_t blinkDuration, const uint32_t blinkIterations) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->SetFPDBlink(indicator, blinkDuration, blinkIterations); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult GetFPDBrightness(const Exchange::IDeviceSettingsFPD::FPDIndicator indicator, - uint32_t& brightness) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->GetFPDBrightness(indicator, brightness); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult SetFPDBrightness(const Exchange::IDeviceSettingsFPD::FPDIndicator indicator, - const uint32_t brightness, const bool persist) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->SetFPDBrightness(indicator, brightness, persist); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult GetFPDTextBrightness(const Exchange::IDeviceSettingsFPD::FPDTextDisplay indicator, - uint32_t& brightness) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->GetFPDTextBrightness(indicator, brightness); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult SetFPDTextBrightness(const Exchange::IDeviceSettingsFPD::FPDTextDisplay indicator, - const uint32_t brightness) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->SetFPDTextBrightness(indicator, brightness); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult GetFPDColor(const Exchange::IDeviceSettingsFPD::FPDIndicator indicator, - uint32_t& color) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->GetFPDColor(indicator, color); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult SetFPDColor(const Exchange::IDeviceSettingsFPD::FPDIndicator indicator, - const uint32_t color) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->SetFPDColor(indicator, color); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult EnableFPDClockDisplay(const bool enable) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->EnableFPDClockDisplay(enable); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult SetFPDState(const Exchange::IDeviceSettingsFPD::FPDIndicator indicator, - const Exchange::IDeviceSettingsFPD::FPDState state) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->SetFPDState(indicator, state); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult GetFPDState(const Exchange::IDeviceSettingsFPD::FPDIndicator indicator, - Exchange::IDeviceSettingsFPD::FPDState& state) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->GetFPDState(indicator, state); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult GetFPDTimeFormat(Exchange::IDeviceSettingsFPD::FPDTimeFormat& timeFormat) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->GetFPDTimeFormat(timeFormat); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult SetFPDTimeFormat(const Exchange::IDeviceSettingsFPD::FPDTimeFormat timeFormat) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->SetFPDTimeFormat(timeFormat); - } - _apiLock.Unlock(); - return result; - } - - Core::hresult SetFPDMode(const Exchange::IDeviceSettingsFPD::FPDMode mode) - { - Core::hresult result = Core::ERROR_UNAVAILABLE; - _apiLock.Lock(); - if (_fpdInterface) { - result = _fpdInterface->SetFPDMode(mode); - } - _apiLock.Unlock(); - return result; - } -}; - -// Static member initialization -DeviceSettingsFPD* DeviceSettingsFPD::_instance = nullptr; -Core::CriticalSection DeviceSettingsFPD::_apiLock; +using namespace DeviceSettingsClient; /** * @brief Convert Thunder error code to dsError_t */ static dsError_t ConvertThunderError(uint32_t thunderError) { - if (thunderError == Core::ERROR_NONE) { + if (thunderError == WPEFramework::Core::ERROR_NONE) { return dsERR_NONE; - } else if (thunderError == Core::ERROR_UNAVAILABLE) { + } else if (thunderError == WPEFramework::Core::ERROR_UNAVAILABLE) { return dsERR_OPERATION_NOT_SUPPORTED; - } else if (thunderError == Core::ERROR_BAD_REQUEST) { + } else if (thunderError == WPEFramework::Core::ERROR_BAD_REQUEST) { return dsERR_INVALID_PARAM; } else { return dsERR_GENERAL; } } -// C API implementations using Thunder COM-RPC +// C API implementations using Thunder COM-RPC via ConnectionManager extern "C" { @@ -421,21 +70,21 @@ dsError_t dsSetFPDColor(dsFPDIndicator_t eIndicator, dsFPDColor_t eColor, bool t dsError_t dsFPInit(void) { - printf("<<<<< Front Panel is initialized in Thunder Mode >>>>>>>>\r\n"); + printf("<<<<< Front Panel is initialized in Thunder Mode (using ConnectionManager) >>>>>>>>\r\n"); - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance) { - DeviceSettingsFPD::Init(); - instance = DeviceSettingsFPD::Instance(); + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr) { + ConnectionManager::Init(); + connMgr = ConnectionManager::Instance(); } - if (!instance) { - fprintf(stderr, "[dsFPD-com] Failed to create DeviceSettingsFPD instance\n"); + if (!connMgr) { + fprintf(stderr, "[dsFPD-com] Failed to create ConnectionManager instance\n"); return dsERR_GENERAL; } // Wait for plugin to become operational - if (!instance->WaitForOperational(5000)) { + if (!connMgr->WaitForOperational(5000)) { fprintf(stderr, "[dsFPD-com] DeviceSettings plugin not operational after 5 seconds\n"); return dsERR_GENERAL; } @@ -446,15 +95,8 @@ dsError_t dsFPInit(void) dsError_t dsFPTerm(void) { - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance) { - return dsERR_GENERAL; - } - - // Thunder interface doesn't have explicit Term method - // Terminate instance - DeviceSettingsFPD::Term(); - + // Note: Don't terminate ConnectionManager here as other components may be using it + // ConnectionManager will be terminated by dsConnectionTerm() or at process exit return dsERR_NONE; } @@ -472,42 +114,66 @@ dsError_t dsSetFPText(const char* pszChars) dsError_t dsSetFPTime(dsFPDTimeFormat_t eTime, const unsigned int uHour, const unsigned int uMinutes) { - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } Exchange::IDeviceSettingsFPD::FPDTimeFormat timeFormat = static_cast(eTime); + ConnectionManager::Lock(); // Note: Interface expects minutes and seconds, but API provides hour and minutes // Converting: treating uMinutes as seconds for interface compatibility - uint32_t result = instance->SetFPDTime(timeFormat, uHour, uMinutes); + uint32_t result = fpdInterface->SetFPDTime(timeFormat, uHour, uMinutes); + ConnectionManager::Unlock(); + return ConvertThunderError(result); } dsError_t dsSetFPScroll(unsigned int nScrollHoldOnDur, unsigned int nHorzScrollIterations, unsigned int nVertScrollIterations) { - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } - uint32_t result = instance->SetFPDScroll(nScrollHoldOnDur, nHorzScrollIterations, nVertScrollIterations); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->SetFPDScroll(nScrollHoldOnDur, nHorzScrollIterations, nVertScrollIterations); + ConnectionManager::Unlock(); + return ConvertThunderError(result); } dsError_t dsSetFPBlink(dsFPDIndicator_t eIndicator, unsigned int nBlinkDuration, unsigned int nBlinkIterations) { - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } Exchange::IDeviceSettingsFPD::FPDIndicator indicator = static_cast(eIndicator); - uint32_t result = instance->SetFPDBlink(indicator, nBlinkDuration, nBlinkIterations); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->SetFPDBlink(indicator, nBlinkDuration, nBlinkIterations); + ConnectionManager::Unlock(); + return ConvertThunderError(result); } @@ -518,8 +184,13 @@ dsError_t dsGetFPBrightness(dsFPDIndicator_t eIndicator, dsFPDBrightness_t *pBri return dsERR_INVALID_PARAM; } - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } @@ -527,9 +198,11 @@ dsError_t dsGetFPBrightness(dsFPDIndicator_t eIndicator, dsFPDBrightness_t *pBri static_cast(eIndicator); uint32_t brightness = 0; - uint32_t result = instance->GetFPDBrightness(indicator, brightness); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->GetFPDBrightness(indicator, brightness); + ConnectionManager::Unlock(); - if (result == Core::ERROR_NONE) { + if (result == WPEFramework::Core::ERROR_NONE) { *pBrightness = static_cast(brightness); } @@ -554,15 +227,23 @@ dsError_t dsSetFPDBrightness(dsFPDIndicator_t eIndicator, dsFPDBrightness_t eBri return dsERR_INVALID_PARAM; } - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } Exchange::IDeviceSettingsFPD::FPDIndicator indicator = static_cast(eIndicator); - uint32_t result = instance->SetFPDBrightness(indicator, static_cast(eBrightness), toPersist); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->SetFPDBrightness(indicator, static_cast(eBrightness), toPersist); + ConnectionManager::Unlock(); + return ConvertThunderError(result); } @@ -573,8 +254,13 @@ dsError_t dsGetFPTextBrightness(dsFPDTextDisplay_t eIndicator, dsFPDBrightness_t return dsERR_INVALID_PARAM; } - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } @@ -582,9 +268,11 @@ dsError_t dsGetFPTextBrightness(dsFPDTextDisplay_t eIndicator, dsFPDBrightness_t static_cast(eIndicator); uint32_t brightness = 0; - uint32_t result = instance->GetFPDTextBrightness(indicator, brightness); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->GetFPDTextBrightness(indicator, brightness); + ConnectionManager::Unlock(); - if (result == Core::ERROR_NONE) { + if (result == WPEFramework::Core::ERROR_NONE) { *pBrightness = static_cast(brightness); } @@ -593,15 +281,23 @@ dsError_t dsGetFPTextBrightness(dsFPDTextDisplay_t eIndicator, dsFPDBrightness_t dsError_t dsSetFPTextBrightness(dsFPDTextDisplay_t eIndicator, dsFPDBrightness_t eBrightness) { - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } Exchange::IDeviceSettingsFPD::FPDTextDisplay indicator = static_cast(eIndicator); - uint32_t result = instance->SetFPDTextBrightness(indicator, static_cast(eBrightness)); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->SetFPDTextBrightness(indicator, static_cast(eBrightness)); + ConnectionManager::Unlock(); + return ConvertThunderError(result); } @@ -612,8 +308,13 @@ dsError_t dsGetFPColor(dsFPDIndicator_t eIndicator, dsFPDColor_t *pColor) return dsERR_INVALID_PARAM; } - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } @@ -621,9 +322,11 @@ dsError_t dsGetFPColor(dsFPDIndicator_t eIndicator, dsFPDColor_t *pColor) static_cast(eIndicator); uint32_t color = 0; - uint32_t result = instance->GetFPDColor(indicator, color); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->GetFPDColor(indicator, color); + ConnectionManager::Unlock(); - if (result == Core::ERROR_NONE) { + if (result == WPEFramework::Core::ERROR_NONE) { *pColor = static_cast(color); } @@ -637,8 +340,13 @@ dsError_t dsSetFPColor(dsFPDIndicator_t eIndicator, dsFPDColor_t eColor) dsError_t dsSetFPDColor(dsFPDIndicator_t eIndicator, dsFPDColor_t eColor, bool toPersist) { - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } @@ -646,25 +354,41 @@ dsError_t dsSetFPDColor(dsFPDIndicator_t eIndicator, dsFPDColor_t eColor, bool t static_cast(eIndicator); // Thunder interface doesn't support persist flag - ignore it - uint32_t result = instance->SetFPDColor(indicator, static_cast(eColor)); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->SetFPDColor(indicator, static_cast(eColor)); + ConnectionManager::Unlock(); + return ConvertThunderError(result); } dsError_t dsFPEnableCLockDisplay(int enable) { - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } - uint32_t result = instance->EnableFPDClockDisplay(enable != 0); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->EnableFPDClockDisplay(enable != 0); + ConnectionManager::Unlock(); + return ConvertThunderError(result); } dsError_t dsSetFPState(dsFPDIndicator_t eIndicator, dsFPDState_t state) { - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } @@ -673,7 +397,10 @@ dsError_t dsSetFPState(dsFPDIndicator_t eIndicator, dsFPDState_t state) Exchange::IDeviceSettingsFPD::FPDState fpdState = static_cast(state); - uint32_t result = instance->SetFPDState(indicator, fpdState); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->SetFPDState(indicator, fpdState); + ConnectionManager::Unlock(); + return ConvertThunderError(result); } @@ -684,8 +411,13 @@ dsError_t dsGetFPState(dsFPDIndicator_t eIndicator, dsFPDState_t* state) return dsERR_INVALID_PARAM; } - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } @@ -693,9 +425,11 @@ dsError_t dsGetFPState(dsFPDIndicator_t eIndicator, dsFPDState_t* state) static_cast(eIndicator); Exchange::IDeviceSettingsFPD::FPDState fpdState; - uint32_t result = instance->GetFPDState(indicator, fpdState); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->GetFPDState(indicator, fpdState); + ConnectionManager::Unlock(); - if (result == Core::ERROR_NONE) { + if (result == WPEFramework::Core::ERROR_NONE) { *state = static_cast(fpdState); } @@ -709,15 +443,22 @@ dsError_t dsGetFPTimeFormat(dsFPDTimeFormat_t *pTimeFormat) return dsERR_INVALID_PARAM; } - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } Exchange::IDeviceSettingsFPD::FPDTimeFormat timeFormat; - uint32_t result = instance->GetFPDTimeFormat(timeFormat); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->GetFPDTimeFormat(timeFormat); + ConnectionManager::Unlock(); - if (result == Core::ERROR_NONE) { + if (result == WPEFramework::Core::ERROR_NONE) { *pTimeFormat = static_cast(timeFormat); } @@ -726,29 +467,45 @@ dsError_t dsGetFPTimeFormat(dsFPDTimeFormat_t *pTimeFormat) dsError_t dsSetFPTimeFormat(dsFPDTimeFormat_t eTimeFormat) { - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } Exchange::IDeviceSettingsFPD::FPDTimeFormat timeFormat = static_cast(eTimeFormat); - uint32_t result = instance->SetFPDTimeFormat(timeFormat); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->SetFPDTimeFormat(timeFormat); + ConnectionManager::Unlock(); + return ConvertThunderError(result); } dsError_t dsSetFPDMode(dsFPDMode_t eMode) { - DeviceSettingsFPD* instance = DeviceSettingsFPD::Instance(); - if (!instance || !instance->IsOperational()) { + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsFPD* fpdInterface = connMgr->GetFPDInterface(); + if (!fpdInterface) { return dsERR_GENERAL; } Exchange::IDeviceSettingsFPD::FPDMode mode = static_cast(eMode); - uint32_t result = instance->SetFPDMode(mode); + ConnectionManager::Lock(); + uint32_t result = fpdInterface->SetFPDMode(mode); + ConnectionManager::Unlock(); + return ConvertThunderError(result); } diff --git a/rpc/cli/dsHdmiIn-com.cpp b/rpc/cli/dsHdmiIn-com.cpp new file mode 100644 index 00000000..8a28acbc --- /dev/null +++ b/rpc/cli/dsHdmiIn-com.cpp @@ -0,0 +1,651 @@ +/* + * 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. +*/ + +/** +* @defgroup devicesettings +* @{ +* @defgroup rpc +* @{ +**/ + +#ifdef USE_WPE_THUNDER_PLUGIN + +#include +#include + +#include "dsHdmiIn.h" +#include "dsError.h" +#include "dsclientlogger.h" +#include "dsConnectionManager.h" + +// Thunder COM-RPC includes +#ifndef MODULE_NAME +#define MODULE_NAME DeviceSettings_HDMIIn_Client +#endif + +#include + +using namespace WPEFramework; +using namespace DeviceSettingsClient; + +/** + * @brief Convert Thunder error code to dsError_t + */ +static dsError_t ConvertThunderError(uint32_t thunderError) +{ + if (thunderError == WPEFramework::Core::ERROR_NONE) { + return dsERR_NONE; + } else if (thunderError == WPEFramework::Core::ERROR_UNAVAILABLE) { + return dsERR_OPERATION_NOT_SUPPORTED; + } else if (thunderError == WPEFramework::Core::ERROR_BAD_REQUEST) { + return dsERR_INVALID_PARAM; + } else { + return dsERR_GENERAL; + } +} + +// C API implementations using Thunder COM-RPC via ConnectionManager + +extern "C" { + +dsError_t dsHdmiInInit(void) +{ + printf("<<<<< HDMI In is initialized in Thunder Mode (using ConnectionManager) >>>>>>>>\r\n"); + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr) { + ConnectionManager::Init(); + connMgr = ConnectionManager::Instance(); + } + + if (!connMgr) { + fprintf(stderr, "[dsHdmiIn-com] Failed to create ConnectionManager instance\n"); + return dsERR_GENERAL; + } + + // Wait for plugin to become operational + if (!connMgr->WaitForOperational(5000)) { + fprintf(stderr, "[dsHdmiIn-com] DeviceSettings plugin not operational after 5 seconds\n"); + return dsERR_GENERAL; + } + + return dsERR_NONE; +} + +dsError_t dsHdmiInTerm(void) +{ + // Note: Don't terminate ConnectionManager here as other components may be using it + // ConnectionManager will be terminated by dsConnectionTerm() or at process exit + return dsERR_NONE; +} + +dsError_t dsHdmiInGetNumberOfInputs(uint8_t* pNumberOfInputs) +{ + if (pNumberOfInputs == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: pNumberOfInputs is NULL\n"); + return dsERR_INVALID_PARAM; + } + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + int32_t count = 0; + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->GetHDMIInNumbefOfInputs(count); + ConnectionManager::Unlock(); + + if (result == WPEFramework::Core::ERROR_NONE) { + *pNumberOfInputs = static_cast(count); + } + + return ConvertThunderError(result); +} + +dsError_t dsHdmiInGetStatus(dsHdmiInStatus_t* pStatus) +{ + if (pStatus == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: pStatus is NULL\n"); + return dsERR_INVALID_PARAM; + } + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInStatus hdmiStatus; + Exchange::IDeviceSettingsHDMIIn::IHDMIInPortConnectionStatusIterator* portConnectionStatus = nullptr; + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->GetHDMIInStatus(hdmiStatus, portConnectionStatus); + ConnectionManager::Unlock(); + + if (result == WPEFramework::Core::ERROR_NONE) { + pStatus->isPresented = hdmiStatus.isPresented; + pStatus->activePort = static_cast(hdmiStatus.activePort); + + // TODO: Handle portConnectionStatus iterator if needed + if (portConnectionStatus) { + portConnectionStatus->Release(); + } + } + + return ConvertThunderError(result); +} + +dsError_t dsHdmiInSelectPort(dsHdmiInPort_t ePort, bool audioMix, dsVideoPlaneType_t videoPlaneType, bool topMost) +{ + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = + static_cast(ePort); + Exchange::IDeviceSettingsHDMIIn::HDMIVideoPlaneType planeType = + static_cast(videoPlaneType); + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->SelectHDMIInPort(port, audioMix, topMost, planeType); + ConnectionManager::Unlock(); + + return ConvertThunderError(result); +} + +dsError_t dsHdmiInScaleVideo(int32_t x, int32_t y, int32_t width, int32_t height) +{ + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInVideoRectangle videoPosition; + videoPosition.x = x; + videoPosition.y = y; + videoPosition.width = width; + videoPosition.height = height; + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->ScaleHDMIInVideo(videoPosition); + ConnectionManager::Unlock(); + + return ConvertThunderError(result); +} + +dsError_t dsHdmiInSelectZoomMode(dsVideoZoom_t zoomMode) +{ + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInVideoZoom zoom = + static_cast(zoomMode); + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->SelectHDMIZoomMode(zoom); + ConnectionManager::Unlock(); + + return ConvertThunderError(result); +} + +dsError_t dsHdmiInGetCurrentVideoMode(dsVideoPortResolution_t* resolution) +{ + if (resolution == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: resolution is NULL\n"); + return dsERR_INVALID_PARAM; + } + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIVideoPortResolution videoPortResolution; + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->GetHDMIVideoMode(videoPortResolution); + ConnectionManager::Unlock(); + + if (result == WPEFramework::Core::ERROR_NONE) { + strncpy(resolution->name, videoPortResolution.name.c_str(), sizeof(resolution->name) - 1); + resolution->name[sizeof(resolution->name) - 1] = '\0'; + resolution->pixelResolution = static_cast(videoPortResolution.pixelResolution); + resolution->aspectRatio = static_cast(videoPortResolution.aspectRatio); + resolution->stereoScopicMode = static_cast(videoPortResolution.stereoScopicMode); + resolution->frameRate = static_cast(videoPortResolution.frameRate); + resolution->interlaced = videoPortResolution.interlaced; + } + + return ConvertThunderError(result); +} + +dsError_t dsGetEDIDBytesInfo(int iHdmiPort, unsigned char* edid, int* length) +{ + if (edid == NULL || length == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter\n"); + return dsERR_INVALID_PARAM; + } + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = + static_cast(iHdmiPort); + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->GetEdidBytes(port, static_cast(*length), edid); + ConnectionManager::Unlock(); + + return ConvertThunderError(result); +} + +dsError_t dsGetHDMISPDInfo(int iHdmiPort, unsigned char* data) +{ + if (data == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: data is NULL\n"); + return dsERR_INVALID_PARAM; + } + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = + static_cast(iHdmiPort); + + // Assuming SPD info frame size (adjust as needed) + const uint16_t spdBytesLength = 32; + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->GetHDMISPDInformation(port, spdBytesLength, data); + ConnectionManager::Unlock(); + + return ConvertThunderError(result); +} + +dsError_t dsGetEdidVersion(int iHdmiPort, int* edidVersion) +{ + if (edidVersion == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: edidVersion is NULL\n"); + return dsERR_INVALID_PARAM; + } + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = + static_cast(iHdmiPort); + Exchange::IDeviceSettingsHDMIIn::HDMIInEdidVersion version; + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->GetHDMIEdidVersion(port, version); + ConnectionManager::Unlock(); + + if (result == WPEFramework::Core::ERROR_NONE) { + *edidVersion = static_cast(version); + } + + return ConvertThunderError(result); +} + +dsError_t dsSetEdidVersion(int iHdmiPort, int edidVersion) +{ + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = + static_cast(iHdmiPort); + Exchange::IDeviceSettingsHDMIIn::HDMIInEdidVersion version = + static_cast(edidVersion); + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->SetHDMIEdidVersion(port, version); + ConnectionManager::Unlock(); + + return ConvertThunderError(result); +} + +dsError_t dsGetAllmStatus(dsHdmiInPort_t iHdmiPort, bool* allmStatus) +{ + if (allmStatus == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: allmStatus is NULL\n"); + return dsERR_INVALID_PARAM; + } + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = + static_cast(iHdmiPort); + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->GetHDMIInAllmStatus(port, *allmStatus); + ConnectionManager::Unlock(); + + return ConvertThunderError(result); +} + +dsError_t dsGetEdid2AllmSupport(dsHdmiInPort_t iHdmiPort, bool* allmSupport) +{ + if (allmSupport == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: allmSupport is NULL\n"); + return dsERR_INVALID_PARAM; + } + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = + static_cast(iHdmiPort); + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->GetHDMIInEdid2AllmSupport(port, *allmSupport); + ConnectionManager::Unlock(); + + return ConvertThunderError(result); +} + +dsError_t dsSetEdid2AllmSupport(dsHdmiInPort_t iHdmiPort, bool allmSupport) +{ + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = + static_cast(iHdmiPort); + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->SetHDMIInEdid2AllmSupport(port, allmSupport); + ConnectionManager::Unlock(); + + return ConvertThunderError(result); +} + +dsError_t dsGetAVLatency(int* audio_latency, int* video_latency) +{ + if (audio_latency == NULL || video_latency == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter\n"); + return dsERR_INVALID_PARAM; + } + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + uint32_t videoLatency = 0; + uint32_t audioLatency = 0; + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->GetHDMIInAVLatency(videoLatency, audioLatency); + ConnectionManager::Unlock(); + + if (result == WPEFramework::Core::ERROR_NONE) { + *audio_latency = static_cast(audioLatency); + *video_latency = static_cast(videoLatency); + } + + return ConvertThunderError(result); +} + +dsError_t dsGetHdmiVersion(dsHdmiInPort_t iHdmiPort, dsHdmiVersion_t* capversion) +{ + if (capversion == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: capversion is NULL\n"); + return dsERR_INVALID_PARAM; + } + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = + static_cast(iHdmiPort); + Exchange::IDeviceSettingsHDMIIn::HDMIInCapabilityVersion capabilityVersion; + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->GetHDMIVersion(port, capabilityVersion); + ConnectionManager::Unlock(); + + if (result == WPEFramework::Core::ERROR_NONE) { + *capversion = static_cast(capabilityVersion); + } + + return ConvertThunderError(result); +} + +dsError_t dsSetVRRSupport(dsHdmiInPort_t iHdmiPort, bool vrrSupport) +{ + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = + static_cast(iHdmiPort); + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->SetVRRSupport(port, vrrSupport); + ConnectionManager::Unlock(); + + return ConvertThunderError(result); +} + +dsError_t dsGetVRRSupport(dsHdmiInPort_t iHdmiPort, bool* vrrSupport) +{ + if (vrrSupport == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: vrrSupport is NULL\n"); + return dsERR_INVALID_PARAM; + } + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = + static_cast(iHdmiPort); + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->GetVRRSupport(port, *vrrSupport); + ConnectionManager::Unlock(); + + return ConvertThunderError(result); +} + +dsError_t dsHdmiInGetVRRStatus(dsHdmiInPort_t iHdmiPort, dsHdmiInVrrStatus_t* vrrStatus) +{ + if (vrrStatus == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: vrrStatus is NULL\n"); + return dsERR_INVALID_PARAM; + } + + ConnectionManager* connMgr = ConnectionManager::Instance(); + if (!connMgr || !connMgr->IsOperational()) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn* hdmiInInterface = connMgr->GetHDMIInInterface(); + if (!hdmiInInterface) { + return dsERR_GENERAL; + } + + Exchange::IDeviceSettingsHDMIIn::HDMIInPort port = + static_cast(iHdmiPort); + Exchange::IDeviceSettingsHDMIIn::HDMIInVRRStatus status; + + ConnectionManager::Lock(); + uint32_t result = hdmiInInterface->GetVRRStatus(port, status); + ConnectionManager::Unlock(); + + if (result == WPEFramework::Core::ERROR_NONE) { + vrrStatus->vrrType = static_cast(status.vrrType); + vrrStatus->vrrFreeSyncFramerateHz = status.vrrFreeSyncFramerateHz; + } + + return ConvertThunderError(result); +} + +// Placeholder for unsupported APIs in Thunder mode +dsError_t dsHdmiInRegisterConnectCB(dsHdmiInConnectCB_t CBFunc) +{ + fprintf(stderr, "[dsHdmiIn-com] dsHdmiInRegisterConnectCB not supported in Thunder mode\n"); + return dsERR_OPERATION_NOT_SUPPORTED; +} + +dsError_t dsHdmiInRegisterSignalChangeCB(dsHdmiInSignalChangeCB_t CBFunc) +{ + fprintf(stderr, "[dsHdmiIn-com] dsHdmiInRegisterSignalChangeCB not supported in Thunder mode\n"); + return dsERR_OPERATION_NOT_SUPPORTED; +} + +dsError_t dsHdmiInRegisterStatusChangeCB(dsHdmiInStatusChangeCB_t CBFunc) +{ + fprintf(stderr, "[dsHdmiIn-com] dsHdmiInRegisterStatusChangeCB not supported in Thunder mode\n"); + return dsERR_OPERATION_NOT_SUPPORTED; +} + +dsError_t dsHdmiInRegisterVideoModeUpdateCB(dsHdmiInVideoModeUpdateCB_t CBFunc) +{ + fprintf(stderr, "[dsHdmiIn-com] dsHdmiInRegisterVideoModeUpdateCB not supported in Thunder mode\n"); + return dsERR_OPERATION_NOT_SUPPORTED; +} + +dsError_t dsHdmiInRegisterAllmChangeCB(dsHdmiInAllmChangeCB_t CBFunc) +{ + fprintf(stderr, "[dsHdmiIn-com] dsHdmiInRegisterAllmChangeCB not supported in Thunder mode\n"); + return dsERR_OPERATION_NOT_SUPPORTED; +} + +dsError_t dsHdmiInRegisterAVLatencyChangeCB(dsAVLatencyChangeCB_t CBFunc) +{ + fprintf(stderr, "[dsHdmiIn-com] dsHdmiInRegisterAVLatencyChangeCB not supported in Thunder mode\n"); + return dsERR_OPERATION_NOT_SUPPORTED; +} + +dsError_t dsHdmiInRegisterAviContentTypeChangeCB(dsAviContentTypeChangeCB_t CBFunc) +{ + fprintf(stderr, "[dsHdmiIn-com] dsHdmiInRegisterAviContentTypeChangeCB not supported in Thunder mode\n"); + return dsERR_OPERATION_NOT_SUPPORTED; +} + +} // extern "C" + +#endif // USE_WPE_THUNDER_PLUGIN + +/** @} */ +/** @} */ From 282327834cd18eb527c299bed8b9f141a549b075 Mon Sep 17 00:00:00 2001 From: Manimaran Renganathan Date: Thu, 5 Feb 2026 09:58:53 +0000 Subject: [PATCH 14/16] Revert "Revert "Resolved compilation errors"" This reverts commit 8c15bc0fd60fa4151c765d215253f01380a68e46. --- rpc/cli/dsConnectionManager.h | 4 ++++ rpc/cli/dsHdmiIn-com.cpp | 18 +++++++++--------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/rpc/cli/dsConnectionManager.h b/rpc/cli/dsConnectionManager.h index eed60bf4..e553fab6 100644 --- a/rpc/cli/dsConnectionManager.h +++ b/rpc/cli/dsConnectionManager.h @@ -22,6 +22,10 @@ #ifdef USE_WPE_THUNDER_PLUGIN +#ifndef MODULE_NAME +#define MODULE_NAME DeviceSettings_ConnectionManager +#endif + #include #include #include diff --git a/rpc/cli/dsHdmiIn-com.cpp b/rpc/cli/dsHdmiIn-com.cpp index 8a28acbc..5d51eee0 100644 --- a/rpc/cli/dsHdmiIn-com.cpp +++ b/rpc/cli/dsHdmiIn-com.cpp @@ -267,7 +267,7 @@ dsError_t dsHdmiInGetCurrentVideoMode(dsVideoPortResolution_t* resolution) return ConvertThunderError(result); } -dsError_t dsGetEDIDBytesInfo(int iHdmiPort, unsigned char* edid, int* length) +dsError_t dsGetEDIDBytesInfo(dsHdmiInPort_t iHdmiPort, unsigned char* edid, int* length) { if (edid == NULL || length == NULL) { fprintf(stderr, "[dsHdmiIn-com] Invalid parameter\n"); @@ -294,7 +294,7 @@ dsError_t dsGetEDIDBytesInfo(int iHdmiPort, unsigned char* edid, int* length) return ConvertThunderError(result); } -dsError_t dsGetHDMISPDInfo(int iHdmiPort, unsigned char* data) +dsError_t dsGetHDMISPDInfo(dsHdmiInPort_t iHdmiPort, unsigned char* data) { if (data == NULL) { fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: data is NULL\n"); @@ -323,7 +323,7 @@ dsError_t dsGetHDMISPDInfo(int iHdmiPort, unsigned char* data) return ConvertThunderError(result); } -dsError_t dsGetEdidVersion(int iHdmiPort, int* edidVersion) +dsError_t dsGetEdidVersion(dsHdmiInPort_t iHdmiPort, tv_hdmi_edid_version_t* edidVersion) { if (edidVersion == NULL) { fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: edidVersion is NULL\n"); @@ -349,13 +349,13 @@ dsError_t dsGetEdidVersion(int iHdmiPort, int* edidVersion) ConnectionManager::Unlock(); if (result == WPEFramework::Core::ERROR_NONE) { - *edidVersion = static_cast(version); + *edidVersion = static_cast(version); } return ConvertThunderError(result); } -dsError_t dsSetEdidVersion(int iHdmiPort, int edidVersion) +dsError_t dsSetEdidVersion(dsHdmiInPort_t iHdmiPort, tv_hdmi_edid_version_t edidVersion) { ConnectionManager* connMgr = ConnectionManager::Instance(); if (!connMgr || !connMgr->IsOperational()) { @@ -486,7 +486,7 @@ dsError_t dsGetAVLatency(int* audio_latency, int* video_latency) return ConvertThunderError(result); } -dsError_t dsGetHdmiVersion(dsHdmiInPort_t iHdmiPort, dsHdmiVersion_t* capversion) +dsError_t dsGetHdmiVersion(dsHdmiInPort_t iHdmiPort, dsHdmiMaxCapabilityVersion_t* capversion) { if (capversion == NULL) { fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: capversion is NULL\n"); @@ -512,7 +512,7 @@ dsError_t dsGetHdmiVersion(dsHdmiInPort_t iHdmiPort, dsHdmiVersion_t* capversion ConnectionManager::Unlock(); if (result == WPEFramework::Core::ERROR_NONE) { - *capversion = static_cast(capabilityVersion); + *capversion = static_cast(capabilityVersion); } return ConvertThunderError(result); @@ -594,7 +594,7 @@ dsError_t dsHdmiInGetVRRStatus(dsHdmiInPort_t iHdmiPort, dsHdmiInVrrStatus_t* vr if (result == WPEFramework::Core::ERROR_NONE) { vrrStatus->vrrType = static_cast(status.vrrType); - vrrStatus->vrrFreeSyncFramerateHz = status.vrrFreeSyncFramerateHz; + vrrStatus->vrrAmdfreesyncFramerate_Hz = status.vrrFreeSyncFramerateHz; } return ConvertThunderError(result); @@ -637,7 +637,7 @@ dsError_t dsHdmiInRegisterAVLatencyChangeCB(dsAVLatencyChangeCB_t CBFunc) return dsERR_OPERATION_NOT_SUPPORTED; } -dsError_t dsHdmiInRegisterAviContentTypeChangeCB(dsAviContentTypeChangeCB_t CBFunc) +dsError_t dsHdmiInRegisterAviContentTypeChangeCB(dsHdmiInAviContentTypeChangeCB_t CBFunc) { fprintf(stderr, "[dsHdmiIn-com] dsHdmiInRegisterAviContentTypeChangeCB not supported in Thunder mode\n"); return dsERR_OPERATION_NOT_SUPPORTED; From 29e9c5e4ef8103e250698c9c814db2b650d851cc Mon Sep 17 00:00:00 2001 From: Manimaran Renganathan Date: Thu, 5 Feb 2026 09:58:56 +0000 Subject: [PATCH 15/16] Revert "Revert "Added the Makefile and Makefile.am changes in devicesettings /rpc/cli"" This reverts commit 7e25fcc9390e6fb027bed2a6573b53bea15658bc. --- rpc/cli/Makefile | 8 ++++---- rpc/cli/Makefile.am | 8 +++++++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/rpc/cli/Makefile b/rpc/cli/Makefile index 7b2575ee..a10f6551 100644 --- a/rpc/cli/Makefile +++ b/rpc/cli/Makefile @@ -24,12 +24,12 @@ INSTALL := $(PWD)/install # Conditional compilation: Thunder vs IARM ifdef USE_WPE_THUNDER_PLUGIN - # Thunder mode - use dsFPD-com.cpp, exclude dsFPD.c + # Thunder mode - use *-com.cpp files, exclude legacy .c implementations OBJS := $(patsubst %.cpp,%.o,$(wildcard *.cpp)) - OBJS += $(patsubst %.c,%.o,$(filter-out dsFPD.c,$(wildcard *.c))) + OBJS += $(patsubst %.c,%.o,$(filter-out dsFPD.c dsHdmiIn.c,$(wildcard *.c))) else - # IARM mode - use dsFPD.c, exclude dsFPD-com.cpp - OBJS := $(patsubst %.cpp,%.o,$(filter-out dsFPD-com.cpp,$(wildcard *.cpp))) + # IARM mode - use legacy .c files, exclude Thunder -com.cpp implementations + OBJS := $(patsubst %.cpp,%.o,$(filter-out dsFPD-com.cpp dsHdmiIn-com.cpp dsConnectionManager.cpp,$(wildcard *.cpp))) OBJS += $(patsubst %.c,%.o,$(wildcard *.c)) endif diff --git a/rpc/cli/Makefile.am b/rpc/cli/Makefile.am index 27f50c1b..0b98e994 100644 --- a/rpc/cli/Makefile.am +++ b/rpc/cli/Makefile.am @@ -32,11 +32,17 @@ libdshalcli_la_CFLAGS = -g -fPIC -D_REENTRANT -Wall # Conditional compilation for Thunder COM-RPC if USE_THUNDER_PLUGIN FPD_SOURCE = dsFPD-com.cpp + HDMIIN_SOURCE = dsHdmiIn-com.cpp + COMPOSITEIN_SOURCE = + THUNDER_SOURCES = dsConnectionManager.cpp THUNDER_LIBS = -lWPEFrameworkCore -lWPEFrameworkCOM else FPD_SOURCE = dsFPD.c + HDMIIN_SOURCE = dsHdmiIn.c + COMPOSITEIN_SOURCE = dsCompositeIn.c + THUNDER_SOURCES = THUNDER_LIBS = endif -libdshalcli_la_SOURCES = dsAudio.c dsclientlogger.c dsDisplay.c $(FPD_SOURCE) dsHost.cpp dsVideoDevice.c dsVideoPort.c +libdshalcli_la_SOURCES = dsAudio.c dsclientlogger.c dsDisplay.c $(FPD_SOURCE) $(HDMIIN_SOURCE) $(COMPOSITEIN_SOURCE) $(THUNDER_SOURCES) dsHost.cpp dsVideoDevice.c dsVideoPort.c libdshalcli_la_LIBADD = $(THUNDER_LIBS) From 13a8e6d59e4e82ab90405aa245a5b105b3335148 Mon Sep 17 00:00:00 2001 From: Manimaran Renganathan Date: Thu, 5 Feb 2026 09:58:58 +0000 Subject: [PATCH 16/16] Revert "Revert "Resolved undefined reference error in dsHdmiIn-com.cpp file"" This reverts commit 3944baf409fa950dc2f5e3b7d7f7c922883dafdb. --- rpc/cli/dsHdmiIn-com.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/rpc/cli/dsHdmiIn-com.cpp b/rpc/cli/dsHdmiIn-com.cpp index 5d51eee0..aee2ce4f 100644 --- a/rpc/cli/dsHdmiIn-com.cpp +++ b/rpc/cli/dsHdmiIn-com.cpp @@ -518,7 +518,7 @@ dsError_t dsGetHdmiVersion(dsHdmiInPort_t iHdmiPort, dsHdmiMaxCapabilityVersion_ return ConvertThunderError(result); } -dsError_t dsSetVRRSupport(dsHdmiInPort_t iHdmiPort, bool vrrSupport) +dsError_t dsHdmiInSetVRRSupport(dsHdmiInPort_t iHdmiPort, bool vrrSupport) { ConnectionManager* connMgr = ConnectionManager::Instance(); if (!connMgr || !connMgr->IsOperational()) { @@ -540,7 +540,7 @@ dsError_t dsSetVRRSupport(dsHdmiInPort_t iHdmiPort, bool vrrSupport) return ConvertThunderError(result); } -dsError_t dsGetVRRSupport(dsHdmiInPort_t iHdmiPort, bool* vrrSupport) +dsError_t dsHdmiInGetVRRSupport(dsHdmiInPort_t iHdmiPort, bool* vrrSupport) { if (vrrSupport == NULL) { fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: vrrSupport is NULL\n"); @@ -600,6 +600,21 @@ dsError_t dsHdmiInGetVRRStatus(dsHdmiInPort_t iHdmiPort, dsHdmiInVrrStatus_t* vr return ConvertThunderError(result); } +dsError_t dsGetSupportedGameFeaturesList(dsSupportedGameFeatureList_t* feature) +{ + if (feature == NULL) { + fprintf(stderr, "[dsHdmiIn-com] Invalid parameter: feature is NULL\n"); + return dsERR_INVALID_PARAM; + } + + // This function is not yet implemented in Thunder COM-RPC mode + // For now, return empty list + feature->gameFeatureCount = 0; + feature->gameFeatureList[0] = '\0'; + fprintf(stderr, "[dsHdmiIn-com] dsGetSupportedGameFeaturesList not fully implemented in Thunder mode\n"); + return dsERR_OPERATION_NOT_SUPPORTED; +} + // Placeholder for unsupported APIs in Thunder mode dsError_t dsHdmiInRegisterConnectCB(dsHdmiInConnectCB_t CBFunc) {