diff --git a/CHANGELOG.md b/CHANGELOG.md index c5dc9e7c..65db12a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,42 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [1.0.29](https://github.com/rdkcentral/devicesettings/compare/1.0.28...1.0.29) + +- RDKEMW-10899: Adding IARMBus dependency during Build Time [`#205`](https://github.com/rdkcentral/devicesettings/pull/205) +- Merge tag '1.0.28' into develop [`05c2d95`](https://github.com/rdkcentral/devicesettings/commit/05c2d95b7b413f3322c3a0b746fd9ccf260d3ad2) + +#### [1.0.28](https://github.com/rdkcentral/devicesettings/compare/1.0.27...1.0.28) + +> 13 January 2026 + +- RDKEMW-9781: Video format issue on MTK [`#199`](https://github.com/rdkcentral/devicesettings/pull/199) +- RDKEMW-12054: Fix Coverity identified issues [`#190`](https://github.com/rdkcentral/devicesettings/pull/190) +- 1.0.28 release change log updates [`f11f7de`](https://github.com/rdkcentral/devicesettings/commit/f11f7de47304fbf0a8669d1894c243dc86c76e02) +- Merge tag '1.0.27' into develop [`56fabff`](https://github.com/rdkcentral/devicesettings/commit/56fabffd8576c37eedb03dac31c3238fa318977d) + +#### [1.0.27](https://github.com/rdkcentral/devicesettings/compare/1.0.26...1.0.27) + +> 12 January 2026 + +- RDKEMW-11232 getAudioFormatApi issue on Xione-UK [`#188`](https://github.com/rdkcentral/devicesettings/pull/188) +- 1.0.27 release change log updates [`6594764`](https://github.com/rdkcentral/devicesettings/commit/6594764c3fde44fdb313576482cd7c2589fe1493) +- Merge tag '1.0.26' into develop [`62858d9`](https://github.com/rdkcentral/devicesettings/commit/62858d954e5871070b4e0433c9e06abaf8ff97d1) + +#### [1.0.26](https://github.com/rdkcentral/devicesettings/compare/1.0.25...1.0.26) + +> 8 January 2026 + +- RDKEMW-11168, RDKEMW-4848: pass the proper handle to dsEnableHDCP [`#182`](https://github.com/rdkcentral/devicesettings/pull/182) +- 1.0.26 release change log updates [`898b0bb`](https://github.com/rdkcentral/devicesettings/commit/898b0bbcbc5e16bd1c5f4bcf2e881b8ef037c8af) +- Merge tag '1.0.25' into develop [`ce8af83`](https://github.com/rdkcentral/devicesettings/commit/ce8af8303729b6a01fe4d8240de74fe365cdafe4) + #### [1.0.25](https://github.com/rdkcentral/devicesettings/compare/1.0.24...1.0.25) +> 20 November 2025 + - Feature/rdkemw 7496 [`#134`](https://github.com/rdkcentral/devicesettings/pull/134) +- 1.0.25 release change log updates [`75b7563`](https://github.com/rdkcentral/devicesettings/commit/75b7563fc461eeaa31bd68140f29ccf0900a6655) - Merge tag '1.0.24' into develop [`4e94421`](https://github.com/rdkcentral/devicesettings/commit/4e94421d193d4d5e7dea28ccf49198c7dc2bf1d4) #### [1.0.24](https://github.com/rdkcentral/devicesettings/compare/1.0.23...1.0.24) diff --git a/ds/Makefile b/ds/Makefile index d69caba9..e27e1bcc 100644 --- a/ds/Makefile +++ b/ds/Makefile @@ -33,17 +33,17 @@ INCLUDE := -I$(PWD) \ -I$(PWD)/config \ -I$(PWD)/hal/include \ -I$(PWD)/hal/src \ + -I$(PWD)/ds/include \ -I$(PWD)/ds \ - -I$(PWD)/rpc/include \ - -I$(PWD)/ds/include + -I$(PWD)/rpc/include else INCLUDE := -I$(PWD) \ -I$(LOG4C_INSTALL_DIR)/include \ -I$(PWD)/config \ -I$(PWD)/hal/include \ + -I$(PWD)/ds/include \ -I$(PWD)/ds \ - -I$(PWD)/rpc/include \ - -I$(PWD)/ds/include + -I$(PWD)/rpc/include endif @@ -59,8 +59,8 @@ all: install library: $(OBJS) @echo "Building $(LIBNAMEFULL) ...." - $(CXX) $(OBJS) $(CFLAGS) $(DSHAL_LDFLAGS) -L$(INSTALL)/lib -ldshalcli -shared -o $(LIBNAMEFULL) - $(CXX) $(OBJS) $(CFLAGS) -L$(INSTALL)/lib -ldshalcli -shared -o $(LIBNAMECLI) + $(CXX) $(OBJS) $(CFLAGS) $(DSHAL_LDFLAGS) -L$(INSTALL)/lib -lIARMBus -ldshalcli -shared -o $(LIBNAMEFULL) + $(CXX) $(OBJS) $(CFLAGS) -L$(INSTALL)/lib -lIARMBus -ldshalcli -shared -o $(LIBNAMECLI) %.o: %.cpp @echo "Building $@ ...." diff --git a/ds/audioOutputPort.cpp b/ds/audioOutputPort.cpp index e5c8fabc..2d5fde04 100644 --- a/ds/audioOutputPort.cpp +++ b/ds/audioOutputPort.cpp @@ -131,7 +131,7 @@ AudioOutputPort::AudioOutputPort(const int type, const int index, const int id) out << getType().getName() << _index; _name = out.str(); } - printf ("\nAudioOutputPort init: _type:%d _index:%d _handle:%d\n", _type, _index, _handle); + printf ("\nAudioOutputPort init: _type:%d _index:%d _handle:%ld\n", _type, _index, (long)_handle); if (dsERR_NONE == ret) { //dsGetAudioCompression (_handle, (dsAudioCompression_t *)&_compression); dsGetAudioEncoding (_handle, (dsAudioEncoding_t *)&_encoding); @@ -184,7 +184,7 @@ dsError_t AudioOutputPort::reInitializeAudioOutputPort() _name = out.str(); } - printf ("\nAudioOutputPort init: _type:%d _index:%d _handle:%d\n", _type, _index, _handle); + printf ("\nAudioOutputPort init: _type:%d _index:%d _handle:%ld\n", _type, _index,(long)_handle); if (dsERR_NONE == ret) { //dsGetAudioCompression>(_handle, (dsAudioCompression_t *)&_compression); dsGetAudioEncoding(_handle, (dsAudioEncoding_t *)&_encoding); @@ -1422,11 +1422,11 @@ void AudioOutputPort::setAudioDelay(const uint32_t audioDelayMs) dsError_t ret = dsERR_NONE; uint32_t ms = audioDelayMs; - INT_INFO("AudioOutputPort [%s], setting delay to [%lu] ms\n", _name.c_str(), audioDelayMs); + INT_INFO("AudioOutputPort [%s], setting delay to [%u] ms\n", _name.c_str(), audioDelayMs); if (ms > audioDelayMsMax) { - INT_ERROR("AudioOutputPort [%s], delay [%lu] ms, exceeds max [%lu]. Setting Max \n", + INT_ERROR("AudioOutputPort [%s], delay [%u] ms, exceeds max [%u]. Setting Max \n", _name.c_str(), audioDelayMs, audioDelayMsMax); diff --git a/ds/audioOutputPortConfig.cpp b/ds/audioOutputPortConfig.cpp index c3ab1cc6..2b1664fd 100644 --- a/ds/audioOutputPortConfig.cpp +++ b/ds/audioOutputPortConfig.cpp @@ -34,6 +34,9 @@ #include "dsUtl.h" #include "stdlib.h" #include "dslogger.h" +#include +#include "manager.hpp" + namespace device { @@ -108,68 +111,155 @@ List AudioOutputPortConfig::getSupportedTypes() return supportedTypes; } -void AudioOutputPortConfig::load() +void dumpconfig(audioConfigs_t *config) { - try { - /* - * Load Constants First. - */ - for (int i = 0; i < dsAUDIO_ENC_MAX; i++) { - _aEncodings.push_back(AudioEncoding(i)); - } - - for (int i = 0; i < dsAUDIO_CMP_MAX; i++) { - _aCompressions.push_back(AudioCompression(i)); - - } - - for (int i = 0; i < dsAUDIO_STEREO_MAX; i++) { - _aStereoModes.push_back(AudioStereoMode(i)); - - } - - for (int i = 0; i < dsAUDIOPORT_TYPE_MAX; i++) { - _aPortTypes.push_back(AudioOutputPortType(i)); - - } - - /* - * Initialize Audio portTypes (encodings, compressions etc.) - * and its port instances (db, level etc) - */ - for (size_t i = 0; i < dsUTL_DIM(kConfigs); i++) { - const dsAudioTypeConfig_t *typeCfg = &kConfigs[i]; - AudioOutputPortType &aPortType = AudioOutputPortType::getInstance(typeCfg->typeId); - aPortType.enable(); - for (size_t j = 0; j < typeCfg->numSupportedEncodings; j++) { - aPortType.addEncoding(AudioEncoding::getInstance(typeCfg->encodings[j])); - _aEncodings.at(typeCfg->encodings[j]).enable(); - } - for (size_t j = 0; j < typeCfg->numSupportedCompressions; j++) { - aPortType.addCompression(typeCfg->compressions[j]); - _aCompressions.at(typeCfg->compressions[j]).enable(); - - } - for (size_t j = 0; j < typeCfg->numSupportedStereoModes; j++) { - aPortType.addStereoMode(typeCfg->stereoModes[j]); - _aStereoModes.at(typeCfg->stereoModes[j]).enable(); - - } - } - - /* - * set up ports based on kPorts[] - */ - for (size_t i = 0; i < dsUTL_DIM(kPorts); i++) { - const dsAudioPortConfig_t *port = &kPorts[i]; - _aPorts.push_back(AudioOutputPort((port->id.type), port->id.index, i)); - _aPortTypes.at(port->id.type).addPort(_aPorts.at(i)); - } + if (nullptr == config) { + INT_ERROR("Audio config is NULL"); + return; + } + if ( -1 == access("/opt/dsMgrDumpDeviceConfigs", F_OK) ) { + INT_INFO("Dumping of Device configs is disabled"); + return; + } + + int configSize = -1, portSize = -1; + INT_INFO("\n=============== Starting to Dump Audio Configs ===============\n"); + if( nullptr != config->pKConfigs ) + { + configSize = (config->pKConfigSize) ? *(config->pKConfigSize) : -1; + + for (int i = 0; i < configSize; i++) { + const dsAudioTypeConfig_t *typeCfg = &(config->pKConfigs[i]); + INT_INFO("typeCfg->typeId = %d", typeCfg->typeId); + INT_INFO("typeCfg->name = %s", typeCfg->name); + INT_INFO("typeCfg->numSupportedEncodings = %zu", typeCfg->numSupportedEncodings); + INT_INFO("typeCfg->numSupportedCompressions = %zu", typeCfg->numSupportedCompressions); + INT_INFO("typeCfg->numSupportedStereoModes = %zu", typeCfg->numSupportedStereoModes); + } + } + else + { + INT_ERROR("kAudioConfigs is NULL"); + } + + if( nullptr != config->pKPorts ) + { + portSize = (config->pKPortSize) ? *(config->pKPortSize) : -1; + for (int i = 0; i < portSize; i++) { + const dsAudioPortConfig_t *portCfg = &(config->pKPorts[i]); + INT_INFO("portCfg->id.type = %d", portCfg->id.type); + INT_INFO("portCfg->id.index = %d", portCfg->id.index); + } + } + else + { + INT_ERROR("kAudioPorts is NULL"); + } + + INT_INFO("\n=============== Dump Audio Configs done ===============\n"); +} - } - catch(const Exception &e) { - throw e; - } +void AudioOutputPortConfig::load(audioConfigs_t* dynamicAudioConfigs) +{ + int configSize = -1, portSize = -1; + audioConfigs_t configuration = {0}; + + INT_INFO("Enter function"); + try { + /* + * Load Constants First. + */ + for (int i = 0; i < dsAUDIO_ENC_MAX; i++) { + _aEncodings.push_back(AudioEncoding(i)); + } + + for (int i = 0; i < dsAUDIO_CMP_MAX; i++) { + _aCompressions.push_back(AudioCompression(i)); + + } + + for (int i = 0; i < dsAUDIO_STEREO_MAX; i++) { + _aStereoModes.push_back(AudioStereoMode(i)); + + } + + for (int i = 0; i < dsAUDIOPORT_TYPE_MAX; i++) { + _aPortTypes.push_back(AudioOutputPortType(i)); + + } + + INT_INFO("Using '%s' config", dynamicAudioConfigs ? "dynamic" : "static"); + if ( nullptr != dynamicAudioConfigs ) + { + configuration = *dynamicAudioConfigs; + configSize = (configuration.pKConfigSize) ? *(configuration.pKConfigSize) : -1; + portSize = (configuration.pKPortSize) ? *(configuration.pKPortSize) : -1; + } + else { + configuration.pKConfigs = kConfigs; + configSize = dsUTL_DIM(kConfigs); + configuration.pKConfigSize = &configSize; + configuration.pKPorts = kPorts; + portSize = dsUTL_DIM(kPorts); + configuration.pKPortSize = &portSize; + } + + INT_INFO("Audio Config[%p] ConfigSize[%d] Ports[%p] PortSize[%d]", + configuration.pKConfigs, + configSize, + configuration.pKPorts, + portSize); + + dumpconfig(&configuration); + + /* + * Check if configs are loaded properly + */ + if (( nullptr != configuration.pKConfigs ) && ( nullptr != configuration.pKPorts )) + { + /* + * Initialize Audio portTypes (encodings, compressions etc.) + * and its port instances (db, level etc) + */ + for (int i = 0; i < configSize; i++) { + const dsAudioTypeConfig_t *typeCfg = &(configuration.pKConfigs[i]); + AudioOutputPortType &aPortType = AudioOutputPortType::getInstance(typeCfg->typeId); + aPortType.enable(); + for (int j = 0; j < typeCfg->numSupportedEncodings; j++) { + const dsAudioEncoding_t* encoding = &typeCfg->encodings[j]; + aPortType.addEncoding(AudioEncoding::getInstance(*encoding)); + _aEncodings.at(*encoding).enable(); + } + for (int j = 0; j < typeCfg->numSupportedCompressions; j++) { + const dsAudioCompression_t* compression = &typeCfg->compressions[j]; + aPortType.addCompression(*compression); + _aCompressions.at(*compression).enable(); + } + for (int j = 0; j < typeCfg->numSupportedStereoModes; j++) { + const dsAudioStereoMode_t *stereoMode = &typeCfg->stereoModes[j]; + aPortType.addStereoMode(*stereoMode); + _aStereoModes.at(*stereoMode).enable(); + } + } + + /* + * set up ports based on kPorts[] + */ + for (int i = 0; i < portSize; i++) { + const dsAudioPortConfig_t *portCfg = &configuration.pKPorts[i]; + _aPorts.push_back(AudioOutputPort((portCfg->id.type), portCfg->id.index, i)); + _aPortTypes.at(portCfg->id.type).addPort(_aPorts.at(i)); + } + INT_INFO("Audio Configs loaded successfully"); + } + else { + INT_ERROR("Audio Configs loading failed"); + } + } + catch(const Exception &e) { + throw e; + } + INT_INFO("Exit function"); } void AudioOutputPortConfig::release() @@ -187,8 +277,5 @@ void AudioOutputPortConfig::release() } } - - - /** @} */ /** @} */ diff --git a/ds/audioOutputPortConfig.hpp b/ds/audioOutputPortConfig.hpp index 90526b99..54db385a 100644 --- a/ds/audioOutputPortConfig.hpp +++ b/ds/audioOutputPortConfig.hpp @@ -38,6 +38,14 @@ #include #include +typedef struct audioConfigs +{ + const dsAudioTypeConfig_t *pKConfigs; + const dsAudioPortConfig_t *pKPorts; + int *pKConfigSize; + int *pKPortSize; +}audioConfigs_t; + namespace device { class AudioOutputPortConfig { @@ -66,7 +74,7 @@ class AudioOutputPortConfig { List getPorts(); List getSupportedTypes(); - void load(); + void load(audioConfigs_t* dynamicAudioConfigs); void release(); }; diff --git a/ds/dslogger.cpp b/ds/dslogger.cpp index 2fd2f81e..9cdb7322 100644 --- a/ds/dslogger.cpp +++ b/ds/dslogger.cpp @@ -30,8 +30,12 @@ #include "dslogger.h" +#include // for SYS_gettid +#include // for syscall + #define unlikely(x) (__builtin_expect(!!(x), 0)) -#define MAX_LOG_BUFF 512 +#define MAX_LOG_BUFF 1024 +#define kFormatMessageSize (MAX_LOG_BUFF - 128) DS_LogCb logCb = NULL; @@ -40,29 +44,34 @@ void DS_RegisterForLog(DS_LogCb cb) logCb = cb; } -int ds_log(int priority, const char* fileName, int lineNum, const char *format, ...) +int ds_log(LogLevel priority, const char* fileName, int lineNum, const char *func, const char *format, ...) { - char tmp_buff[MAX_LOG_BUFF] = {'\0'}; - - int offset = snprintf(tmp_buff, MAX_LOG_BUFF, "[%s:%d] ", fileName, lineNum); + char formatted[MAX_LOG_BUFF] = {'\0'}; + enum LogLevel {INFO_LEVEL = 0, WARN_LEVEL, ERROR_LEVEL, DEBUG_LEVEL, TRACE_LEVEL}; + const char *levelMap[] = { "INFO", "WARN", "ERROR", "DEBUG", "TRACE"}; - // formatting error - if (unlikely(offset < 0)) { - offset = 0; - tmp_buff[0] = '\0'; // Ensure buffer is null-terminated if snprintf fails + if (!func || !fileName || !format) + { + return -1; } - va_list args; - va_start(args, format); - vsnprintf(tmp_buff + offset, MAX_LOG_BUFF - offset, format, args); - va_end(args); + va_list argptr; + va_start(argptr, format); + vsnprintf(formatted, kFormatMessageSize, format, argptr); + va_end(argptr); if (nullptr != logCb) { - logCb(priority, tmp_buff); + logCb(priority, formatted); } else { - return printf("%s\n", tmp_buff); + fprintf(stderr, "[DS][%d] %s [%s:%d] %s: %s \n", + (int)syscall(SYS_gettid), + levelMap[static_cast(priority)], + fileName, + lineNum, + func, + formatted); + fflush(stderr); } - return 0; } diff --git a/ds/edid-parser.cpp b/ds/edid-parser.cpp index 728a735c..9d51077c 100644 --- a/ds/edid-parser.cpp +++ b/ds/edid-parser.cpp @@ -55,7 +55,6 @@ static void parse_std_timing(unsigned char* bytes, edid_data_t* data_ptr) { case 1: v = (h * 3) / 4; break; case 2: v = (h * 4) / 5; break; case 3: v = (h * 9) / 16; break; - default: return; } int r = (bytes[idx + 1] & 0x3F) + 60; INT_DEBUG("STD %dx%d@%d\n", h, v, r); @@ -381,8 +380,6 @@ static void parse_ext_timing(unsigned char* bytes, edid_data_t* data_ptr) { case 6: break; // 'Use Extended Tag' case 7: parse_extended_db(&bytes[idx], data_ptr); break; - // default - unsupported - default: INT_DEBUG("Unsupported extension tag: 0x%X\n", tag); } idx += len + 1; } diff --git a/ds/frontPanelConfig.cpp b/ds/frontPanelConfig.cpp index e8c932b2..5d4d1030 100644 --- a/ds/frontPanelConfig.cpp +++ b/ds/frontPanelConfig.cpp @@ -41,6 +41,7 @@ #include "frontPanelSettings.hpp" #include "illegalArgumentException.hpp" #include "dslogger.h" +#include "manager.hpp" using namespace std; @@ -56,6 +57,7 @@ namespace device { FrontPanelConfig::FrontPanelConfig() { m_isFPInitialized = false; + m_isFPConfigLoaded = false; } @@ -69,6 +71,7 @@ FrontPanelConfig::~FrontPanelConfig() { //dsFPTerm(); m_isFPInitialized = false; + m_isFPConfigLoaded = false; } @@ -92,7 +95,6 @@ FrontPanelConfig & FrontPanelConfig::getInstance() errorCode = dsFPInit(); if (dsERR_NONE == errorCode) { - _singleton.load(); _singleton.m_isFPInitialized = true; INT_INFO("dsFPInit success\n"); } @@ -337,6 +339,64 @@ List FrontPanelConfig::getTextDisplays() return rTexts; } +void dumpconfig(fpdConfigs_t *configuration) +{ + if (nullptr == configuration) { + INT_ERROR("configuration is NULL"); + return; + } + if ( -1 == access("/opt/dsMgrDumpDeviceConfigs", F_OK) ) { + INT_INFO("Dumping of Device configs is disabled"); + return; + } + int indicatorSize = -1; + int indicatorColorSize = -1; + + // Dump the configuration details + INT_INFO("\n=============== Starting to Dump FrontPanel Configs ===============\n"); + + if (( nullptr != configuration->pKFPDIndicatorColors) && ( nullptr != configuration->pKIndicators)) + { + int indicatorSize = (configuration->pKIndicators_size) ? *(configuration->pKIndicators_size) : -1; + int indicatorColorSize = (configuration->pKFPDIndicatorColors_size) ? *(configuration->pKFPDIndicatorColors_size) : -1; + + for (int i = 0; i < indicatorColorSize; i++) { + const dsFPDColorConfig_t* fpdColorCfg = &configuration->pKFPDIndicatorColors[i]; + INT_INFO(" Color ID: %d, color: %d", fpdColorCfg->id, fpdColorCfg->color); + } + INT_INFO("Indicators:"); + for (int i = 0; i < indicatorSize; i++) { + const dsFPDIndicatorConfig_t* fpdIndicatorCfg = &configuration->pKIndicators[i]; + INT_INFO(" Indicator ID: %d, Max Brightness: %d, Max Cycle Rate: %d, Levels: %d, Color Mode: %d", + fpdIndicatorCfg->id, + fpdIndicatorCfg->maxBrightness, + fpdIndicatorCfg->maxCycleRate, + fpdIndicatorCfg->levels, + fpdIndicatorCfg->colorMode); + } + } + + if ( nullptr != configuration->pKTextDisplays) { + int textDisplaySize = (configuration->pKTextDisplays_size) ? *(configuration->pKTextDisplays_size) : -1; + INT_INFO("Text Displays: textDisplaySize =%d", textDisplaySize); + for (int i = 0; i < textDisplaySize; i++) { + const dsFPDTextDisplayConfig_t* fpdTextDisplayCfg = &configuration->pKTextDisplays[i]; + INT_INFO(" Text Display ID: %d, Max Brightness: %d, Max Cycle Rate: %d, Levels: %d, Max Horizontal Iterations: %d, Max Vertical Iterations: %d, Supported Characters: %s, Color Mode: %d", + fpdTextDisplayCfg->id, + fpdTextDisplayCfg->maxBrightness, + fpdTextDisplayCfg->maxCycleRate, + fpdTextDisplayCfg->levels, + fpdTextDisplayCfg->maxHorizontalIterations, + fpdTextDisplayCfg->maxVerticalIterations, + (fpdTextDisplayCfg->supportedCharacters) ? fpdTextDisplayCfg->supportedCharacters : DEFAULT_FPD_TEXT_DISPLAY_SUPPORTED_CHARACTERS, + fpdTextDisplayCfg->colorMode); + } + } + else { + INT_INFO(" No Text Displays configured."); + } + INT_INFO("\n=============== Dump FrontPanel Configs done ===============\n"); +} /** * @fn FrontPanelConfig::load() @@ -345,51 +405,106 @@ List FrontPanelConfig::getTextDisplays() * * @return None */ -void FrontPanelConfig::load() +void FrontPanelConfig::load(fpdConfigs_t* dynamicFPDConfigs) { - /* - * Create Indicators - * 1. Create Supported Colors. - * 2. Create Indicators. - */ - { - for (size_t i = 0; i < dsUTL_DIM(kIndicatorColors); i++) { - _colors.push_back(FrontPanelIndicator::Color(kIndicatorColors[i].id)); - } + /* + * Create Indicators + * 1. Create Supported Colors. + * 2. Create Indicators. + */ + int indicatorSize, indicatorColorSize, textDisplaySize; + fpdConfigs_t configuration = {0}; + INT_INFO("Enter function"); + if (( false == m_isFPInitialized) || (true == m_isFPConfigLoaded)) { + INT_ERROR("'%s'", (!m_isFPInitialized) ? "Front Panel not initialized" : "Front Panel Config already loaded"); + return; + } - for (size_t i = 0; i < dsUTL_DIM(kIndicators); i++) { - /* All indicators support a same set of colors */ - _indicators.push_back(FrontPanelIndicator(kIndicators[i].id, - kIndicators[i].maxBrightness, - kIndicators[i].maxCycleRate, - kIndicators[i].levels, - kIndicators[i].colorMode)); - } + INT_INFO("Using '%s' config", dynamicFPDConfigs ? "dynamic" : "static"); + if ( nullptr != dynamicFPDConfigs ) + { + configuration = *dynamicFPDConfigs; + indicatorSize = (configuration.pKIndicators_size) ? *(configuration.pKIndicators_size) : -1; + indicatorColorSize = (configuration.pKFPDIndicatorColors_size) ? *(configuration.pKFPDIndicatorColors_size) : -1; + textDisplaySize = (configuration.pKTextDisplays_size) ? *(configuration.pKTextDisplays_size) : -1; + } + else { + configuration.pKFPDIndicatorColors = kIndicatorColors; + indicatorColorSize = dsUTL_DIM(kIndicatorColors); + configuration.pKFPDIndicatorColors_size = &indicatorColorSize; + configuration.pKIndicators = kIndicators; + indicatorSize = dsUTL_DIM(kIndicators); + configuration.pKIndicators_size = &indicatorSize; + configuration.pKTextDisplays = kTextDisplays; + textDisplaySize = dsUTL_DIM(kTextDisplays); + configuration.pKTextDisplays_size = &textDisplaySize; + } - } + INT_INFO("FPD IndicatorColors[%p] IndicatorColors_size[%d] Indicators[%p] Indicators_size[%d] TextDisplays[%p] TextDisplays_size[%d]", + configuration.pKFPDIndicatorColors, + indicatorColorSize, + configuration.pKIndicators, + indicatorSize, + configuration.pKTextDisplays, + textDisplaySize); - { - /* - * Create TextDisplays - * 1. Use Supported Colors created for indicators. - * 2. Create Text Displays. - */ - for (size_t i = 0; i < dsUTL_DIM(kTextDisplays); i++) { - _textDisplays.push_back( - FrontPanelTextDisplay(kTextDisplays[i].id, - kTextDisplays[i].maxBrightness, - kTextDisplays[i].maxCycleRate, - kTextDisplays[i].levels, - kTextDisplays[i].maxHorizontalIterations, - kTextDisplays[i].maxVerticalIterations, - kTextDisplays[i].supportedCharacters, - kTextDisplays[i].colorMode)); - } - } -} + dumpconfig(&configuration); + if (( nullptr != configuration.pKFPDIndicatorColors ) && ( nullptr != configuration.pKIndicators)) + { + for (int i = 0; i < indicatorColorSize; i++) { + const dsFPDColorConfig_t* fpdColorCfg = &configuration.pKFPDIndicatorColors[i]; + _colors.push_back(FrontPanelIndicator::Color(fpdColorCfg->id)); + } + + for (int i = 0; i < indicatorSize; i++) { + const dsFPDIndicatorConfig_t* fpdIndicatorCfg = &configuration.pKIndicators[i]; + /* All indicators support a same set of colors */ + _indicators.push_back(FrontPanelIndicator(fpdIndicatorCfg->id, + fpdIndicatorCfg->maxBrightness, + fpdIndicatorCfg->maxCycleRate, + fpdIndicatorCfg->levels, + fpdIndicatorCfg->colorMode)); + } + } + else { + INT_ERROR("No valid indicator configuration found\n"); + } + + if ( nullptr != configuration.pKTextDisplays ) + { + /* + * Create TextDisplays + * 1. Use Supported Colors created for indicators. + * 2. Create Text Displays. + */ + INT_DEBUG("Text Displays \n"); + for (int i = 0; i < textDisplaySize; i++) { + const dsFPDTextDisplayConfig_t* fpdTextDisplayCfg = &configuration.pKTextDisplays[i]; + if (nullptr == fpdTextDisplayCfg->supportedCharacters) { + INT_ERROR("supportedCharacters is NULL at %d, using '%s' string...", i, DEFAULT_FPD_TEXT_DISPLAY_SUPPORTED_CHARACTERS); + } + _textDisplays.push_back( + FrontPanelTextDisplay(fpdTextDisplayCfg->id, + fpdTextDisplayCfg->maxBrightness, + fpdTextDisplayCfg->maxCycleRate, + fpdTextDisplayCfg->levels, + fpdTextDisplayCfg->maxHorizontalIterations, + fpdTextDisplayCfg->maxVerticalIterations, + (fpdTextDisplayCfg->supportedCharacters) ? std::string(fpdTextDisplayCfg->supportedCharacters) : std::string(DEFAULT_FPD_TEXT_DISPLAY_SUPPORTED_CHARACTERS), + fpdTextDisplayCfg->colorMode)); + } + } + else + { + INT_ERROR("No valid text display configuration found\n"); + } + m_isFPConfigLoaded = true; + INT_INFO("Exit function"); + return; } +} /** @} */ /** @} */ diff --git a/ds/frontPanelIndicator.cpp b/ds/frontPanelIndicator.cpp index 7a4d0202..68bae9a9 100644 --- a/ds/frontPanelIndicator.cpp +++ b/ds/frontPanelIndicator.cpp @@ -67,7 +67,6 @@ int stringToNumber (std::string text) return number; } - namespace { const char *_colorNames[] = { "Blue", @@ -100,7 +99,6 @@ namespace { }; - inline bool isIndicatorValid(int id) { return dsFPDIndicator_isValid(id); } diff --git a/ds/hdmiIn.cpp b/ds/hdmiIn.cpp index 514cff14..cb941da3 100755 --- a/ds/hdmiIn.cpp +++ b/ds/hdmiIn.cpp @@ -341,7 +341,7 @@ static std::string getResolutionStr (dsVideoResolution_t resolution) break; } - printf ("%s:%d - ResolutionStr: %s\n", __PRETTY_FUNCTION__,__LINE__, resolutionStr.c_str()); + INT_INFO("ResolutionStr: %s", resolutionStr.c_str()); return resolutionStr; } @@ -412,20 +412,20 @@ static std::string getFrameRateStr (dsVideoFrameRate_t frameRate) break; } - printf ("%s:%d - FrameRateStr: %s\n", __PRETTY_FUNCTION__,__LINE__, FrameRateStr.c_str()); + INT_INFO("FrameRateStr: %s", FrameRateStr.c_str()); return FrameRateStr; } static std::string getInterlacedStr (bool interlaced) { std::string InterlacedStr = (interlaced) ? "i" : "p"; - printf ("%s:%d - InterlacedStr: %s\n", __PRETTY_FUNCTION__,__LINE__, InterlacedStr.c_str()); + INT_INFO("InterlacedStr: %s", InterlacedStr.c_str()); return InterlacedStr; } static std::string CreateResolutionStr (const dsVideoPortResolution_t &resolution) { - printf("%s ---> \n", __PRETTY_FUNCTION__); + INT_INFO("--->"); std::string resolutionStr = getResolutionStr(resolution.pixelResolution); if(resolutionStr.compare("unknown") != 0){ @@ -433,7 +433,7 @@ static std::string CreateResolutionStr (const dsVideoPortResolution_t &resolutio getInterlacedStr(resolution.interlaced) + getFrameRateStr(resolution.frameRate); } - printf ("%s <--- %s\n", __PRETTY_FUNCTION__, resolutionStr.c_str()); + INT_INFO("<--- %s", resolutionStr.c_str()); return resolutionStr; } @@ -461,7 +461,7 @@ std::string HdmiInput::getCurrentVideoMode () const } std::string resolutionStr = CreateResolutionStr (resolution); - printf("%s:%d - Resolution =%s\n", __PRETTY_FUNCTION__,__LINE__, resolutionStr.c_str()); + INT_INFO("Resolution =%s", resolutionStr.c_str()); return resolutionStr; } @@ -478,13 +478,13 @@ void HdmiInput::getCurrentVideoModeObj (dsVideoPortResolution_t& resolution) throw Exception(eError); } - printf("%s:%d - pixelResolution =%d interlaced:%d frameRate:%d\n", __PRETTY_FUNCTION__, __LINE__, resolution.pixelResolution, resolution.interlaced, resolution.frameRate); + INT_INFO("pixelResolution =%d interlaced:%d frameRate:%d", resolution.pixelResolution, resolution.interlaced, resolution.frameRate); } void HdmiInput::getEDIDBytesInfo (int iHdmiPort, std::vector &edidArg) const { - printf("HdmiInput::getEDIDBytesInfo \r\n"); + INT_INFO("HdmiInput::getEDIDBytesInfo"); dsError_t ret = dsERR_NONE; int length = 0; @@ -493,10 +493,10 @@ void HdmiInput::getEDIDBytesInfo (int iHdmiPort, std::vector &edidArg) const char* exceptionstr = ""; ret = dsGetEDIDBytesInfo (static_cast(iHdmiPort), edid, &length); - printf("HdmiInput::getEDIDBytesInfo has ret %d\r\n", ret); + INT_INFO("HdmiInput::getEDIDBytesInfo has ret %d", ret); if (ret == dsERR_NONE) { if (length <= MAX_EDID_BYTES_LEN) { - printf("HdmiInput::getEDIDBytesInfo has %d bytes\r\n", length); + INT_INFO("HdmiInput::getEDIDBytesInfo has %d bytes", length); if (edid_parser::EDID_STATUS_OK == edid_parser::EDID_Verify(edid, length)) { edidArg.clear(); edidArg.insert(edidArg.begin(), edid, edid + length); @@ -518,17 +518,17 @@ void HdmiInput::getEDIDBytesInfo (int iHdmiPort, std::vector &edidArg) } void HdmiInput::getHDMISPDInfo (int iHdmiPort, std::vector &data) { - printf("HdmiInput::getHDMISPDInfo \r\n"); + INT_INFO("HdmiInput::getHDMISPDInfo"); unsigned char spdinfo[sizeof(struct dsSpd_infoframe_st)] = {0}; const char* exceptionstr = ""; dsError_t ret = dsGetHDMISPDInfo (static_cast(iHdmiPort), spdinfo); - printf("HdmiInput::getHDMISPDInfo has ret %d\r\n", ret); + INT_INFO("HdmiInput::getHDMISPDInfo has ret %d", ret); data.clear(); if (ret == dsERR_NONE) { if (sizeof(spdinfo) <= sizeof(struct dsSpd_infoframe_st)) { - printf("HdmiInput::getHDMISPDInfo has %d bytes\r\n", sizeof(spdinfo)); + printf("HdmiInput::getHDMISPDInfo has %zu bytes\r\n", sizeof(spdinfo)); data.insert(data.begin(), spdinfo, spdinfo + sizeof(struct dsSpd_infoframe_st)); } else { ret = dsERR_OPERATION_NOT_SUPPORTED; @@ -537,11 +537,11 @@ void HdmiInput::getHDMISPDInfo (int iHdmiPort, std::vector &data) { } else { exceptionstr = "getHDMISPDInfo failed"; } - printf("HdmiInput::getHDMISPDInfo data: \r\n"); + INT_INFO("HdmiInput::getHDMISPDInfo data:"); for (int itr = 0; itr < data.size(); itr++) { printf("%02X ", data[itr]); } - printf("\n"); + INT_INFO(""); if (ret != dsERR_NONE) { throw Exception(ret, exceptionstr); @@ -550,17 +550,17 @@ void HdmiInput::getHDMISPDInfo (int iHdmiPort, std::vector &data) { } void HdmiInput::setEdidVersion (int iHdmiPort, int iEdidVersion) { - printf ("HdmiInput::setEdidVersion \r\n"); + INT_INFO("HdmiInput::setEdidVersion"); dsError_t ret = dsSetEdidVersion (static_cast(iHdmiPort), static_cast(iEdidVersion)); if (ret != dsERR_NONE) { throw Exception(ret); } - printf ("%s:%d - Set EDID Version = %d\n", __PRETTY_FUNCTION__, __LINE__, iEdidVersion); + INT_INFO("Set EDID Version = %d", iEdidVersion); } void HdmiInput::getEdidVersion (int iHdmiPort, int *iEdidVersion) { - printf ("HdmiInput::getEdidVersion \r\n"); + INT_INFO("HdmiInput::getEdidVersion"); tv_hdmi_edid_version_t EdidVersion; dsError_t ret = dsGetEdidVersion (static_cast(iHdmiPort), &EdidVersion); if (ret != dsERR_NONE) @@ -569,7 +569,7 @@ void HdmiInput::getEdidVersion (int iHdmiPort, int *iEdidVersion) { } int tmp = static_cast(EdidVersion); *iEdidVersion = tmp; - printf ("%s:%d - EDID Version = %d\n", __PRETTY_FUNCTION__, __LINE__, *iEdidVersion); + INT_INFO("EDID Version = %d", *iEdidVersion); } void HdmiInput::setVRRSupport(int iHdmiPort, bool vrrSupport) @@ -579,7 +579,7 @@ void HdmiInput::setVRRSupport(int iHdmiPort, bool vrrSupport) { throw Exception(ret); } - printf ("%s:%d - Set VRR Support = %d\n", __PRETTY_FUNCTION__, __LINE__, vrrSupport); + INT_INFO("Set VRR Support = %d", vrrSupport); } void HdmiInput::getVRRSupport (int iHdmiPort, bool *vrrSupport) { @@ -588,7 +588,7 @@ void HdmiInput::getVRRSupport (int iHdmiPort, bool *vrrSupport) { { throw Exception(ret); } - printf ("%s:%d - EDID VRR Support = %d\n", __PRETTY_FUNCTION__, __LINE__, *vrrSupport); + INT_INFO("EDID VRR Support = %d", *vrrSupport); } void HdmiInput::getVRRStatus (int iHdmiPort, dsHdmiInVrrStatus_t *vrrStatus) { @@ -597,17 +597,17 @@ void HdmiInput::getVRRStatus (int iHdmiPort, dsHdmiInVrrStatus_t *vrrStatus) { { throw Exception(ret); } - printf ("%s:%d - VRR Type = %d , VRR FrameRate = %f\n", __FUNCTION__, __LINE__, vrrStatus->vrrType,vrrStatus->vrrAmdfreesyncFramerate_Hz); + INT_INFO("VRR Type = %d , VRR FrameRate = %f", vrrStatus->vrrType,vrrStatus->vrrAmdfreesyncFramerate_Hz); } void HdmiInput::getHdmiALLMStatus (int iHdmiPort, bool *allmStatus) { - printf ("HdmiInput::getHdmiALLMStatus \r\n"); + INT_INFO("HdmiInput::getHdmiALLMStatus"); dsError_t ret = dsGetAllmStatus (static_cast(iHdmiPort), allmStatus); if (ret != dsERR_NONE) { throw Exception(ret); } - printf ("%s:%d - ALLM Status = %d\n", __FUNCTION__, __LINE__, *allmStatus); + INT_INFO("ALLM Status = %d", *allmStatus); } void HdmiInput::getSupportedGameFeatures (std::vector &featureList) { @@ -629,7 +629,7 @@ void HdmiInput::getSupportedGameFeatures (std::vector &featureList) } if(featureList.size() != feList.gameFeatureCount){ - printf ("%s:%d - Number of Supported Game Features in list doesn't match with count from HAL", __FUNCTION__, __LINE__); + INT_ERROR("Number of Supported Game Features in list doesn't match with count from HAL"); throw Exception(dsERR_GENERAL); } } @@ -637,7 +637,7 @@ void HdmiInput::getSupportedGameFeatures (std::vector &featureList) void HdmiInput::getAVLatency (int *audio_output_delay,int *video_latency) { dsError_t ret = dsGetAVLatency (audio_output_delay,video_latency); - printf ("HdmiInput::getHdmiDAL_ - VideoLatency: %d , Audio Latency: %d \r\n",*video_latency,*audio_output_delay); + INT_INFO("VideoLatency: %d , Audio Latency: %d",*video_latency,*audio_output_delay); if (ret != dsERR_NONE) { throw Exception(ret); @@ -646,24 +646,24 @@ void HdmiInput::getAVLatency (int *audio_output_delay,int *video_latency) { void HdmiInput::setEdid2AllmSupport(int iHdmiPort,bool allmSupport) { - printf ("HdmiInput::setEdid2AllmSupport \r\n"); + INT_INFO("HdmiInput::setEdid2AllmSupport"); dsError_t ret = dsSetEdid2AllmSupport (static_cast(iHdmiPort), allmSupport); if (ret != dsERR_NONE) { throw Exception(ret); } - printf ("%s:%d - Set EDID Allm Support = %d\n", __PRETTY_FUNCTION__, __LINE__, allmSupport); + INT_INFO("Set EDID Allm Support = %d", allmSupport); } void HdmiInput::getEdid2AllmSupport (int iHdmiPort, bool *allmSupport) { - printf ("HdmiInput::getEdid2AllmSupport \r\n"); + INT_INFO("HdmiInput::getEdid2AllmSupport"); dsError_t ret = dsGetEdid2AllmSupport (static_cast(iHdmiPort), allmSupport); if (ret != dsERR_NONE) { throw Exception(ret); } - printf ("%s:%d - EDID allm Support = %d\n", __PRETTY_FUNCTION__, __LINE__, *allmSupport); + INT_INFO("EDID allm Support = %d", *allmSupport); } void HdmiInput::getHdmiVersion (int iHdmiPort, dsHdmiMaxCapabilityVersion_t *capversion) { @@ -675,7 +675,7 @@ void HdmiInput::getHdmiVersion (int iHdmiPort, dsHdmiMaxCapabilityVersion_t *cap throw Exception(ret); } - printf ("%s:%d - HDMI Compatibility Version = %d\n", __PRETTY_FUNCTION__, __LINE__, *capversion); + INT_INFO("HDMI Compatibility Version = %d", *capversion); } dsError_t HdmiInput::getHDMIARCPortId(int &portId) { diff --git a/ds/host.cpp b/ds/host.cpp index e2475e14..fd790ea3 100644 --- a/ds/host.cpp +++ b/ds/host.cpp @@ -385,6 +385,53 @@ Host::~Host() return std::string(socID); } + intptr_t Host::getAudioPortHandle() + { + try + { + if (isHDMIOutPortPresent()) + { + //STB profile with single audio output port + AudioOutputPort aPort = getAudioOutputPort("HDMI0"); + return aPort.getOutputPortHandle(); + } + else + { + //TV profile with multiple audio output ports + // First check the ports which are dynamically conected and finally fallback to SPEAKER0 which is always connected. + const std::string audio_ports[] = {"HDMI_ARC0", "HEADPHONE0", "SPDIF0", "SPEAKER0"}; + + // Try each port in priority order + for (const auto& portName : audio_ports) + { + try + { + AudioOutputPort aPort = getAudioOutputPort(portName); + cout << "Checking audio port: " << portName << " isEnabled: " << aPort.isEnabled() << " isConnected: " << aPort.isConnected() << "\n"; + // Check if port is enabled and connected + if (aPort.isEnabled() && aPort.isConnected()) + { + cout << "Using audio port: " << portName << "\n"; + return aPort.getOutputPortHandle(); + } + } + catch(const std::exception& e) + { + // Port not found or error accessing it, log and continue to next port + cout << "Exception while accessing audio port " << portName << ": " << e.what() << "\n"; + continue; + } + } + } + } + catch(const std::exception& e) + { + cout << " Exception Thrown in getAudioPortHandle().. returning NULL...: " << e.what() << "\n"; + } + + return NULL; + } + /** * Host::getCurrentAudioFormat(dsAudioFormat_t &audioFormat) * @brief @@ -397,8 +444,8 @@ Host::~Host() { dsError_t ret = dsERR_NONE; dsAudioFormat_t aFormat; - - ret = dsGetAudioFormat(NULL, &aFormat); + intptr_t audioPortHandle = getAudioPortHandle(); + ret = dsGetAudioFormat(audioPortHandle, &aFormat); if (ret == dsERR_NONE) { @@ -758,7 +805,7 @@ Host::~Host() { throw Exception(ret); } - printf ("%s:%d - Set Audio Mixer levels for audio input: %d with volume = %d\n", __PRETTY_FUNCTION__, __LINE__,aInput, volume); + INT_INFO("Set Audio Mixer levels for audio input: %d with volume = %d",aInput, volume); } DefaultImpl& Host::impl() diff --git a/ds/include/audioOutputPort.hpp b/ds/include/audioOutputPort.hpp index 9dec5126..0d050ffd 100644 --- a/ds/include/audioOutputPort.hpp +++ b/ds/include/audioOutputPort.hpp @@ -93,6 +93,7 @@ class AudioOutputPort : public Enumerable { const AudioOutputPortType & getType() const; int getId() const {return _id;}; int getIndex() const {return _index; }; + intptr_t getOutputPortHandle() const { return _handle;}; /** diff --git a/ds/include/dslogger.h b/ds/include/dslogger.h index e356979d..de8fb822 100644 --- a/ds/include/dslogger.h +++ b/ds/include/dslogger.h @@ -33,12 +33,9 @@ #include "dsregisterlog.h" -int ds_log(int priority, const char* fileName, int lineNum, const char *format, ...); +enum LogLevel {INFO_LEVEL = 0, WARN_LEVEL, ERROR_LEVEL, DEBUG_LEVEL, TRACE_LEVEL}; -#define INFO_LEVEL 0 -#define WARN_LEVEL 1 -#define ERROR_LEVEL 2 -#define DEBUG_LEVEL 3 +int ds_log(LogLevel level, const char* fileName, int lineNum, const char *func, const char *format, ...); // Helper to extract filename from full path // E.g. "/path/to/file.cpp" -> "file.cpp" @@ -52,13 +49,13 @@ static inline const char* fileName(const char* path) { #define DS_LOG_LEVEL ERROR_LEVEL #endif -#define INT_INFO(FORMAT, ...) ds_log(INFO_LEVEL, fileName(__FILE__), __LINE__, FORMAT, ##__VA_ARGS__ ) -#define INT_WARN(FORMAT, ...) ds_log(WARN_LEVEL, fileName(__FILE__), __LINE__, FORMAT, ##__VA_ARGS__ ) -#define INT_ERROR(FORMAT, ...) ds_log(ERROR_LEVEL, fileName(__FILE__), __LINE__, FORMAT, ##__VA_ARGS__ ) +#define INT_INFO(FORMAT, ...) ds_log(INFO_LEVEL, fileName(__FILE__), __LINE__, __FUNCTION__, FORMAT, ##__VA_ARGS__ ) +#define INT_WARN(FORMAT, ...) ds_log(WARN_LEVEL, fileName(__FILE__), __LINE__, __FUNCTION__, FORMAT, ##__VA_ARGS__ ) +#define INT_ERROR(FORMAT, ...) ds_log(ERROR_LEVEL, fileName(__FILE__), __LINE__, __FUNCTION__, FORMAT, ##__VA_ARGS__ ) // conditionally enable debug logs, based on DS_LOG_LEVEL #if DS_LOG_LEVEL >= DEBUG_LEVEL -#define INT_DEBUG(FORMAT, ...) ds_log(DEBUG_LEVEL, fileName(__FILE__), __LINE__, FORMAT, ##__VA_ARGS__ ) +#define INT_DEBUG(FORMAT, ...) ds_log(DEBUG_LEVEL, fileName(__FILE__), __LINE__, __FUNCTION__, FORMAT, ##__VA_ARGS__ ) #else #define INT_DEBUG(FORMAT, ...) ((void)0) #endif diff --git a/ds/include/exception.hpp b/ds/include/exception.hpp index 463435c7..bbb9836e 100644 --- a/ds/include/exception.hpp +++ b/ds/include/exception.hpp @@ -64,7 +64,7 @@ class Exception : public std::exception { * * @return None */ - Exception(const char *msg = "No Message for this exception") throw() : _msg(msg) { + Exception(const char *msg = "No Message for this exception") throw() : _err(0), _msg(msg) { } diff --git a/ds/include/frontPanelConfig.hpp b/ds/include/frontPanelConfig.hpp index 77c243ba..a85d4c0f 100644 --- a/ds/include/frontPanelConfig.hpp +++ b/ds/include/frontPanelConfig.hpp @@ -44,6 +44,18 @@ */ using namespace std; +typedef struct fpdConfigs +{ + const dsFPDColorConfig_t *pKFPDIndicatorColors; + const dsFPDIndicatorConfig_t *pKIndicators; + const dsFPDTextDisplayConfig_t *pKTextDisplays; + int *pKFPDIndicatorColors_size; + int *pKIndicators_size; + int *pKTextDisplays_size; +}fpdConfigs_t; + +#define DEFAULT_FPD_TEXT_DISPLAY_SUPPORTED_CHARACTERS "ABCEDFG" + namespace device { @@ -59,12 +71,11 @@ class FrontPanelConfig { std::vector _textDisplays; //!< Container to hold all the FrontPanelTextDisplay instances. std::vector _colors; //!< Container to hold all the Color instances. bool m_isFPInitialized; + bool m_isFPConfigLoaded; FrontPanelConfig(); virtual ~FrontPanelConfig(); - void load(); - public: static FrontPanelConfig & getInstance(); @@ -80,11 +91,12 @@ class FrontPanelConfig { List getIndicators(); List getTextDisplays(); - /* Initialize Front Panel */ - void fPInit(); - /* Terminate Front Panel */ - void fPTerm(); + /* Initialize Front Panel */ + void fPInit(); + /* Terminate Front Panel */ + void fPTerm(); + void load(fpdConfigs_t* dynamicFPDConfigs); }; } diff --git a/ds/include/host.hpp b/ds/include/host.hpp index 02adbfa8..a6a9ce53 100644 --- a/ds/include/host.hpp +++ b/ds/include/host.hpp @@ -431,6 +431,7 @@ class Host { void setSecondaryLanguage(const std::string sLang); void getSecondaryLanguage(std::string& sLang); bool isHDMIOutPortPresent(); + intptr_t getAudioPortHandle(); std::string getDefaultVideoPortName(); std::string getDefaultAudioPortName(); void getCurrentAudioFormat(dsAudioFormat_t& audioFormat); diff --git a/ds/include/manager.hpp b/ds/include/manager.hpp index 2539569a..bcf53014 100644 --- a/ds/include/manager.hpp +++ b/ds/include/manager.hpp @@ -149,6 +149,10 @@ #ifndef _DS_MANAGER_HPP_ #define _DS_MANAGER_HPP_ +#include +#include // for access API + +using namespace std; /** * @file manager.hpp @@ -156,6 +160,24 @@ */ namespace device { +typedef enum DeviceCapabilityTypes { + DEVICE_CAPABILITY_INVALID = 0x00000000, + DEVICE_CAPABILITY_AUDIO_PORT = 0x00000001, + DEVICE_CAPABILITY_VIDEO_PORT = 0x00000002, + DEVICE_CAPABILITY_VIDEO_DEVICE = 0x00000004, + DEVICE_CAPABILITY_FRONT_PANEL = 0x00000008, + DEVICE_CAPABILITY_MAX = 0xFFFFFFFF +} +DeviceCapabilityTypes; + +typedef struct dlSymbolLookup { + const char* name; + void** dataptr; +} +dlSymbolLookup; + +bool LoadDLSymbols(void* pDLHandle, const dlSymbolLookup* symbols, int numberOfSymbols); +void loadDeviceCapabilities(unsigned int capabilityType); /** * @class Manager @@ -169,7 +191,7 @@ class Manager { static void Initialize(); static void DeInitialize(); static void load(); //!< This function is being used for loading configure in-process DSMgr. - static int IsInitialized; //!< Indicates the application has initialized with devicettings modules. + static int IsInitialized; //!< Indicates the application has initialized with devicettings modules. }; } diff --git a/ds/manager.cpp b/ds/manager.cpp index eedcd8b2..7c88ed71 100644 --- a/ds/manager.cpp +++ b/ds/manager.cpp @@ -43,6 +43,10 @@ #include "exception.hpp" #include #include +#include +#include +#include "dsHALConfig.h" +#include "frontPanelConfig.hpp" /** * @file manager.cpp @@ -62,6 +66,129 @@ namespace device { int Manager::IsInitialized = 0; //!< Indicates the application has initialized with devicettings modules. static std::mutex gManagerInitMutex; +static dsError_t initializeFunctionWithRetry(const char* functionName, std::function initFunc); + +bool LoadDLSymbols(void* pDLHandle, const dlSymbolLookup* symbols, int numberOfSymbols) +{ + int currentSymbols = 0; + bool isAllSymbolsLoaded = false; + if ((nullptr == pDLHandle) || (nullptr == symbols)) { + INT_ERROR("Invalid DL Handle or symbolsPtr"); + } + else { + INT_INFO("numberOfSymbols = %d",numberOfSymbols); + for (int i = 0; i < numberOfSymbols; i++) { + if (( nullptr == symbols[i].dataptr) || ( nullptr == symbols[i].name)) { + INT_ERROR("Invalid symbol entry at index [%d]", i); + continue; + } + *(symbols[i].dataptr) = dlsym(pDLHandle, symbols[i].name); + if (nullptr == *(symbols[i].dataptr)) { + INT_ERROR("[%s] is not defined", symbols[i].name); + } + else { + currentSymbols++; + INT_INFO("[%s] is defined and loaded, data[%p]", symbols[i].name, *(symbols[i].dataptr)); + } + } + isAllSymbolsLoaded = (numberOfSymbols) ? (currentSymbols == numberOfSymbols) : false; + } + return isAllSymbolsLoaded; +} + +void loadDeviceCapabilities(unsigned int capabilityType) +{ + void* pDLHandle = nullptr; + bool isSymbolsLoaded = false; + + INT_INFO("Entering capabilityType = 0x%08X", capabilityType); + dlerror(); // clear old error + pDLHandle = dlopen(RDK_DSHAL_NAME, RTLD_LAZY); + + if (nullptr == pDLHandle) { + const char* dlError = dlerror(); + INT_WARN("Failed to dlopen '%s': %s - Falling back to static configurations", + RDK_DSHAL_NAME, dlError ? dlError : "Unknown error"); + } else { + INT_INFO("Successfully opened dynamic library '%s'", RDK_DSHAL_NAME); + } + + INT_INFO("DL Instance '%s'", (nullptr == pDLHandle ? "NULL" : "Valid")); + + // Audio Port Config + if (DEVICE_CAPABILITY_AUDIO_PORT & capabilityType) { + audioConfigs_t dynamicAudioConfigs = {0 }; + dlSymbolLookup audioConfigSymbols[] = { + {"kAudioConfigs", (void**)&dynamicAudioConfigs.pKConfigs}, + {"kAudioPorts", (void**)&dynamicAudioConfigs.pKPorts}, + {"kAudioConfigs_size", (void**)&dynamicAudioConfigs.pKConfigSize}, + {"kAudioPorts_size", (void**)&dynamicAudioConfigs.pKPortSize} + }; + + isSymbolsLoaded = false; + if (nullptr != pDLHandle) { + isSymbolsLoaded = LoadDLSymbols(pDLHandle, audioConfigSymbols, sizeof(audioConfigSymbols)/sizeof(dlSymbolLookup)); + } + AudioOutputPortConfig::getInstance().load(isSymbolsLoaded ? &dynamicAudioConfigs : nullptr); + } + + // Video Port Config + if (DEVICE_CAPABILITY_VIDEO_PORT & capabilityType) { + videoPortConfigs_t dynamicVideoPortConfigs = {0}; + dlSymbolLookup videoPortConfigSymbols[] = { + {"kVideoPortConfigs", (void**)&dynamicVideoPortConfigs.pKConfigs}, + {"kVideoPortConfigs_size", (void**)&dynamicVideoPortConfigs.pKVideoPortConfigs_size}, + {"kVideoPortPorts", (void**)&dynamicVideoPortConfigs.pKPorts}, + {"kVideoPortPorts_size", (void**)&dynamicVideoPortConfigs.pKVideoPortPorts_size}, + {"kResolutionsSettings", (void**)&dynamicVideoPortConfigs.pKResolutionsSettings}, + {"kResolutionsSettings_size", (void**)&dynamicVideoPortConfigs.pKResolutionsSettings_size} + }; + + isSymbolsLoaded = false; + if (nullptr != pDLHandle) { + isSymbolsLoaded = LoadDLSymbols(pDLHandle, videoPortConfigSymbols, sizeof(videoPortConfigSymbols)/sizeof(dlSymbolLookup)); + } + VideoOutputPortConfig::getInstance().load(isSymbolsLoaded ? &dynamicVideoPortConfigs : nullptr); + } + + // Video Device Config + if (DEVICE_CAPABILITY_VIDEO_DEVICE & capabilityType) { + videoDeviceConfig_t dynamicVideoDeviceConfigs = {0}; + dlSymbolLookup videoDeviceConfigSymbols[] = { + {"kVideoDeviceConfigs", (void**)&dynamicVideoDeviceConfigs.pKVideoDeviceConfigs}, + {"kVideoDeviceConfigs_size", (void**)&dynamicVideoDeviceConfigs.pKVideoDeviceConfigs_size} + }; + isSymbolsLoaded = false; + if (nullptr != pDLHandle) { + isSymbolsLoaded = LoadDLSymbols(pDLHandle, videoDeviceConfigSymbols, sizeof(videoDeviceConfigSymbols)/sizeof(dlSymbolLookup)); + } + VideoDeviceConfig::getInstance().load(isSymbolsLoaded ? &dynamicVideoDeviceConfigs : nullptr); + } + + // Front Panel Config + if (DEVICE_CAPABILITY_FRONT_PANEL & capabilityType) { + fpdConfigs_t dynamicFPDConfigs = {0}; + dlSymbolLookup fpdConfigSymbols[] = { + {"kFPDIndicatorColors", (void**)&dynamicFPDConfigs.pKFPDIndicatorColors}, + {"kFPDIndicatorColors_size", (void**)&dynamicFPDConfigs.pKFPDIndicatorColors_size}, + {"kIndicators", (void**)&dynamicFPDConfigs.pKIndicators}, + {"kIndicators_size", (void**)&dynamicFPDConfigs.pKIndicators_size}, + {"kFPDTextDisplays", (void**)&dynamicFPDConfigs.pKTextDisplays}, + {"kFPDTextDisplays_size", (void**)&dynamicFPDConfigs.pKTextDisplays_size} + }; + isSymbolsLoaded = false; + if (nullptr != pDLHandle) { + isSymbolsLoaded = LoadDLSymbols(pDLHandle, fpdConfigSymbols, sizeof(fpdConfigSymbols)/sizeof(dlSymbolLookup)); + } + FrontPanelConfig::getInstance().load(isSymbolsLoaded ? &dynamicFPDConfigs : nullptr); + } + + if (nullptr != pDLHandle) { + dlclose(pDLHandle); + pDLHandle = nullptr; + } + INT_INFO("Exiting ..."); +} Manager::Manager() { // TODO Auto-generated constructor stub @@ -79,6 +206,41 @@ Manager::~Manager() { }\ } +/** + * @brief Retry initialization function with configurable retry logic. + * + * This helper function attempts to initialize a device settings component by calling + * the provided initialization function. It retries the operation with a delay between + * attempts until either the operation succeeds, the maximum retry count is reached, + * or (optionally) a specific error state is encountered. + * + * @param[in] functionName Name of the initialization function being called. Used for logging + * purposes to identify which component is being initialized. + * @param[in] initFunc Lambda or function object that performs the actual initialization. + * Should return dsError_t indicating success (dsERR_NONE) or an error code. + * + * @return dsERR_NONE on successful initialization, or the last error code encountered after + * all retry attempts are exhausted. When checkInvalidState is true, also returns + * immediately with the error code if a non-dsERR_INVALID_STATE error occurs. + */ +dsError_t initializeFunctionWithRetry(const char* functionName, + std::function initFunc) +{ + dsError_t err = dsERR_GENERAL; + unsigned int retryCount = 0; + unsigned int maxRetries = 25; + + do { + err = initFunc(); + printf("Manager::Initialize:%s result :%d retryCount :%d\n", + functionName, err, retryCount); + if (dsERR_NONE == err) break; + usleep(100000); + } while (retryCount++ < maxRetries); + + return err; +} + /** * @addtogroup dssettingsmanagerapi * @{ @@ -105,53 +267,55 @@ Manager::~Manager() { */ void Manager::Initialize() { - {std::lock_guard lock(gManagerInitMutex); - printf("Entering %s count %d with thread id %lu\n",__FUNCTION__,IsInitialized,pthread_self()); + bool needInit = false; + + {std::lock_guard lock(gManagerInitMutex); + printf("Entering %s count %d with thread id %lu\n",__FUNCTION__,IsInitialized,pthread_self()); + if (IsInitialized == 0) { + needInit = true; + } + IsInitialized++; + } - try { - if (0 == IsInitialized) { - - dsError_t err = dsERR_GENERAL; - unsigned int retryCount = 0; - // This retry logic will wait for the device manager initialization from the client side - // until the device manager service initialization is completed. The retry mechanism checks - // only for dsERR_INVALID_STATE, which is reported if the underlying service is not ready. - // Once the service is ready, other port initializations can be called directly without any delay. - // That's why the retry logic is applied only for dsDisplayInit. - do { - err = dsDisplayInit(); - printf ("Manager::Initialize: result :%d retryCount :%d\n", err, retryCount); - if (dsERR_NONE == err) break; - usleep(100000); - } while(( dsERR_INVALID_STATE == err) && (retryCount++ < 25)); + try { + if (needInit) { + dsError_t err = dsERR_GENERAL; + + err = initializeFunctionWithRetry("dsDisplayInit", dsDisplayInit); CHECK_RET_VAL(err); - err = dsAudioPortInit(); + + err = initializeFunctionWithRetry("dsAudioPortInit", dsAudioPortInit); CHECK_RET_VAL(err); - err = dsVideoPortInit(); + + err = initializeFunctionWithRetry("dsVideoPortInit", dsVideoPortInit); CHECK_RET_VAL(err); - err = dsVideoDeviceInit(); - CHECK_RET_VAL(err); - AudioOutputPortConfig::getInstance().load(); - VideoOutputPortConfig::getInstance().load(); - VideoDeviceConfig::getInstance().load(); - } - IsInitialized++; + + err = initializeFunctionWithRetry("dsVideoDeviceInit", dsVideoDeviceInit); + CHECK_RET_VAL(err); + + loadDeviceCapabilities(device::DEVICE_CAPABILITY_VIDEO_PORT | + device::DEVICE_CAPABILITY_AUDIO_PORT | + device::DEVICE_CAPABILITY_VIDEO_DEVICE | + device::DEVICE_CAPABILITY_FRONT_PANEL); + } } catch(const Exception &e) { - cout << "Caught exception during Initialization" << e.what() << endl; - throw e; - } - } - printf("Exiting %s with thread %lu\n",__FUNCTION__,pthread_self()); + cout << "Caught exception during Initialization" << e.what() << endl; + std::lock_guard lock(gManagerInitMutex); + IsInitialized--; + throw e; + } + + INT_INFO("Exiting ... with thread id %lu",pthread_self()); } void Manager::load() { - printf("%d:%s load start\n", __LINE__, __FUNCTION__); - device::AudioOutputPortConfig::getInstance().load(); - device::VideoOutputPortConfig::getInstance().load(); - device::VideoDeviceConfig::getInstance().load(); - printf("%d:%s load completed\n", __LINE__, __FUNCTION__); + INT_INFO("Enter function"); + loadDeviceCapabilities( device::DEVICE_CAPABILITY_VIDEO_PORT | + device::DEVICE_CAPABILITY_AUDIO_PORT | + device::DEVICE_CAPABILITY_VIDEO_DEVICE); + INT_INFO("Exit function"); } /** @@ -176,7 +340,7 @@ void Manager::load() void Manager::DeInitialize() { {std::lock_guard lock(gManagerInitMutex); - printf("Entering %s count %d with thread id: %lu\n",__FUNCTION__,IsInitialized,pthread_self()); + INT_INFO("Entering ... count %d with thread id %lu",IsInitialized,pthread_self()); if(IsInitialized>0)IsInitialized--; if (0 == IsInitialized) { @@ -190,8 +354,7 @@ void Manager::DeInitialize() dsDisplayTerm(); } } - printf("Exiting %s with thread %lu\n",__FUNCTION__,pthread_self()); - + INT_INFO("Exiting ... with thread %lu",pthread_self()); } } diff --git a/ds/videoDevice.cpp b/ds/videoDevice.cpp index 37452a0c..494a8d93 100644 --- a/ds/videoDevice.cpp +++ b/ds/videoDevice.cpp @@ -33,6 +33,7 @@ #include "illegalArgumentException.hpp" #include "exception.hpp" #include "videoDeviceConfig.hpp" +#include "videoOutputPortConfig.hpp" #include "dsVideoResolutionSettings.h" #include "host.hpp" @@ -101,7 +102,7 @@ VideoDevice & VideoDevice::getInstance(int id) * @param[in] id Port id. * @return None. */ -VideoDevice::VideoDevice(int id) +VideoDevice::VideoDevice(int id): _dfc(0) { dsError_t ret = dsGetVideoDevice(id, &_handle); @@ -258,16 +259,16 @@ void VideoDevice::getHDRCapabilities(int *capabilities) dsGetHDRCapabilities(_handle, capabilities); } + void VideoDevice::getSettopSupportedResolutions(std::list& stbSupportedResoltuions) { - size_t numResolutions = dsUTL_DIM(kResolutions); - for (size_t i = 0; i < numResolutions; i++) - { - dsVideoPortResolution_t *resolution = &kResolutions[i]; - stbSupportedResoltuions.push_back(std::string(resolution->name)); + stbSupportedResoltuions.clear(); + + const std::vector& resolutions = VideoOutputPortConfig::getInstance()._originalSupportedResolutions; + + for (const VideoResolution& res : resolutions) { + stbSupportedResoltuions.push_back(res.getName()); } - - return; } unsigned int VideoDevice::getSupportedVideoCodingFormats() const diff --git a/ds/videoDeviceConfig.cpp b/ds/videoDeviceConfig.cpp index 0a25b478..491d93c5 100644 --- a/ds/videoDeviceConfig.cpp +++ b/ds/videoDeviceConfig.cpp @@ -33,7 +33,7 @@ #include "videoDFC.hpp" #include #include "dslogger.h" - +#include "manager.hpp" namespace device { @@ -86,8 +86,46 @@ VideoDFC & VideoDeviceConfig::getDefaultDFC() return _vDFCs.back(); } -void VideoDeviceConfig::load() +void dumpconfig(videoDeviceConfig_t *config) +{ + if (nullptr == config) { + INT_ERROR("Video config is NULL"); + return; + } + if ( -1 == access("/opt/dsMgrDumpDeviceConfigs", F_OK) ) { + INT_INFO("Dumping of Device configs is disabled"); + return; + } + + INT_INFO("\n=============== Starting to Dump VideoDevice Configs ===============\n"); + + if( nullptr != config->pKVideoDeviceConfigs ) + { + int configSize = (config->pKVideoDeviceConfigs_size) ? *(config->pKVideoDeviceConfigs_size) : -1; + INT_INFO("pKVideoDeviceConfigs = %p", config->pKVideoDeviceConfigs); + INT_INFO("videoDeviceConfigs_size = %d", configSize); + for (int i = 0; i < configSize; i++) { + dsVideoConfig_t* videoDeviceConfig = &config->pKVideoDeviceConfigs[i]; + INT_INFO("pKVideoDeviceConfigs[%d].numSupportedDFCs = %lu ", i, videoDeviceConfig->numSupportedDFCs); + for (int j = 0; j < videoDeviceConfig->numSupportedDFCs; j++) { + INT_INFO(" Address of pKVideoDeviceConfigs[%d].supportedDFCs[%d] = %d", i, j, videoDeviceConfig->supportedDFCs[j]); + } + } + } + else + { + INT_ERROR(" kVideoDeviceConfigs is NULL"); + } + + INT_INFO("\n=============== Dump VideoDevice Configs done ===============\n"); +} + +void VideoDeviceConfig::load(videoDeviceConfig_t* dynamicVideoDeviceConfigs) { + int configSize = -1; + videoDeviceConfig_t configuration = {0}; + + INT_INFO("Enter function"); /* * Load Constants First. */ @@ -95,16 +133,41 @@ void VideoDeviceConfig::load() _vDFCs.push_back(VideoDFC(i)); } + INT_INFO("Using '%s' config", dynamicVideoDeviceConfigs ? "dynamic" : "static"); + if ( nullptr != dynamicVideoDeviceConfigs ) + { + configuration = *dynamicVideoDeviceConfigs; + configSize = (configuration.pKVideoDeviceConfigs_size) ? *(configuration.pKVideoDeviceConfigs_size) : -1; + } + else { + configuration.pKVideoDeviceConfigs = (dsVideoConfig_t *)kConfigs; + configSize = dsUTL_DIM(kConfigs); + configuration.pKVideoDeviceConfigs_size = &configSize; + } + + INT_INFO("VideoDevice Config[%p] ConfigSize[%d]", configuration.pKVideoDeviceConfigs, configSize); + + dumpconfig(&configuration); + /* * Initialize Video Devices (supported DFCs etc.) */ - for (size_t i = 0; i < dsUTL_DIM(kConfigs); i++) { - _vDevices.push_back(VideoDevice(i)); - - for (size_t j = 0; j < kConfigs[i].numSupportedDFCs; j++) { - _vDevices.at(i).addDFC(VideoDFC::getInstance(kConfigs[i].supportedDFCs[j])); + if ( nullptr != configuration.pKVideoDeviceConfigs ) + { + for (int i = 0; i < configSize; i++) { + dsVideoConfig_t* videoDeviceCfg = &configuration.pKVideoDeviceConfigs[i]; + _vDevices.push_back(VideoDevice(i)); + + for (int j = 0; j < videoDeviceCfg->numSupportedDFCs; j++) { + _vDevices.at(i).addDFC(VideoDFC::getInstance(videoDeviceCfg->supportedDFCs[j])); + } } } + else + { + INT_ERROR(" Configs are NULL and config size are -1"); + } + INT_INFO("Exit function"); } void VideoDeviceConfig::release() diff --git a/ds/videoDeviceConfig.hpp b/ds/videoDeviceConfig.hpp index 65fcf791..c6b0659d 100644 --- a/ds/videoDeviceConfig.hpp +++ b/ds/videoDeviceConfig.hpp @@ -35,6 +35,12 @@ #include "videoDevice.hpp" #include +typedef struct videoDeviceConfig +{ + dsVideoConfig_t *pKVideoDeviceConfigs; + int *pKVideoDeviceConfigs_size; +}videoDeviceConfig_t; + namespace device { class VideoDeviceConfig { @@ -55,7 +61,7 @@ class VideoDeviceConfig { VideoDFC & getDFC(int id); VideoDFC & getDefaultDFC(); - void load(); + void load(videoDeviceConfig_t* dynamicVideoDeviceConfigs); void release(); }; diff --git a/ds/videoOutputPort.cpp b/ds/videoOutputPort.cpp index c77aa5c4..a5b29674 100644 --- a/ds/videoOutputPort.cpp +++ b/ds/videoOutputPort.cpp @@ -128,7 +128,7 @@ VideoOutputPort::VideoOutputPort(const int type, const int index, const int id, _resolution(resolution), _display(*this) { - dsError_t ret = dsGetVideoPort((dsVideoPortType_t)_type, _index, &_handle); + dsError_t ret = dsGetVideoPort((dsVideoPortType_t)_type, _index, &_handle); { std::stringstream out; @@ -138,25 +138,25 @@ VideoOutputPort::VideoOutputPort(const int type, const int index, const int id, if (ret == dsERR_NONE) { bool enabled = false; - ret = dsIsVideoPortEnabled(_handle, &enabled); + ret = dsIsVideoPortEnabled(_handle, &enabled); if (ret == dsERR_NONE) { _enabled = enabled; _contentProtected = false; bool connected = false; - ret = dsIsDisplayConnected(_handle, &connected); + ret = dsIsDisplayConnected(_handle, &connected); if (ret == dsERR_NONE) { - _displayConnected = connected; + _displayConnected = connected; } else { - throw IllegalArgumentException(); + throw IllegalArgumentException(); } } else { } } else { - throw IllegalArgumentException(); + throw IllegalArgumentException(); } } @@ -465,7 +465,7 @@ bool VideoOutputPort::isDynamicResolutionSupported() const */ void VideoOutputPort::setResolution(const std::string &resolutionName, bool persist/* = true*/, bool isIgnoreEdid/* = false*/) { - printf("ResOverride VideoOutputPort::setResolution resolutionName:%s persist:%d isIgnoreEdid:%d line:%d\r\n", resolutionName.c_str(), persist, isIgnoreEdid, __LINE__); + INT_INFO("ResOverride VideoOutputPort::setResolution resolutionName:%s persist:%d isIgnoreEdid:%d", resolutionName.c_str(), persist, isIgnoreEdid); if (0 && resolutionName.compare(_resolution) == 0) { return; } diff --git a/ds/videoOutputPortConfig.cpp b/ds/videoOutputPortConfig.cpp index 8f1e475c..faf80a23 100644 --- a/ds/videoOutputPortConfig.cpp +++ b/ds/videoOutputPortConfig.cpp @@ -42,6 +42,7 @@ #include "videoResolution.hpp" #include "dslogger.h" #include "host.hpp" +#include "manager.hpp" #include @@ -99,7 +100,7 @@ const VideoResolution &VideoOutputPortConfig::getVideoResolution (int id) const return _supportedResolutions.at(id); } else { - cout<<"returns default resolution 720p"< VideoOutputPortConfig::getSupportedResolutions(bool isIgn intptr_t _handle = 0; //CID:98922 - Uninit bool force_disable_4K = true; - printf ("\nResOverride VideoOutputPortConfig::getSupportedResolutions isIgnoreEdid:%d\n", isIgnoreEdid); + INT_INFO("VideoOutputPortConfig::getSupportedResolutions isIgnoreEdid=%d", isIgnoreEdid); if (!isIgnoreEdid) { try { std::string strVideoPort = device::Host::getInstance().getDefaultVideoPortName(); @@ -184,11 +185,11 @@ List VideoOutputPortConfig::getSupportedResolutions(bool isIgn dsError = dsGetEDID(_handle, edid); if(dsError != dsERR_NONE) { - cout <<" dsGetEDID failed so setting edid->numOfSupportedResolution to 0"<< endl; + INT_ERROR("dsGetEDID failed with error %d, setting edid->numOfSupportedResolution to 0", dsError); edid->numOfSupportedResolution = 0; } - cout <<" EDID Num of Resolution ......."<< edid->numOfSupportedResolution << endl; + INT_INFO("EDID reports %d supported resolutions", edid->numOfSupportedResolution); for (size_t i = 0; i < edid->numOfSupportedResolution; i++) { dsVideoPortResolution_t *resolution = &edid->suppResolutionList[i]; @@ -210,26 +211,16 @@ List VideoOutputPortConfig::getSupportedResolutions(bool isIgn }catch (...) { isDynamicList = 0; - cout << "VideoOutputPortConfig::getSupportedResolutions Thrown. Exception..."<name), - resolution->pixelResolution, - resolution->aspectRatio, - resolution->stereoScopicMode, - resolution->frameRate, - resolution->interlaced)); - } + INT_INFO("_originalSupportedResolutions size: %zu", _originalSupportedResolutions.size()); + for (const VideoResolution& resolution : _originalSupportedResolutions) { + tmpsupportedResolutions.push_back(resolution); + } } if (!isIgnoreEdid) { try { @@ -237,7 +228,7 @@ List VideoOutputPortConfig::getSupportedResolutions(bool isIgn } catch(...) { - cout<<"Failed to get status of forceDisable4K!"<::iterator it = tmpsupportedResolutions.begin(); it != tmpsupportedResolutions.end(); it++) { if (it->isEnabled()) { @@ -254,7 +245,7 @@ List VideoOutputPortConfig::getSupportedResolutions(bool isIgn } } {std::lock_guard lock(gSupportedResolutionsMutex); - cout<<"_supportedResolutions cache updated"< VideoOutputPortConfig::getSupportedResolutions(bool isIgn } - -void VideoOutputPortConfig::load() +void dumpconfig(videoPortConfigs_t *config) { - try { - /* - * Load Constants First. - */ - for (size_t i = 0; i < dsVIDEO_PIXELRES_MAX; i++) { - _vPixelResolutions.push_back(PixelResolution(i)); - } - for (size_t i = 0; i < dsVIDEO_ASPECT_RATIO_MAX; i++) { - _vAspectRatios.push_back(AspectRatio(i)); - } - for (size_t i = 0; i < dsVIDEO_SSMODE_MAX; i++) { - _vStereoScopieModes.push_back(StereoScopicMode(i)); - } - for (size_t i = 0; i < dsVIDEO_FRAMERATE_MAX; i++) { - _vFrameRates.push_back(FrameRate((int)i)); - } - - for (size_t i = 0; i < dsVIDEOPORT_TYPE_MAX; i++) { - _vPortTypes.push_back(VideoOutputPortType((int)i)); - } - - /* Initialize a set of supported resolutions - * - */ - size_t numResolutions = dsUTL_DIM(kResolutions); - for (size_t i = 0; i < numResolutions; i++) { - dsVideoPortResolution_t *resolution = &kResolutions[i]; - {std::lock_guard lock(gSupportedResolutionsMutex); - _supportedResolutions.push_back( - VideoResolution( - i, /* id */ - std::string(resolution->name), - resolution->pixelResolution, - resolution->aspectRatio, - resolution->stereoScopicMode, - resolution->frameRate, - resolution->interlaced)); - } - } - - - /* - * Initialize Video portTypes (Only Enable POrts) - * and its port instances (curr resolution) - */ - for (size_t i = 0; i < dsUTL_DIM(kConfigs); i++) - { - const dsVideoPortTypeConfig_t *typeCfg = &kConfigs[i]; - VideoOutputPortType &vPortType = VideoOutputPortType::getInstance(typeCfg->typeId); - vPortType.enable(); - vPortType.setRestrictedResolution(typeCfg->restrictedResollution); - } - - /* - * set up ports based on kPorts[] - */ - for (size_t i = 0; i < dsUTL_DIM(kPorts); i++) { - const dsVideoPortPortConfig_t *port = &kPorts[i]; - - _vPorts.push_back( - VideoOutputPort((port->id.type), port->id.index, i, - AudioOutputPortType::getInstance(kPorts[i].connectedAOP.type).getPort(kPorts[i].connectedAOP.index).getId(), - std::string(port->defaultResolution))); - - _vPortTypes.at(port->id.type).addPort(_vPorts.at(i)); - - } + if (nullptr == config) { + INT_ERROR("Video config is NULL"); + return; + } + if ( -1 == access("/opt/dsMgrDumpDeviceConfigs", F_OK) ) { + INT_INFO("Dumping of Device configs is disabled"); + return; + } + INT_INFO("\n=============== Starting to Dump VideoPort Configs ===============\n"); + + int configSize = -1, portSize = -1, resolutionSize = -1; + if (( nullptr != config->pKConfigs ) && ( nullptr != config->pKPorts ) && ( nullptr != config->pKResolutionsSettings )) + { + configSize = (config->pKVideoPortConfigs_size) ? *(config->pKVideoPortConfigs_size) : -1; + portSize = (config->pKVideoPortPorts_size) ? *(config->pKVideoPortPorts_size) : -1; + resolutionSize = (config->pKResolutionsSettings_size) ? *(config->pKResolutionsSettings_size) : -1; + INT_INFO("pKConfigs = %p", config->pKConfigs); + INT_INFO("pKConfigSize pointer %p = %d", config->pKVideoPortConfigs_size, configSize); + INT_INFO("pKPorts = %p", config->pKPorts); + INT_INFO("pKPortSize pointer %p = %d", config->pKVideoPortPorts_size, portSize); + INT_INFO("pKResolutionsSettings = %p", config->pKResolutionsSettings); + INT_INFO("pKResolutionsSettingsSize pointer %p = %d", config->pKResolutionsSettings_size, resolutionSize); + + INT_INFO("\n\n############### Dumping Video Resolutions Settings ############### \n\n"); + + for (int i = 0; i < resolutionSize; i++) { + dsVideoPortResolution_t *resolution = &(config->pKResolutionsSettings[i]); + INT_INFO("resolution->name = %s", resolution->name); + INT_INFO("resolution->pixelResolution= %d", resolution->pixelResolution); + INT_INFO("resolution->aspectRatio= %d", resolution->aspectRatio); + INT_INFO("resolution->stereoScopicMode= %d", resolution->stereoScopicMode); + INT_INFO("resolution->frameRate= %d", resolution->frameRate); + INT_INFO("resolution->interlaced= %d", resolution->interlaced); + } + + INT_INFO("\n ############### Dumping Video Port Configurations ############### \n"); + + for (int i = 0; i < configSize; i++) + { + const dsVideoPortTypeConfig_t *typeCfg = &(config->pKConfigs[i]); + INT_INFO("typeCfg->typeId = %d", typeCfg->typeId); + INT_INFO("typeCfg->name = %s", (typeCfg->name) ? typeCfg->name : "NULL"); + INT_INFO("typeCfg->dtcpSupported= %d", typeCfg->dtcpSupported); + INT_INFO("typeCfg->hdcpSupported = %d", typeCfg->hdcpSupported); + INT_INFO("typeCfg->restrictedResollution = %d", typeCfg->restrictedResollution); + INT_INFO("typeCfg->numSupportedResolutions= %lu", typeCfg->numSupportedResolutions); + + if ((typeCfg->supportedResolutions != NULL) && (typeCfg->numSupportedResolutions > 0)) + { + INT_INFO("typeCfg->supportedResolutions = %p", typeCfg->supportedResolutions); + INT_INFO("typeCfg->supportedResolutions->name = %s", (typeCfg->supportedResolutions->name) ? typeCfg->supportedResolutions->name : "NULL"); + INT_INFO("typeCfg->supportedResolutions->pixelResolution= %d", typeCfg->supportedResolutions->pixelResolution); + INT_INFO("typeCfg->supportedResolutions->aspectRatio= %d", typeCfg->supportedResolutions->aspectRatio); + INT_INFO("typeCfg->supportedResolutions->stereoScopicMode= %d", typeCfg->supportedResolutions->stereoScopicMode); + INT_INFO("typeCfg->supportedResolutions->frameRate= %d", typeCfg->supportedResolutions->frameRate); + INT_INFO("typeCfg->supportedResolutions->interlaced= %d", typeCfg->supportedResolutions->interlaced); + } + else + { + INT_INFO("typeCfg has no supportedResolutions entries to dump (pointer is %p, numSupportedResolutions = %lu)", + typeCfg->supportedResolutions, + typeCfg->numSupportedResolutions); + } + } + INT_INFO("\n############### Dumping Video Port Connections ###############\n"); + + for (int i = 0; i < portSize; i++) { + const dsVideoPortPortConfig_t *portCfg = &(config->pKPorts[i]); + INT_INFO("portCfg->id.type = %d", portCfg->id.type); + INT_INFO("portCfg->id.index = %d", portCfg->id.index); + INT_INFO("portCfg->connectedAOP.type = %d", portCfg->connectedAOP.type); + INT_INFO("portCfg->connectedAOP.index = %d", portCfg->connectedAOP.index); + INT_INFO("portCfg->defaultResolution = %s", (portCfg->defaultResolution) ? portCfg->defaultResolution : "NULL"); + } + } + else + { + INT_ERROR("pKConfigs or pKPorts or pKResolutionsSettings is NULL"); + } + INT_INFO("\n=============== Dump VideoPort Configs done ===============\n"); +} - } - catch (...) { - cout << "VIdeo Outport Exception Thrown. ..."<name), + resolution->pixelResolution, + resolution->aspectRatio, + resolution->stereoScopicMode, + resolution->frameRate, + resolution->interlaced); + {std::lock_guard lock(gSupportedResolutionsMutex); + _supportedResolutions.push_back(vidRes); + _originalSupportedResolutions.push_back(vidRes); + } + INT_INFO("[DsMgr] Loaded resolution[%d]: name='%s' pixelRes=%d aspectRatio=%d frameRate=%d", + i, resolution->name, resolution->pixelResolution, resolution->aspectRatio, resolution->frameRate); + } + + /* + * Initialize Video portTypes (Only Enable POrts) + * and its port instances (curr resolution) + */ + for (int i = 0; i < configSize; i++) + { + const dsVideoPortTypeConfig_t *typeCfg = &(configuration.pKConfigs[i]); + VideoOutputPortType &vPortType = VideoOutputPortType::getInstance(typeCfg->typeId); + vPortType.enable(); + vPortType.setRestrictedResolution(typeCfg->restrictedResollution); + } + + /* + * set up ports based on kPorts[] + */ + for (int i = 0; i < portSize; i++) { + const dsVideoPortPortConfig_t *portCfg = &(configuration.pKPorts[i]); + if (nullptr == portCfg->defaultResolution) { + INT_ERROR("defaultResolution is NULL at %d, using empty string...", i); + } + _vPorts.push_back( + VideoOutputPort((portCfg->id.type), portCfg->id.index, i, + AudioOutputPortType::getInstance(portCfg->connectedAOP.type).getPort(portCfg->connectedAOP.index).getId(), + (portCfg->defaultResolution) ? std::string(portCfg->defaultResolution) : std::string(""))); + _vPortTypes.at(portCfg->id.type).addPort(_vPorts.at(i)); + } + } + else + { + INT_ERROR("Video output port configs, ports, or resolutions is NULL"); + throw Exception("Failed to load video outport config"); + } + } + catch (...) { + INT_ERROR("Exception thrown while loading video output port config"); throw Exception("Failed to load video outport config"); - } - + } } void VideoOutputPortConfig::release() @@ -361,7 +472,5 @@ void VideoOutputPortConfig::release() } } } - - /** @} */ /** @} */ diff --git a/ds/videoOutputPortConfig.hpp b/ds/videoOutputPortConfig.hpp index 4b011e02..2dec0d53 100644 --- a/ds/videoOutputPortConfig.hpp +++ b/ds/videoOutputPortConfig.hpp @@ -33,13 +33,19 @@ #include "videoOutputPortType.hpp" #include "videoResolution.hpp" - - - - #include #include +typedef struct videoPortConfigs +{ + const dsVideoPortTypeConfig_t *pKConfigs; + int *pKVideoPortConfigs_size; + const dsVideoPortPortConfig_t *pKPorts; + int *pKVideoPortPorts_size; + dsVideoPortResolution_t *pKResolutionsSettings; + int *pKResolutionsSettings_size; +}videoPortConfigs_t; + namespace device { class VideoOutputPortConfig { @@ -59,6 +65,7 @@ class VideoOutputPortConfig { ~VideoOutputPortConfig(); public: + std::vector _originalSupportedResolutions; static VideoOutputPortConfig & getInstance(); const PixelResolution &getPixelResolution(int id) const; @@ -74,7 +81,7 @@ class VideoOutputPortConfig { List getSupportedTypes(); List getSupportedResolutions(bool isIgnoreEdid=false); - void load(); + void load(videoPortConfigs_t* dynamicVideoPortConfigs); void release(); }; diff --git a/ds/videoOutputPortType.cpp b/ds/videoOutputPortType.cpp index 87ebbaa6..2e112058 100644 --- a/ds/videoOutputPortType.cpp +++ b/ds/videoOutputPortType.cpp @@ -36,7 +36,7 @@ #include "illegalArgumentException.hpp" #include "videoOutputPortConfig.hpp" #include "dslogger.h" - +#include "dsVideoPort.h" #include @@ -209,19 +209,26 @@ void VideoOutputPortType::enabledDTCP() */ void VideoOutputPortType::enabledHDCP(bool contentProtect , char *hdcpKey , size_t keySize ) { - dsError_t ret = dsERR_NONE; - if (device::Host::getInstance().isHDMIOutPortPresent()){ - ret = dsEnableHDCP(dsVIDEOPORT_TYPE_HDMI, contentProtect, hdcpKey, keySize); + dsError_t ret = dsERR_NONE; + intptr_t handle = -1; + + // Assuming isHDMIOutPortPresent() will only be 'true' for Source devices + dsVideoPortType_t portType = device::Host::getInstance().isHDMIOutPortPresent() + ? dsVIDEOPORT_TYPE_HDMI + : dsVIDEOPORT_TYPE_INTERNAL; + ret = dsGetVideoPort(portType, 0, &handle); + if ((ret == dsERR_NONE) && (handle != -1)) { + ret = dsEnableHDCP(handle, contentProtect, hdcpKey, keySize); + } else { + INT_ERROR("VideoOutputPortType::enabledHDCP: Error type %d, handle=%p, error code=%d", portType, (void *)handle, ret); + // Set ret to an error code on dsGetVideoPort failure or invalid handle to ensure exception is thrown + ret = dsERR_GENERAL; } - else{ - ret = dsEnableHDCP(dsVIDEOPORT_TYPE_INTERNAL , contentProtect, hdcpKey, keySize); + + if (ret != dsERR_NONE) { + throw IllegalArgumentException(); } - - if (ret != dsERR_NONE) - { - throw IllegalArgumentException(); - } - _hdcpSupported = true; + _hdcpSupported = true; } diff --git a/rpc/cli/Makefile b/rpc/cli/Makefile index 8acae1df..ab24c14f 100644 --- a/rpc/cli/Makefile +++ b/rpc/cli/Makefile @@ -37,7 +37,7 @@ all: install library: $(OBJS) @echo "Building $(LIBNAMEFULL) ...." - $(CXX) $(OBJS) $(CFLAGS) -shared -o $(LIBNAMEFULL) + $(CXX) $(OBJS) $(CFLAGS) -lIARMBus -shared -o $(LIBNAMEFULL) %.o: %.cpp @echo "Building $@ ...." diff --git a/rpc/cli/dsVideoPort.c b/rpc/cli/dsVideoPort.c index 5ff4c9e4..d8e15541 100644 --- a/rpc/cli/dsVideoPort.c +++ b/rpc/cli/dsVideoPort.c @@ -82,7 +82,7 @@ dsError_t dsGetVideoPort(dsVideoPortType_t type, int index, intptr_t *handle) ¶m, sizeof(param)); - printf("%s..%d-%d\n",__func__,param.type,param.handle); + printf("%s..%d-%ld\n",__func__,param.type,(long)param.handle); if (IARM_RESULT_SUCCESS == rpcRet) { @@ -530,7 +530,7 @@ dsError_t dsEnableHDCP(intptr_t handle, bool contentProtect, char *hdcpKey, siz } } - printf("IARM:CLI:dsEnableHDCP %d, %p, %d\r\n", contentProtect, hdcpKey, keySize); + printf("IARM:CLI:dsEnableHDCP %d, %p, %zu\r\n", contentProtect, hdcpKey, keySize); IARM_Result_t rpcRet = IARM_RESULT_SUCCESS; rpcRet = IARM_Bus_Call(IARM_BUS_DSMGR_NAME, diff --git a/rpc/include/dsAudioConfig.h b/rpc/include/dsAudioConfig.h new file mode 100644 index 00000000..9723d79c --- /dev/null +++ b/rpc/include/dsAudioConfig.h @@ -0,0 +1,77 @@ +/* + * 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 +* @{ +**/ + +#ifndef _DS_AUDIO_CONFIG_H_ +#define _DS_AUDIO_CONFIG_H_ + +#include "dsTypes.h" +#include "dsError.h" +#include "dsConfigs.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief Load audio output port configuration + * + * @param[in] dynamicAudioConfigs Pointer to dynamic audio configuration, or NULL for static config + * @return dsERR_NONE on success, dsERR_GENERAL on error + */ +dsError_t dsLoadAudioOutputPortConfig(const audioConfigs_t* dynamicAudioConfigs); + +/** + * @brief Get audio type configurations + * + * @param[out] outConfigSize Pointer to store the number of audio type configs, or NULL + * @param[out] outConfigs Pointer to store the audio type configs array, or NULL + * @return dsERR_NONE on success, dsERR_GENERAL on error + */ +dsError_t _dsGetAudioTypeConfigs(int* outConfigSize, const dsAudioTypeConfig_t** outConfigs); + +/** + * @brief Get audio port configurations + * + * @param[out] outPortSize Pointer to store the number of audio port configs, or NULL + * @param[out] outPorts Pointer to store the audio port configs array, or NULL + * @return dsERR_NONE on success, dsERR_GENERAL on error + */ +dsError_t _dsGetAudioPortConfigs(int* outPortSize, const dsAudioPortConfig_t** outPorts); + +/** + * @brief Free audio configuration resources + */ +void dsAudioConfigFree(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _DS_AUDIO_CONFIG_H_ */ + +/** @} */ +/** @} */ diff --git a/rpc/include/dsConfigs.h b/rpc/include/dsConfigs.h new file mode 100644 index 00000000..5bea4ca8 --- /dev/null +++ b/rpc/include/dsConfigs.h @@ -0,0 +1,83 @@ +/* + * 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 +* @{ +**/ + +#ifndef _DS_CONFIGS_H_ +#define _DS_CONFIGS_H_ + +#include "dsTypes.h" +#include "dsError.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct audioConfigs +{ + const dsAudioTypeConfig_t *pKAudioConfigs; + const dsAudioPortConfig_t *pKAudioPorts; + int *pKConfigSize; + int *pKPortSize; +}audioConfigs_t; + +typedef struct videoPortConfigs +{ + const dsVideoPortTypeConfig_t *pKVideoPortConfigs; + int *pKVideoPortConfigs_size; + const dsVideoPortPortConfig_t *pKVideoPortPorts; + int *pKVideoPortPorts_size; + dsVideoPortResolution_t *pKVideoPortResolutionsSettings; + int *pKResolutionsSettings_size; + int *pKDefaultResIndex; +}videoPortConfigs_t; + +typedef struct videoDeviceConfig +{ + dsVideoConfig_t *pKVideoDeviceConfigs; + int *pKVideoDeviceConfigs_size; +}videoDeviceConfig_t; + +/** + * @brief Load all device settings configurations + * + * Loads audio, video port, and video device configurations from HAL library + * @return dsERR_NONE on success, dsERR_GENERAL on failure + */ +dsError_t dsLoadConfigs(void); + +/** + * Free the config dynamic pointers + * @return dsERR_NONE on success, dsERR_GENERAL on failure + */ +dsError_t dsFreeConfig(); + +#ifdef __cplusplus +} +#endif + +#endif /* _DS_CONFIGS_H_ */ + +/** @} */ +/** @} */ diff --git a/rpc/include/dsVideoDeviceConfig.h b/rpc/include/dsVideoDeviceConfig.h new file mode 100644 index 00000000..f95ef795 --- /dev/null +++ b/rpc/include/dsVideoDeviceConfig.h @@ -0,0 +1,67 @@ +/* + * 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 +* @{ +**/ + +#ifndef _DS_VIDEO_DEVICE_CONFIG_H_ +#define _DS_VIDEO_DEVICE_CONFIG_H_ + +#include "dsTypes.h" +#include "dsError.h" +#include "dsConfigs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Load video device configuration + * + * @param[in] dynamicVideoDeviceConfigs Pointer to dynamic video device configuration, or NULL for static config + * @return dsERR_NONE on success, dsERR_GENERAL on error + */ +dsError_t dsLoadVideoDeviceConfig(const videoDeviceConfig_t* dynamicVideoDeviceConfigs); + +/** + * @brief Get video device configurations + * + * @param[out] outConfigSize Pointer to store the number of video device configs, or NULL + * @param[out] outConfigs Pointer to store the video device configs array, or NULL + * @return dsERR_NONE on success, dsERR_GENERAL on error + */ +dsError_t _dsGetVideoDeviceConfigs(int* outConfigSize, dsVideoConfig_t** outConfigs); + +/** + * @brief Free video device configuration resources + */ +void dsVideoDeviceConfigFree(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _DS_VIDEO_DEVICE_CONFIG_H_ */ + +/** @} */ +/** @} */ diff --git a/rpc/include/dsVideoPortConfig.h b/rpc/include/dsVideoPortConfig.h new file mode 100644 index 00000000..be525120 --- /dev/null +++ b/rpc/include/dsVideoPortConfig.h @@ -0,0 +1,94 @@ +/* + * 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 +* @{ +**/ + +#ifndef _DS_VIDEO_PORT_CONFIG_H_ +#define _DS_VIDEO_PORT_CONFIG_H_ + +#include "dsTypes.h" +#include "dsError.h" +#include "dsConfigs.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief Load video output port configuration + * + * @param[in] dynamicVideoPortConfigs Pointer to dynamic video port configuration, or NULL for static config + * @return dsERR_NONE on success, dsERR_GENERAL on error + */ +dsError_t dsLoadVideoOutputPortConfig(const videoPortConfigs_t* dynamicVideoPortConfigs); + +/** + * @brief Get video port type configurations + * + * @param[out] outConfigSize Pointer to store the number of video port type configs, or NULL + * @param[out] outConfigs Pointer to store the video port type configs array, or NULL + * @return dsERR_NONE on success, dsERR_GENERAL on error + */ +dsError_t _dsGetVideoPortTypeConfigs(int* outConfigSize, const dsVideoPortTypeConfig_t** outConfigs); + +/** + * @brief Get video port port configurations + * + * @param[out] outPortSize Pointer to store the number of video port port configs, or NULL + * @param[out] outPorts Pointer to store the video port port configs array, or NULL + * @return dsERR_NONE on success, dsERR_GENERAL on error + */ +dsError_t _dsGetVideoPortPortConfigs(int* outPortSize, const dsVideoPortPortConfig_t** outPorts); + +/** + * @brief Get video port resolutions + * + * @param[out] outResolutionSize Pointer to store the number of video port resolutions, or NULL + * @param[out] outResolutions Pointer to store the video port resolutions array, or NULL + * @return dsERR_NONE on success, dsERR_GENERAL on error + */ +dsError_t _dsGetVideoPortResolutions(int* outResolutionSize, dsVideoPortResolution_t** outResolutions); + +/** + * @brief Get default resolution index + * + * @param[out] outDefaultIndex Pointer to store the default resolution index, or NULL + * @return dsERR_NONE on success, dsERR_GENERAL on error + */ +dsError_t _dsGetDefaultResolutionIndex(int* outDefaultIndex); + +/** + * @brief Free video port configuration resources + */ +void dsVideoPortConfigFree(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _DS_VIDEO_PORT_CONFIG_H_ */ + +/** @} */ +/** @} */ diff --git a/rpc/include/dsserverlogger.h b/rpc/include/dsserverlogger.h index b2df3944..d33d3973 100644 --- a/rpc/include/dsserverlogger.h +++ b/rpc/include/dsserverlogger.h @@ -30,22 +30,30 @@ #define _DS_SERVER_LOGGER_H_ #include +#include #include "dsserverregisterlog.h" int ds_server_log(int priority,const char *format, ...); +// Helper to extract filename from full path +// E.g. "/path/to/file.cpp" -> "file.cpp" +// IMPORTANT: This will work for Unix style paths only +static inline const char* fileName(const char* path) { + const char* slash = strrchr(path, '/'); + return slash ? slash + 1 : path; +} #if (defined(DSMGR_LOGGER_ENABLED)) #include "rdk_debug.h" void dsServer_Rdklogger_Init(); -#define INT_ERROR(FORMAT, ...) LOG_ERROR(PREFIX(FORMAT), __LINE__, __FUNCTION__, ##__VA_ARGS__) -#define INT_WARNING(FORMAT, ...) LOG_WARNING(PREFIX(FORMAT), __LINE__, __FUNCTION__, ##__VA_ARGS__) -#define INT_INFO(FORMAT, ...) LOG_INFO(PREFIX(FORMAT), __LINE__, __FUNCTION__, ##__VA_ARGS__) -#define INT_DEBUG(FORMAT, ...) LOG_DEBUG(PREFIX(FORMAT), __LINE__, __FUNCTION__, ##__VA_ARGS__) -#define INT_TRACE(FORMAT, ...) LOG_TRACE(PREFIX(FORMAT), __LINE__, __FUNCTION__, ##__VA_ARGS__) +#define INT_ERROR(FORMAT, ...) LOG_ERROR(PREFIX(FORMAT), fileName(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__) +#define INT_WARNING(FORMAT, ...) LOG_WARNING(PREFIX(FORMAT), fileName(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__) +#define INT_INFO(FORMAT, ...) LOG_INFO(PREFIX(FORMAT), fileName(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__) +#define INT_DEBUG(FORMAT, ...) LOG_DEBUG(PREFIX(FORMAT), fileName(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__) +#define INT_TRACE(FORMAT, ...) LOG_TRACE(PREFIX(FORMAT), fileName(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__) -#define PREFIX(FORMAT) "%d\t: %s - " FORMAT +#define PREFIX(FORMAT) "[%s:%d] %s: " FORMAT extern int b_rdk_logger_enabled; diff --git a/rpc/srv/Makefile.am b/rpc/srv/Makefile.am index c1bfadf1..1a700b1f 100644 --- a/rpc/srv/Makefile.am +++ b/rpc/srv/Makefile.am @@ -29,4 +29,6 @@ lib_LTLIBRARIES = libdshalsrv.la libdshalsrv_la_CPPFLAGS = $(INCLUDE_FILES) libdshalsrv_la_CXXFLAGS= -std=c++0x -g -fPIC -D_REENTRANT -Wall libdshalsrv_la_CFLAGS = -x c++ -g -fPIC -D_REENTRANT -Wall -libdshalsrv_la_SOURCES = dsHost.cpp hostPersistence.cpp dsAudio.c dsDisplay.c dsFPD.c dsMgr.c dsVideoDevice.c dsVideoPort.c dsserverlogger.c +libdshalsrv_la_SOURCES = dsHost.cpp hostPersistence.cpp dsAudio.c dsDisplay.c dsFPD.c dsMgr.c dsVideoDevice.c dsVideoPort.c dsserverlogger.c \ + dsConfigs.c dsAudioConfig.c dsVideoPortConfig.c dsVideoDeviceConfig.c dsCompositeIn.c dsHdmiIn.c +libdshalsrv_la_LIBADD = -ldl diff --git a/rpc/srv/dsAudio.c b/rpc/srv/dsAudio.c index 7d085ffd..fb6f95b8 100755 --- a/rpc/srv/dsAudio.c +++ b/rpc/srv/dsAudio.c @@ -49,7 +49,7 @@ #include "dsMgr.h" #include "hostPersistence.hpp" #include "dsserverlogger.h" -#include "dsAudioSettings.h" +#include "dsAudioConfig.h" #include "safec_lib.h" @@ -1624,7 +1624,7 @@ void AudioConfigInit() m_volumeLeveller.level = atoi(_volLevellerLevel.c_str()); //SPEAKER init handle = 0; - INT_DEBUG("bDolbyVolumeOverrideCheck value: %d\n", bDolbyVolumeOverrideCheck); + INT_DEBUG("bDolbyVolumeOverrideCheck value: %d\n", (int)bDolbyVolumeOverrideCheck); if(bDolbyVolumeOverrideCheck && dsGetAudioPort(dsAUDIOPORT_TYPE_SPEAKER,0,&handle) == dsERR_NONE) { if (dsSetVolumeLevellerFunc(handle, m_volumeLeveller) == dsERR_NONE) { INT_INFO("Port %s: Initialized Volume Leveller : Mode: %d, Level: %d\n","SPEAKER0", m_volumeLeveller.mode, m_volumeLeveller.level); @@ -2357,10 +2357,18 @@ IARM_Result_t dsAudioMgr_init() IARM_Result_t dsAudioMgr_term() { #ifdef DS_AUDIO_SETTINGS_PERSISTENCE - if(persist_audioLevel_timer_threadIsAlive){ + bool shouldJoin = false; + pthread_t threadId; + IARM_BUS_Lock(lock); + shouldJoin = persist_audioLevel_timer_threadIsAlive; + if(shouldJoin){ persist_audioLevel_timer_threadIsAlive=false; + threadId = persist_audioLevel_timer_threadId; pthread_cond_signal(&audioLevelTimerCV); - pthread_join(persist_audioLevel_timer_threadId,NULL); + } + IARM_BUS_Unlock(lock); + if(shouldJoin){ + pthread_join(threadId,NULL); } #endif return IARM_RESULT_SUCCESS; @@ -3707,12 +3715,17 @@ IARM_Result_t _dsGetAudioFormat(void *arg) { dsAudioFormat_t aFormat = dsAUDIO_FORMAT_NONE; param->audioFormat = dsAUDIO_FORMAT_NONE; - - if (func(param->handle, &aFormat) == dsERR_NONE) + dsError_t ret = dsERR_NONE; + ret = func(param->handle, &aFormat); + if (ret == dsERR_NONE) { param->audioFormat = aFormat; result = IARM_RESULT_SUCCESS; } + else + { + INT_INFO("%s dsGetAudioFormat failed ret=%d\n",__FUNCTION__, ret); + } } IARM_BUS_Unlock(lock); @@ -3777,17 +3790,23 @@ IARM_Result_t _dsGetEncoding(void *arg) static dsAudioPortType_t _GetAudioPortType(intptr_t handle) { - int numPorts,i; + int numPorts = 0; + int i; intptr_t halhandle = 0; + const dsAudioPortConfig_t *pAudioPorts = NULL; - numPorts = dsUTL_DIM(kSupportedPortTypes); + // Get audio port configurations from AudioOutputPortConfig + if (_dsGetAudioPortConfigs(&numPorts, &pAudioPorts) != dsERR_NONE) { + INT_ERROR("Failed to get audio port configurations\n"); + return dsAUDIOPORT_TYPE_MAX; + } for(i=0; i< numPorts; i++) { - if(dsGetAudioPort (kPorts[i].id.type, kPorts[i].id.index, &halhandle) == dsERR_NONE) { + if(dsGetAudioPort (pAudioPorts[i].id.type, pAudioPorts[i].id.index, &halhandle) == dsERR_NONE) { if (handle == halhandle) { - return kPorts[i].id.type; + return pAudioPorts[i].id.type; } } } @@ -7222,6 +7241,7 @@ static void* persist_audioLevel_timer_threadFunc(void* arg) { break; } // wait for 3 sec, then update the latest audio level from cache variable + /* coverity[sleep : FALSE] */ if(audioLevel_timer_set){ sleep(3); diff --git a/rpc/srv/dsAudioConfig.c b/rpc/srv/dsAudioConfig.c new file mode 100644 index 00000000..cab63ec1 --- /dev/null +++ b/rpc/srv/dsAudioConfig.c @@ -0,0 +1,445 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2026 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 +* @{ +**/ + +#include +#include +#include +#include +#include "dsserverlogger.h" +#include "dsTypes.h" +#include "dsError.h" +#include "dsAudioConfig.h" +#include "dsAudioSettings.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct audioConfigsLocal +{ + dsAudioTypeConfig_t *pKAudioConfigs; + dsAudioPortConfig_t *pKAudioPorts; + int kConfigSize; + int kPortSize; +}audioConfigsLocal_t; + +static audioConfigsLocal_t audioConfiguration = {0}; + +void audioDumpconfig(audioConfigsLocal_t *config) +{ + if (NULL == config) { + INT_ERROR("Audio config is NULL\n"); + return; + } + if ( -1 == access("/opt/dsMgrDumpDeviceConfigs", F_OK) ) { + INT_INFO("Dumping of Device configs is disabled\n"); + return; + } + + int configSize = -1, portSize = -1; + INT_INFO("\n=============== Starting to Dump Audio Configs ===============\n"); + if( NULL != config->pKAudioConfigs ) + { + configSize = config->kConfigSize; + + for (int i = 0; i < configSize; i++) { + const dsAudioTypeConfig_t *typeCfg = &(config->pKAudioConfigs[i]); + INT_INFO("typeCfg->typeId = %d\n", typeCfg->typeId); + INT_INFO("typeCfg->name = %s\n", typeCfg->name); + INT_INFO("typeCfg->numSupportedEncodings = %zu\n", typeCfg->numSupportedEncodings); + INT_INFO("typeCfg->numSupportedCompressions = %zu\n", typeCfg->numSupportedCompressions); + INT_INFO("typeCfg->numSupportedStereoModes = %zu\n", typeCfg->numSupportedStereoModes); + } + } + else + { + INT_ERROR("kAudioConfigs is NULL\n"); + } + + if( NULL != config->pKAudioPorts ) + { + portSize = config->kPortSize; + for (int i = 0; i < portSize; i++) { + const dsAudioPortConfig_t *portCfg = &(config->pKAudioPorts[i]); + INT_INFO("portCfg->id.type = %d\n", portCfg->id.type); + INT_INFO("portCfg->id.index = %d\n", portCfg->id.index); + } + } + else + { + INT_ERROR("kAudioPorts is NULL\n"); + } + + INT_INFO("\n=============== Dump Audio Configs done ===============\n"); +} + +static int allocateAndCopyAudioConfigs(const dsAudioTypeConfig_t* source, int numElements, bool isDynamic) +{ + const char* configType = isDynamic ? "dynamic" : "static"; + + if (numElements <= 0) { + INT_ERROR("Invalid %s config numElements: %d\n", configType, numElements); + return -1; + } + + audioConfiguration.pKAudioConfigs = (dsAudioTypeConfig_t*)malloc(numElements * sizeof(dsAudioTypeConfig_t)); + if (audioConfiguration.pKAudioConfigs == NULL) { + INT_ERROR("Failed to allocate memory for %s audio configs\n", configType); + return -1; + } + + // Deep copy each audio type config + for (int i = 0; i < numElements; i++) { + dsAudioTypeConfig_t *dest = &audioConfiguration.pKAudioConfigs[i]; + const dsAudioTypeConfig_t *src = &source[i]; + + // Copy primitive fields + dest->typeId = src->typeId; + dest->numSupportedCompressions = src->numSupportedCompressions; + dest->numSupportedEncodings = src->numSupportedEncodings; + dest->numSupportedStereoModes = src->numSupportedStereoModes; + + // Deep copy name string + if (src->name != NULL) { + dest->name = strdup(src->name); + if (dest->name == NULL) { + INT_ERROR("Failed to duplicate name for audio config %d\n", i); + // Cleanup previously allocated items + for (int j = 0; j < i; j++) { + free((void*)audioConfiguration.pKAudioConfigs[j].name); + free((void*)audioConfiguration.pKAudioConfigs[j].compressions); + free((void*)audioConfiguration.pKAudioConfigs[j].encodings); + free((void*)audioConfiguration.pKAudioConfigs[j].stereoModes); + } + free(audioConfiguration.pKAudioConfigs); + audioConfiguration.pKAudioConfigs = NULL; + return -1; + } + } else { + dest->name = NULL; + } + + // Deep copy compressions array + if (src->compressions != NULL && src->numSupportedCompressions > 0) { + size_t size = src->numSupportedCompressions * sizeof(dsAudioCompression_t); + dest->compressions = (dsAudioCompression_t*)malloc(size); + if (dest->compressions == NULL) { + INT_ERROR("Failed to allocate compressions for audio config %d\n", i); + free((void*)dest->name); + // Cleanup previously allocated items + for (int j = 0; j < i; j++) { + free((void*)audioConfiguration.pKAudioConfigs[j].name); + free((void*)audioConfiguration.pKAudioConfigs[j].compressions); + free((void*)audioConfiguration.pKAudioConfigs[j].encodings); + free((void*)audioConfiguration.pKAudioConfigs[j].stereoModes); + } + free(audioConfiguration.pKAudioConfigs); + audioConfiguration.pKAudioConfigs = NULL; + return -1; + } + memcpy((void*)dest->compressions, src->compressions, size); + } else { + dest->compressions = NULL; + } + + // Deep copy encodings array + if (src->encodings != NULL && src->numSupportedEncodings > 0) { + size_t size = src->numSupportedEncodings * sizeof(dsAudioEncoding_t); + dest->encodings = (dsAudioEncoding_t*)malloc(size); + if (dest->encodings == NULL) { + INT_ERROR("Failed to allocate encodings for audio config %d\n", i); + free((void*)dest->name); + free((void*)dest->compressions); + // Cleanup previously allocated items + for (int j = 0; j < i; j++) { + free((void*)audioConfiguration.pKAudioConfigs[j].name); + free((void*)audioConfiguration.pKAudioConfigs[j].compressions); + free((void*)audioConfiguration.pKAudioConfigs[j].encodings); + free((void*)audioConfiguration.pKAudioConfigs[j].stereoModes); + } + free(audioConfiguration.pKAudioConfigs); + audioConfiguration.pKAudioConfigs = NULL; + return -1; + } + memcpy((void*)dest->encodings, src->encodings, size); + } else { + dest->encodings = NULL; + } + + // Deep copy stereoModes array + if (src->stereoModes != NULL && src->numSupportedStereoModes > 0) { + size_t size = src->numSupportedStereoModes * sizeof(dsAudioStereoMode_t); + dest->stereoModes = (dsAudioStereoMode_t*)malloc(size); + if (dest->stereoModes == NULL) { + INT_ERROR("Failed to allocate stereoModes for audio config %d\n", i); + free((void*)dest->name); + free((void*)dest->compressions); + free((void*)dest->encodings); + // Cleanup previously allocated items + for (int j = 0; j < i; j++) { + free((void*)audioConfiguration.pKAudioConfigs[j].name); + free((void*)audioConfiguration.pKAudioConfigs[j].compressions); + free((void*)audioConfiguration.pKAudioConfigs[j].encodings); + free((void*)audioConfiguration.pKAudioConfigs[j].stereoModes); + } + free(audioConfiguration.pKAudioConfigs); + audioConfiguration.pKAudioConfigs = NULL; + return -1; + } + memcpy((void*)dest->stereoModes, src->stereoModes, size); + } else { + dest->stereoModes = NULL; + } + } + + INT_INFO("Deep copied %d audio configs (%s)", numElements, configType); + return numElements; +} + +static int allocateAndCopyAudioPorts(const dsAudioPortConfig_t* source, int numElements, bool isDynamic) +{ + const char* configType = isDynamic ? "dynamic" : "static"; + + if (numElements <= 0) { + INT_ERROR("Invalid %s port numElements: %d\n", configType, numElements); + return -1; + } + + audioConfiguration.pKAudioPorts = (dsAudioPortConfig_t*)malloc(numElements * sizeof(dsAudioPortConfig_t)); + if (audioConfiguration.pKAudioPorts == NULL) { + INT_ERROR("Failed to allocate memory for %s audio ports\n", configType); + return -1; + } + + // Deep copy each audio port config + for (int i = 0; i < numElements; i++) { + dsAudioPortConfig_t *dest = &audioConfiguration.pKAudioPorts[i]; + const dsAudioPortConfig_t *src = &source[i]; + + // Copy port ID + dest->id = src->id; + + // Deep copy connectedVOPs array - it's an array of size dsVIDEOPORT_TYPE_MAX + if (src->connectedVOPs != NULL) { + size_t arraySize = dsVIDEOPORT_TYPE_MAX * sizeof(dsVideoPortPortId_t); + dest->connectedVOPs = (dsVideoPortPortId_t*)malloc(arraySize); + if (dest->connectedVOPs == NULL) { + INT_ERROR("Failed to allocate connectedVOPs for audio port %d\n", i); + // Cleanup previously allocated items + for (int j = 0; j < i; j++) { + free((void*)audioConfiguration.pKAudioPorts[j].connectedVOPs); + } + free(audioConfiguration.pKAudioPorts); + audioConfiguration.pKAudioPorts = NULL; + return -1; + } + memcpy((void*)dest->connectedVOPs, src->connectedVOPs, arraySize); + } else { + dest->connectedVOPs = NULL; + } + } + + INT_INFO("Deep copied %d audio ports (%s)", numElements, configType); + return numElements; +} + +dsError_t dsLoadAudioOutputPortConfig(const audioConfigs_t* dynamicAudioConfigs) +{ + int configSize, portSize; + const dsAudioTypeConfig_t* audioConfigs; + const dsAudioPortConfig_t* audioPorts; + bool isDynamic; + + + INT_INFO("Using '%s' config\n", dynamicAudioConfigs ? "dynamic" : "static"); + + // Set up parameters based on config source + if (NULL != dynamicAudioConfigs) { + configSize = *(dynamicAudioConfigs->pKConfigSize); + portSize = *(dynamicAudioConfigs->pKPortSize); + audioConfigs = dynamicAudioConfigs->pKAudioConfigs; + audioPorts = dynamicAudioConfigs->pKAudioPorts; + isDynamic = true; + } else { + configSize = dsUTL_DIM(kConfigs); + portSize = dsUTL_DIM(kPorts); + audioConfigs = kConfigs; + audioPorts = kPorts; + isDynamic = false; + } + + // Allocate and copy audio type configs + if (allocateAndCopyAudioConfigs(audioConfigs, configSize, isDynamic) == -1) { + INT_ERROR("Failed to allocate audio type configs\n"); + return dsERR_GENERAL; + } + + // Allocate and copy audio port configs + if (allocateAndCopyAudioPorts(audioPorts, portSize, isDynamic) == -1) { + INT_ERROR("Failed to allocate audio port configs\n"); + // Clean up previously allocated audio configs with their deep-copied fields + if (audioConfiguration.pKAudioConfigs != NULL) { + for (int i = 0; i < configSize; i++) { + dsAudioTypeConfig_t *config = &audioConfiguration.pKAudioConfigs[i]; + if (config->name != NULL) { + free((void*)config->name); + } + if (config->compressions != NULL) { + free((void*)config->compressions); + } + if (config->encodings != NULL) { + free((void*)config->encodings); + } + if (config->stereoModes != NULL) { + free((void*)config->stereoModes); + } + } + free(audioConfiguration.pKAudioConfigs); + audioConfiguration.pKAudioConfigs = NULL; + } + return dsERR_GENERAL; + } + + INT_INFO("Store sizes configSize =%d, portSize =%d\n", configSize, portSize); + + audioConfiguration.kConfigSize = configSize; + audioConfiguration.kPortSize = portSize; + INT_INFO("Store sizes audioConfiguration.kConfigSize = %d\n", audioConfiguration.kConfigSize); + INT_INFO("Store sizes audioConfiguration.kPortSize = %d\n", audioConfiguration.kPortSize); + + INT_INFO("Audio Config[%p] ConfigSize[%d] Ports[%p] PortSize[%d]\n", + audioConfiguration.pKAudioConfigs ? audioConfiguration.pKAudioConfigs : NULL, + audioConfiguration.kConfigSize, + audioConfiguration.pKAudioPorts? audioConfiguration.pKAudioPorts : NULL, + audioConfiguration.kPortSize); + + audioDumpconfig(&audioConfiguration); + return dsERR_NONE; +} + +// Getter functions for use across srv code +dsError_t _dsGetAudioTypeConfigs(int* outConfigSize, const dsAudioTypeConfig_t** outConfigs) +{ + + if((outConfigSize == NULL) || (outConfigs == NULL)) + { + INT_ERROR("Invalid argument pointer\n"); + return dsERR_GENERAL; + } + + if (outConfigSize != NULL) { + *outConfigSize = audioConfiguration.kConfigSize; + } + if (outConfigs != NULL) { + *outConfigs = audioConfiguration.pKAudioConfigs; + } + + return dsERR_NONE; +} + +dsError_t _dsGetAudioPortConfigs(int* outPortSize, const dsAudioPortConfig_t** outPorts) +{ + + if((outPortSize == NULL) || (outPorts == NULL)) + { + INT_ERROR("Invalid argument pointer\n"); + return dsERR_GENERAL; + } + if (outPortSize != NULL) { + *outPortSize = audioConfiguration.kPortSize; + } + if (outPorts != NULL) { + *outPorts = audioConfiguration.pKAudioPorts; + } + + return dsERR_NONE; +} + +void dsAudioConfigFree(void) +{ + INT_INFO("Freeing Audio configuration resources\n"); + + // Free audio configs and their deep-copied fields + if (audioConfiguration.pKAudioConfigs != NULL) { + for (int i = 0; i < audioConfiguration.kConfigSize; i++) { + dsAudioTypeConfig_t *config = &audioConfiguration.pKAudioConfigs[i]; + + // Free name string + if (config->name != NULL) { + free((void*)config->name); + } + + // Free compressions array + if (config->compressions != NULL) { + free((void*)config->compressions); + } + + // Free encodings array + if (config->encodings != NULL) { + free((void*)config->encodings); + } + + // Free stereoModes array + if (config->stereoModes != NULL) { + free((void*)config->stereoModes); + } + } + + free(audioConfiguration.pKAudioConfigs); + audioConfiguration.pKAudioConfigs = NULL; + INT_INFO("Freed pKAudioConfigs and all deep-copied fields\n"); + } + + // Free audio ports and their deep-copied fields + if (audioConfiguration.pKAudioPorts != NULL) { + for (int i = 0; i < audioConfiguration.kPortSize; i++) { + dsAudioPortConfig_t *port = &audioConfiguration.pKAudioPorts[i]; + + // Free connectedVOPs array + if (port->connectedVOPs != NULL) { + free((void*)port->connectedVOPs); + } + } + + free(audioConfiguration.pKAudioPorts); + audioConfiguration.pKAudioPorts = NULL; + INT_INFO("Freed pKAudioPorts and all deep-copied fields\n"); + } + + // Reset size variables + audioConfiguration.kConfigSize = 0; + audioConfiguration.kPortSize = 0; + + INT_INFO("Audio configuration freed successfully\n"); +} + +#ifdef __cplusplus +} +#endif + +/** @} */ +/** @} */ diff --git a/rpc/srv/dsConfigs.c b/rpc/srv/dsConfigs.c new file mode 100644 index 00000000..15aff0d2 --- /dev/null +++ b/rpc/srv/dsConfigs.c @@ -0,0 +1,234 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2026 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 +* @{ +**/ + +#include +#include +#include +#include +#include "dsserverlogger.h" +#include "dsAudioConfig.h" +#include "dsVideoPortConfig.h" +#include "dsVideoDeviceConfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef RDK_DSHAL_NAME +#define RDK_DSHAL_NAME "libdshal.so" +#endif + +#define DEVICE_CAPABILITY_VIDEO_PORT 0x01 +#define DEVICE_CAPABILITY_AUDIO_PORT 0x02 +#define DEVICE_CAPABILITY_VIDEO_DEVICE 0x04 +#define DEVICE_CAPABILITY_FRONT_PANEL 0x08 + +typedef struct { + const char* name; + void** dataptr; +} dlSymbolLookup_t; + +static int configsLoaded = 0; + + +static int LoadDLSymbols(void* pDLHandle, const dlSymbolLookup_t* symbols, int numberOfSymbols) +{ + int currentSymbols = 0; + int isAllSymbolsLoaded = 0; + + if ((NULL == pDLHandle) || (NULL == symbols)) { + INT_ERROR("Invalid DL Handle or symbolsPtr\n"); + return 0; + } + + INT_INFO("numberOfSymbols = %d\n", numberOfSymbols); + for (int i = 0; i < numberOfSymbols; i++) { + if ((NULL == symbols[i].dataptr) || (NULL == symbols[i].name)) { + INT_ERROR("Invalid symbol entry at index [%d]\n", i); + continue; + } + *(symbols[i].dataptr) = dlsym(pDLHandle, symbols[i].name); + if (NULL == *(symbols[i].dataptr)) { + INT_ERROR("[%s] is not defined\n", symbols[i].name); + } + else { + currentSymbols++; + INT_INFO("[%s] is defined and loaded, data[%p]\n", symbols[i].name, *(symbols[i].dataptr)); + } + } + isAllSymbolsLoaded = (numberOfSymbols) ? (currentSymbols == numberOfSymbols) : 0; + return isAllSymbolsLoaded; +} + +static dsError_t loadDeviceCapabilities(unsigned int capabilityType) +{ + void* pDLHandle = NULL; + int isSymbolsLoaded = 0; + dsError_t ret = dsERR_GENERAL, audioRet = dsERR_NONE, videoRet = dsERR_NONE, videoPortRet = dsERR_NONE; + + INT_INFO("Entering capabilityType = 0x%08X\n", capabilityType); + dlerror(); /* clear old error */ + pDLHandle = dlopen(RDK_DSHAL_NAME, RTLD_LAZY); + INT_INFO("DL Instance '%s'\n", (NULL == pDLHandle ? "NULL" : "Valid")); + + /* Audio Port Config */ + if (DEVICE_CAPABILITY_AUDIO_PORT & capabilityType) { + audioConfigs_t dynamicAudioConfigs; + memset(&dynamicAudioConfigs, 0, sizeof(audioConfigs_t)); + + dlSymbolLookup_t audioConfigSymbols[] = { + {"kAudioConfigs", (void**)&dynamicAudioConfigs.pKAudioConfigs}, + {"kAudioPorts", (void**)&dynamicAudioConfigs.pKAudioPorts}, + {"kAudioConfigs_size", (void**)&dynamicAudioConfigs.pKConfigSize}, + {"kAudioPorts_size", (void**)&dynamicAudioConfigs.pKPortSize} + }; + + isSymbolsLoaded = 0; + if (NULL != pDLHandle) { + isSymbolsLoaded = LoadDLSymbols(pDLHandle, audioConfigSymbols, + sizeof(audioConfigSymbols)/sizeof(dlSymbolLookup_t)); + } + audioRet = dsLoadAudioOutputPortConfig(isSymbolsLoaded ? &dynamicAudioConfigs : NULL); + if(audioRet == dsERR_GENERAL) + { + INT_ERROR("dsLoadAudioOutputPortConfig() failed"); + } + } + + /* Video Port Config */ + if (DEVICE_CAPABILITY_VIDEO_PORT & capabilityType) { + videoPortConfigs_t dynamicVideoPortConfigs; + memset(&dynamicVideoPortConfigs, 0, sizeof(videoPortConfigs_t)); + + dlSymbolLookup_t videoPortConfigSymbols[] = { + {"kVideoPortConfigs", (void**)&dynamicVideoPortConfigs.pKVideoPortConfigs}, + {"kVideoPortConfigs_size", (void**)&dynamicVideoPortConfigs.pKVideoPortConfigs_size}, + {"kVideoPortPorts", (void**)&dynamicVideoPortConfigs.pKVideoPortPorts}, + {"kVideoPortPorts_size", (void**)&dynamicVideoPortConfigs.pKVideoPortPorts_size}, + {"kResolutionsSettings", (void**)&dynamicVideoPortConfigs.pKVideoPortResolutionsSettings}, + {"kResolutionsSettings_size", (void**)&dynamicVideoPortConfigs.pKResolutionsSettings_size}, + {"kDefaultResIndex", (void**)&dynamicVideoPortConfigs.pKDefaultResIndex} + }; + + isSymbolsLoaded = 0; + if (NULL != pDLHandle) { + isSymbolsLoaded = LoadDLSymbols(pDLHandle, videoPortConfigSymbols, + sizeof(videoPortConfigSymbols)/sizeof(dlSymbolLookup_t)); + } + videoPortRet = dsLoadVideoOutputPortConfig(isSymbolsLoaded ? &dynamicVideoPortConfigs : NULL); + if(videoPortRet == dsERR_GENERAL) + { + INT_ERROR("dsLoadVideoOutputPortConfig() failed"); + } + } + + /* Video Device Config */ + if (DEVICE_CAPABILITY_VIDEO_DEVICE & capabilityType) { + videoDeviceConfig_t dynamicVideoDeviceConfigs; + memset(&dynamicVideoDeviceConfigs, 0, sizeof(videoDeviceConfig_t)); + + dlSymbolLookup_t videoDeviceConfigSymbols[] = { + {"kVideoDeviceConfigs", (void**)&dynamicVideoDeviceConfigs.pKVideoDeviceConfigs}, + {"kVideoDeviceConfigs_size", (void**)&dynamicVideoDeviceConfigs.pKVideoDeviceConfigs_size} + }; + + isSymbolsLoaded = 0; + if (NULL != pDLHandle) { + isSymbolsLoaded = LoadDLSymbols(pDLHandle, videoDeviceConfigSymbols, + sizeof(videoDeviceConfigSymbols)/sizeof(dlSymbolLookup_t)); + } + videoRet = dsLoadVideoDeviceConfig(isSymbolsLoaded ? &dynamicVideoDeviceConfigs : NULL); + if(videoRet == dsERR_GENERAL) + { + INT_ERROR("dsLoadVideoDeviceConfig() failed"); + } + } + + if (NULL != pDLHandle) { + dlclose(pDLHandle); + pDLHandle = NULL; + } + + // Only check error codes for capabilities that were requested + if (((capabilityType & DEVICE_CAPABILITY_AUDIO_PORT) && (audioRet == dsERR_GENERAL)) || + ((capabilityType & DEVICE_CAPABILITY_VIDEO_DEVICE) && (videoRet == dsERR_GENERAL)) || + ((capabilityType & DEVICE_CAPABILITY_VIDEO_PORT) && (videoPortRet == dsERR_GENERAL))) + { + INT_ERROR("Failed to load device capabilities: audioRet=%d, videoRet=%d, videoPortRet=%d\n", audioRet, videoRet, videoPortRet); + return dsERR_GENERAL; + } + INT_INFO("Exiting ...\n"); + return dsERR_NONE; +} + +dsError_t dsLoadConfigs(void) +{ + dsError_t ret = dsERR_GENERAL; + + INT_INFO("Enter function\n"); + + // Check if configs are already loaded + if (configsLoaded) { + INT_INFO("Configs already loaded, skipping reload\n"); + return dsERR_NONE; + } + + //TODO:Add the mutex lock handel in future + ret = loadDeviceCapabilities(DEVICE_CAPABILITY_VIDEO_PORT | + DEVICE_CAPABILITY_AUDIO_PORT | + DEVICE_CAPABILITY_VIDEO_DEVICE); + if (ret == dsERR_GENERAL) + { + INT_ERROR("[srv] load failed\n "); + return ret; + } + + // Mark configs as loaded + configsLoaded = 1; + INT_INFO("Exit function\n"); + return dsERR_NONE; +} + +dsError_t dsFreeConfig() +{ + // Free dynamically allocated configuration memory + INT_INFO("Freeing device configuration resources\n"); + dsAudioConfigFree(); + dsVideoDeviceConfigFree(); + dsVideoPortConfigFree(); + + // Reset loaded flag so configs can be reloaded if needed + configsLoaded = 0; + INT_INFO("Config freed and reload flag reset\n"); + return dsERR_NONE; +} + +#ifdef __cplusplus +} +#endif + +/** @} */ +/** @} */ diff --git a/rpc/srv/dsDisplay.c b/rpc/srv/dsDisplay.c index 982a8b57..4eab1afe 100644 --- a/rpc/srv/dsDisplay.c +++ b/rpc/srv/dsDisplay.c @@ -46,8 +46,7 @@ #include "dsMgr.h" #include "dsserverlogger.h" #include "dsVideoPort.h" -#include "dsVideoPortSettings.h" -#include "dsVideoResolutionSettings.h" +#include "dsVideoPortConfig.h" #include "dsInternal.h" #include "safec_lib.h" @@ -578,20 +577,33 @@ static void filterEDIDResolution(intptr_t handle, dsDisplayEDID_t *edid) { errno_t rc = -1; dsVideoPortResolution_t *edidResn = NULL; - dsVideoPortResolution_t *presolution = NULL; - dsDisplayEDID_t *edidData = (dsDisplayEDID_t*)malloc(sizeof(dsDisplayEDID_t)); - dsVideoPortType_t _VPortType = _GetDisplayPortType(handle); + dsVideoPortResolution_t *presolution = NULL, *pVideoResolutionsSettings = NULL; + if (edid == NULL) { - free(edidData); - return; // Handle malloc failure + INT_ERROR("Invalid EDID parameter\n"); + return; + } + + dsVideoPortType_t _VPortType = _GetDisplayPortType(handle); + dsDisplayEDID_t *edidData = (dsDisplayEDID_t*)malloc(sizeof(dsDisplayEDID_t)); + if (edidData == NULL) { + INT_ERROR("Failed to allocate memory for EDID data\n"); + return; } + int numOfSupportedResolution = 0; if(_VPortType == dsVIDEOPORT_TYPE_HDMI) { INT_DEBUG("EDID for HDMI Port\r\n"); - size_t iCount = dsUTL_DIM(kResolutions); - + int iCount = 0; + //Get details from libds + if (_dsGetVideoPortResolutions(&iCount, &pVideoResolutionsSettings) != dsERR_NONE) { + INT_ERROR("Failed to get video port resolutions, leaving EDID unchanged\n"); + free(edidData); + return; + } + /*Initialize the struct*/ memset(edidData,0,sizeof(*edidData)); /*Copy the content */ @@ -604,14 +616,14 @@ static void filterEDIDResolution(intptr_t handle, dsDisplayEDID_t *edid) edid->numOfSupportedResolution = 0; for (size_t i = 0; i < iCount; i++) { - presolution = &kResolutions[i]; + presolution = &pVideoResolutionsSettings[i]; for (size_t j = 0; j < edidData->numOfSupportedResolution; j++) { edidResn = &(edidData->suppResolutionList[j]); if (0 == (strcmp(presolution->name,edidResn->name))) { - edid->suppResolutionList[edid->numOfSupportedResolution] = kResolutions[i]; + edid->suppResolutionList[edid->numOfSupportedResolution] = pVideoResolutionsSettings[i]; edid->numOfSupportedResolution++; numOfSupportedResolution++; INT_DEBUG("[DsMgr] presolution->name : %s, resolution count : %d\r\n",presolution->name,numOfSupportedResolution); @@ -646,14 +658,19 @@ static dsVideoPortType_t _GetDisplayPortType(intptr_t handle) { int numPorts,i; intptr_t halhandle = 0; + const dsVideoPortPortConfig_t *pVideoPortPorts = NULL; - numPorts = dsUTL_DIM(kSupportedPortTypes); + if (_dsGetVideoPortPortConfigs(&numPorts, &pVideoPortPorts) != dsERR_NONE) { + INT_ERROR("Failed to get video port port configurations\n"); + return dsVIDEOPORT_TYPE_MAX; + } + for(i=0; i< numPorts; i++) { - dsGetDisplay(kPorts[i].id.type, kPorts[i].id.index, &halhandle); + dsGetDisplay(pVideoPortPorts[i].id.type, pVideoPortPorts[i].id.index, &halhandle); if (handle == halhandle) { - return kPorts[i].id.type; + return pVideoPortPorts[i].id.type; } } INT_INFO("Error: The Requested Display is not part of Platform Port Configuration \r\n"); diff --git a/rpc/srv/dsMgr.c b/rpc/srv/dsMgr.c old mode 100755 new mode 100644 index 9de34e5a..2955ea99 --- a/rpc/srv/dsMgr.c +++ b/rpc/srv/dsMgr.c @@ -41,6 +41,7 @@ #include "hostPersistence.hpp" #include "dsInternal.h" +#include "dsConfigs.h" profile_t profileType = PROFILE_INVALID; @@ -113,7 +114,12 @@ IARM_Result_t dsMgr_init() profileType = searchRdkProfile(); INT_INFO("[%s]: profileType=%d\r\n", __FUNCTION__, profileType); - device::HostPersistence::getInstance().load(); + INT_INFO("[%s]: Loading device configurations\r\n", __FUNCTION__); + if (dsLoadConfigs() != dsERR_NONE) { + INT_ERROR("[%s]: Failed to load device configurations\r\n", __FUNCTION__); + return IARM_RESULT_INVALID_STATE; + } + device::HostPersistence::getInstance().load(); dsServer_Rdklogger_Init(); dsHostInit(); dsDisplayMgr_init(); @@ -124,6 +130,7 @@ IARM_Result_t dsMgr_init() dsHostMgr_init(); dsHdmiInMgr_init(); dsCompositeInMgr_init(); + return ret; } @@ -139,6 +146,12 @@ IARM_Result_t dsMgr_term() dsHostMgr_term(); dsHdmiInMgr_term(); dsCompositeInMgr_term(); + + if (dsFreeConfig() != dsERR_NONE) { + INT_ERROR("Failed to free device configurations\r\n"); + ret = IARM_RESULT_INVALID_STATE; + } + return ret; } diff --git a/rpc/srv/dsVideoDeviceConfig.c b/rpc/srv/dsVideoDeviceConfig.c new file mode 100644 index 00000000..5257c531 --- /dev/null +++ b/rpc/srv/dsVideoDeviceConfig.c @@ -0,0 +1,220 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2026 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 +* @{ +**/ + +#include +#include +#include +#include +#include "dsserverlogger.h" +#include "dsTypes.h" +#include "dsError.h" +#include "dsVideoDeviceConfig.h" +#include "dsVideoDeviceSettings.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct videoDeviceConfigLocal +{ + dsVideoConfig_t *pKVideoDeviceConfigs; + int kVideoDeviceConfigs_size; +}videoDeviceConfigLocal_t; + +static videoDeviceConfigLocal_t videoDeviceConfiguration = {0}; + +void videoDeviceDumpconfig(videoDeviceConfigLocal_t *config) +{ + if (NULL == config) { + INT_ERROR("Video config is NULL\n"); + return; + } + if ( -1 == access("/opt/dsMgrDumpDeviceConfigs", F_OK) ) { + INT_INFO("Dumping of Device configs is disabled\n"); + return; + } + + INT_INFO("\n=============== Starting to Dump VideoDevice Configs ===============\n"); + + if( NULL != config->pKVideoDeviceConfigs ) + { + int configSize = config->kVideoDeviceConfigs_size; + INT_INFO("pKVideoDeviceConfigs = %p\n", config->pKVideoDeviceConfigs); + INT_INFO("videoDeviceConfigs_size = %d\n", configSize); + for (int i = 0; i < configSize; i++) { + dsVideoConfig_t* videoDeviceConfig = &config->pKVideoDeviceConfigs[i]; + INT_INFO("pKVideoDeviceConfigs[%d].numSupportedDFCs = %lu\n", i, videoDeviceConfig->numSupportedDFCs); + for (int j = 0; j < videoDeviceConfig->numSupportedDFCs; j++) { + INT_INFO(" Address of pKVideoDeviceConfigs[%d].supportedDFCs[%d] = %d\n", i, j, videoDeviceConfig->supportedDFCs[j]); + } + } + } + else + { + INT_ERROR(" kVideoDeviceConfigs is NULL\n"); + } + + INT_INFO("\n=============== Dump VideoDevice Configs done ===============\n"); +} + +static int allocateAndCopyVideoDeviceConfigs(const dsVideoConfig_t* source, int numElements, bool isDynamic) +{ + const char* configType = isDynamic ? "dynamic" : "static"; + + if (numElements <= 0) { + INT_ERROR("Invalid %s video device config numElements: %d\n", configType, numElements); + return -1; + } + + videoDeviceConfiguration.pKVideoDeviceConfigs = (dsVideoConfig_t*)malloc(numElements * sizeof(dsVideoConfig_t)); + if (videoDeviceConfiguration.pKVideoDeviceConfigs == NULL) { + INT_ERROR("Failed to allocate memory for %s video device configs\n", configType); + return -1; + } + + /* First copy the structures themselves. Pointer fields (such as 'supportedDFCs') will be + * fixed up below to avoid shallow copies into HAL-owned memory. */ + memcpy(videoDeviceConfiguration.pKVideoDeviceConfigs, source, numElements * sizeof(dsVideoConfig_t)); + + /* Deep copy the 'supportedDFCs' array for each config so it does not reference + * memory owned by the HAL library, which may be unloaded. */ + for (int i = 0; i < numElements; ++i) + { + if (source[i].supportedDFCs != NULL && source[i].numSupportedDFCs > 0) + { + size_t dfcArraySize = source[i].numSupportedDFCs * sizeof(dsVideoZoom_t); + dsVideoZoom_t *dupDFCs = (dsVideoZoom_t*)malloc(dfcArraySize); + if (dupDFCs == NULL) + { + INT_ERROR("Failed to duplicate %s video device config supportedDFCs at index %d\n", configType, i); + /* Clean up any DFCs already duplicated and the configs array itself. */ + for (int j = 0; j < i; ++j) + { + if (videoDeviceConfiguration.pKVideoDeviceConfigs[j].supportedDFCs != NULL) + { + free((void*)videoDeviceConfiguration.pKVideoDeviceConfigs[j].supportedDFCs); + videoDeviceConfiguration.pKVideoDeviceConfigs[j].supportedDFCs = NULL; + } + } + free(videoDeviceConfiguration.pKVideoDeviceConfigs); + videoDeviceConfiguration.pKVideoDeviceConfigs = NULL; + return -1; + } + memcpy(dupDFCs, source[i].supportedDFCs, dfcArraySize); + videoDeviceConfiguration.pKVideoDeviceConfigs[i].supportedDFCs = dupDFCs; + } + else + { + videoDeviceConfiguration.pKVideoDeviceConfigs[i].supportedDFCs = NULL; + } + } + + INT_INFO("Allocated and copied %d video device configs (%s)\n", numElements, configType); + return numElements; +} + +dsError_t dsLoadVideoDeviceConfig(const videoDeviceConfig_t* dynamicVideoDeviceConfigs) +{ + int configSize; + const dsVideoConfig_t* videoConfigs; + bool isDynamic; + + INT_INFO("Using '%s' config\n", dynamicVideoDeviceConfigs ? "dynamic" : "static"); + + // Set up parameters based on config source + if (NULL != dynamicVideoDeviceConfigs) { + configSize = *(dynamicVideoDeviceConfigs->pKVideoDeviceConfigs_size); + videoConfigs = dynamicVideoDeviceConfigs->pKVideoDeviceConfigs; + isDynamic = true; + } else { + configSize = dsUTL_DIM(kConfigs); + videoConfigs = kConfigs; + isDynamic = false; + } + + // Allocate and copy video device configs + if (allocateAndCopyVideoDeviceConfigs(videoConfigs, configSize, isDynamic) == -1) { + INT_ERROR("Failed to allocate video device configs\n"); + return dsERR_GENERAL; + } + + INT_INFO("Store sizes configSize =%d\n", configSize); + videoDeviceConfiguration.kVideoDeviceConfigs_size = configSize; + INT_INFO("Store sizes videoDeviceConfiguration.kVideoDeviceConfigs_size = %d\n", videoDeviceConfiguration.kVideoDeviceConfigs_size); + + INT_INFO("VideoDevice Config[%p] ConfigSize[%d]\n", + videoDeviceConfiguration.pKVideoDeviceConfigs, + videoDeviceConfiguration.kVideoDeviceConfigs_size); + videoDeviceDumpconfig(&videoDeviceConfiguration); + return dsERR_NONE; +} + +// Getter functions for use across srv code +dsError_t _dsGetVideoDeviceConfigs(int* outConfigSize, dsVideoConfig_t** outConfigs) +{ + if((outConfigSize == NULL) || (outConfigs == NULL)) + { + INT_ERROR("Invalid argument pointer\n"); + return dsERR_GENERAL; + } + + *outConfigSize = videoDeviceConfiguration.kVideoDeviceConfigs_size; + *outConfigs = videoDeviceConfiguration.pKVideoDeviceConfigs; + + return dsERR_NONE; +} + +void dsVideoDeviceConfigFree(void) +{ + INT_INFO("Freeing VideoDevice configuration resources\n"); + + // Free video device configs + if (videoDeviceConfiguration.pKVideoDeviceConfigs != NULL) { + // Free each supportedDFCs array + for (int i = 0; i < videoDeviceConfiguration.kVideoDeviceConfigs_size; ++i) { + if (videoDeviceConfiguration.pKVideoDeviceConfigs[i].supportedDFCs != NULL) { + free((void*)videoDeviceConfiguration.pKVideoDeviceConfigs[i].supportedDFCs); + videoDeviceConfiguration.pKVideoDeviceConfigs[i].supportedDFCs = NULL; + INT_INFO("Freed pKVideoDeviceConfigs[%d].supportedDFCs\n", i); + } + } + free(videoDeviceConfiguration.pKVideoDeviceConfigs); + videoDeviceConfiguration.pKVideoDeviceConfigs = NULL; + INT_INFO("Freed pKVideoDeviceConfigs\n"); + } + + // Reset size variable + videoDeviceConfiguration.kVideoDeviceConfigs_size = 0; + + INT_INFO("VideoDevice configuration freed successfully\n"); +} + +#ifdef __cplusplus +} +#endif + +/** @} */ +/** @} */ diff --git a/rpc/srv/dsVideoPort.c b/rpc/srv/dsVideoPort.c index 21ffdcd2..a397a5b9 100644 --- a/rpc/srv/dsVideoPort.c +++ b/rpc/srv/dsVideoPort.c @@ -51,7 +51,7 @@ #include "hostPersistence.hpp" #include "dsserverlogger.h" #include "dsTypes.h" -#include "dsVideoPortSettings.h" +#include "dsVideoPortConfig.h" #include "dsInternal.h" #include "safec_lib.h" #include @@ -1701,16 +1701,21 @@ IARM_Result_t _dsSupportedTvResolutions(void *arg) static dsVideoPortType_t _GetVideoPortType(intptr_t handle) { - int numPorts,i; + int numPorts = 0, i; intptr_t halhandle = 0; - - numPorts = dsUTL_DIM(kSupportedPortTypes); + const dsVideoPortPortConfig_t *pVideoPortPorts = NULL; + + if (_dsGetVideoPortPortConfigs(&numPorts, &pVideoPortPorts) != dsERR_NONE) { + INT_ERROR("Failed to get video port port configurations\n"); + return dsVIDEOPORT_TYPE_MAX; + } + for(i=0; i< numPorts; i++) { - dsGetVideoPort(kPorts[i].id.type, kPorts[i].id.index, &halhandle); + dsGetVideoPort(pVideoPortPorts[i].id.type, pVideoPortPorts[i].id.index, &halhandle); if (handle == halhandle) { - return kPorts[i].id.type; + return pVideoPortPorts[i].id.type; } } INT_ERROR("Error: The Requested Video Port is not part of Platform Port Configuration \r\n"); @@ -1894,7 +1899,22 @@ static std::string getCompatibleResolution(dsVideoPortResolution_t *SrcResn) case dsVIDEO_PIXELRES_4096x2160: case dsVIDEO_PIXELRES_MAX: default: - return resolution.assign(kResolutions[kDefaultResIndex].name); + { + int numResolutions = 0; + dsVideoPortResolution_t* resolutions = NULL; + int defaultIndex = 0; + if (_dsGetVideoPortResolutions(&numResolutions, &resolutions) != dsERR_NONE) { + INT_ERROR("Failed to get video port resolutions\n"); + break; + } + if (_dsGetDefaultResolutionIndex(&defaultIndex) != dsERR_NONE) { + INT_ERROR("Failed to get default resolution index\n"); + break; + } + if ((resolutions != NULL) && (defaultIndex >= 0) && (defaultIndex < numResolutions)) { + return resolution.assign(resolutions[defaultIndex].name); + } + } break; } } @@ -1916,11 +1936,34 @@ static bool IsCompatibleResolution(dsVideoResolution_t pixelResolution1,dsVideo static dsVideoResolution_t getPixelResolution(std::string &resolution ) { - dsVideoPortResolution_t *Resn = &kResolutions[kDefaultResIndex]; - - for (unsigned int i = 0; i < dsUTL_DIM(kResolutions); i++) + dsVideoPortResolution_t *pVideoResolutionsSettings = NULL; + dsVideoPortResolution_t *Resn = NULL; + int iCount = 0, defaultIndex = 0; + if (_dsGetVideoPortResolutions(&iCount, &pVideoResolutionsSettings) != dsERR_NONE) { + INT_ERROR("Failed to get video port resolutions\n"); + return dsVIDEO_PIXELRES_MAX; + } + + if (iCount <= 0 || pVideoResolutionsSettings == NULL) { + INT_ERROR("_dsGetVideoPortResolutions returned invalid values (iCount=%d, pVideoResolutionsSettings=%p)\n", iCount, pVideoResolutionsSettings); + return dsVIDEO_PIXELRES_MAX; + } + + if (_dsGetDefaultResolutionIndex(&defaultIndex) != dsERR_NONE) { + INT_ERROR("Failed to get default resolution index using first element of array\n"); + } + + if ((defaultIndex >= 0) && (defaultIndex < iCount)) { + Resn = &pVideoResolutionsSettings[defaultIndex]; + } + else + { + Resn = &pVideoResolutionsSettings[0]; + } + + for (int i = 0; i < iCount; i++) { - Resn = &kResolutions[i]; + Resn = &pVideoResolutionsSettings[i]; if (resolution.compare(Resn->name) == 0 ) { break; @@ -2251,17 +2294,24 @@ static dsError_t _dsVideoFormatUpdateRegisterCB (dsVideoFormatUpdateCB_t cbFun) return eRet; } +//This function does not have any caller. bool isComponentPortPresent() { bool componentPortPresent = false; - int numPorts,i; - - numPorts = dsUTL_DIM(kSupportedPortTypes); - for(i=0; i< numPorts; i++) - { - if (kSupportedPortTypes[i] == dsVIDEOPORT_TYPE_COMPONENT) + int numTypeConfigs = 0; + const dsVideoPortTypeConfig_t* typeConfigs = NULL; + + if (_dsGetVideoPortTypeConfigs(&numTypeConfigs, &typeConfigs) != dsERR_NONE) { + INT_ERROR("Failed to get video port type configurations\n"); + return false; + } + if (typeConfigs) { + for(int i=0; i< numTypeConfigs; i++) { - componentPortPresent = true;; + if (typeConfigs[i].typeId == dsVIDEOPORT_TYPE_COMPONENT) + { + componentPortPresent = true; + } } } INT_INFO(" componentPortPresent :%d\n",componentPortPresent); @@ -2385,14 +2435,20 @@ void _dsSyncHdmiStatus(const std::string& key, int val) { intptr_t dsGetDefaultPortHandle() { - int numPorts,i; + int numPorts = 0, i; intptr_t halhandle = 0; - numPorts = dsUTL_DIM(kSupportedPortTypes); + const dsVideoPortPortConfig_t *pVideoPortPorts = NULL; + + if (_dsGetVideoPortPortConfigs(&numPorts, &pVideoPortPorts) != dsERR_NONE) { + INT_ERROR("Failed to get video port port configurations\n"); + return halhandle; + } + for(i=0; i< numPorts; i++) { - dsGetVideoPort(kPorts[i].id.type, kPorts[i].id.index, &halhandle); - if (dsVIDEOPORT_TYPE_HDMI == kPorts[i].id.type || - dsVIDEOPORT_TYPE_INTERNAL == kPorts[i].id.type) + dsGetVideoPort(pVideoPortPorts[i].id.type, pVideoPortPorts[i].id.index, &halhandle); + if (dsVIDEOPORT_TYPE_HDMI == pVideoPortPorts[i].id.type || + dsVIDEOPORT_TYPE_INTERNAL == pVideoPortPorts[i].id.type) { return halhandle; } diff --git a/rpc/srv/dsVideoPortConfig.c b/rpc/srv/dsVideoPortConfig.c new file mode 100644 index 00000000..cbafb7b7 --- /dev/null +++ b/rpc/srv/dsVideoPortConfig.c @@ -0,0 +1,484 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2026 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 +* @{ +**/ + +#include +#include +#include +#include +#include "dsserverlogger.h" +#include "dsTypes.h" +#include "dsError.h" +#include "dsVideoPortSettings.h" +#include "dsVideoResolutionSettings.h" +#include "dsVideoPortConfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct videoPortConfigsLocal +{ + dsVideoPortTypeConfig_t *pKVideoPortConfigs; + int kVideoPortConfigs_size; + dsVideoPortPortConfig_t *pKVideoPortPorts; + int kVideoPortPorts_size; + dsVideoPortResolution_t *pKVideoPortResolutionsSettings; + int kResolutionsSettings_size; + int kDefaultResIndex; +}videoPortConfigsLocal_t; + +static videoPortConfigsLocal_t videoPortConfiguration = {0}; + +void videoPortDumpconfig(videoPortConfigsLocal_t *config) +{ + if (NULL == config) { + INT_ERROR("Video config is NULL\n"); + return; + } + if ( -1 == access("/opt/dsMgrDumpDeviceConfigs", F_OK) ) { + INT_INFO("Dumping of Device configs is disabled\n"); + return; + } + INT_INFO("\n=============== Starting to Dump VideoPort Configs ===============\n"); + + int configSize = -1, portSize = -1, resolutionSize = -1; + if (( NULL != config->pKVideoPortConfigs ) && ( NULL != config->pKVideoPortPorts ) && ( NULL != config->pKVideoPortResolutionsSettings )) + { + configSize = config->kVideoPortConfigs_size; + portSize = config->kVideoPortPorts_size; + resolutionSize = config->kResolutionsSettings_size; + INT_INFO("pKVideoPortConfigs = %p\n", config->pKVideoPortConfigs); + INT_INFO("kVideoPortConfigs_size = %d\n", configSize); + INT_INFO("pKVideoPortPorts = %p\n", config->pKVideoPortPorts); + INT_INFO("kVideoPortPorts_size = %d\n", portSize); + INT_INFO("pKResolutionsSettings = %p\n", config->pKVideoPortResolutionsSettings); + INT_INFO("kResolutionsSettings_size = %d\n", resolutionSize); + + INT_INFO("\n\n############### Dumping Video Resolutions Settings ############### \n\n"); + + for (int i = 0; i < resolutionSize; i++) { + dsVideoPortResolution_t *resolution = &(config->pKVideoPortResolutionsSettings[i]); + INT_INFO("resolution->name = %s\n", (resolution->name)? resolution->name : "NULL"); + INT_INFO("resolution->pixelResolution= %d\n", resolution->pixelResolution); + INT_INFO("resolution->aspectRatio= %d\n", resolution->aspectRatio); + INT_INFO("resolution->stereoScopicMode= %d\n", resolution->stereoScopicMode); + INT_INFO("resolution->frameRate= %d\n", resolution->frameRate); + INT_INFO("resolution->interlaced= %d\n", resolution->interlaced); + } + + INT_INFO("\n ############### Dumping Video Port Configurations ############### \n"); + + for (int i = 0; i < configSize; i++) + { + const dsVideoPortTypeConfig_t *typeCfg = &(config->pKVideoPortConfigs[i]); + INT_INFO("typeCfg->typeId = %d\n", typeCfg->typeId); + INT_INFO("typeCfg->name = %s\n", (typeCfg->name) ? typeCfg->name : "NULL"); + INT_INFO("typeCfg->dtcpSupported= %d\n", typeCfg->dtcpSupported); + INT_INFO("typeCfg->hdcpSupported = %d\n", typeCfg->hdcpSupported); + INT_INFO("typeCfg->restrictedResollution = %d\n", typeCfg->restrictedResollution); + INT_INFO("typeCfg->numSupportedResolutions= %lu\n", typeCfg->numSupportedResolutions); + + if ((typeCfg->supportedResolutions != NULL) && (typeCfg->numSupportedResolutions > 0)) + { + INT_INFO("typeCfg->supportedResolutions->name = %s\n", + (typeCfg->supportedResolutions->name) ? typeCfg->supportedResolutions->name : "NULL"); + INT_INFO("typeCfg->supportedResolutions->pixelResolution= %d\n", + typeCfg->supportedResolutions->pixelResolution); + INT_INFO("typeCfg->supportedResolutions->aspectRatio= %d\n", + typeCfg->supportedResolutions->aspectRatio); + INT_INFO("typeCfg->supportedResolutions->stereoScopicMode= %d\n", + typeCfg->supportedResolutions->stereoScopicMode); + INT_INFO("typeCfg->supportedResolutions->frameRate= %d\n", + typeCfg->supportedResolutions->frameRate); + INT_INFO("typeCfg->supportedResolutions->interlaced= %d\n", + typeCfg->supportedResolutions->interlaced); + } + else + { + INT_INFO("typeCfg has no supportedResolutions entries to dump (pointer is %p, numSupportedResolutions = %lu)\n", + typeCfg->supportedResolutions, + typeCfg->numSupportedResolutions); + } + } + INT_INFO("\n############### Dumping Video Port Connections ###############\n"); + + for (int i = 0; i < portSize; i++) { + const dsVideoPortPortConfig_t *portCfg = &(config->pKVideoPortPorts[i]); + INT_INFO("portCfg->id.type = %d\n", portCfg->id.type); + INT_INFO("portCfg->id.index = %d\n", portCfg->id.index); + INT_INFO("portCfg->connectedAOP.type = %d\n", portCfg->connectedAOP.type); + INT_INFO("portCfg->connectedAOP.index = %d\n", portCfg->connectedAOP.index); + INT_INFO("portCfg->defaultResolution = %s\n", (portCfg->defaultResolution) ? portCfg->defaultResolution : "NULL"); + } + } + else + { + INT_ERROR("pKConfigs or pKPorts or pKResolutionsSettings is NULL\n"); + } + INT_INFO("\n=============== Dump VideoPort Configs done ===============\n"); + INT_INFO("Exit function\n"); +} + +static int allocateAndCopyVideoPortConfigs(const dsVideoPortTypeConfig_t* source, int numElements, bool isDynamic) +{ + const char* configType = isDynamic ? "dynamic" : "static"; + + if (numElements <= 0) { + INT_ERROR("Invalid %s video port config numElements: %d\n", configType, numElements); + return -1; + } + + videoPortConfiguration.pKVideoPortConfigs = (dsVideoPortTypeConfig_t*)malloc(numElements * sizeof(dsVideoPortTypeConfig_t)); + if (videoPortConfiguration.pKVideoPortConfigs == NULL) { + INT_ERROR("Failed to allocate memory for %s video port configs\n", configType); + return -1; + } + + /* First copy the structures themselves. Pointer fields (such as 'name') will be + * fixed up below to avoid shallow copies into HAL-owned memory. */ + memcpy(videoPortConfiguration.pKVideoPortConfigs, source, numElements * sizeof(dsVideoPortTypeConfig_t)); + + /* Deep copy the 'name' pointer for each config so it does not reference + * memory owned by the HAL library, which may be unloaded. */ + for (int i = 0; i < numElements; ++i) + { + if (source[i].name != NULL) + { + char *dupName = strdup(source[i].name); + if (dupName == NULL) + { + INT_ERROR("Failed to duplicate %s video port config name at index %d\n", configType, i); + /* Clean up any names already duplicated and the configs array itself. */ + for (int j = 0; j < i; ++j) + { + if (videoPortConfiguration.pKVideoPortConfigs[j].name != NULL) + { + free((void*)videoPortConfiguration.pKVideoPortConfigs[j].name); + videoPortConfiguration.pKVideoPortConfigs[j].name = NULL; + } + } + free(videoPortConfiguration.pKVideoPortConfigs); + videoPortConfiguration.pKVideoPortConfigs = NULL; + return -1; + } + videoPortConfiguration.pKVideoPortConfigs[i].name = dupName; + } + else + { + videoPortConfiguration.pKVideoPortConfigs[i].name = NULL; + } + } + + INT_INFO("Allocated and copied %d video port configs (%s)\n", numElements, configType); + return numElements; +} + +static int allocateAndCopyVideoPortPorts(const dsVideoPortPortConfig_t* source, int numElements, bool isDynamic) +{ + const char* configType = isDynamic ? "dynamic" : "static"; + + if (numElements <= 0) { + INT_ERROR("Invalid %s video port port numElements: %d\n", configType, numElements); + return -1; + } + + videoPortConfiguration.pKVideoPortPorts = (dsVideoPortPortConfig_t*)malloc(numElements * sizeof(dsVideoPortPortConfig_t)); + if (videoPortConfiguration.pKVideoPortPorts == NULL) { + INT_ERROR("Failed to allocate memory for %s video port ports\n", configType); + return -1; + } + + /* First copy the structures themselves. Pointer fields (such as 'defaultResolution') will be + * fixed up below to avoid shallow copies into HAL-owned memory. */ + memcpy(videoPortConfiguration.pKVideoPortPorts, source, numElements * sizeof(dsVideoPortPortConfig_t)); + + /* Deep copy the 'defaultResolution' pointer for each port so it does not reference + * memory owned by the HAL library, which may be unloaded. */ + for (int i = 0; i < numElements; ++i) + { + if (source[i].defaultResolution != NULL) + { + char *dupResolution = strdup(source[i].defaultResolution); + if (dupResolution == NULL) + { + INT_ERROR("Failed to duplicate %s video port default resolution at index %d\n", configType, i); + /* Clean up any resolutions already duplicated and the ports array itself. */ + for (int j = 0; j < i; ++j) + { + if (videoPortConfiguration.pKVideoPortPorts[j].defaultResolution != NULL) + { + free((void*)videoPortConfiguration.pKVideoPortPorts[j].defaultResolution); + videoPortConfiguration.pKVideoPortPorts[j].defaultResolution = NULL; + } + } + free(videoPortConfiguration.pKVideoPortPorts); + videoPortConfiguration.pKVideoPortPorts = NULL; + return -1; + } + videoPortConfiguration.pKVideoPortPorts[i].defaultResolution = dupResolution; + } + else + { + videoPortConfiguration.pKVideoPortPorts[i].defaultResolution = NULL; + } + } + + INT_INFO("Allocated and copied %d video port ports (%s)\n", numElements, configType); + return numElements; +} + +static int allocateAndCopyVideoPortResolutions(const dsVideoPortResolution_t* source, int numElements, bool isDynamic) +{ + const char* configType = isDynamic ? "dynamic" : "static"; + + if (numElements <= 0) { + INT_ERROR("Invalid %s video port resolution numElements: %d\n", configType, numElements); + return -1; + } + + videoPortConfiguration.pKVideoPortResolutionsSettings = (dsVideoPortResolution_t*)malloc(numElements * sizeof(dsVideoPortResolution_t)); + if (videoPortConfiguration.pKVideoPortResolutionsSettings == NULL) { + INT_ERROR("Failed to allocate memory for %s video port resolutions\n", configType); + return -1; + } + + /* Copy the structures. The 'name' field is a fixed array (char[32]), + * so memcpy correctly copies the entire content, not just a pointer. */ + memcpy(videoPortConfiguration.pKVideoPortResolutionsSettings, source, numElements * sizeof(dsVideoPortResolution_t)); + INT_INFO("Allocated and copied %d video port resolutions (%s)\n", numElements, configType); + return numElements; +} + +dsError_t dsLoadVideoOutputPortConfig(const videoPortConfigs_t* dynamicVideoPortConfigs) +{ + int configSize, portSize, resolutionSize, defaultResIndex; + const dsVideoPortTypeConfig_t* videoPortConfigs; + const dsVideoPortPortConfig_t* videoPortPorts; + const dsVideoPortResolution_t* videoPortResolutions; + bool isDynamic; + + INT_INFO("Using '%s' config\n", dynamicVideoPortConfigs ? "dynamic" : "static"); + + // Set up parameters based on config source + if (NULL != dynamicVideoPortConfigs) { + configSize = *(dynamicVideoPortConfigs->pKVideoPortConfigs_size); + portSize = *(dynamicVideoPortConfigs->pKVideoPortPorts_size); + resolutionSize = *(dynamicVideoPortConfigs->pKResolutionsSettings_size); + defaultResIndex = *(dynamicVideoPortConfigs->pKDefaultResIndex); + videoPortConfigs = dynamicVideoPortConfigs->pKVideoPortConfigs; + videoPortPorts = dynamicVideoPortConfigs->pKVideoPortPorts; + videoPortResolutions = dynamicVideoPortConfigs->pKVideoPortResolutionsSettings; + isDynamic = true; + } else { + configSize = dsUTL_DIM(kConfigs); + portSize = dsUTL_DIM(kPorts); + resolutionSize = dsUTL_DIM(kResolutions); + defaultResIndex = kDefaultResIndex; + videoPortConfigs = kConfigs; + videoPortPorts = kPorts; + videoPortResolutions = kResolutions; + isDynamic = false; + } + + // Allocate and copy video port resolutions FIRST (needed by configs) + if (allocateAndCopyVideoPortResolutions(videoPortResolutions, resolutionSize, isDynamic) == -1) { + INT_ERROR("Failed to allocate video port resolutions\n"); + return dsERR_GENERAL; + } + + // Allocate and copy video port type configs + if (allocateAndCopyVideoPortConfigs(videoPortConfigs, configSize, isDynamic) == -1) { + INT_ERROR("Failed to allocate video port configs\n"); + // Clean up previously allocated memory + if (videoPortConfiguration.pKVideoPortResolutionsSettings != NULL) { + free(videoPortConfiguration.pKVideoPortResolutionsSettings); + videoPortConfiguration.pKVideoPortResolutionsSettings = NULL; + } + return dsERR_GENERAL; + } + + // Update supportedResolutions pointers to point to our copied resolutions array + for (int i = 0; i < configSize; ++i) { + if (videoPortConfiguration.pKVideoPortConfigs[i].supportedResolutions != NULL) { + videoPortConfiguration.pKVideoPortConfigs[i].supportedResolutions = + videoPortConfiguration.pKVideoPortResolutionsSettings; + INT_INFO("Updated config[%d] supportedResolutions pointer to %p\n", + i, videoPortConfiguration.pKVideoPortResolutionsSettings); + } + } + + // Allocate and copy video port ports + if (allocateAndCopyVideoPortPorts(videoPortPorts, portSize, isDynamic) == -1) { + INT_ERROR("Failed to allocate video port ports\n"); + // Clean up previously allocated memory + if (videoPortConfiguration.pKVideoPortConfigs != NULL) { + for (int i = 0; i < configSize; ++i) { + if (videoPortConfiguration.pKVideoPortConfigs[i].name != NULL) { + free((void*)videoPortConfiguration.pKVideoPortConfigs[i].name); + } + } + free(videoPortConfiguration.pKVideoPortConfigs); + videoPortConfiguration.pKVideoPortConfigs = NULL; + } + if (videoPortConfiguration.pKVideoPortResolutionsSettings != NULL) { + free(videoPortConfiguration.pKVideoPortResolutionsSettings); + videoPortConfiguration.pKVideoPortResolutionsSettings = NULL; + } + return dsERR_GENERAL; + } + + videoPortConfiguration.kDefaultResIndex = defaultResIndex; + INT_INFO("Store sizes videoPortConfiguration.kDefaultResIndex = %d\n", videoPortConfiguration.kDefaultResIndex); + + INT_INFO("Store sizes configSize =%d, portSize =%d, resolutionSize = %d\n", configSize, portSize, resolutionSize); + videoPortConfiguration.kVideoPortConfigs_size = configSize; + videoPortConfiguration.kVideoPortPorts_size = portSize; + videoPortConfiguration.kResolutionsSettings_size = resolutionSize; + INT_INFO("Store sizes kVideoPortConfigs_size = %d\n", videoPortConfiguration.kVideoPortConfigs_size); + INT_INFO("Store sizes kVideoPortPorts_size = %d\n", videoPortConfiguration.kVideoPortPorts_size); + INT_INFO("Store sizes kResolutionsSettings_size = %d\n", videoPortConfiguration.kResolutionsSettings_size); + + INT_INFO("VideoPort Config[%p] ConfigSize[%d] Ports[%p] PortSize[%d] Resolutions[%p] ResolutionSize[%d] DefaultResIndex[%d]\n", + videoPortConfiguration.pKVideoPortConfigs, + videoPortConfiguration.kVideoPortConfigs_size, + videoPortConfiguration.pKVideoPortPorts, + videoPortConfiguration.kVideoPortPorts_size, + videoPortConfiguration.pKVideoPortResolutionsSettings, + videoPortConfiguration.kResolutionsSettings_size, + videoPortConfiguration.kDefaultResIndex); + videoPortDumpconfig(&videoPortConfiguration); + return dsERR_NONE; +} + +// Getter functions for use across srv code +dsError_t _dsGetVideoPortTypeConfigs(int* outConfigSize, const dsVideoPortTypeConfig_t** outConfigs) +{ + if((outConfigSize == NULL) || (outConfigs == NULL)) + { + INT_ERROR("Invalid argument pointer\n"); + return dsERR_GENERAL; + } + + *outConfigSize = videoPortConfiguration.kVideoPortConfigs_size; + *outConfigs = videoPortConfiguration.pKVideoPortConfigs; + + return dsERR_NONE; +} + +dsError_t _dsGetVideoPortPortConfigs(int* outPortSize, const dsVideoPortPortConfig_t** outPorts) +{ + if((outPortSize == NULL) || (outPorts == NULL)) + { + INT_ERROR("Invalid argument pointer\n"); + return dsERR_GENERAL; + } + + *outPortSize = videoPortConfiguration.kVideoPortPorts_size; + *outPorts = videoPortConfiguration.pKVideoPortPorts; + + return dsERR_NONE; +} + +dsError_t _dsGetVideoPortResolutions(int* outResolutionSize, dsVideoPortResolution_t** outResolutions) +{ + if((outResolutionSize == NULL) || (outResolutions == NULL)) + { + INT_ERROR("Invalid argument pointer\n"); + return dsERR_GENERAL; + } + + *outResolutionSize = videoPortConfiguration.kResolutionsSettings_size; + *outResolutions = videoPortConfiguration.pKVideoPortResolutionsSettings; + + return dsERR_NONE; +} + +dsError_t _dsGetDefaultResolutionIndex(int* outDefaultIndex) +{ + + if(outDefaultIndex == NULL) + { + INT_ERROR("Invalid argument pointer\n"); + return dsERR_GENERAL; + } + + *outDefaultIndex = videoPortConfiguration.kDefaultResIndex; + + return dsERR_NONE; +} + +void dsVideoPortConfigFree(void) +{ + INT_INFO("Freeing VideoPort configuration resources\n"); + + // Free video port configs and their allocated name strings + if (videoPortConfiguration.pKVideoPortConfigs != NULL) { + for (int i = 0; i < videoPortConfiguration.kVideoPortConfigs_size; ++i) { + if (videoPortConfiguration.pKVideoPortConfigs[i].name != NULL) { + free((void*)videoPortConfiguration.pKVideoPortConfigs[i].name); + videoPortConfiguration.pKVideoPortConfigs[i].name = NULL; + } + } + free(videoPortConfiguration.pKVideoPortConfigs); + videoPortConfiguration.pKVideoPortConfigs = NULL; + INT_INFO("Freed pKVideoPortConfigs\n"); + } + + // Free video port ports and their allocated defaultResolution strings + if (videoPortConfiguration.pKVideoPortPorts != NULL) { + for (int i = 0; i < videoPortConfiguration.kVideoPortPorts_size; ++i) { + if (videoPortConfiguration.pKVideoPortPorts[i].defaultResolution != NULL) { + free((void*)videoPortConfiguration.pKVideoPortPorts[i].defaultResolution); + videoPortConfiguration.pKVideoPortPorts[i].defaultResolution = NULL; + } + } + free(videoPortConfiguration.pKVideoPortPorts); + videoPortConfiguration.pKVideoPortPorts = NULL; + INT_INFO("Freed pKVideoPortPorts\n"); + } + + // Free video port resolutions (name is embedded array, not allocated) + if (videoPortConfiguration.pKVideoPortResolutionsSettings != NULL) { + free(videoPortConfiguration.pKVideoPortResolutionsSettings); + videoPortConfiguration.pKVideoPortResolutionsSettings = NULL; + INT_INFO("Freed pKVideoPortResolutionsSettings\n"); + } + + // Reset size variables + videoPortConfiguration.kVideoPortConfigs_size = 0; + videoPortConfiguration.kVideoPortPorts_size = 0; + videoPortConfiguration.kResolutionsSettings_size = 0; + videoPortConfiguration.kDefaultResIndex = 0; + + INT_INFO("VideoPort configuration freed successfully\n"); +} + +#ifdef __cplusplus +} +#endif + +/** @} */ +/** @} */ diff --git a/sample/testFrontPanel.cpp b/sample/testFrontPanel.cpp old mode 100755 new mode 100644 index b1bddee4..fec714bf --- a/sample/testFrontPanel.cpp +++ b/sample/testFrontPanel.cpp @@ -118,7 +118,12 @@ int main(int argc, char *argv[]) printf("Exception Caught during [%s]\r\n", argv[0]); } - device::Manager::DeInitialize(); + try { + device::Manager::DeInitialize(); + } + catch (...) { + printf("Unknown exception during DeInitialize\n"); + } IARM_Bus_Disconnect();