From 08cabf5c81bc92603d36c096add9639a441867bb Mon Sep 17 00:00:00 2001 From: nhanasi Date: Thu, 30 Apr 2026 17:05:00 -0400 Subject: [PATCH 1/2] Data Model Parameter Documentation (#459) * Added Workflow for the JSON parse logic * ParodusClient module * Current workflow update * DML List * DML Updates * remove unwanted * Spike updates * rebase (#457) * Added Workflow for the JSON parse logic (#444) Co-authored-by: Hanasi * tr69hostif 1.4.0 release changelog updates * RDKEMW-15041: Add RFC Handlers for meminsight RFC (#426) * RDKEMW-15041: Add RFC Handlers for meminsight RFC * RDKEMW-15041: Add RFC Handlers for meminsight RFC * Update Device_DeviceInfo.cpp * Update Device_DeviceInfo.cpp * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update data-model-generic.xml * Add processmonitor RFC * rebase (#447) * tr69hostif 1.3.7 release changelog updates (#424) * tr69hostif 1.3.6 release changelog updates (#418) Co-authored-by: nhanas001c * RDKEMW-14686: Fix the wifi signal strength api calls (#416) * Update Device_WiFi_EndPoint.cpp * Update Device_WiFi_EndPoint.cpp * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Update Device_WiFi_EndPoint.cpp --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * tr69hostif 1.3.7 release changelog updates --------- Co-authored-by: nhanas001c Co-authored-by: Vismal S Kumar Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * RDKEMW-10029: Remove duplicate RedRecovery parameter Signed-off-by: AnanthaC * tr69hostif 1.3.8 release changelog updates * tr69hostif - Updated Runtime Dependencies and JSON usage (#437) * Adding tools for agentic development * Create README document with overview * Add readme for GH default rendering * Update the ReadME for each sub folder of tr69 module * Fix Readme rendering issue * Fix Render issue for Overview file * Fix rendering issue in data-flow.md * Fix rendering issue in dataflow * Fix render issue in threading-model.md * Fix Render issue in src/hostif/docs/README.md * Fix render issue in parodusclient * Fix render issue in deviceinfor and ip readme file * Update docs/api/public-api.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Remove duplicate tr69hostif-issue-triage skill (#433) * Initial plan * Remove duplicate tr69hostif-issue-triage skill Co-authored-by: shibu-kv <89052442+shibu-kv@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: shibu-kv <89052442+shibu-kv@users.noreply.github.com> * [WIP] [WIP] Addressing feedback on TR69HostIF documentation enhancements (#434) * Initial plan * docs(Time): fix CurrentLocalTime description to use time+localtime Co-authored-by: shibu-kv <89052442+shibu-kv@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: shibu-kv <89052442+shibu-kv@users.noreply.github.com> * Json Usage Readme for tr69hostif * Updated readme for runtime dependencies --------- Co-authored-by: shibu-kv Co-authored-by: nhanas001c Co-authored-by: Hanasi Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: shibu-kv <89052442+shibu-kv@users.noreply.github.com> * RDKEMW-15382 Crash observed in hostif (#427) Co-authored-by: mtirum011 * tr69hostif: Add Document for L2 Coverage and Thunder Plugin details (#442) * tr69hostif document readme for plugin and datamodel information * L2 coverage Documentation for tr69hostif --------- Co-authored-by: Hanasi * Add rrd enable default value to false (#443) Co-authored-by: Abhinav P V * tr69hostif 1.3.9 release changelog updates * Added Workflow for the JSON parse logic (#444) Co-authored-by: Hanasi --------- Signed-off-by: AnanthaC Co-authored-by: nhanasi Co-authored-by: nhanas001c Co-authored-by: Vismal S Kumar Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: AnanthaC Co-authored-by: shibu-kv Co-authored-by: Hanasi Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: shibu-kv <89052442+shibu-kv@users.noreply.github.com> Co-authored-by: madhubabutt <114217841+madhubabutt@users.noreply.github.com> Co-authored-by: mtirum011 Co-authored-by: Ananth916 <74174916+Ananth916@users.noreply.github.com> Co-authored-by: Abhinavpv28 <162570454+Abhinavpv28@users.noreply.github.com> Co-authored-by: Abhinav P V * rebase (#448) * tr69hostif 1.3.7 release changelog updates (#424) * tr69hostif 1.3.6 release changelog updates (#418) Co-authored-by: nhanas001c * RDKEMW-14686: Fix the wifi signal strength api calls (#416) * Update Device_WiFi_EndPoint.cpp * Update Device_WiFi_EndPoint.cpp * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Update Device_WiFi_EndPoint.cpp --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * tr69hostif 1.3.7 release changelog updates --------- Co-authored-by: nhanas001c Co-authored-by: Vismal S Kumar Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * RDKEMW-10029: Remove duplicate RedRecovery parameter Signed-off-by: AnanthaC * tr69hostif 1.3.8 release changelog updates * tr69hostif - Updated Runtime Dependencies and JSON usage (#437) * Adding tools for agentic development * Create README document with overview * Add readme for GH default rendering * Update the ReadME for each sub folder of tr69 module * Fix Readme rendering issue * Fix Render issue for Overview file * Fix rendering issue in data-flow.md * Fix rendering issue in dataflow * Fix render issue in threading-model.md * Fix Render issue in src/hostif/docs/README.md * Fix render issue in parodusclient * Fix render issue in deviceinfor and ip readme file * Update docs/api/public-api.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Remove duplicate tr69hostif-issue-triage skill (#433) * Initial plan * Remove duplicate tr69hostif-issue-triage skill Co-authored-by: shibu-kv <89052442+shibu-kv@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: shibu-kv <89052442+shibu-kv@users.noreply.github.com> * [WIP] [WIP] Addressing feedback on TR69HostIF documentation enhancements (#434) * Initial plan * docs(Time): fix CurrentLocalTime description to use time+localtime Co-authored-by: shibu-kv <89052442+shibu-kv@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: shibu-kv <89052442+shibu-kv@users.noreply.github.com> * Json Usage Readme for tr69hostif * Updated readme for runtime dependencies --------- Co-authored-by: shibu-kv Co-authored-by: nhanas001c Co-authored-by: Hanasi Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: shibu-kv <89052442+shibu-kv@users.noreply.github.com> * RDKEMW-15382 Crash observed in hostif (#427) Co-authored-by: mtirum011 * tr69hostif: Add Document for L2 Coverage and Thunder Plugin details (#442) * tr69hostif document readme for plugin and datamodel information * L2 coverage Documentation for tr69hostif --------- Co-authored-by: Hanasi * Add rrd enable default value to false (#443) Co-authored-by: Abhinav P V * tr69hostif 1.3.9 release changelog updates * Added Workflow for the JSON parse logic (#444) Co-authored-by: Hanasi --------- Signed-off-by: AnanthaC Co-authored-by: nhanasi Co-authored-by: nhanas001c Co-authored-by: Vismal S Kumar Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: AnanthaC Co-authored-by: shibu-kv Co-authored-by: Hanasi Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: shibu-kv <89052442+shibu-kv@users.noreply.github.com> Co-authored-by: madhubabutt <114217841+madhubabutt@users.noreply.github.com> Co-authored-by: mtirum011 Co-authored-by: Ananth916 <74174916+Ananth916@users.noreply.github.com> Co-authored-by: Abhinavpv28 <162570454+Abhinavpv28@users.noreply.github.com> Co-authored-by: Abhinav P V * Update Device_DeviceInfo.cpp * Update Device_DeviceInfo.h --------- Signed-off-by: AnanthaC Co-authored-by: Satya Sundar Sahu Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: nhanasi Co-authored-by: nhanas001c Co-authored-by: Vismal S Kumar Co-authored-by: AnanthaC Co-authored-by: shibu-kv Co-authored-by: Hanasi Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: shibu-kv <89052442+shibu-kv@users.noreply.github.com> Co-authored-by: madhubabutt <114217841+madhubabutt@users.noreply.github.com> Co-authored-by: mtirum011 Co-authored-by: Ananth916 <74174916+Ananth916@users.noreply.github.com> Co-authored-by: Abhinavpv28 <162570454+Abhinavpv28@users.noreply.github.com> Co-authored-by: Abhinav P V * tr69hostif 1.4.1 release changelog updates * RDKEMW-15141 Update the Missing Coverity Reports Fixes (#441) Co-authored-by: mtirum011 Co-authored-by: nhanasi Co-authored-by: Shibu Kakkoth Vayalambron * Update workflow for the partner Defaults usage (#451) * Add workflow for partner default usage * Update the bootstap details --------- Co-authored-by: Hanasi * RDK-59998 : Remove getprofiledata dml from hostif (#455) * Update Device_DeviceInfo.cpp * Update Device_DeviceInfo.h * dml * Update hostIf_DeviceClient_ReqHandler.cpp --------- Co-authored-by: Abhinav P V * tr69hostif 1.4.2 release changelog updates --------- Signed-off-by: AnanthaC Co-authored-by: Hanasi Co-authored-by: nhanas001c Co-authored-by: Gomathi Shankar Co-authored-by: Satya Sundar Sahu Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Vismal S Kumar Co-authored-by: AnanthaC Co-authored-by: shibu-kv Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: shibu-kv <89052442+shibu-kv@users.noreply.github.com> Co-authored-by: madhubabutt <114217841+madhubabutt@users.noreply.github.com> Co-authored-by: mtirum011 Co-authored-by: Ananth916 <74174916+Ananth916@users.noreply.github.com> Co-authored-by: Abhinavpv28 <162570454+Abhinavpv28@users.noreply.github.com> Co-authored-by: Abhinav P V * Update cov_build.sh * Update parodus-module-analysis.md * Update cov_build.sh * Create dsVideoResolutionSettings.h * Create telemetry_busmessage_sender.h * Update cov_build.sh * Update cov_build.sh * Create dsAudioSettings.h * Create dsVideoDeviceSettings.h * Create dsVideoPortSettings.h * Update dsVideoResolutionSettings.h * Update rfcapi.h * Create telemetry_msgsender_stub.c * Update cov_build.sh --------- Signed-off-by: AnanthaC Co-authored-by: Hanasi Co-authored-by: nhanas001c Co-authored-by: Gomathi Shankar Co-authored-by: Satya Sundar Sahu Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Vismal S Kumar Co-authored-by: AnanthaC Co-authored-by: shibu-kv Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: shibu-kv <89052442+shibu-kv@users.noreply.github.com> Co-authored-by: madhubabutt <114217841+madhubabutt@users.noreply.github.com> Co-authored-by: mtirum011 Co-authored-by: Ananth916 <74174916+Ananth916@users.noreply.github.com> Co-authored-by: Abhinavpv28 <162570454+Abhinavpv28@users.noreply.github.com> Co-authored-by: Abhinav P V --- cov_build.sh | 44 +- docs/api/dml_parameter_list.md | 918 ++++++++++++++++++ .../docs/parodus-module-analysis.md | 426 ++++++++ src/unittest/stubs/dsAudioSettings.h | 65 ++ src/unittest/stubs/dsVideoDeviceSettings.h | 38 + src/unittest/stubs/dsVideoPortSettings.h | 46 + .../stubs/dsVideoResolutionSettings.h | 48 + src/unittest/stubs/rfcapi.h | 1 - .../stubs/telemetry_busmessage_sender.h | 24 + src/unittest/stubs/telemetry_msgsender_stub.c | 16 + 10 files changed, 1614 insertions(+), 12 deletions(-) create mode 100644 docs/api/dml_parameter_list.md create mode 100644 src/hostif/parodusClient/docs/parodus-module-analysis.md create mode 100644 src/unittest/stubs/dsAudioSettings.h create mode 100644 src/unittest/stubs/dsVideoDeviceSettings.h create mode 100644 src/unittest/stubs/dsVideoPortSettings.h create mode 100644 src/unittest/stubs/dsVideoResolutionSettings.h create mode 100644 src/unittest/stubs/telemetry_busmessage_sender.h create mode 100644 src/unittest/stubs/telemetry_msgsender_stub.c diff --git a/cov_build.sh b/cov_build.sh index a9e92048b..727b18425 100644 --- a/cov_build.sh +++ b/cov_build.sh @@ -6,6 +6,7 @@ apt-get update && apt-get install -y libsoup-3.0 #Build rfc cd $ROOT +rm -rf rfc git clone https://github.com/rdkcentral/rfc.git cd rfc autoreconf -i @@ -21,13 +22,14 @@ cd ../utils make && make install #Build yajl - tr69 alone needs this specific version -cd $ROOT +cd $ROOT +rm -rf yajl git clone https://github.com/lloyd/yajl.git -b 1.x cd yajl mkdir build cd build cmake .. -make +make make install cd $ROOT @@ -40,18 +42,38 @@ git clone https://github.com/rdkcentral/rdkvhal-devicesettings-raspberrypi4.git git clone https://github.com/rdkcentral/iarmbus.git git clone https://github.com/rdkcentral/remote_debugger.git -# Build devicesettings version with fixes for native build and use that as a stub -# TODO This is not present in mainline versions. Component maintainers will have to provide this in future. +cp $WORKDIR/src/unittest/stubs/telemetry_busmessage_sender.h /usr/local/include/ +cp $WORKDIR/src/unittest/stubs/dsVideoResolutionSettings.h /usr/rdk-halif-device_settings/include/dsVideoResolutionSettings.h +cp $WORKDIR/src/unittest/stubs/dsAudioSettings.h /usr/rdkvhal-devicesettings-raspberrypi4/dsAudioSettings.h +cp $WORKDIR/src/unittest/stubs/dsVideoPortSettings.h /usr/rdkvhal-devicesettings-raspberrypi4/dsVideoPortSettings.h +cp $WORKDIR/src/unittest/stubs/dsVideoResolutionSettings.h /usr/rdkvhal-devicesettings-raspberrypi4/dsVideoResolutionSettings.h +cp $WORKDIR/src/unittest/stubs/dsVideoDeviceSettings.h /usr/rdkvhal-devicesettings-raspberrypi4/dsVideoDeviceSettings.h + +gcc -fPIC -shared -o /usr/local/lib/libtelemetry_msgsender.so $WORKDIR/src/unittest/stubs/telemetry_msgsender_stub.c +rm -f $WORKDIR/src/unittest/stubs/rdk_debug.h + cd $ROOT rm -rf devicesettings -git clone https://github.com/rdkcentral/devicesettings.git -b feature/RDKE-539 +git clone https://github.com/rdkcentral/devicesettings.git cd devicesettings autoreconf -i sed -i '/#include "dsAudio.h"/d' /usr/devicesettings/rpc/cli/dsAudio.c sed -i '/device::HdmiInput::getInstance().isPortConnected(portId);/d' /usr/devicesettings/ds/audioOutputPort.cpp ./configure -make INCLUDE_FILES="-I/usr/rdk-halif-device_settings/include -I/usr/rpc/include -I/usr/devicesettings/rpc/cli -I/usr/devicesettings/rpc/include -I/usr/iarmbus/core/include -I$WORKDIR/src/unittest/stubs -I/usr/devicesettings/rpc/srv -I/usr/rdkvhal-devicesettings-raspberrypi4" libds_la_CPPFLAGS="-I/usr/rdk-halif-device_settings/include -I/usr/devicesettings/ds/include -I$WORKDIR/src/unittest/stubs/ -I/usr/rdkvhal-devicesettings-raspberrypi4 -I/usr/devicesettings/rpc/include -I/usr/devicesettings/rpc/cli/ -I/usr/devicesettings/rpc/srv -I/usr/devicesettings/ds/include -I/usr/devicesettings/ds/" CFLAGS="-fpermissive" -make install +DS_COMMON_INCLUDES="-I/usr/rdk-halif-device_settings/include \ + -I/usr/rpc/include \ + -I/usr/devicesettings/rpc/cli \ + -I/usr/devicesettings/rpc/include \ + -I/usr/iarmbus/core/include \ + -I$WORKDIR/src/unittest/stubs \ + -I/usr/devicesettings/rpc/srv \ + -I/usr/rdkvhal-devicesettings-raspberrypi4" +make \ + CPPFLAGS="$DS_COMMON_INCLUDES" \ + libds_la_CPPFLAGS="-I/usr/rdk-halif-device_settings/include -I/usr/devicesettings/ds/include -I$WORKDIR/src/unittest/stubs/ -I/usr/rdkvhal-devicesettings-raspberrypi4 -I/usr/devicesettings/rpc/include -I/usr/devicesettings/rpc/cli/ -I/usr/devicesettings/rpc/srv -I/usr/devicesettings/ds/include -I/usr/devicesettings/ds/ -DRDK_DSHAL_NAME='\"libdshal.so\"'" \ + libdshalsrv_la_CPPFLAGS="-I/usr/iarmbus/core/include -I/usr/devicesettings/rpc/include -I/usr/devicesettings/rpc/srv -I/usr/rdk-halif-device_settings/include -I$WORKDIR/src/unittest/stubs -isystem $WORKDIR/src/unittest/stubs -DDSMGR_LOGGER_ENABLED=ON -DRDK_DSHAL_NAME='\"libdshal.so\"'" \ + CFLAGS="-fpermissive" \ + install # Build and deploy stubs for IARMBus echo "Building IARMBus stubs" @@ -68,16 +90,16 @@ cp libWPEFrameworkPowerController.so /usr/local/lib/libWPEFrameworkPowerControll echo "##### Building tr69hostif module" cd $WORKDIR sed -i '/PKG_CHECK_MODULES(\[PROCPS\], \[libproc >= 3.2.8\])/s/^/#/' ./configure.ac -rm -f ./src/unittest/stubs/rdk_debug.h + autoreconf -i ./configure --enable-IPv6=yes make AM_CXXFLAGS="-I$WORKDIR/src/unittest/stubs -I$WORKDIR/src/hostif/include -I/usr/include/cjson -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I$WORKDIR/src/hostif/handlers/include -I$WORKDIR/src/hostif/parodusClient/waldb -I$WORKDIR/src/hostif/profiles/DeviceInfo -I/usr/include/cjson -I$WORKDIR/src/hostif/profiles/Time -I$WORKDIR/src/hostif/profiles/Device -I/usr/include/libsoup-3.0 -I/usr/include/yajl -I$WORKDIR/src/hostif/profiles/STBService -I$WORKDIR/src/unittest/stubs/ds -I/usr/devicesettings/ds -I/usr/local/include -I$WORKDIR/src/hostif/profiles/IP -I$WORKDIR/src/hostif/profiles/Ethernet -I/usr/local/include/rbus -I$WORKDIR/src/hostif/parodusClient/pal -I/usr/rdk-halif-device_settings/include -I/usr/local/include/libparodus -I/usr/local/include -I/usr/rdkvhal-devicesettings-raspberrypi4 -I/usr/local/include/ -I/usr/include/yajl -I/usr/tinyxml2 -I/usr/devicesettings/ds -I/$WORKDIR/src/hostif/httpserver/include -I/usr/remote_debugger/src/ -DIPV6_SUPPORT" \ -AM_LDFLAGS="-L/usr/local/lib -lrbus -lsecure_wrapper -lcurl -lrfcapi -lrdkloggers -llibparodus -lglib-2.0 -lnanomsg -lIARMBus -lWPEFrameworkPowerController -lds -ldshalcli -ldshalsrv -lwrp-c -lwdmp-c -lprocps -ltrower-base64 -lcimplog -lsoup-3.0 -L/usr/lib/x86_64-linux-gnu -lyajl -L/usr/local/lib/x86_64-linux-gnu -ltinyxml2" CXXFLAGS="-fpermissive -DPARODUS_ENABLE -DUSE_REMOTE_DEBUGGER" -make install +AM_LDFLAGS="-L/usr/local/lib -lrbus -lsecure_wrapper -lcurl -lrfcapi -lrdkloggers -llibparodus -lglib-2.0 -lnanomsg -lIARMBus -lWPEFrameworkPowerController -lds -ldshalcli -ldshalsrv -lwrp-c -lwdmp-c -lprocps -ltrower-base64 -lcimplog -lsoup-3.0 -L/usr/lib/x86_64-linux-gnu -lyajl -L/usr/local/lib/x86_64-linux-gnu -ltinyxml2" CXXFLAGS="-fpermissive -DPARODUS_ENABLE -DUSE_REMOTE_DEBUGGER" \ + install cd ./src/hostif/parodusClient/pal/mock-parodus/ sh mock_parodus_build.sh ln -sf /usr/local/bin/tr181 /usr/bin/tr181Set -rbuscli set Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.MOCASSH.Enable boolean true +rbuscli set Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.MOCASSH.Enable boolean true diff --git a/docs/api/dml_parameter_list.md b/docs/api/dml_parameter_list.md new file mode 100644 index 000000000..260300708 --- /dev/null +++ b/docs/api/dml_parameter_list.md @@ -0,0 +1,918 @@ +# TR-181 Datamodel Parameter List + +> **Automation Test Suite Reference** - Generated from dml_list.txt (TR-181 v2.12, Comcast/RDK) + +| Access | Count | Test Action | +|--------|-------|-------------| +| readOnly | 356 | GET only - assert non-empty or expected value | +| readWrite | 548 | GET + SET - verify set/get round-trip | +| **Total** | **904** | | + +--- + +| # | Parameter | Access | Data Type | Description | +|---|-----------|--------|-----------|-------------| +| 1 | `Device.DeviceInfo.AdditionalSoftwareVersion` | readOnly | string | Additional software version string reported by the device. | +| 2 | `Device.DeviceInfo.Description` | readOnly | string | Text description reported by the device. | +| 3 | `Device.DeviceInfo.FirstUseDate` | readOnly | dateTime | Date and time when the device was first put into service. | +| 4 | `Device.DeviceInfo.HardwareVersion` | readOnly | string | Version string reported for the device. | +| 5 | `Device.DeviceInfo.Manufacturer` | readOnly | string | Manufacturer reported for the device. | +| 6 | `Device.DeviceInfo.ManufacturerOUI` | readOnly | string | OUI identifying the device manufacturer. | +| 7 | `Device.DeviceInfo.MemoryStatus.Free` | readOnly | unsignedInt | Currently available memory reported by the device. | +| 8 | `Device.DeviceInfo.MemoryStatus.Total` | readOnly | unsignedInt | Total installed memory reported by the device. | +| 9 | `Device.DeviceInfo.Migration.MigrationStatus` | readOnly | string | Current migration state reported by the migration workflow. | +| 10 | `Device.DeviceInfo.MigrationPreparer.MigrationReady` | readOnly | string | Reports whether the migration preparer considers the device ready. | +| 11 | `Device.DeviceInfo.ModelName` | readOnly | string | Model identifier reported for the device. | +| 12 | `Device.DeviceInfo.ProcessStatus.CPUUsage` | readOnly | unsignedInt | Aggregate CPU usage reported for the device. | +| 13 | `Device.DeviceInfo.ProcessStatus.Process.{i}.CPUTime` | readOnly | unsignedInt | CPU time consumed by this process entry. | +| 14 | `Device.DeviceInfo.ProcessStatus.Process.{i}.Command` | readOnly | string | Command line associated with this process entry. | +| 15 | `Device.DeviceInfo.ProcessStatus.Process.{i}.PID` | readOnly | unsignedInt | Process ID for this process entry. | +| 16 | `Device.DeviceInfo.ProcessStatus.Process.{i}.Priority` | readOnly | unsignedInt | Scheduling priority for this process entry. | +| 17 | `Device.DeviceInfo.ProcessStatus.Process.{i}.Size` | readOnly | unsignedInt | Reported memory footprint for this process entry. | +| 18 | `Device.DeviceInfo.ProcessStatus.Process.{i}.State` | readOnly | string | Configuration or status value for this process entry. | +| 19 | `Device.DeviceInfo.ProcessStatus.ProcessNumberOfEntries` | readOnly | unsignedInt | Number of process entries currently exposed in the Process table. | +| 20 | `Device.DeviceInfo.Processor.{i}.Architecture` | readOnly | string | Processor architecture reported for this processor entry. | +| 21 | `Device.DeviceInfo.ProcessorNumberOfEntries` | readOnly | unsignedInt | Number of processor entries currently exposed in the Processor table. | +| 22 | `Device.DeviceInfo.ProductClass` | readOnly | string | Product class identifier reported by the device. | +| 23 | `Device.DeviceInfo.ProvisioningCode` | readWrite | string | ACS-managed provisioning code used to classify or provision the device. | +| 24 | `Device.DeviceInfo.SerialNumber` | readOnly | string | Serial number reported for the device. | +| 25 | `Device.DeviceInfo.SoftwareVersion` | readOnly | string | Version string reported for the device. | +| 26 | `Device.DeviceInfo.SupportedDataModel.1.Features` | readOnly | string | Feature set advertised for this supported data model entry. | +| 27 | `Device.DeviceInfo.SupportedDataModel.1.URL` | readOnly | string | URL used by this supported data model entry. | +| 28 | `Device.DeviceInfo.SupportedDataModel.1.URN` | readOnly | string | URN identifier for this supported data model entry. | +| 29 | `Device.DeviceInfo.SupportedDataModel.2.Features` | readWrite | string | Feature set advertised for this supported data model entry. | +| 30 | `Device.DeviceInfo.SupportedDataModel.2.URL` | readWrite | string | URL used by this supported data model entry. | +| 31 | `Device.DeviceInfo.SupportedDataModel.2.URN` | readWrite | string | URN identifier for this supported data model entry. | +| 32 | `Device.DeviceInfo.SupportedDataModelNumberOfEntries` | readOnly | unsignedInt | Number of supported data model entries reported by the device. | +| 33 | `Device.DeviceInfo.UpTime` | readOnly | unsignedInt | Seconds since the device last booted. | +| 34 | `Device.DeviceInfo.VendorLogFileNumberOfEntries` | readOnly | unsignedInt | Number of vendor log file entries exposed by the device. | +| 35 | `Device.DeviceInfo.X_COMCAST-COM_FirmwareDownloadStatus` | readOnly | string | Current firmware download status reported by the Comcast platform. | +| 36 | `Device.DeviceInfo.X_COMCAST-COM_FirmwareFilename` | readOnly | string | Firmware filename reported by the Comcast platform. | +| 37 | `Device.DeviceInfo.X_COMCAST-COM_FirmwareToDownload` | readOnly | string | Firmware image identifier selected for download on the Comcast platform. | +| 38 | `Device.DeviceInfo.X_COMCAST-COM_PowerStatus` | readOnly | string | Current power state reported by the Comcast platform. | +| 39 | `Device.DeviceInfo.X_COMCAST-COM_Reset` | readWrite | string | Triggers the Comcast platform reset workflow. | +| 40 | `Device.DeviceInfo.X_COMCAST-COM_STB_IP` | readOnly | string | IP address currently assigned to the set-top box. | +| 41 | `Device.DeviceInfo.X_COMCAST-COM_STB_MAC` | readOnly | string | MAC address of the set-top box. | +| 42 | `Device.DeviceInfo.X_RDKCENTRAL-COM.BootStatus` | readOnly | string | Current boot status reported by the platform. | +| 43 | `Device.DeviceInfo.X_RDKCENTRAL-COM.CPUTemp` | readWrite | int | Current CPU temperature reported by the platform. | +| 44 | `Device.DeviceInfo.X_RDKCENTRAL-COM.IUI.AppsVersion` | readWrite | string | Version string for the installed IUI applications bundle. | +| 45 | `Device.DeviceInfo.X_RDKCENTRAL-COM.IUI.Version` | readWrite | string | Version string for the installed IUI platform. | +| 46 | `Device.DeviceInfo.X_RDKCENTRAL-COM_BootTime` | readOnly | unsignedInt | Boot time reported by the platform. | +| 47 | `Device.DeviceInfo.X_RDKCENTRAL-COM_Experience` | readOnly | string | Current user experience label reported by the platform. | +| 48 | `Device.DeviceInfo.X_RDKCENTRAL-COM_FirmwareDownloadDeferReboot` | readWrite | boolean | Controls whether reboot is deferred after a firmware download. | +| 49 | `Device.DeviceInfo.X_RDKCENTRAL-COM_FirmwareDownloadNow` | readWrite | boolean | Triggers immediate firmware download processing. | +| 50 | `Device.DeviceInfo.X_RDKCENTRAL-COM_FirmwareDownloadPercent` | readOnly | int | Firmware download completion percentage reported by the platform. | +| 51 | `Device.DeviceInfo.X_RDKCENTRAL-COM_FirmwareDownloadProtocol` | readWrite | string | Protocol used for firmware download. | +| 52 | `Device.DeviceInfo.X_RDKCENTRAL-COM_FirmwareDownloadStatus` | readOnly | string | Current firmware download status reported by the platform. | +| 53 | `Device.DeviceInfo.X_RDKCENTRAL-COM_FirmwareDownloadURL` | readWrite | string | Firmware download URL configured for the platform. | +| 54 | `Device.DeviceInfo.X_RDKCENTRAL-COM_FirmwareDownloadUseCodebig` | readWrite | boolean | Controls whether Codebig is used for firmware download. | +| 55 | `Device.DeviceInfo.X_RDKCENTRAL-COM_FirmwareFilename` | readOnly | string | Firmware filename reported by the platform. | +| 56 | `Device.DeviceInfo.X_RDKCENTRAL-COM_FirmwareToDownload` | readWrite | string | Firmware image identifier selected for download. | +| 57 | `Device.DeviceInfo.X_RDKCENTRAL-COM_FirmwareUpdateState` | readOnly | string | Current firmware update state reported by the platform. | +| 58 | `Device.DeviceInfo.X_RDKCENTRAL-COM_IPRemoteSupport.Enable` | readWrite | boolean | Enables or disables IP remote support. | +| 59 | `Device.DeviceInfo.X_RDKCENTRAL-COM_IPRemoteSupport.IPAddr` | readOnly | string | IP address currently assigned to the IP remote interface. | +| 60 | `Device.DeviceInfo.X_RDKCENTRAL-COM_IPRemoteSupport.MACAddr` | readOnly | string | MAC address of the IP remote interface. | +| 61 | `Device.DeviceInfo.X_RDKCENTRAL-COM_LastRebootReason` | readWrite | string | Reason recorded for the most recent reboot. | +| 62 | `Device.DeviceInfo.X_RDKCENTRAL-COM_Manufacturing.UIbranding` | readWrite | string | Configured UI branding label for the device. | +| 63 | `Device.DeviceInfo.X_RDKCENTRAL-COM_PreferredGatewayType` | readWrite | string | Preferred gateway type configured for the device. | +| 64 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RDKDownloadManager.DownloadStatus` | readWrite | boolean | Current download status for the related feature. | +| 65 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RDKVersion` | readOnly | string | RDK software version reported by the platform. | +| 66 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.AuthService.Host` | readWrite | string | Host value used by RFC setting AuthService Host. | +| 67 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Bootstrap.Control.ClearDB` | readWrite | boolean | Control flag used by RFC setting Bootstrap Control ClearDB. | +| 68 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Bootstrap.Control.ClearDBEnd` | readWrite | boolean | Control flag used by RFC setting Bootstrap Control ClearDBEnd. | +| 69 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Bootstrap.NetflixESNprefix` | readWrite | string | RFC configuration value for Bootstrap NetflixESNprefix. | +| 70 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Bootstrap.OsClass` | readWrite | string | RFC configuration value for Bootstrap OsClass. | +| 71 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Bootstrap.PartnerName` | readWrite | string | RFC configuration value for Bootstrap PartnerName. | +| 72 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Bootstrap.PartnerProductName` | readWrite | string | RFC configuration value for Bootstrap PartnerProductName. | +| 73 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Bootstrap.SsrUrl` | readWrite | string | Endpoint URL used by RFC setting Bootstrap SsrUrl. | +| 74 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Bootstrap.XconfRecoveryUrl` | readWrite | string | Endpoint URL used by RFC setting Bootstrap XconfRecoveryUrl. | +| 75 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Bootstrap.XconfUrl` | readWrite | string | Endpoint URL used by RFC setting Bootstrap XconfUrl. | +| 76 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.ClearParam` | readWrite | string | RFC configuration value for ClearParam. | +| 77 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.CloudStore.Uri` | readWrite | string | Endpoint URL used by RFC setting CloudStore Uri. | +| 78 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Control.ClearDB` | readWrite | boolean | Control flag used by RFC setting Control ClearDB. | +| 79 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Control.ClearDBEnd` | readWrite | boolean | Control flag used by RFC setting Control ClearDBEnd. | +| 80 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Control.ConfigChangeTime` | readWrite | unsignedInt | RFC configuration value for Control ConfigChangeTime. | +| 81 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Control.ConfigSetHash` | readWrite | string | RFC configuration value for Control ConfigSetHash. | +| 82 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Control.ConfigSetTime` | readWrite | unsignedInt | RFC configuration value for Control ConfigSetTime. | +| 83 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Control.RetrieveNow` | readWrite | unsignedInt | Control flag used by RFC setting Control RetrieveNow. | +| 84 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Control.XconfSelector` | readWrite | string | RFC configuration value for Control XconfSelector. | +| 85 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Control.XconfUrl` | readWrite | string | Endpoint URL used by RFC setting Control XconfUrl. | +| 86 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.CrashUpload.S3BucketUrl` | readWrite | string | Endpoint URL used by RFC setting CrashUpload S3BucketUrl. | +| 87 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.CrashUpload.S3SigningUrl` | readWrite | string | Endpoint URL used by RFC setting CrashUpload S3SigningUrl. | +| 88 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.CrashUpload.crashPortalDEVUrl` | readWrite | string | Endpoint URL used by RFC setting CrashUpload crashPortalDEVUrl. | +| 89 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.CrashUpload.crashPortalPRODUrl` | readWrite | string | Endpoint URL used by RFC setting CrashUpload crashPortalPRODUrl. | +| 90 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.CrashUpload.crashPortalSTBUrl` | readWrite | string | Endpoint URL used by RFC setting CrashUpload crashPortalSTBUrl. | +| 91 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.CrashUpload.crashPortalVBNUrl` | readWrite | string | Endpoint URL used by RFC setting CrashUpload crashPortalVBNUrl. | +| 92 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.DAC.ConfigURL` | readWrite | string | Endpoint URL used by RFC setting DAC ConfigURL. | +| 93 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.DAC.dacBundleFirmwareCompatibilityKey` | readWrite | string | RFC configuration value for DAC dacBundleFirmwareCompatibilityKey. | +| 94 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.DAC.dacBundlePlatformName` | readWrite | string | RFC configuration value for DAC dacBundlePlatformName. | +| 95 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.DynamicIUIUpdate.IUISelector` | readWrite | string | RFC configuration value for DynamicIUIUpdate IUISelector. | +| 96 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.DynamicIUIUpdate.Pathway.Uri` | readWrite | string | Endpoint URL used by RFC setting DynamicIUIUpdate Pathway Uri. | +| 97 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.1080pGraphics.Enable` | readWrite | boolean | RFC flag that enables or disables Feature 1080pGraphics Enable. | +| 98 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.AAMP_CFG.DashPlaybackExclusions` | readWrite | string | RFC configuration value for Feature AAMP CFG DashPlaybackExclusions. | +| 99 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.AAMP_CFG.DashPlaybackInclusions` | readWrite | string | RFC configuration value for Feature AAMP CFG DashPlaybackInclusions. | +| 100 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.AAMP_CFG.b64Config` | readWrite | string | RFC configuration value for Feature AAMP CFG b64Config. | +| 101 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.AccountInfo.AccountID` | readWrite | string | RFC configuration value for Feature AccountInfo AccountID. | +| 102 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Airplay.Enable` | readWrite | boolean | RFC flag that enables or disables Feature Airplay Enable. | +| 103 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.AmazonPrimeVideo.SyePlayer.Enable` | readWrite | boolean | RFC flag that enables or disables Feature AmazonPrimeVideo SyePlayer Enable. | +| 104 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.AppConfig.App.{i}.AppName` | readWrite | string | RFC configuration value for Feature AppConfig App entry AppName. | +| 105 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.AppConfig.App.{i}.AppSize` | readWrite | string | RFC configuration value for Feature AppConfig App entry AppSize. | +| 106 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.AppConfig.App.{i}.AppUrl` | readWrite | string | Endpoint URL used by RFC setting Feature AppConfig App entry AppUrl. | +| 107 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.AppConfig.AppCnt` | readWrite | unsignedInt | RFC configuration value for Feature AppConfig AppCnt. | +| 108 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.AppConfig.Enable` | readWrite | boolean | RFC flag that enables or disables Feature AppConfig Enable. | +| 109 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.AppHibernate.DelayInSecLaunchedToSuspended` | readWrite | unsignedInt | RFC configuration value for Feature AppHibernate DelayInSecLaunchedToSuspended. | +| 110 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.AppHibernate.DelayInSecResumedToSuspended` | readWrite | unsignedInt | RFC configuration value for Feature AppHibernate DelayInSecResumedToSuspended. | +| 111 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.AppHibernate.Enable` | readWrite | boolean | RFC flag that enables or disables Feature AppHibernate Enable. | +| 112 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.AutoReboot.Enable` | readWrite | boolean | RFC flag that enables or disables Feature AutoReboot Enable. | +| 113 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.AutoReboot.fwDelayReboot` | readWrite | int | RFC configuration value for Feature AutoReboot fwDelayReboot. | +| 114 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.BTR.AudioIn.Enable` | readWrite | boolean | RFC flag that enables or disables Feature BTR AudioIn Enable. | +| 115 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.BTR.DebugMode.Enable` | readWrite | boolean | RFC flag that enables or disables Feature BTR DebugMode Enable. | +| 116 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.BTR.GamePad.Enable` | readWrite | boolean | RFC flag that enables or disables Feature BTR GamePad Enable. | +| 117 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.BTSplitAudio.Enable` | readWrite | boolean | RFC flag that enables or disables Feature BTSplitAudio Enable. | +| 118 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.BTSplitAudio.Language` | readWrite | string | RFC configuration value for Feature BTSplitAudio Language. | +| 119 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.BootstrapConfig.Enable` | readWrite | boolean | RFC flag that enables or disables Feature BootstrapConfig Enable. | +| 120 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.CDLDM.CDLModuleUrl` | readWrite | string | Endpoint URL used by RFC setting Feature CDLDM CDLModuleUrl. | +| 121 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.CPC1960.Enable` | readWrite | boolean | RFC flag that enables or disables Feature CPC1960 Enable. | +| 122 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.CRL.DirectOCSP` | readWrite | boolean | RFC configuration value for Feature CRL DirectOCSP. | +| 123 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.CRL.Enable` | readWrite | boolean | RFC flag that enables or disables Feature CRL Enable. | +| 124 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Canary.wakeUpEnd` | readWrite | int | RFC configuration value for Feature Canary wakeUpEnd. | +| 125 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Canary.wakeUpStart` | readWrite | int | RFC configuration value for Feature Canary wakeUpStart. | +| 126 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.CrashportalEndpoint.Enable` | readWrite | string | RFC flag that enables or disables Feature CrashportalEndpoint Enable. | +| 127 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.CrashportalEndpoint.URL` | readWrite | string | Endpoint URL used by RFC setting Feature CrashportalEndpoint URL. | +| 128 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.CredDwnld.Enable` | readWrite | string | RFC flag that enables or disables Feature CredDwnld Enable. | +| 129 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.CredDwnld.Use` | readWrite | string | RFC configuration value for Feature CredDwnld Use. | +| 130 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.DAB.Enable` | readWrite | boolean | RFC flag that enables or disables Feature DAB Enable. | +| 131 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.DHCPv6Client.Enable` | readWrite | boolean | RFC flag that enables or disables Feature DHCPv6Client Enable. | +| 132 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.DNSStrictOrder.Enable` | readWrite | boolean | RFC flag that enables or disables Feature DNSStrictOrder Enable. | +| 133 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.DefaultSupportedLocales` | readWrite | string | RFC configuration value for Feature DefaultSupportedLocales. | +| 134 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.DtmAnalytics.Enable` | readWrite | string | RFC flag that enables or disables Feature DtmAnalytics Enable. | +| 135 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.DtmAnalytics.RecordsToBuffer` | readWrite | string | RFC configuration value for Feature DtmAnalytics RecordsToBuffer. | +| 136 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.DtmAnalytics.ServiceUrl` | readWrite | string | Endpoint URL used by RFC setting Feature DtmAnalytics ServiceUrl. | +| 137 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.EnableHttpCDL.Enable` | readWrite | boolean | RFC flag that enables or disables Feature EnableHttpCDL Enable. | +| 138 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.EntOsAppPlatform.EnableDistPlatform` | readWrite | boolean | RFC configuration value for Feature EntOsAppPlatform EnableDistPlatform. | +| 139 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.FOG_CFG.b64Config` | readWrite | string | RFC configuration value for Feature FOG CFG b64Config. | +| 140 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.FWUpdate.AutoExcluded.Enable` | readWrite | boolean | RFC flag that enables or disables Feature FWUpdate AutoExcluded Enable. | +| 141 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.FWUpdate.AutoExcluded.XconfUrl` | readWrite | string | Endpoint URL used by RFC setting Feature FWUpdate AutoExcluded XconfUrl. | +| 142 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.HdmiCecSink.CECVersion` | readWrite | string | RFC configuration value for Feature HdmiCecSink CECVersion. | +| 143 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.IDS.Enable` | readWrite | boolean | RFC flag that enables or disables Feature IDS Enable. | +| 144 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.IDS.ScanTask` | readWrite | string | RFC configuration value for Feature IDS ScanTask. | +| 145 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.IPControl.Service.Discovery.Enable` | readWrite | boolean | RFC flag that enables or disables Feature IPControl Service Discovery Enable. | +| 146 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.IPControl.Subsystem.RICS.Enable` | readWrite | boolean | RFC flag that enables or disables Feature IPControl Subsystem RICS Enable. | +| 147 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.IPRemotePort.Enable` | readWrite | boolean | RFC flag that enables or disables Feature IPRemotePort Enable. | +| 148 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.InactiveApplications.Maximum` | readWrite | unsignedInt | RFC configuration value for Feature InactiveApplications Maximum. | +| 149 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.IncrementalCDL.Enable` | readWrite | boolean | RFC flag that enables or disables Feature IncrementalCDL Enable. | +| 150 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.JSPPCache.Enable` | readWrite | boolean | RFC flag that enables or disables Feature JSPPCache Enable. | +| 151 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.LSA.AdCacheEnable` | readWrite | string | RFC configuration value for Feature LSA AdCacheEnable. | +| 152 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.LSA.Advt_Opt_Out_Key` | readWrite | string | RFC configuration value for Feature LSA Advt Opt Out Key. | +| 153 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.LSA.AltconReceiver` | readWrite | string | RFC configuration value for Feature LSA AltconReceiver. | +| 154 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.LSA.ByteRangeDownload` | readWrite | string | RFC configuration value for Feature LSA ByteRangeDownload. | +| 155 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.LSA.Enable` | readWrite | string | RFC flag that enables or disables Feature LSA Enable. | +| 156 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.LSA.PSNUrl` | readWrite | string | Endpoint URL used by RFC setting Feature LSA PSNUrl. | +| 157 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.LSA.PlacementReqUrl` | readWrite | string | Endpoint URL used by RFC setting Feature LSA PlacementReqUrl. | +| 158 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.LSA.ProgrammerEnable` | readWrite | string | RFC configuration value for Feature LSA ProgrammerEnable. | +| 159 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.LSA.Schema_Location` | readWrite | string | RFC configuration value for Feature LSA Schema Location. | +| 160 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.LSA.Schemas_NGOD` | readWrite | string | RFC configuration value for Feature LSA Schemas NGOD. | +| 161 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.LSA.Schemas_admin` | readWrite | string | RFC configuration value for Feature LSA Schemas admin. | +| 162 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.LSA.Schemas_core` | readWrite | string | RFC configuration value for Feature LSA Schemas core. | +| 163 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.LSA.XMLNS_Schema` | readWrite | string | RFC configuration value for Feature LSA XMLNS Schema. | +| 164 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.LSA.XMLSchema_Instance` | readWrite | string | RFC configuration value for Feature LSA XMLSchema Instance. | +| 165 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.LSA.Xifaid_Xml_Key` | readWrite | string | RFC configuration value for Feature LSA Xifaid Xml Key. | +| 166 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.LaunchDarkly.EnvKeyLabel` | readWrite | string | RFC configuration value for Feature LaunchDarkly EnvKeyLabel. | +| 167 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.LnFUseXPKI.Enable` | readWrite | boolean | RFC flag that enables or disables Feature LnFUseXPKI Enable. | +| 168 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.LogUploadBeforeDeepSleep.Enable` | readWrite | boolean | RFC flag that enables or disables Feature LogUploadBeforeDeepSleep Enable. | +| 169 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.LogUploadEndpoint.Enable` | readWrite | string | RFC flag that enables or disables Feature LogUploadEndpoint Enable. | +| 170 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.LogUploadEndpoint.URL` | readWrite | string | Endpoint URL used by RFC setting Feature LogUploadEndpoint URL. | +| 171 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.LoudnessEquivalence.Enable` | readWrite | boolean | RFC flag that enables or disables Feature LoudnessEquivalence Enable. | +| 172 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.MEMSWAP.Enable` | readWrite | string | RFC flag that enables or disables Feature MEMSWAP Enable. | +| 173 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.MOCASSH.Enable` | readWrite | boolean | RFC flag that enables or disables Feature MOCASSH Enable. | +| 174 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.MS12.DAPv2_Enable` | readWrite | boolean | RFC configuration value for Feature MS12 DAPv2 Enable. | +| 175 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.MS12.DE_Enable` | readWrite | boolean | RFC configuration value for Feature MS12 DE Enable. | +| 176 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.MTLS.mTlsXcSsr.Enable` | readWrite | boolean | RFC flag that enables or disables Feature MTLS mTlsXcSsr Enable. | +| 177 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ManageableNotification.Enable` | readWrite | boolean | RFC flag that enables or disables Feature ManageableNotification Enable. | +| 178 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Miracast.Enable` | readWrite | boolean | RFC flag that enables or disables Feature Miracast Enable. | +| 179 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.NTP.failoverServer` | readWrite | string | RFC configuration value for Feature NTP failoverServer. | +| 180 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.NonPersistent.WebPACDL.Enable` | readWrite | boolean | RFC flag that enables or disables Feature NonPersistent WebPACDL Enable. | +| 181 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.NonRootSupport.ApparmorBlocklist` | readWrite | string | RFC configuration value for Feature NonRootSupport ApparmorBlocklist. | +| 182 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.NonRootSupport.Blocklist` | readWrite | string | RFC configuration value for Feature NonRootSupport Blocklist. | +| 183 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.NonRootSupport.Enable` | readWrite | boolean | RFC flag that enables or disables Feature NonRootSupport Enable. | +| 184 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.PeriodicFWCheck.Enable` | readWrite | boolean | RFC flag that enables or disables Feature PeriodicFWCheck Enable. | +| 185 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.PeriodicFwCheck.timeperiod` | readWrite | unsignedInt | RFC configuration value for Feature PeriodicFwCheck timeperiod. | +| 186 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.PingTelemetry.BurstCnt` | readWrite | unsignedInt | RFC configuration value for Feature PingTelemetry BurstCnt. | +| 187 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.PingTelemetry.Enable` | readWrite | boolean | RFC flag that enables or disables Feature PingTelemetry Enable. | +| 188 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.PingTelemetry.EndTime` | readWrite | unsignedInt | RFC configuration value for Feature PingTelemetry EndTime. | +| 189 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.PingTelemetry.StartTime` | readWrite | unsignedInt | RFC configuration value for Feature PingTelemetry StartTime. | +| 190 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.PingTelemetry.Type` | readWrite | string | RFC configuration value for Feature PingTelemetry Type. | +| 191 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Power.DeepSleepNotification.Enable` | readWrite | boolean | RFC flag that enables or disables Feature Power DeepSleepNotification Enable. | +| 192 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Power.PwrMgr2.Enable` | readWrite | boolean | RFC flag that enables or disables Feature Power PwrMgr2 Enable. | +| 193 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Power.UserInactivityNotification.Enable` | readWrite | boolean | RFC flag that enables or disables Feature Power UserInactivityNotification Enable. | +| 194 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Power.UserInactivityNotification.TimeMinutes` | readWrite | unsignedInt | RFC configuration value for Feature Power UserInactivityNotification TimeMinutes. | +| 195 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Preference.URL` | readWrite | string | Endpoint URL used by RFC setting Feature Preference URL. | +| 196 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.PressAndRelease.EOSMethod` | readWrite | int | RFC configuration value for Feature PressAndRelease EOSMethod. | +| 197 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.PressAndRelease.EOSTimeout` | readWrite | int | RFC configuration value for Feature PressAndRelease EOSTimeout. | +| 198 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ProtectX1Services.Enable` | readWrite | boolean | RFC flag that enables or disables Feature ProtectX1Services Enable. | +| 199 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RDKBROWSER2_CFG.BACKGROUND_MEM_USAGE_HIGH_WATERMARK` | readWrite | unsignedInt | RFC configuration value for Feature RDKBROWSER2 CFG BACKGROUND MEM USAGE HIGH WATERMARK. | +| 200 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RDKBROWSER2_CFG.BACKGROUND_MEM_USAGE_LOW_WATERMARK` | readWrite | unsignedInt | RFC configuration value for Feature RDKBROWSER2 CFG BACKGROUND MEM USAGE LOW WATERMARK. | +| 201 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RDKBROWSER2_CFG.HTML_APP_RESURRECTION_PERIOD.days` | readWrite | unsignedInt | RFC configuration value for Feature RDKBROWSER2 CFG HTML APP RESURRECTION PERIOD days. | +| 202 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RDKRemoteDebugger.Enable` | readWrite | boolean | RFC flag that enables or disables Feature RDKRemoteDebugger Enable. | +| 203 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RDKRemoteDebugger.IssueType` | readWrite | string | RFC configuration value for Feature RDKRemoteDebugger IssueType. | +| 204 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RDKRemoteDebugger.WebCfgData` | readWrite | string | RFC configuration value for Feature RDKRemoteDebugger WebCfgData. | +| 205 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RDKRemoteDebugger.getProfileData` | readOnly | string | RFC configuration value for Feature RDKRemoteDebugger getProfileData. | +| 206 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RDMDecoupledVersionManagement.Enable` | readWrite | boolean | RFC flag that enables or disables Feature RDMDecoupledVersionManagement Enable. | +| 207 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RF4CE.AudioProfileTarget` | readWrite | int | RFC configuration value for Feature RF4CE AudioProfileTarget. | +| 208 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RF4CE.FF.RspIdle` | readWrite | int | RFC configuration value for Feature RF4CE FF RspIdle. | +| 209 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RF4CE.HostPacketDecryption.Enable` | readWrite | boolean | RFC flag that enables or disables Feature RF4CE HostPacketDecryption Enable. | +| 210 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RF4CE.OpusEncoderParams` | readWrite | string | RFC configuration value for Feature RF4CE OpusEncoderParams. | +| 211 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RF4CE.RspTime.XDIU` | readWrite | int | RFC configuration value for Feature RF4CE RspTime XDIU. | +| 212 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RF4CE.RspTime.XRC` | readWrite | int | RFC configuration value for Feature RF4CE RspTime XRC. | +| 213 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RF4CE.RspTime.XVP` | readWrite | int | RFC configuration value for Feature RF4CE RspTime XVP. | +| 214 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RF4CE.VoiceEncryption.Enable` | readWrite | boolean | RFC flag that enables or disables Feature RF4CE VoiceEncryption Enable. | +| 215 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RebootStop.Detection` | readWrite | boolean | RFC configuration value for Feature RebootStop Detection. | +| 216 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RebootStop.Duration` | readWrite | int | RFC configuration value for Feature RebootStop Duration. | +| 217 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RebootStop.Enable` | readWrite | boolean | RFC flag that enables or disables Feature RebootStop Enable. | +| 218 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RedRecovery.Status` | readWrite | string | Current value reported for RFC setting Feature RedRecovery Status. | +| 219 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Resourcemanager.Blacklist.Enable` | readWrite | boolean | RFC flag that enables or disables Feature Resourcemanager Blacklist Enable. | +| 220 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Resourcemanager.ReserveTTS.Enable` | readWrite | boolean | RFC flag that enables or disables Feature Resourcemanager ReserveTTS Enable. | +| 221 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RoamTrigger` | readWrite | string | RFC configuration value for Feature RoamTrigger. | +| 222 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.SDCARD_SCRATCHPAD.Enable` | readWrite | string | RFC flag that enables or disables Feature SDCARD SCRATCHPAD Enable. | +| 223 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.SHORTS.Enable` | readWrite | boolean | RFC flag that enables or disables Feature SHORTS Enable. | +| 224 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.STAGE.Enable` | readWrite | boolean | RFC flag that enables or disables Feature STAGE Enable. | +| 225 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.SWDLDirect.Enable` | readWrite | boolean | RFC flag that enables or disables Feature SWDLDirect Enable. | +| 226 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.SWDLSpLimit.Enable` | readWrite | boolean | RFC flag that enables or disables Feature SWDLSpLimit Enable. | +| 227 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.SWDLSpLimit.LowSpeed` | readWrite | int | RFC configuration value for Feature SWDLSpLimit LowSpeed. | +| 228 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.SWDLSpLimit.TopSpeed` | readWrite | int | RFC configuration value for Feature SWDLSpLimit TopSpeed. | +| 229 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ScreenCapture.Enable` | readWrite | boolean | RFC flag that enables or disables Feature ScreenCapture Enable. | +| 230 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ScreenCapture.URL` | readWrite | string | Endpoint URL used by RFC setting Feature ScreenCapture URL. | +| 231 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.SecDump.Enable` | readWrite | boolean | RFC flag that enables or disables Feature SecDump Enable. | +| 232 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.SoundPlayer.Enable` | readWrite | boolean | RFC flag that enables or disables Feature SoundPlayer Enable. | +| 233 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.StandbyReboot.Enable` | readWrite | boolean | RFC flag that enables or disables Feature StandbyReboot Enable. | +| 234 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.StandbyReboot.ForceAutoReboot` | readWrite | int | RFC configuration value for Feature StandbyReboot ForceAutoReboot. | +| 235 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.StandbyReboot.StandbyAutoReboot` | readWrite | int | RFC configuration value for Feature StandbyReboot StandbyAutoReboot. | +| 236 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.StorageManager.maxAdaptiveBitRate` | readWrite | int | RFC configuration value for Feature StorageManager maxAdaptiveBitRate. | +| 237 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.StorageManager.maxTSBDurationMinutes` | readWrite | int | RFC configuration value for Feature StorageManager maxTSBDurationMinutes. | +| 238 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.SupportedLanguages` | readWrite | string | RFC configuration value for Feature SupportedLanguages. | +| 239 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.TR069support.Enable` | readWrite | boolean | RFC flag that enables or disables Feature TR069support Enable. | +| 240 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Telemetry.ConfigURL` | readWrite | string | Endpoint URL used by RFC setting Feature Telemetry ConfigURL. | +| 241 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Telemetry.Version` | readWrite | string | Version value for RFC setting Feature Telemetry Version. | +| 242 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ThreadMonitorMinidump.Enable` | readWrite | boolean | RFC flag that enables or disables Feature ThreadMonitorMinidump Enable. | +| 243 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ThreadPrioConfig.Enable` | readWrite | boolean | RFC flag that enables or disables Feature ThreadPrioConfig Enable. | +| 244 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ThunderSecurity.Enable` | readWrite | boolean | RFC flag that enables or disables Feature ThunderSecurity Enable. | +| 245 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.TvSettings.DynamicAutoLatency` | readWrite | boolean | RFC configuration value for Feature TvSettings DynamicAutoLatency. | +| 246 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.UNII3.Enable` | readWrite | boolean | RFC flag that enables or disables Feature UNII3 Enable. | +| 247 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.UPnP.Refactor.Enable` | readWrite | boolean | RFC flag that enables or disables Feature UPnP Refactor Enable. | +| 248 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.UPnPxPKI.Enable` | readWrite | boolean | RFC flag that enables or disables Feature UPnPxPKI Enable. | +| 249 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.USB_AutoMount.Enable` | readWrite | string | RFC flag that enables or disables Feature USB AutoMount Enable. | +| 250 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.USB_HID.Enable` | readWrite | boolean | RFC flag that enables or disables Feature USB HID Enable. | +| 251 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.UploadLogsOnUnscheduledReboot.Disable` | readWrite | boolean | RFC configuration value for Feature UploadLogsOnUnscheduledReboot Disable. | +| 252 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ViperPPUrl` | readWrite | string | Endpoint URL used by RFC setting Feature ViperPPUrl. | +| 253 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Voice.AudioConfidenceThreshold` | readWrite | string | RFC configuration value for Feature Voice AudioConfidenceThreshold. | +| 254 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Voice.AudioDuckingLevel` | readWrite | string | RFC configuration value for Feature Voice AudioDuckingLevel. | +| 255 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Voice.AudioDuckingType` | readWrite | int | RFC configuration value for Feature Voice AudioDuckingType. | +| 256 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Voice.AudioMode` | readWrite | int | RFC configuration value for Feature Voice AudioMode. | +| 257 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Voice.AudioTiming` | readWrite | int | RFC configuration value for Feature Voice AudioTiming. | +| 258 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Voice.KeywordSensitivity` | readWrite | string | RFC configuration value for Feature Voice KeywordSensitivity. | +| 259 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Voice.VSDKConfiguration` | readWrite | string | RFC configuration value for Feature Voice VSDKConfiguration. | +| 260 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.WiFi.WiFiStatsLogInterval` | readWrite | unsignedInt | RFC configuration value for Feature WiFi WiFiStatsLogInterval. | +| 261 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.WiFiReset.Enable` | readWrite | boolean | RFC flag that enables or disables Feature WiFiReset Enable. | +| 262 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.WiFiReset.EthernetLoggingInterval` | readWrite | unsignedInt | RFC configuration value for Feature WiFiReset EthernetLoggingInterval. | +| 263 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.WiFiReset.PacketLossLoggingInterval` | readWrite | string | RFC configuration value for Feature WiFiReset PacketLossLoggingInterval. | +| 264 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.WiFiReset.ReassociateTolerance` | readWrite | unsignedInt | RFC configuration value for Feature WiFiReset ReassociateTolerance. | +| 265 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.WiFiReset.WifiLoggingInterval` | readWrite | unsignedInt | RFC configuration value for Feature WiFiReset WifiLoggingInterval. | +| 266 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.WiFiReset.WifiReassociateInterval` | readWrite | unsignedInt | RFC configuration value for Feature WiFiReset WifiReassociateInterval. | +| 267 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.WiFiReset.WifiResetIntervalForDriverIssue` | readWrite | unsignedInt | RFC configuration value for Feature WiFiReset WifiResetIntervalForDriverIssue. | +| 268 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.WiFiReset.WifiResetIntervalForPacketLoss` | readWrite | unsignedInt | RFC configuration value for Feature WiFiReset WifiResetIntervalForPacketLoss. | +| 269 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.WifiOptimizer.Enable` | readWrite | boolean | RFC flag that enables or disables Feature WifiOptimizer Enable. | +| 270 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.XDial.AppList` | readWrite | string | RFC configuration value for Feature XDial AppList. | +| 271 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.XRDsp.XR19.Configuration` | readWrite | string | RFC configuration value for Feature XRDsp XR19 Configuration. | +| 272 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.XRPairing.ASBDerivationMethod` | readWrite | int | RFC configuration value for Feature XRPairing ASBDerivationMethod. | +| 273 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.XRPairing.ASBEnable` | readWrite | boolean | RFC configuration value for Feature XRPairing ASBEnable. | +| 274 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.XRPairing.ASBFailThreshold` | readWrite | int | RFC configuration value for Feature XRPairing ASBFailThreshold. | +| 275 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.XRPollingConfiguration.Default` | readWrite | string | RFC configuration value for Feature XRPollingConfiguration Default. | +| 276 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.XRPollingConfiguration.Enable` | readWrite | boolean | RFC flag that enables or disables Feature XRPollingConfiguration Enable. | +| 277 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.XRPollingConfiguration.XR11v2` | readWrite | string | RFC configuration value for Feature XRPollingConfiguration XR11v2. | +| 278 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.XRPollingConfiguration.XR15v1` | readWrite | string | RFC configuration value for Feature XRPollingConfiguration XR15v1. | +| 279 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.XRPollingConfiguration.XR15v2` | readWrite | string | RFC configuration value for Feature XRPollingConfiguration XR15v2. | +| 280 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.XRPollingConfiguration.XR16v1` | readWrite | string | RFC configuration value for Feature XRPollingConfiguration XR16v1. | +| 281 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.XRPollingConfiguration.XR19v1` | readWrite | string | RFC configuration value for Feature XRPollingConfiguration XR19v1. | +| 282 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.XRPollingConfiguration.XRAv1` | readWrite | string | RFC configuration value for Feature XRPollingConfiguration XRAv1. | +| 283 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.XRmacPolling.Enable` | readWrite | boolean | RFC flag that enables or disables Feature XRmacPolling Enable. | +| 284 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.XRmacPolling.macPollingInterval` | readWrite | int | RFC configuration value for Feature XRmacPolling macPollingInterval. | +| 285 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.collectd.Enable` | readWrite | boolean | RFC flag that enables or disables Feature collectd Enable. | +| 286 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.collectd.GraphiteURL` | readWrite | string | Endpoint URL used by RFC setting Feature collectd GraphiteURL. | +| 287 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.collectd.Hostname` | readWrite | string | RFC configuration value for Feature collectd Hostname. | +| 288 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.collectd.PortNumber` | readWrite | unsignedInt | RFC configuration value for Feature collectd PortNumber. | +| 289 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ctrlm.device_update` | readWrite | string | RFC configuration value for Feature ctrlm device update. | +| 290 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ctrlm.global` | readWrite | string | RFC configuration value for Feature ctrlm global. | +| 291 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ctrlm.network_ble` | readWrite | string | RFC configuration value for Feature ctrlm network ble. | +| 292 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ctrlm.network_ip` | readWrite | string | RFC configuration value for Feature ctrlm network ip. | +| 293 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ctrlm.network_rf4ce` | readWrite | string | RFC configuration value for Feature ctrlm network rf4ce. | +| 294 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ctrlm.telemetry_report.ble` | readWrite | string | RFC configuration value for Feature ctrlm telemetry report ble. | +| 295 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ctrlm.telemetry_report.global` | readWrite | string | RFC configuration value for Feature ctrlm telemetry report global. | +| 296 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ctrlm.telemetry_report.ip` | readWrite | string | RFC configuration value for Feature ctrlm telemetry report ip. | +| 297 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ctrlm.telemetry_report.rf4ce` | readWrite | string | RFC configuration value for Feature ctrlm telemetry report rf4ce. | +| 298 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ctrlm.telemetry_report.voice` | readWrite | string | RFC configuration value for Feature ctrlm telemetry report voice. | +| 299 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ctrlm.voice` | readWrite | string | RFC configuration value for Feature ctrlm voice. | +| 300 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.ctrlm.vsdk` | readWrite | string | RFC configuration value for Feature ctrlm vsdk. | +| 301 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.eMMCFirmware.Version` | readWrite | string | Version value for RFC setting Feature eMMCFirmware Version. | +| 302 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.eMMCMitigation.Disable` | readWrite | boolean | RFC configuration value for Feature eMMCMitigation Disable. | +| 303 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.fkpskdf.Enable` | readWrite | boolean | RFC flag that enables or disables Feature fkpskdf Enable. | +| 304 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.memcapture.Duration` | readWrite | int | RFC configuration value for Feature memcapture Duration. | +| 305 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.memcapture.Enable` | readWrite | boolean | RFC flag that enables or disables Feature memcapture Enable. | +| 306 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.systemd-analyze.Enable` | readWrite | boolean | RFC flag that enables or disables Feature systemd analyze Enable. | +| 307 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.xMemInsight.Args` | readWrite | string | RFC configuration value for Feature xMemInsight Args. | +| 308 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.xMemInsight.Enable` | readWrite | boolean | RFC flag that enables or disables Feature xMemInsight Enable. | +| 309 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.HostIf.ParodusTokenServerUrl` | readWrite | string | Endpoint URL used by RFC setting HostIf ParodusTokenServerUrl. | +| 310 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Identity.DbgServices.Enable` | readWrite | boolean | RFC flag that enables or disables Identity DbgServices Enable. | +| 311 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Identity.DeviceType` | readWrite | string | RFC configuration value for Identity DeviceType. | +| 312 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.LogUpload.DcaUploadPRODUrl` | readWrite | string | Endpoint URL used by RFC setting LogUpload DcaUploadPRODUrl. | +| 313 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.LogUpload.DcaUploadUrl` | readWrite | string | Endpoint URL used by RFC setting LogUpload DcaUploadUrl. | +| 314 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.LogUpload.DcmLogServerCQAUrl` | readWrite | string | Endpoint URL used by RFC setting LogUpload DcmLogServerCQAUrl. | +| 315 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.LogUpload.DcmLogServerDEVUrl` | readWrite | string | Endpoint URL used by RFC setting LogUpload DcmLogServerDEVUrl. | +| 316 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.LogUpload.DcmLogServerPRODUrl` | readWrite | string | Endpoint URL used by RFC setting LogUpload DcmLogServerPRODUrl. | +| 317 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.LogUpload.DcmLogUrl` | readWrite | string | Endpoint URL used by RFC setting LogUpload DcmLogUrl. | +| 318 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.LogUpload.DcmScpServerUrl` | readWrite | string | Endpoint URL used by RFC setting LogUpload DcmScpServerUrl. | +| 319 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.LogUpload.LogServerUrl` | readWrite | string | Endpoint URL used by RFC setting LogUpload LogServerUrl. | +| 320 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.LogUpload.S3SignedBucketUrl` | readWrite | string | Endpoint URL used by RFC setting LogUpload S3SignedBucketUrl. | +| 321 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.LogUpload.SsrUrl` | readWrite | string | Endpoint URL used by RFC setting LogUpload SsrUrl. | +| 322 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.SecManager.dieselUrl` | readWrite | string | Endpoint URL used by RFC setting SecManager dieselUrl. | +| 323 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.SocProvisioning.Activation` | readWrite | string | RFC configuration value for SocProvisioning Activation. | +| 324 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.SocProvisioning.AuthMessage` | readWrite | string | RFC configuration value for SocProvisioning AuthMessage. | +| 325 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.SocProvisioning.NameSpacePrefix` | readWrite | string | RFC configuration value for SocProvisioning NameSpacePrefix. | +| 326 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.SocProvisioning.NameSpaceUri` | readWrite | string | RFC configuration value for SocProvisioning NameSpaceUri. | +| 327 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.SocProvisioning.Renewal` | readWrite | string | RFC configuration value for SocProvisioning Renewal. | +| 328 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.SocProvisioning.URL1` | readWrite | string | RFC configuration value for SocProvisioning URL1. | +| 329 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.SocProvisioning.URL2` | readWrite | string | RFC configuration value for SocProvisioning URL2. | +| 330 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.SocProvisioning.backoffIntervalMax` | readWrite | unsignedLong | RFC configuration value for SocProvisioning backoffIntervalMax. | +| 331 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.SocProvisioning.disableCredentialsPrefetchCaching` | readWrite | boolean | RFC configuration value for SocProvisioning disableCredentialsPrefetchCaching. | +| 332 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Sysint.CCRProxyUrl` | readWrite | string | Endpoint URL used by RFC setting Sysint CCRProxyUrl. | +| 333 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Sysint.CDNCCPUrl` | readWrite | string | Endpoint URL used by RFC setting Sysint CDNCCPUrl. | +| 334 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Sysint.CcpUrl` | readWrite | string | Endpoint URL used by RFC setting Sysint CcpUrl. | +| 335 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Sysint.DAC15CDLUrl` | readWrite | string | Endpoint URL used by RFC setting Sysint DAC15CDLUrl. | +| 336 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Sysint.EDGEDNSProxyUrl` | readWrite | string | Endpoint URL used by RFC setting Sysint EDGEDNSProxyUrl. | +| 337 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Sysint.FkpsBrokerUrl` | readWrite | string | Endpoint URL used by RFC setting Sysint FkpsBrokerUrl. | +| 338 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Sysint.FkpsUrl` | readWrite | string | Endpoint URL used by RFC setting Sysint FkpsUrl. | +| 339 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Sysint.PRODCDLUrl` | readWrite | string | Endpoint URL used by RFC setting Sysint PRODCDLUrl. | +| 340 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Sysint.XcalUrl` | readWrite | string | Endpoint URL used by RFC setting Sysint XcalUrl. | +| 341 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Sysint.XconfDEVUrl` | readWrite | string | Endpoint URL used by RFC setting Sysint XconfDEVUrl. | +| 342 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Sysint.XconfUrl` | readWrite | string | Endpoint URL used by RFC setting Sysint XconfUrl. | +| 343 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.SystemServices.FriendlyName` | readWrite | string | RFC configuration value for SystemServices FriendlyName. | +| 344 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.TextToSpeech.URL` | readWrite | string | Endpoint URL used by RFC setting TextToSpeech URL. | +| 345 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.LRHAcceptValue` | readWrite | string | RFC configuration value for aamp LRHAcceptValue. | +| 346 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.LRHContentType` | readWrite | string | RFC configuration value for aamp LRHContentType. | +| 347 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.SchemeIdUriDaiStream` | readWrite | string | RFC configuration value for aamp SchemeIdUriDaiStream. | +| 348 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.SchemeIdUriVssStream` | readWrite | string | RFC configuration value for aamp SchemeIdUriVssStream. | +| 349 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.SlowMotion` | readWrite | boolean | RFC configuration value for aamp SlowMotion. | +| 350 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.asyncTune` | readWrite | boolean | RFC configuration value for aamp asyncTune. | +| 351 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.cdvrLiveOffset` | readWrite | unsignedLong | RFC configuration value for aamp cdvrLiveOffset. | +| 352 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.client-dai` | readWrite | boolean | RFC configuration value for aamp client dai. | +| 353 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.curlStore` | readWrite | boolean | RFC configuration value for aamp curlStore. | +| 354 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.defaultBitrate` | readWrite | unsignedLong | RFC configuration value for aamp defaultBitrate. | +| 355 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.defaultBitrate4K` | readWrite | unsignedLong | RFC configuration value for aamp defaultBitrate4K. | +| 356 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.disableAC3` | readWrite | boolean | RFC configuration value for aamp disableAC3. | +| 357 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.disableAC4` | readWrite | boolean | RFC configuration value for aamp disableAC4. | +| 358 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.disableATMOS` | readWrite | boolean | RFC configuration value for aamp disableATMOS. | +| 359 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.disableEC3` | readWrite | boolean | RFC configuration value for aamp disableEC3. | +| 360 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.enableCMCD` | readWrite | boolean | RFC configuration value for aamp enableCMCD. | +| 361 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.enableLiveLatencyCorrection` | readWrite | boolean | RFC configuration value for aamp enableLiveLatencyCorrection. | +| 362 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.enableLowLatencyCorrection` | readWrite | boolean | RFC configuration value for aamp enableLowLatencyCorrection. | +| 363 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.enableLowLatencyDash` | readWrite | boolean | RFC configuration value for aamp enableLowLatencyDash. | +| 364 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.enablePTSReStamp` | readWrite | boolean | RFC configuration value for aamp enablePTSReStamp. | +| 365 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.enableVideoEndEvent` | readWrite | boolean | RFC configuration value for aamp enableVideoEndEvent. | +| 366 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.info` | readWrite | boolean | RFC configuration value for aamp info. | +| 367 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.liveOffset` | readWrite | unsignedLong | RFC configuration value for aamp liveOffset. | +| 368 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.liveOffset4K` | readWrite | string | RFC configuration value for aamp liveOffset4K. | +| 369 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.manifestTimeout` | readWrite | unsignedLong | RFC configuration value for aamp manifestTimeout. | +| 370 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.maxBitrate` | readWrite | unsignedLong | RFC configuration value for aamp maxBitrate. | +| 371 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.maxInitFragCachePerTrack` | readWrite | int | RFC configuration value for aamp maxInitFragCachePerTrack. | +| 372 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.minBitrate` | readWrite | unsignedLong | RFC configuration value for aamp minBitrate. | +| 373 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.networkTimeout` | readWrite | unsignedLong | RFC configuration value for aamp networkTimeout. | +| 374 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.persistBitrateOverSeek` | readWrite | boolean | RFC configuration value for aamp persistBitrateOverSeek. | +| 375 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.playlistTimeout` | readWrite | unsignedLong | RFC configuration value for aamp playlistTimeout. | +| 376 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.preferredDrm` | readWrite | int | RFC configuration value for aamp preferredDrm. | +| 377 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.rateCorrectionDelay` | readWrite | unsignedLong | RFC configuration value for aamp rateCorrectionDelay. | +| 378 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.sharedSSL` | readWrite | boolean | RFC configuration value for aamp sharedSSL. | +| 379 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.stereoOnly` | readWrite | boolean | RFC configuration value for aamp stereoOnly. | +| 380 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.supportTLS` | readWrite | unsignedLong | RFC configuration value for aamp supportTLS. | +| 381 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.tsbInterruptHandling` | readWrite | boolean | RFC configuration value for aamp tsbInterruptHandling. | +| 382 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.useSecManager` | readWrite | boolean | RFC configuration value for aamp useSecManager. | +| 383 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.aamp.useWesterosSink` | readWrite | boolean | RFC configuration value for aamp useWesterosSink. | +| 384 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.apps.watchdogmode` | readWrite | boolean | RFC configuration value for apps watchdogmode. | +| 385 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.fog.ZeroDrmHost` | readWrite | string | RFC configuration value for fog ZeroDrmHost. | +| 386 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.recorder.LongpollUrl` | readWrite | string | Endpoint URL used by RFC setting recorder LongpollUrl. | +| 387 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.recorder.Status` | readWrite | string | Current value reported for RFC setting recorder Status. | +| 388 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.recorder.UpdateSchedule` | readWrite | string | RFC configuration value for recorder UpdateSchedule. | +| 389 | `Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.vodclient.StunnelConnect` | readWrite | string | RFC configuration value for vodclient StunnelConnect. | +| 390 | `Device.DeviceInfo.X_RDKCENTRAL-COM_Reset` | readWrite | string | Triggers the platform-specific reset workflow. | +| 391 | `Device.DeviceInfo.X_RDKCENTRAL-COM_Syndication.PartnerId` | readWrite | string | Partner identifier used for syndication. | +| 392 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xAccount.HotelCheckout.LastResetTime` | readOnly | unsignedLong | Timestamp of the most recent reset event. | +| 393 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xAccount.HotelCheckout.Status` | readOnly | string | Current status of the device. | +| 394 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.ConnectedDevice.{i}.Active` | readOnly | int | Indicates whether the related entry is currently active. | +| 395 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.ConnectedDevice.{i}.DeviceID` | readOnly | string | Device identifier reported for the related entry. | +| 396 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.ConnectedDevice.{i}.DeviceType` | readOnly | string | Device type reported for the related entry. | +| 397 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.ConnectedDevice.{i}.Name` | readOnly | string | Name reported for this connected Bluetooth device. | +| 398 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.ConnectedDeviceCnt` | readOnly | unsignedInt | Number of currently connected Bluetooth device entries. | +| 399 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.DeviceInfo.DeviceID` | readOnly | string | Device identifier reported for the related entry. | +| 400 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.DeviceInfo.MAC` | readOnly | string | MAC address associated with the local Bluetooth adapter. | +| 401 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.DeviceInfo.Manufacturer` | readOnly | int | Manufacturer reported for the local Bluetooth adapter. | +| 402 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.DeviceInfo.Profile` | readOnly | string | Profile reported for the related entry. | +| 403 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.DeviceInfo.RSSI` | readOnly | int | RSSI reported for the related entry. | +| 404 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.DeviceInfo.SignalStrength` | readOnly | string | Signal strength reported for the related entry. | +| 405 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.DiscoveredDevice.{i}.DeviceID` | readOnly | string | Device identifier reported for the related entry. | +| 406 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.DiscoveredDevice.{i}.DeviceType` | readOnly | string | Device type reported for the related entry. | +| 407 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.DiscoveredDevice.{i}.Name` | readOnly | string | Name reported for this discovered Bluetooth device. | +| 408 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.DiscoveredDevice.{i}.Paired` | readOnly | boolean | Indicates whether the related Bluetooth device is paired. | +| 409 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.DiscoveredDeviceCnt` | readOnly | unsignedInt | Number of discovered Bluetooth device entries currently reported. | +| 410 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.DiscoveryEnabled` | readOnly | boolean | Reports whether Bluetooth discovery is currently enabled. | +| 411 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.Enabled` | readOnly | string | Current enabled state of the device. | +| 412 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.GetDeviceInfo` | readOnly | string | Snapshot of detailed Bluetooth adapter information. | +| 413 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.LimitBeaconDetection` | readWrite | boolean | Controls whether Bluetooth beacon detection is restricted by platform policy. | +| 414 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.PairedDevice.{i}.Connected` | readOnly | boolean | Indicates whether the related device is currently connected. | +| 415 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.PairedDevice.{i}.DeviceID` | readOnly | string | Device identifier reported for the related entry. | +| 416 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.PairedDevice.{i}.DeviceType` | readOnly | string | Device type reported for the related entry. | +| 417 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.PairedDevice.{i}.Name` | readOnly | string | Name reported for this paired Bluetooth device. | +| 418 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xBlueTooth.PairedDeviceCnt` | readOnly | unsignedInt | Number of paired Bluetooth device entries currently reported. | +| 419 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xOpsDeviceMgmt.ForwardSSH.Enable` | readWrite | boolean | Enables or disables the xOps forward SSH access path. | +| 420 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xOpsDeviceMgmt.Logging.xOpsDMLogsUploadStatus` | readOnly | string | Current xOps device management log upload status. | +| 421 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xOpsDeviceMgmt.RPC.DeviceManageableNotification` | readWrite | string | Manageable-device notification payload for xOps RPC. | +| 422 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xOpsDeviceMgmt.RPC.FirmwareDownloadCompletedNotification` | readWrite | boolean | xOps RPC notification control for the named event. | +| 423 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xOpsDeviceMgmt.RPC.FirmwareDownloadStartedNotification` | readWrite | string | xOps RPC notification control for the named event. | +| 424 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xOpsDeviceMgmt.RPC.RebootPendingNotification` | readWrite | unsignedInt | xOps RPC notification control for the named event. | +| 425 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xOpsDeviceMgmt.ReverseSSH.xOpsReverseSshArgs` | readWrite | string | Arguments used to start reverse SSH through xOps. | +| 426 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xOpsDeviceMgmt.ReverseSSH.xOpsReverseSshStatus` | readOnly | string | Current reverse SSH status reported by xOps. | +| 427 | `Device.DeviceInfo.X_RDKCENTRAL-COM_xOpsDeviceMgmt.hwHealthTest.Results` | readOnly | string | Result payload reported by the related diagnostic or test. | +| 428 | `Device.DeviceInfo.X_RDK_FirmwareName` | readOnly | string | Firmware image name currently reported by the RDK platform. | +| 429 | `Device.DeviceInfo.X_RDK_RDKProfileName` | readWrite | string | Active RDK profile name associated with the device configuration. | +| 430 | `Device.Ethernet.Interface.{i}.Alias` | readWrite | string | User-assigned alias for this Ethernet interface. | +| 431 | `Device.Ethernet.Interface.{i}.DuplexMode` | readWrite | string | Configured or reported duplex mode for the interface. | +| 432 | `Device.Ethernet.Interface.{i}.Enable` | readWrite | boolean | Enables or disables this Ethernet interface. | +| 433 | `Device.Ethernet.Interface.{i}.LastChange` | readOnly | unsignedInt | Seconds since this Ethernet interface last changed state. | +| 434 | `Device.Ethernet.Interface.{i}.LowerLayers` | readWrite | string | Lower-layer interface references for this Ethernet interface. | +| 435 | `Device.Ethernet.Interface.{i}.MACAddress` | readOnly | string | MAC address associated with this Ethernet interface. | +| 436 | `Device.Ethernet.Interface.{i}.MaxBitRate` | readWrite | int | Configured or negotiated maximum link bit rate for this Ethernet interface. | +| 437 | `Device.Ethernet.Interface.{i}.Name` | readOnly | string | Name reported for this Ethernet interface. | +| 438 | `Device.Ethernet.Interface.{i}.Stats.BroadcastPacketsReceived` | readOnly | unsignedLong | Broadcast packets received on this Ethernet interface. | +| 439 | `Device.Ethernet.Interface.{i}.Stats.BroadcastPacketsSent` | readOnly | unsignedLong | Broadcast packets sent on this Ethernet interface. | +| 440 | `Device.Ethernet.Interface.{i}.Stats.BytesReceived` | readOnly | unsignedLong | Total bytes received on this Ethernet interface. | +| 441 | `Device.Ethernet.Interface.{i}.Stats.BytesSent` | readOnly | unsignedLong | Total bytes sent on this Ethernet interface. | +| 442 | `Device.Ethernet.Interface.{i}.Stats.DiscardPacketsReceived` | readOnly | unsignedInt | Received packets discarded on this Ethernet interface. | +| 443 | `Device.Ethernet.Interface.{i}.Stats.DiscardPacketsSent` | readOnly | unsignedInt | Outbound packets discarded on this Ethernet interface. | +| 444 | `Device.Ethernet.Interface.{i}.Stats.ErrorsReceived` | readOnly | unsignedInt | Receive errors seen on this Ethernet interface. | +| 445 | `Device.Ethernet.Interface.{i}.Stats.ErrorsSent` | readOnly | unsignedInt | Transmit errors seen on this Ethernet interface. | +| 446 | `Device.Ethernet.Interface.{i}.Stats.MulticastPacketsReceived` | readOnly | unsignedLong | Multicast packets received on this Ethernet interface. | +| 447 | `Device.Ethernet.Interface.{i}.Stats.MulticastPacketsSent` | readOnly | unsignedLong | Multicast packets sent on this Ethernet interface. | +| 448 | `Device.Ethernet.Interface.{i}.Stats.PacketsReceived` | readOnly | unsignedLong | Total packets received on this Ethernet interface. | +| 449 | `Device.Ethernet.Interface.{i}.Stats.PacketsSent` | readOnly | unsignedLong | Total packets sent on this Ethernet interface. | +| 450 | `Device.Ethernet.Interface.{i}.Stats.UnicastPacketsReceived` | readOnly | unsignedLong | Unicast packets received on this Ethernet interface. | +| 451 | `Device.Ethernet.Interface.{i}.Stats.UnicastPacketsSent` | readOnly | unsignedLong | Unicast packets sent on this Ethernet interface. | +| 452 | `Device.Ethernet.Interface.{i}.Stats.UnknownProtoPacketsReceived` | readOnly | unsignedInt | Packets with unknown protocol received on this Ethernet interface. | +| 453 | `Device.Ethernet.Interface.{i}.Status` | readOnly | string | Current status of this Ethernet interface. | +| 454 | `Device.Ethernet.Interface.{i}.Upstream` | readOnly | boolean | Indicates whether the interface is designated as upstream. | +| 455 | `Device.Ethernet.InterfaceNumberOfEntries` | readOnly | unsignedInt | Reports the number of entries in this object. | +| 456 | `Device.Ethernet.Link.{i}.Enable` | readWrite | boolean | Enables or disables this Ethernet link. | +| 457 | `Device.Ethernet.Link.{i}.LowerLayers` | readWrite | string | Lower-layer interface references for this Ethernet link. | +| 458 | `Device.Ethernet.Link.{i}.MACAddress` | readOnly | string | MAC address associated with this Ethernet link. | +| 459 | `Device.Ethernet.Link.{i}.Name` | readOnly | string | Name reported for this Ethernet link. | +| 460 | `Device.Ethernet.Link.{i}.Status` | readOnly | string | Current status of this Ethernet link. | +| 461 | `Device.Ethernet.LinkNumberOfEntries` | readOnly | unsignedInt | Reports the number of entries in this object. | +| 462 | `Device.IP.ActivePort.{i}.LocalIPAddress` | readOnly | string | IP address used by this active port entry. | +| 463 | `Device.IP.ActivePort.{i}.LocalPort` | readOnly | unsignedInt | Port value used by this active port entry. | +| 464 | `Device.IP.ActivePort.{i}.RemoteIPAddress` | readOnly | string | IP address used by this active port entry. | +| 465 | `Device.IP.ActivePort.{i}.RemotePort` | readOnly | unsignedInt | Port value used by this active port entry. | +| 466 | `Device.IP.ActivePort.{i}.Status` | readOnly | string | Current status of this active port entry. | +| 467 | `Device.IP.ActivePortNumberOfEntries` | readOnly | unsignedInt | Reports the number of entries in this object. | +| 468 | `Device.IP.Diagnostics.DownloadDiagnostics.BOMTime` | readOnly | dateTime | Beginning of measurement time for the diagnostic run. | +| 469 | `Device.IP.Diagnostics.DownloadDiagnostics.DSCP` | readWrite | unsignedInt | DSCP value used by the diagnostic traffic. | +| 470 | `Device.IP.Diagnostics.DownloadDiagnostics.DiagnosticsState` | readWrite | string | Execution state of the diagnostic. | +| 471 | `Device.IP.Diagnostics.DownloadDiagnostics.DownloadTransports` | readOnly | string | Transfer transports supported by the diagnostic. | +| 472 | `Device.IP.Diagnostics.DownloadDiagnostics.DownloadURL` | readWrite | string | Target URL used by the diagnostic. | +| 473 | `Device.IP.Diagnostics.DownloadDiagnostics.EOMTime` | readOnly | dateTime | End of measurement time for the diagnostic run. | +| 474 | `Device.IP.Diagnostics.DownloadDiagnostics.EthernetPriority` | readWrite | unsignedInt | Ethernet priority used by the diagnostic traffic. | +| 475 | `Device.IP.Diagnostics.DownloadDiagnostics.Interface` | readWrite | string | Interface reference used by the download diagnostic. | +| 476 | `Device.IP.Diagnostics.DownloadDiagnostics.ROMTime` | readOnly | dateTime | Request start time for the diagnostic run. | +| 477 | `Device.IP.Diagnostics.DownloadDiagnostics.TCPOpenRequestTime` | readOnly | dateTime | Timestamp when the diagnostic opened the TCP connection request. | +| 478 | `Device.IP.Diagnostics.DownloadDiagnostics.TCPOpenResponseTime` | readOnly | dateTime | Timestamp when the diagnostic received the TCP connection response. | +| 479 | `Device.IP.Diagnostics.DownloadDiagnostics.TestBytesReceived` | readOnly | unsignedInt | Configured or measured test payload size for the diagnostic. | +| 480 | `Device.IP.Diagnostics.DownloadDiagnostics.TotalBytesReceived` | readOnly | unsignedInt | Total payload bytes transferred during the diagnostic. | +| 481 | `Device.IP.Diagnostics.IPPing.AverageResponseTime` | readOnly | unsignedInt | Measured response time reported by the diagnostic. | +| 482 | `Device.IP.Diagnostics.IPPing.DSCP` | readWrite | unsignedInt | DSCP value used by the diagnostic traffic. | +| 483 | `Device.IP.Diagnostics.IPPing.DataBlockSize` | readWrite | unsignedInt | Payload size used by the diagnostic packets. | +| 484 | `Device.IP.Diagnostics.IPPing.DiagnosticsState` | readWrite | string | Execution state of the diagnostic. | +| 485 | `Device.IP.Diagnostics.IPPing.FailureCount` | readOnly | unsignedInt | Count of failed or successful attempts in the diagnostic run. | +| 486 | `Device.IP.Diagnostics.IPPing.Host` | readWrite | string | Host name or address used by the IP ping diagnostic. | +| 487 | `Device.IP.Diagnostics.IPPing.Interface` | readWrite | string | Interface reference used by the IP ping diagnostic. | +| 488 | `Device.IP.Diagnostics.IPPing.MaximumResponseTime` | readOnly | unsignedInt | Measured response time reported by the diagnostic. | +| 489 | `Device.IP.Diagnostics.IPPing.MinimumResponseTime` | readOnly | unsignedInt | Measured response time reported by the diagnostic. | +| 490 | `Device.IP.Diagnostics.IPPing.NumberOfRepetitions` | readWrite | unsignedInt | Number of attempts configured for the diagnostic. | +| 491 | `Device.IP.Diagnostics.IPPing.SuccessCount` | readOnly | unsignedInt | Count of failed or successful attempts in the diagnostic run. | +| 492 | `Device.IP.Diagnostics.IPPing.Timeout` | readWrite | unsignedInt | Timeout value used by the diagnostic run. | +| 493 | `Device.IP.Diagnostics.TraceRoute.DSCP` | readWrite | unsignedInt | DSCP value used by the diagnostic traffic. | +| 494 | `Device.IP.Diagnostics.TraceRoute.DataBlockSize` | readWrite | unsignedInt | Payload size used by the diagnostic packets. | +| 495 | `Device.IP.Diagnostics.TraceRoute.DiagnosticsState` | readWrite | string | Execution state of the diagnostic. | +| 496 | `Device.IP.Diagnostics.TraceRoute.Host` | readWrite | string | Host name or address used by the traceroute diagnostic. | +| 497 | `Device.IP.Diagnostics.TraceRoute.Interface` | readWrite | string | Interface reference used by the traceroute diagnostic. | +| 498 | `Device.IP.Diagnostics.TraceRoute.MaxHopCount` | readWrite | unsignedInt | Maximum hop count allowed for the traceroute run. | +| 499 | `Device.IP.Diagnostics.TraceRoute.NumberOfTries` | readWrite | unsignedInt | Number of attempts configured for the diagnostic. | +| 500 | `Device.IP.Diagnostics.TraceRoute.ResponseTime` | readOnly | unsignedInt | Measured response time reported by the diagnostic. | +| 501 | `Device.IP.Diagnostics.TraceRoute.RouteHops.{i}.ErrorCode` | readOnly | unsignedInt | Error code reported for this traceroute hop. | +| 502 | `Device.IP.Diagnostics.TraceRoute.RouteHops.{i}.Host` | readOnly | string | Host name or address used by this traceroute hop. | +| 503 | `Device.IP.Diagnostics.TraceRoute.RouteHops.{i}.HostAddress` | readOnly | string | Resolved host address for this traceroute hop. | +| 504 | `Device.IP.Diagnostics.TraceRoute.RouteHops.{i}.RTTimes` | readOnly | string | Round-trip time samples for this traceroute hop. | +| 505 | `Device.IP.Diagnostics.TraceRoute.RouteHopsNumberOfEntries` | readOnly | unsignedInt | Reports the number of entries in the traceroute diagnostic. | +| 506 | `Device.IP.Diagnostics.TraceRoute.Timeout` | readWrite | unsignedInt | Timeout value used by the diagnostic run. | +| 507 | `Device.IP.Diagnostics.UDPEchoConfig.BytesReceived` | readOnly | unsignedInt | Total bytes received by the related diagnostic or service. | +| 508 | `Device.IP.Diagnostics.UDPEchoConfig.BytesResponded` | readOnly | unsignedInt | Total bytes sent in response by the related diagnostic or service. | +| 509 | `Device.IP.Diagnostics.UDPEchoConfig.EchoPlusEnabled` | readWrite | boolean | Echo Plus capability state for the UDP echo server. | +| 510 | `Device.IP.Diagnostics.UDPEchoConfig.EchoPlusSupported` | readOnly | boolean | Echo Plus capability state for the UDP echo server. | +| 511 | `Device.IP.Diagnostics.UDPEchoConfig.Enable` | readWrite | boolean | Enables or disables the UDP echo server. | +| 512 | `Device.IP.Diagnostics.UDPEchoConfig.Interface` | readWrite | string | Interface reference used by the UDP echo server. | +| 513 | `Device.IP.Diagnostics.UDPEchoConfig.PacketsReceived` | readOnly | unsignedInt | Packet count recorded by the UDP echo server. | +| 514 | `Device.IP.Diagnostics.UDPEchoConfig.PacketsResponded` | readOnly | unsignedInt | Packet count recorded by the UDP echo server. | +| 515 | `Device.IP.Diagnostics.UDPEchoConfig.SourceIPAddress` | readWrite | string | IP address used by the UDP echo server. | +| 516 | `Device.IP.Diagnostics.UDPEchoConfig.TimeFirstPacketReceived` | readOnly | dateTime | Timestamp of the first or last packet seen by the UDP echo server. | +| 517 | `Device.IP.Diagnostics.UDPEchoConfig.TimeLastPacketReceived` | readOnly | dateTime | Timestamp of the first or last packet seen by the UDP echo server. | +| 518 | `Device.IP.Diagnostics.UDPEchoConfig.UDPPort` | readWrite | unsignedInt | Port value used by the UDP echo server. | +| 519 | `Device.IP.Diagnostics.UploadDiagnostics.BOMTime` | readOnly | dateTime | Beginning of measurement time for the diagnostic run. | +| 520 | `Device.IP.Diagnostics.UploadDiagnostics.DSCP` | readWrite | unsignedInt | DSCP value used by the diagnostic traffic. | +| 521 | `Device.IP.Diagnostics.UploadDiagnostics.DiagnosticsState` | readWrite | string | Execution state of the diagnostic. | +| 522 | `Device.IP.Diagnostics.UploadDiagnostics.EOMTime` | readOnly | dateTime | End of measurement time for the diagnostic run. | +| 523 | `Device.IP.Diagnostics.UploadDiagnostics.EthernetPriority` | readWrite | unsignedInt | Ethernet priority used by the diagnostic traffic. | +| 524 | `Device.IP.Diagnostics.UploadDiagnostics.Interface` | readWrite | string | Interface reference used by the upload diagnostic. | +| 525 | `Device.IP.Diagnostics.UploadDiagnostics.ROMTime` | readOnly | dateTime | Request start time for the diagnostic run. | +| 526 | `Device.IP.Diagnostics.UploadDiagnostics.TCPOpenRequestTime` | readOnly | dateTime | Timestamp when the diagnostic opened the TCP connection request. | +| 527 | `Device.IP.Diagnostics.UploadDiagnostics.TCPOpenResponseTime` | readOnly | dateTime | Timestamp when the diagnostic received the TCP connection response. | +| 528 | `Device.IP.Diagnostics.UploadDiagnostics.TestFileLength` | readWrite | unsignedInt | Configured or measured test payload size for the diagnostic. | +| 529 | `Device.IP.Diagnostics.UploadDiagnostics.TotalBytesSent` | readOnly | unsignedInt | Total payload bytes transferred during the diagnostic. | +| 530 | `Device.IP.Diagnostics.UploadDiagnostics.UploadTransports` | readOnly | string | Transfer transports supported by the diagnostic. | +| 531 | `Device.IP.Diagnostics.UploadDiagnostics.UploadURL` | readWrite | string | Target URL used by the diagnostic. | +| 532 | `Device.IP.Diagnostics.X_RDKCENTRAL-COM_SpeedTest.Argument` | readWrite | string | Input value used by the RDK speed test. | +| 533 | `Device.IP.Diagnostics.X_RDKCENTRAL-COM_SpeedTest.Authentication` | readWrite | string | Input value used by the RDK speed test. | +| 534 | `Device.IP.Diagnostics.X_RDKCENTRAL-COM_SpeedTest.ClientType` | readWrite | unsignedInt | Client type used by the RDK speed test. | +| 535 | `Device.IP.Diagnostics.X_RDKCENTRAL-COM_SpeedTest.Enable` | readWrite | boolean | Enables or disables the RDK speed test. | +| 536 | `Device.IP.Diagnostics.X_RDKCENTRAL-COM_SpeedTest.Enable_Speedtest` | readWrite | boolean | Configuration or status value for the RDK speed test. | +| 537 | `Device.IP.Diagnostics.X_RDKCENTRAL-COM_SpeedTest.Run` | readWrite | boolean | Triggers immediate execution of the related diagnostic or action. | +| 538 | `Device.IP.Diagnostics.X_RDKCENTRAL-COM_SpeedTest.Status` | readOnly | unsignedInt | Current status of the RDK speed test. | +| 539 | `Device.IP.IPv4Capable` | readOnly | boolean | Indicates whether the device supports IPv4. | +| 540 | `Device.IP.IPv4Enable` | readWrite | boolean | Enables or disables IPv4 on this object. | +| 541 | `Device.IP.IPv4Status` | readOnly | string | Current IPv4 operational status of the device. | +| 542 | `Device.IP.Interface.{i}.Alias` | readWrite | string | User-assigned alias for this IP interface. | +| 543 | `Device.IP.Interface.{i}.AutoIPEnable` | readWrite | boolean | Enables or disables AutoIP on this IP interface. | +| 544 | `Device.IP.Interface.{i}.Enable` | readWrite | boolean | Enables or disables this IP interface. | +| 545 | `Device.IP.Interface.{i}.IPv4Address.{i}.AddressingType` | readOnly | string | Addressing method used for this IPv4 address entry. | +| 546 | `Device.IP.Interface.{i}.IPv4Address.{i}.Alias` | readWrite | string | User-assigned alias for this IPv4 address entry. | +| 547 | `Device.IP.Interface.{i}.IPv4Address.{i}.Enable` | readWrite | boolean | Enables or disables this IPv4 address entry. | +| 548 | `Device.IP.Interface.{i}.IPv4Address.{i}.IPAddress` | readWrite | string | IP address associated with this IPv4 address entry. | +| 549 | `Device.IP.Interface.{i}.IPv4Address.{i}.Status` | readOnly | string | Current status of this IPv4 address entry. | +| 550 | `Device.IP.Interface.{i}.IPv4Address.{i}.SubnetMask` | readWrite | string | Subnet mask assigned to this IPv4 address entry. | +| 551 | `Device.IP.Interface.{i}.IPv4AddressNumberOfEntries` | readOnly | unsignedInt | Reports the number of entries in this IP interface. | +| 552 | `Device.IP.Interface.{i}.IPv4Enable` | readWrite | boolean | Enables or disables IPv4 on this IP interface. | +| 553 | `Device.IP.Interface.{i}.IPv6Address.{i}.Alias` | readWrite | string | User-assigned alias for this IPv6 address entry. | +| 554 | `Device.IP.Interface.{i}.IPv6Address.{i}.Anycast` | readWrite | boolean | Indicates whether this IPv6 address is anycast. | +| 555 | `Device.IP.Interface.{i}.IPv6Address.{i}.Enable` | readWrite | boolean | Enables or disables this IPv6 address entry. | +| 556 | `Device.IP.Interface.{i}.IPv6Address.{i}.IPAddress` | readWrite | string | IP address associated with this IPv6 address entry. | +| 557 | `Device.IP.Interface.{i}.IPv6Address.{i}.IPAddressStatus` | readOnly | string | Current status of this IPv6 address. | +| 558 | `Device.IP.Interface.{i}.IPv6Address.{i}.Origin` | readOnly | string | Origin by which the related address or prefix was created. | +| 559 | `Device.IP.Interface.{i}.IPv6Address.{i}.PreferredLifetime` | readWrite | dateTime | Preferred lifetime for the related address or prefix. | +| 560 | `Device.IP.Interface.{i}.IPv6Address.{i}.Prefix` | readWrite | string | IP prefix associated with the related address or prefix entry. | +| 561 | `Device.IP.Interface.{i}.IPv6Address.{i}.Status` | readOnly | string | Current status of this IPv6 address entry. | +| 562 | `Device.IP.Interface.{i}.IPv6Address.{i}.ValidLifetime` | readWrite | dateTime | Valid lifetime for the related address or prefix. | +| 563 | `Device.IP.Interface.{i}.IPv6AddressNumberOfEntries` | readOnly | unsignedInt | Reports the number of entries in this IP interface. | +| 564 | `Device.IP.Interface.{i}.IPv6Enable` | readWrite | boolean | Enables or disables IPv6 on this IP interface. | +| 565 | `Device.IP.Interface.{i}.IPv6Prefix.{i}.Alias` | readWrite | string | User-assigned alias for this IPv6 prefix entry. | +| 566 | `Device.IP.Interface.{i}.IPv6Prefix.{i}.Autonomous` | readWrite | boolean | Indicates whether the prefix is used for autonomous addressing. | +| 567 | `Device.IP.Interface.{i}.IPv6Prefix.{i}.ChildPrefixBits` | readWrite | string | Child prefix bits delegated from this IPv6 prefix. | +| 568 | `Device.IP.Interface.{i}.IPv6Prefix.{i}.Enable` | readWrite | boolean | Enables or disables this IPv6 prefix entry. | +| 569 | `Device.IP.Interface.{i}.IPv6Prefix.{i}.OnLink` | readWrite | boolean | Indicates whether the prefix is advertised as on-link. | +| 570 | `Device.IP.Interface.{i}.IPv6Prefix.{i}.Origin` | readOnly | string | Origin by which the related address or prefix was created. | +| 571 | `Device.IP.Interface.{i}.IPv6Prefix.{i}.ParentPrefix` | readWrite | string | Parent prefix reference for this IPv6 prefix entry. | +| 572 | `Device.IP.Interface.{i}.IPv6Prefix.{i}.PreferredLifetime` | readWrite | dateTime | Preferred lifetime for the related address or prefix. | +| 573 | `Device.IP.Interface.{i}.IPv6Prefix.{i}.Prefix` | readWrite | string | IP prefix associated with the related address or prefix entry. | +| 574 | `Device.IP.Interface.{i}.IPv6Prefix.{i}.PrefixStatus` | readOnly | string | Current status of this IPv6 prefix. | +| 575 | `Device.IP.Interface.{i}.IPv6Prefix.{i}.StaticType` | readWrite | string | Static type assigned to this IPv6 prefix entry. | +| 576 | `Device.IP.Interface.{i}.IPv6Prefix.{i}.Status` | readOnly | string | Current status of this IPv6 prefix entry. | +| 577 | `Device.IP.Interface.{i}.IPv6Prefix.{i}.ValidLifetime` | readWrite | dateTime | Valid lifetime for the related address or prefix. | +| 578 | `Device.IP.Interface.{i}.IPv6PrefixNumberOfEntries` | readOnly | unsignedInt | Reports the number of entries in this IP interface. | +| 579 | `Device.IP.Interface.{i}.LastChange` | readOnly | unsignedInt | Seconds since this IP interface last changed state. | +| 580 | `Device.IP.Interface.{i}.Loopback` | readWrite | boolean | Indicates whether this IP interface operates as loopback. | +| 581 | `Device.IP.Interface.{i}.LowerLayers` | readWrite | string | Lower-layer interface references for this IP interface. | +| 582 | `Device.IP.Interface.{i}.MaxMTUSize` | readWrite | unsignedInt | Maximum MTU configured for this IP interface. | +| 583 | `Device.IP.Interface.{i}.Name` | readOnly | string | Name reported for this IP interface. | +| 584 | `Device.IP.Interface.{i}.Reset` | readWrite | boolean | Triggers a reset action for this IP interface. | +| 585 | `Device.IP.Interface.{i}.Router` | readWrite | string | Router reference associated with this IP interface. | +| 586 | `Device.IP.Interface.{i}.Stats.BroadcastPacketsReceived` | readOnly | unsignedLong | Broadcast packets received on this IP interface. | +| 587 | `Device.IP.Interface.{i}.Stats.BroadcastPacketsSent` | readOnly | unsignedLong | Broadcast packets sent on this IP interface. | +| 588 | `Device.IP.Interface.{i}.Stats.BytesReceived` | readOnly | unsignedLong | Total bytes received on this IP interface. | +| 589 | `Device.IP.Interface.{i}.Stats.BytesSent` | readOnly | unsignedLong | Total bytes sent on this IP interface. | +| 590 | `Device.IP.Interface.{i}.Stats.DiscardPacketsReceived` | readOnly | unsignedInt | Received packets discarded on this IP interface. | +| 591 | `Device.IP.Interface.{i}.Stats.DiscardPacketsSent` | readOnly | unsignedInt | Outbound packets discarded on this IP interface. | +| 592 | `Device.IP.Interface.{i}.Stats.ErrorsReceived` | readOnly | unsignedInt | Receive errors seen on this IP interface. | +| 593 | `Device.IP.Interface.{i}.Stats.ErrorsSent` | readOnly | unsignedInt | Transmit errors seen on this IP interface. | +| 594 | `Device.IP.Interface.{i}.Stats.MulticastPacketsReceived` | readOnly | unsignedLong | Multicast packets received on this IP interface. | +| 595 | `Device.IP.Interface.{i}.Stats.MulticastPacketsSent` | readOnly | unsignedLong | Multicast packets sent on this IP interface. | +| 596 | `Device.IP.Interface.{i}.Stats.PacketsReceived` | readOnly | unsignedLong | Total packets received on this IP interface. | +| 597 | `Device.IP.Interface.{i}.Stats.PacketsSent` | readOnly | unsignedLong | Total packets sent on this IP interface. | +| 598 | `Device.IP.Interface.{i}.Stats.UnicastPacketsReceived` | readOnly | unsignedLong | Unicast packets received on this IP interface. | +| 599 | `Device.IP.Interface.{i}.Stats.UnicastPacketsSent` | readOnly | unsignedLong | Unicast packets sent on this IP interface. | +| 600 | `Device.IP.Interface.{i}.Stats.UnknownProtoPacketsReceived` | readOnly | unsignedInt | Packets with unknown protocol received on this IP interface. | +| 601 | `Device.IP.Interface.{i}.Status` | readOnly | string | Current status of this IP interface. | +| 602 | `Device.IP.Interface.{i}.Type` | readOnly | string | Type reported for the related object. | +| 603 | `Device.IP.Interface.{i}.ULAEnable` | readWrite | boolean | Enables or disables ULA addressing on this IP interface. | +| 604 | `Device.IP.InterfaceNumberOfEntries` | readOnly | unsignedInt | Reports the number of entries in this object. | +| 605 | `Device.IP.ULAPrefix` | readWrite | string | Current ULA prefix configured for the device. | +| 606 | `Device.InterfaceStack.{i}.HigherLayer` | readOnly | string | Higher-layer interface reference in this stack relationship. | +| 607 | `Device.InterfaceStack.{i}.LowerLayer` | readOnly | string | Lower-layer interface reference in this stack relationship. | +| 608 | `Device.InterfaceStackNumberOfEntries` | readOnly | unsignedInt | Reports the number of entries in this object. | +| 609 | `Device.ManagementServer.AliasBasedAddressing` | readOnly | boolean | Indicates whether alias-based addressing is supported. | +| 610 | `Device.ManagementServer.AutoCreateInstances` | readWrite | boolean | Controls automatic creation of multi-instance objects. | +| 611 | `Device.ManagementServer.CWMPRetryIntervalMultiplier` | readWrite | unsignedInt | CWMP retry timing parameter used by the management client. | +| 612 | `Device.ManagementServer.CWMPRetryMinimumWaitInterval` | readWrite | unsignedInt | CWMP retry timing parameter used by the management client. | +| 613 | `Device.ManagementServer.ConnectionRequestURL` | readOnly | string | URL used by the ACS to issue connection requests. | +| 614 | `Device.ManagementServer.ConnectionRequestUsername` | readWrite | string | Username used by the management server client. | +| 615 | `Device.ManagementServer.DefaultActiveNotificationThrottle` | readWrite | unsignedInt | Throttle interval for active notifications. | +| 616 | `Device.ManagementServer.DownloadProgressURL` | readOnly | string | URL used to report download progress. | +| 617 | `Device.ManagementServer.EnableCWMP` | readWrite | boolean | Enables or disables CWMP communication. | +| 618 | `Device.ManagementServer.InstanceMode` | readWrite | string | Instance addressing mode used by the management client. | +| 619 | `Device.ManagementServer.KickURL` | readOnly | string | Kick URL exposed by the management client. | +| 620 | `Device.ManagementServer.NATDetected` | readOnly | boolean | Indicates whether NAT is detected for ACS communication. | +| 621 | `Device.ManagementServer.ParameterKey` | readOnly | string | Parameter key associated with the most recent configuration change. | +| 622 | `Device.ManagementServer.PeriodicInformEnable` | readWrite | boolean | Enables or disables periodic Inform messages. | +| 623 | `Device.ManagementServer.PeriodicInformInterval` | readWrite | unsignedInt | Interval between periodic Inform messages, in seconds. | +| 624 | `Device.ManagementServer.PeriodicInformTime` | readWrite | dateTime | Reference time for scheduling periodic Inform messages. | +| 625 | `Device.ManagementServer.STUNEnable` | readWrite | boolean | Enables or disables STUN for connection requests. | +| 626 | `Device.ManagementServer.STUNMaximumKeepAlivePeriod` | readWrite | int | STUN keepalive timing value used by the management client. | +| 627 | `Device.ManagementServer.STUNMinimumKeepAlivePeriod` | readWrite | unsignedInt | STUN keepalive timing value used by the management client. | +| 628 | `Device.ManagementServer.STUNPassword` | readWrite | string | Shared secret or password used by the management server client. | +| 629 | `Device.ManagementServer.STUNServerAddress` | readWrite | string | STUN server address used by the management client. | +| 630 | `Device.ManagementServer.STUNServerPort` | readWrite | unsignedInt | STUN server port used by the management client. | +| 631 | `Device.ManagementServer.STUNUsername` | readWrite | string | Username used by the management server client. | +| 632 | `Device.ManagementServer.UDPConnectionRequestAddress` | readOnly | string | UDP address used for connection requests. | +| 633 | `Device.ManagementServer.URL` | readWrite | string | URL used by the management server client. | +| 634 | `Device.ManagementServer.UpgradesManaged` | readWrite | boolean | Indicates whether software upgrades are managed by the ACS. | +| 635 | `Device.ManagementServer.Username` | readWrite | string | Username used by the management server client. | +| 636 | `Device.Services.STBService.1.Capabilities.HDMI.SupportedResolutions` | readOnly | string | Display resolutions supported by the related capability or device. | +| 637 | `Device.Services.STBService.1.Capabilities.VideoDecoder.VideoStandards` | readOnly | string | Video standards supported by the decoder capability. | +| 638 | `Device.Services.STBService.1.Capabilities.VideoDecoder.X_RDKCENTRAL-COM_MPEGHPart2.ProfileLevel.1.Alias` | readOnly | string | User-assigned alias for this MPEG-H Part 2 profile-level entry. | +| 639 | `Device.Services.STBService.1.Capabilities.VideoDecoder.X_RDKCENTRAL-COM_MPEGHPart2.ProfileLevel.1.Level` | readOnly | string | Profile level value for this codec capability entry. | +| 640 | `Device.Services.STBService.1.Capabilities.VideoDecoder.X_RDKCENTRAL-COM_MPEGHPart2.ProfileLevel.1.MaximumDecodingCapability` | readOnly | unsignedInt | Maximum decoding capability reported for this codec entry. | +| 641 | `Device.Services.STBService.1.Capabilities.VideoDecoder.X_RDKCENTRAL-COM_MPEGHPart2.ProfileLevel.1.Profile` | readOnly | string | Profile reported for the related entry. | +| 642 | `Device.Services.STBService.1.Capabilities.VideoDecoder.X_RDKCENTRAL-COM_MPEGHPart2.ProfileLevelNumberOfEntries` | readOnly | unsignedInt | Reports the number of entries in the STB video decoder capability set. | +| 643 | `Device.Services.STBService.1.Components.AudioOutput.1.AudioFormat` | readOnly | string | Current audio format reported for this output. | +| 644 | `Device.Services.STBService.1.Components.AudioOutput.1.AudioLevel` | readWrite | unsignedInt | Current audio level for this output. | +| 645 | `Device.Services.STBService.1.Components.AudioOutput.1.CancelMute` | readWrite | boolean | Clears mute state for this audio output when set. | +| 646 | `Device.Services.STBService.1.Components.AudioOutput.1.Enable` | readWrite | boolean | Enables or disables this audio output. | +| 647 | `Device.Services.STBService.1.Components.AudioOutput.1.Name` | readOnly | string | Name reported for this audio output. | +| 648 | `Device.Services.STBService.1.Components.AudioOutput.1.Status` | readOnly | string | Current status of this audio output. | +| 649 | `Device.Services.STBService.1.Components.AudioOutput.1.X_COMCAST-COM_AudioCompression` | readWrite | string | Audio compression mode configured for this output. | +| 650 | `Device.Services.STBService.1.Components.AudioOutput.1.X_COMCAST-COM_AudioDB` | readWrite | string | Audio level in dB for this output. | +| 651 | `Device.Services.STBService.1.Components.AudioOutput.1.X_COMCAST-COM_AudioEncoding` | readWrite | string | Audio encoding mode configured for this output. | +| 652 | `Device.Services.STBService.1.Components.AudioOutput.1.X_COMCAST-COM_AudioGain` | readWrite | string | Audio gain setting for this output. | +| 653 | `Device.Services.STBService.1.Components.AudioOutput.1.X_COMCAST-COM_AudioLoopThru` | readWrite | string | Loop-through audio mode for this output. | +| 654 | `Device.Services.STBService.1.Components.AudioOutput.1.X_COMCAST-COM_AudioOptimalLevel` | readWrite | string | Optimal audio level setting for this output. | +| 655 | `Device.Services.STBService.1.Components.AudioOutput.1.X_COMCAST-COM_AudioStereoMode` | readWrite | string | Stereo mode configured for this output. | +| 656 | `Device.Services.STBService.1.Components.AudioOutput.1.X_COMCAST-COM_MaxAudioDB` | readOnly | string | Maximum supported audio level in dB for this output. | +| 657 | `Device.Services.STBService.1.Components.AudioOutput.1.X_COMCAST-COM_MinAudioDB` | readOnly | string | Minimum supported audio level in dB for this output. | +| 658 | `Device.Services.STBService.1.Components.AudioOutputNumberOfEntries` | readOnly | unsignedInt | Reports the number of entries in the STB service. | +| 659 | `Device.Services.STBService.1.Components.HDMI.1.DisplayDevice.AutoLipSyncSupport` | readOnly | boolean | Indicates whether the connected display supports auto lip-sync. | +| 660 | `Device.Services.STBService.1.Components.HDMI.1.DisplayDevice.CECSupport` | readOnly | boolean | Indicates whether the connected display supports CEC. | +| 661 | `Device.Services.STBService.1.Components.HDMI.1.DisplayDevice.EEDID` | readOnly | string | EDID data reported by the connected HDMI display. | +| 662 | `Device.Services.STBService.1.Components.HDMI.1.DisplayDevice.HDMI3DPresent` | readOnly | boolean | Indicates whether the connected display reports HDMI 3D support. | +| 663 | `Device.Services.STBService.1.Components.HDMI.1.DisplayDevice.PreferredResolution` | readOnly | string | Preferred resolution reported by the connected display. | +| 664 | `Device.Services.STBService.1.Components.HDMI.1.DisplayDevice.Status` | readOnly | string | Current status of the connected HDMI display. | +| 665 | `Device.Services.STBService.1.Components.HDMI.1.DisplayDevice.SupportedResolutions` | readOnly | string | Display resolutions supported by the related capability or device. | +| 666 | `Device.Services.STBService.1.Components.HDMI.1.DisplayDevice.VideoLatency` | readOnly | unsignedInt | Video latency reported by the connected display. | +| 667 | `Device.Services.STBService.1.Components.HDMI.1.DisplayDevice.X_COMCAST-COM_EDID` | readOnly | string | EDID data reported by the connected HDMI display. | +| 668 | `Device.Services.STBService.1.Components.HDMI.1.Enable` | readWrite | boolean | Enables or disables this HDMI output. | +| 669 | `Device.Services.STBService.1.Components.HDMI.1.Name` | readOnly | string | Name reported for this HDMI output. | +| 670 | `Device.Services.STBService.1.Components.HDMI.1.ResolutionMode` | readWrite | string | Resolution selection mode for this HDMI output. | +| 671 | `Device.Services.STBService.1.Components.HDMI.1.ResolutionValue` | readWrite | string | Current resolution value for this HDMI output. | +| 672 | `Device.Services.STBService.1.Components.HDMI.1.Status` | readOnly | string | Current status of this HDMI output. | +| 673 | `Device.Services.STBService.1.Components.HDMINumberOfEntries` | readOnly | unsignedInt | Reports the number of entries in the STB service. | +| 674 | `Device.Services.STBService.1.Components.VideoDecoder.1.ContentAspectRatio` | readOnly | string | Current content aspect ratio reported by the video decoder. | +| 675 | `Device.Services.STBService.1.Components.VideoDecoder.1.Enable` | readWrite | boolean | Enables or disables this video decoder. | +| 676 | `Device.Services.STBService.1.Components.VideoDecoder.1.Name` | readOnly | string | Name reported for this video decoder. | +| 677 | `Device.Services.STBService.1.Components.VideoDecoder.1.Status` | readOnly | string | Current status of this video decoder. | +| 678 | `Device.Services.STBService.1.Components.VideoDecoder.1.X_COMCAST-COM_Standby` | readWrite | boolean | Standby state for this video decoder. | +| 679 | `Device.Services.STBService.1.Components.VideoDecoder.1.X_RDKCENTRAL-COM_MPEGHPart2` | readOnly | string | MPEG-H Part 2 capability string reported by the decoder. | +| 680 | `Device.Services.STBService.1.Components.VideoDecoderNumberOfEntries` | readOnly | unsignedInt | Reports the number of entries in the STB service. | +| 681 | `Device.Services.STBService.1.Components.VideoOutput.1.AspectRatioBehaviour` | readWrite | string | Aspect-ratio handling mode for this video output. | +| 682 | `Device.Services.STBService.1.Components.VideoOutput.1.DisplayFormat` | readWrite | string | Display format configured for this video output. | +| 683 | `Device.Services.STBService.1.Components.VideoOutput.1.Enable` | readWrite | boolean | Enables or disables this video output. | +| 684 | `Device.Services.STBService.1.Components.VideoOutput.1.HDCP` | readWrite | boolean | HDCP state configured for this video output. | +| 685 | `Device.Services.STBService.1.Components.VideoOutput.1.Name` | readOnly | string | Name reported for this video output. | +| 686 | `Device.Services.STBService.1.Components.VideoOutput.1.Status` | readOnly | string | Current status of this video output. | +| 687 | `Device.Services.STBService.1.Components.VideoOutput.1.VideoFormat` | readWrite | string | Video format configured for this video output. | +| 688 | `Device.Services.STBService.1.Components.VideoOutputNumberOfEntries` | readOnly | unsignedInt | Reports the number of entries in the STB service. | +| 689 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_RF4CE.Remote.1.BatteryLevelLoaded` | readOnly | unsignedInt | Battery metric reported for this RF4CE remote. | +| 690 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_RF4CE.Remote.1.BatteryLevelUnloaded` | readOnly | unsignedInt | Battery metric reported for this RF4CE remote. | +| 691 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_RF4CE.Remote.1.BatteryPercentage` | readOnly | unsignedInt | Battery metric reported for this RF4CE remote. | +| 692 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_RF4CE.Remote.1.BatteryReplacement` | readOnly | boolean | Indicates whether the RF4CE remote battery should be replaced. | +| 693 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_RF4CE.Remote.1.ImpendingDoom` | readOnly | boolean | Indicates whether the RF4CE remote reports a critical battery condition. | +| 694 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_RF4CE.Remote.1.LinkQuality` | readOnly | unsignedInt | Link quality reported for this RF4CE remote. | +| 695 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_RF4CE.Remote.1.MACAddress` | readOnly | string | MAC address associated with this RF4CE remote. | +| 696 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_RF4CE.Remote.1.NetworkAddress` | readOnly | unsignedInt | Network address reported for the related RF4CE object. | +| 697 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_RF4CE.Remote.1.RemoteId` | readOnly | unsignedInt | Remote identifier reported for this RF4CE remote. | +| 698 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_RF4CE.Remote.1.RemoteType` | readOnly | string | Remote type reported for this RF4CE remote. | +| 699 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_RF4CE.Remote.1.SignalStrength` | readOnly | int | Signal strength reported for the related entry. | +| 700 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_RF4CE.Remote.1.VersionInfoHW` | readOnly | string | Version information reported for the related RF4CE object. | +| 701 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_RF4CE.Remote.1.VersionInfoSW` | readOnly | string | Version information reported for the related RF4CE object. | +| 702 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_RF4CE.rf4ceActiveChannel` | readOnly | unsignedInt | RF4CE network property reported by the subsystem. | +| 703 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_RF4CE.rf4ceMACAddress` | readOnly | string | RF4CE network property reported by the subsystem. | +| 704 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_RF4CE.rf4ceNetworkAddress` | readOnly | unsignedInt | RF4CE network property reported by the subsystem. | +| 705 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_RF4CE.rf4cePANID` | readOnly | unsignedInt | RF4CE network property reported by the subsystem. | +| 706 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_RF4CE.rf4cePairedRemotesNumberOfEntries` | readOnly | unsignedInt | Reports the number of entries in the RF4CE subsystem. | +| 707 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_RF4CE.rf4ceVersionInfo` | readOnly | string | Version information reported for the related RF4CE object. | +| 708 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_eMMCFlash.Capacity` | readOnly | unsignedInt | Storage capacity reported for the device. | +| 709 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_eMMCFlash.DeviceReport` | readOnly | string | Detailed health report for the storage device. | +| 710 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_eMMCFlash.FirmwareVersion` | readOnly | string | Version string reported for the eMMC flash device. | +| 711 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_eMMCFlash.LifeElapsedA` | readOnly | int | Wear indicator reported for the storage device. | +| 712 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_eMMCFlash.LifeElapsedB` | readOnly | int | Wear indicator reported for the storage device. | +| 713 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_eMMCFlash.LotID` | readOnly | string | Manufacturing lot identifier for the device. | +| 714 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_eMMCFlash.Manufacturer` | readOnly | string | Manufacturer reported for the eMMC flash device. | +| 715 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_eMMCFlash.Model` | readOnly | string | Model identifier reported for the eMMC flash device. | +| 716 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_eMMCFlash.PreEOLStateEUDA` | readOnly | string | Pre-EOL health state for the named storage area. | +| 717 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_eMMCFlash.PreEOLStateMLC` | readOnly | string | Pre-EOL health state for the named storage area. | +| 718 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_eMMCFlash.PreEOLStateSystem` | readOnly | string | Pre-EOL health state for the named storage area. | +| 719 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_eMMCFlash.ReadOnly` | readOnly | boolean | Indicates whether the device is operating in read-only mode. | +| 720 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_eMMCFlash.SerialNumber` | readOnly | string | Serial number reported for the eMMC flash device. | +| 721 | `Device.Services.STBService.1.Components.X_RDKCENTRAL-COM_eMMCFlash.TSBQualified` | readOnly | boolean | Indicates whether the storage device is qualified for TSB use. | +| 722 | `Device.Services.STBService.1.Enable` | readWrite | boolean | Enables or disables the STB service. | +| 723 | `Device.Services.STBServiceNumberOfEntries` | readOnly | unsignedInt | Reports the number of entries in this object. | +| 724 | `Device.Time.ChronyEnable` | readWrite | boolean | Enables or disables Chrony-based time synchronization. | +| 725 | `Device.Time.CurrentLocalTime` | readWrite | string | Current local time reported by the device. | +| 726 | `Device.Time.Enable` | readWrite | boolean | Enables or disables the system time service. | +| 727 | `Device.Time.LocalTimeZone` | readWrite | string | Current local timezone setting reported by the device. | +| 728 | `Device.Time.NTPMaxpoll` | readWrite | unsignedInt | Chrony NTP poll interval setting. | +| 729 | `Device.Time.NTPMaxstep` | readWrite | string | Chrony maxstep setting used during large time corrections. | +| 730 | `Device.Time.NTPMinpoll` | readWrite | unsignedInt | Chrony NTP poll interval setting. | +| 731 | `Device.Time.NTPServer1` | readWrite | string | Configured NTP server address for the numbered slot. | +| 732 | `Device.Time.NTPServer1Directive` | readWrite | string | Chrony directive used for the numbered NTP server slot. | +| 733 | `Device.Time.NTPServer2` | readWrite | string | Configured NTP server address for the numbered slot. | +| 734 | `Device.Time.NTPServer2Directive` | readWrite | string | Chrony directive used for the numbered NTP server slot. | +| 735 | `Device.Time.NTPServer3` | readWrite | string | Configured NTP server address for the numbered slot. | +| 736 | `Device.Time.NTPServer3Directive` | readWrite | string | Chrony directive used for the numbered NTP server slot. | +| 737 | `Device.Time.NTPServer4` | readWrite | string | Configured NTP server address for the numbered slot. | +| 738 | `Device.Time.NTPServer4Directive` | readWrite | string | Chrony directive used for the numbered NTP server slot. | +| 739 | `Device.Time.NTPServer5` | readWrite | string | Configured NTP server address for the numbered slot. | +| 740 | `Device.Time.NTPServer5Directive` | readWrite | string | Chrony directive used for the numbered NTP server slot. | +| 741 | `Device.Time.Status` | readWrite | string | Current status of the system time service. | +| 742 | `Device.Time.X_RDK_CurrentUTCTime` | readOnly | string | Current UTC time reported by the device. | +| 743 | `Device.WiFi.AccessPoint.{i}.Alias` | readWrite | string | User-assigned alias for this Wi-Fi access point. | +| 744 | `Device.WiFi.AccessPoint.{i}.AssociatedDevice.{i}.Active` | readOnly | boolean | Indicates whether the related entry is currently active. | +| 745 | `Device.WiFi.AccessPoint.{i}.AssociatedDevice.{i}.AuthenticationState` | readOnly | boolean | Configuration or status value for this associated Wi-Fi client. | +| 746 | `Device.WiFi.AccessPoint.{i}.AssociatedDevice.{i}.LastDataDownlinkRate` | readOnly | unsignedInt | Configuration or status value for this associated Wi-Fi client. | +| 747 | `Device.WiFi.AccessPoint.{i}.AssociatedDevice.{i}.LastDataUplinkRate` | readOnly | unsignedInt | Configuration or status value for this associated Wi-Fi client. | +| 748 | `Device.WiFi.AccessPoint.{i}.AssociatedDevice.{i}.MACAddress` | readOnly | string | MAC address associated with this associated Wi-Fi client. | +| 749 | `Device.WiFi.AccessPoint.{i}.AssociatedDevice.{i}.Retransmissions` | readOnly | unsignedInt | Configuration or status value for this associated Wi-Fi client. | +| 750 | `Device.WiFi.AccessPoint.{i}.AssociatedDevice.{i}.SignalStrength` | readOnly | int | Signal strength reported for the related entry. | +| 751 | `Device.WiFi.AccessPoint.{i}.AssociatedDeviceNumberOfEntries` | readOnly | unsignedInt | Reports the number of entries in this Wi-Fi access point. | +| 752 | `Device.WiFi.AccessPoint.{i}.Enable` | readWrite | boolean | Enables or disables this Wi-Fi access point. | +| 753 | `Device.WiFi.AccessPoint.{i}.RetryLimit` | readWrite | unsignedInt | Configuration or status value for this Wi-Fi access point. | +| 754 | `Device.WiFi.AccessPoint.{i}.SSIDAdvertisementEnabled` | readWrite | boolean | Controls whether this access point advertises its SSID. | +| 755 | `Device.WiFi.AccessPoint.{i}.SSIDReference` | readWrite | string | Reference to the SSID object used by this entry. | +| 756 | `Device.WiFi.AccessPoint.{i}.Security.KeyPassphrase` | readWrite | string | Passphrase configured for the related Wi-Fi profile. | +| 757 | `Device.WiFi.AccessPoint.{i}.Security.ModeEnabled` | readWrite | string | Security mode currently enabled for the related Wi-Fi object. | +| 758 | `Device.WiFi.AccessPoint.{i}.Security.ModesSupported` | readOnly | string | Security modes supported by the related Wi-Fi object. | +| 759 | `Device.WiFi.AccessPoint.{i}.Security.PreSharedKey` | readWrite | hexBinary | Pre-shared key configured for the related Wi-Fi object. | +| 760 | `Device.WiFi.AccessPoint.{i}.Security.RadiusSecret` | readWrite | string | Shared secret or password used by this Wi-Fi access point. | +| 761 | `Device.WiFi.AccessPoint.{i}.Security.RadiusServerIPAddr` | readWrite | string | RADIUS server IP address used by this access point. | +| 762 | `Device.WiFi.AccessPoint.{i}.Security.RadiusServerPort` | readWrite | unsignedInt | Port value used by this Wi-Fi access point. | +| 763 | `Device.WiFi.AccessPoint.{i}.Security.RekeyingInterval` | readWrite | unsignedInt | Key rekey interval for this Wi-Fi security profile. | +| 764 | `Device.WiFi.AccessPoint.{i}.Security.WEPKey` | readWrite | hexBinary | WEP key configured for the related Wi-Fi object. | +| 765 | `Device.WiFi.AccessPoint.{i}.Status` | readOnly | string | Current status of this Wi-Fi access point. | +| 766 | `Device.WiFi.AccessPoint.{i}.UAPSDCapability` | readOnly | boolean | U-APSD capability or enable state for this access point. | +| 767 | `Device.WiFi.AccessPoint.{i}.UAPSDEnable` | readWrite | boolean | U-APSD capability or enable state for this access point. | +| 768 | `Device.WiFi.AccessPoint.{i}.WMMCapability` | readOnly | boolean | WMM capability or enable state for this access point. | +| 769 | `Device.WiFi.AccessPoint.{i}.WMMEnable` | readWrite | boolean | WMM capability or enable state for this access point. | +| 770 | `Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled` | readWrite | string | WPS configuration methods enabled or supported for the related Wi-Fi object. | +| 771 | `Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsSupported` | readOnly | string | WPS configuration methods enabled or supported for the related Wi-Fi object. | +| 772 | `Device.WiFi.AccessPoint.{i}.WPS.Enable` | readWrite | boolean | Enables or disables this Wi-Fi access point. | +| 773 | `Device.WiFi.AccessPointNumberOfEntries` | readOnly | unsignedInt | Reports the number of entries in this object. | +| 774 | `Device.WiFi.EndPoint.{i}.Alias` | readWrite | string | User-assigned alias for this Wi-Fi endpoint. | +| 775 | `Device.WiFi.EndPoint.{i}.Enable` | readWrite | boolean | Enables or disables this Wi-Fi endpoint. | +| 776 | `Device.WiFi.EndPoint.{i}.Profile.{i}.Alias` | readWrite | string | User-assigned alias for this Wi-Fi endpoint profile. | +| 777 | `Device.WiFi.EndPoint.{i}.Profile.{i}.Enable` | readWrite | boolean | Enables or disables this Wi-Fi endpoint profile. | +| 778 | `Device.WiFi.EndPoint.{i}.Profile.{i}.Location` | readWrite | string | Location hint associated with this Wi-Fi endpoint profile. | +| 779 | `Device.WiFi.EndPoint.{i}.Profile.{i}.Priority` | readWrite | unsignedInt | Scheduling priority for this Wi-Fi endpoint profile. | +| 780 | `Device.WiFi.EndPoint.{i}.Profile.{i}.SSID` | readWrite | string | SSID string used by the related Wi-Fi object. | +| 781 | `Device.WiFi.EndPoint.{i}.Profile.{i}.Security.KeyPassphrase` | readWrite | string | Passphrase configured for the related Wi-Fi profile. | +| 782 | `Device.WiFi.EndPoint.{i}.Profile.{i}.Security.ModeEnabled` | readWrite | string | Security mode currently enabled for the related Wi-Fi object. | +| 783 | `Device.WiFi.EndPoint.{i}.Profile.{i}.Security.PreSharedKey` | readWrite | hexBinary | Pre-shared key configured for the related Wi-Fi object. | +| 784 | `Device.WiFi.EndPoint.{i}.Profile.{i}.Security.WEPKey` | readWrite | hexBinary | WEP key configured for the related Wi-Fi object. | +| 785 | `Device.WiFi.EndPoint.{i}.Profile.{i}.Status` | readOnly | string | Current status of this Wi-Fi endpoint profile. | +| 786 | `Device.WiFi.EndPoint.{i}.ProfileNumberOfEntries` | readOnly | unsignedInt | Reports the number of entries in this Wi-Fi endpoint. | +| 787 | `Device.WiFi.EndPoint.{i}.ProfileReference` | readWrite | string | Reference to the active Wi-Fi endpoint profile. | +| 788 | `Device.WiFi.EndPoint.{i}.SSIDReference` | readOnly | string | Reference to the SSID object used by this entry. | +| 789 | `Device.WiFi.EndPoint.{i}.Security.ModesEnabled` | readOnly | string | Security mode currently enabled for the related Wi-Fi object. | +| 790 | `Device.WiFi.EndPoint.{i}.Security.ModesSupported` | readOnly | string | Security modes supported by the related Wi-Fi object. | +| 791 | `Device.WiFi.EndPoint.{i}.Stats.LastDataDownlinkRate` | readOnly | unsignedInt | Most recent downlink data rate for this Wi-Fi endpoint. | +| 792 | `Device.WiFi.EndPoint.{i}.Stats.LastDataUplinkRate` | readOnly | unsignedInt | Most recent uplink data rate for this Wi-Fi endpoint. | +| 793 | `Device.WiFi.EndPoint.{i}.Stats.Retransmissions` | readOnly | unsignedInt | Retransmission count observed for this Wi-Fi endpoint. | +| 794 | `Device.WiFi.EndPoint.{i}.Stats.SignalStrength` | readOnly | int | Reported signal strength for this Wi-Fi endpoint. | +| 795 | `Device.WiFi.EndPoint.{i}.Status` | readOnly | string | Current status of this Wi-Fi endpoint. | +| 796 | `Device.WiFi.EndPoint.{i}.WPS.ConfigMethodsEnabled` | readWrite | string | WPS configuration methods enabled or supported for the related Wi-Fi object. | +| 797 | `Device.WiFi.EndPoint.{i}.WPS.ConfigMethodsSupported` | readOnly | string | WPS configuration methods enabled or supported for the related Wi-Fi object. | +| 798 | `Device.WiFi.EndPoint.{i}.WPS.Enable` | readWrite | boolean | Enables or disables this Wi-Fi endpoint. | +| 799 | `Device.WiFi.EndPointNumberOfEntries` | readOnly | unsignedInt | Reports the number of entries in this object. | +| 800 | `Device.WiFi.Radio.{i}.OperatingChannelBandwidth` | readOnly | string | Current operating channel bandwidth of this Wi-Fi radio. | +| 801 | `Device.WiFi.Radio.{i}.Stats.Noise` | readOnly | int | Reported noise floor for this Wi-Fi radio. | +| 802 | `Device.WiFi.Radio.{i}.Stats.PacketsReceived` | readOnly | unsignedLong | Total packets received on this Wi-Fi radio. | +| 803 | `Device.WiFi.RadioNumberOfEntries` | readOnly | unsignedInt | Reports the number of entries in this object. | +| 804 | `Device.WiFi.SSID.{i}.Alias` | readWrite | string | User-assigned alias for this SSID interface. | +| 805 | `Device.WiFi.SSID.{i}.BSSID` | readOnly | string | BSSID reported for this SSID interface. | +| 806 | `Device.WiFi.SSID.{i}.Enable` | readWrite | boolean | Enables or disables this SSID interface. | +| 807 | `Device.WiFi.SSID.{i}.LastChange` | readOnly | unsignedInt | Seconds since this SSID interface last changed state. | +| 808 | `Device.WiFi.SSID.{i}.LowerLayers` | readWrite | string | Lower-layer interface references for this SSID interface. | +| 809 | `Device.WiFi.SSID.{i}.MACAddress` | readOnly | string | MAC address associated with this SSID interface. | +| 810 | `Device.WiFi.SSID.{i}.Name` | readOnly | string | Name reported for this SSID interface. | +| 811 | `Device.WiFi.SSID.{i}.SSID` | readWrite | string | SSID string used by the related Wi-Fi object. | +| 812 | `Device.WiFi.SSID.{i}.Stats.BroadcastPacketsReceived` | readOnly | unsignedLong | Broadcast packets received on this SSID interface. | +| 813 | `Device.WiFi.SSID.{i}.Stats.BroadcastPacketsSent` | readOnly | unsignedLong | Broadcast packets sent on this SSID interface. | +| 814 | `Device.WiFi.SSID.{i}.Stats.BytesReceived` | readOnly | unsignedLong | Total bytes received on this SSID interface. | +| 815 | `Device.WiFi.SSID.{i}.Stats.BytesSent` | readOnly | unsignedLong | Total bytes sent on this SSID interface. | +| 816 | `Device.WiFi.SSID.{i}.Stats.DiscardPacketsReceived` | readOnly | unsignedInt | Received packets discarded on this SSID interface. | +| 817 | `Device.WiFi.SSID.{i}.Stats.DiscardPacketsSent` | readOnly | unsignedInt | Outbound packets discarded on this SSID interface. | +| 818 | `Device.WiFi.SSID.{i}.Stats.ErrorsReceived` | readOnly | unsignedInt | Receive errors seen on this SSID interface. | +| 819 | `Device.WiFi.SSID.{i}.Stats.ErrorsSent` | readOnly | unsignedInt | Transmit errors seen on this SSID interface. | +| 820 | `Device.WiFi.SSID.{i}.Stats.MulticastPacketsReceived` | readOnly | unsignedLong | Multicast packets received on this SSID interface. | +| 821 | `Device.WiFi.SSID.{i}.Stats.MulticastPacketsSent` | readOnly | unsignedLong | Multicast packets sent on this SSID interface. | +| 822 | `Device.WiFi.SSID.{i}.Stats.PacketsReceived` | readOnly | unsignedLong | Total packets received on this SSID interface. | +| 823 | `Device.WiFi.SSID.{i}.Stats.PacketsSent` | readOnly | unsignedLong | Total packets sent on this SSID interface. | +| 824 | `Device.WiFi.SSID.{i}.Stats.UnicastPacketsReceived` | readOnly | unsignedLong | Unicast packets received on this SSID interface. | +| 825 | `Device.WiFi.SSID.{i}.Stats.UnicastPacketsSent` | readOnly | unsignedLong | Unicast packets sent on this SSID interface. | +| 826 | `Device.WiFi.SSID.{i}.Stats.UnknownProtoPacketsReceived` | readOnly | unsignedInt | Packets with unknown protocol received on this SSID interface. | +| 827 | `Device.WiFi.SSID.{i}.Status` | readOnly | string | Current status of this SSID interface. | +| 828 | `Device.WiFi.SSIDNumberOfEntries` | readOnly | unsignedInt | Reports the number of entries in this object. | +| 829 | `Device.WiFi.X_RDKCENTRAL-COM_ClientRoaming.80211kvrEnable` | readWrite | boolean | Enables or disables 802.11k/v/r roaming support. | +| 830 | `Device.WiFi.X_RDKCENTRAL-COM_ClientRoaming.Enable` | readWrite | boolean | Enables or disables the Wi-Fi client roaming policy. | +| 831 | `Device.WiFi.X_RDKCENTRAL-COM_ClientRoaming.PostAssn_APcontrolBeaconsMissedTime` | readWrite | unsignedInt | Band-steering threshold or control used by the client roaming policy. | +| 832 | `Device.WiFi.X_RDKCENTRAL-COM_ClientRoaming.PostAssn_APcontrolThresholdLevel` | readWrite | int | Band-steering threshold or control used by the client roaming policy. | +| 833 | `Device.WiFi.X_RDKCENTRAL-COM_ClientRoaming.PostAssn_APcontrolTimeframe` | readWrite | unsignedInt | Band-steering threshold or control used by the client roaming policy. | +| 834 | `Device.WiFi.X_RDKCENTRAL-COM_ClientRoaming.PostAssn_BackOffTime` | readWrite | unsignedInt | Band-steering threshold or control used by the client roaming policy. | +| 835 | `Device.WiFi.X_RDKCENTRAL-COM_ClientRoaming.PostAssn_BestDeltaLevelConnected` | readWrite | unsignedInt | Band-steering threshold or control used by the client roaming policy. | +| 836 | `Device.WiFi.X_RDKCENTRAL-COM_ClientRoaming.PostAssn_BestDeltaLevelDisconnected` | readWrite | unsignedInt | Band-steering threshold or control used by the client roaming policy. | +| 837 | `Device.WiFi.X_RDKCENTRAL-COM_ClientRoaming.PostAssn_SelfSteerBeaconsMissedTime` | readWrite | unsignedInt | Band-steering threshold or control used by the client roaming policy. | +| 838 | `Device.WiFi.X_RDKCENTRAL-COM_ClientRoaming.PostAssn_SelfSteerThresholdLevel` | readWrite | int | Band-steering threshold or control used by the client roaming policy. | +| 839 | `Device.WiFi.X_RDKCENTRAL-COM_ClientRoaming.PostAssn_SelfSteerTimeframe` | readWrite | unsignedInt | Band-steering threshold or control used by the client roaming policy. | +| 840 | `Device.WiFi.X_RDKCENTRAL-COM_ClientRoaming.PreAssn_BestDeltaLevel` | readWrite | unsignedInt | Band-steering threshold or control used by the client roaming policy. | +| 841 | `Device.WiFi.X_RDKCENTRAL-COM_ClientRoaming.PreAssn_BestThresholdLevel` | readWrite | int | Band-steering threshold or control used by the client roaming policy. | +| 842 | `Device.WiFi.X_RDKCENTRAL-COM_ClientRoaming.SelfSteer_OverrideEnable` | readWrite | boolean | Band-steering threshold or control used by the client roaming policy. | +| 843 | `Device.WiFi.X_RDKCENTRAL-COM_WiFiEnable` | readWrite | boolean | Master enable for the Wi-Fi subsystem. | +| 844 | `Device.X_COMCAST-COM_Xcalibur.Client.SecuritySystem.ssDeviceId` | readOnly | string | Security system device identifier. | +| 845 | `Device.X_COMCAST-COM_Xcalibur.Client.SecuritySystem.ssDeviceReg` | readOnly | dateTime | Security system device registration time. | +| 846 | `Device.X_COMCAST-COM_Xcalibur.Client.SecuritySystem.ssErrorCnt` | readOnly | unsignedInt | Security system error count. | +| 847 | `Device.X_COMCAST-COM_Xcalibur.Client.SecuritySystem.ssRegTs` | readOnly | boolean | Indicates whether a security system registration timestamp is available. | +| 848 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.ConnectionTable.xreAppId` | readOnly | string | Application identifier for this XRE connection entry. | +| 849 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.ConnectionTable.xreConnEstTs` | readOnly | string | Connection establishment timestamp for this XRE connection entry. | +| 850 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.ConnectionTable.xreConnIfName` | readOnly | string | Interface name used by this XRE connection entry. | +| 851 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.ConnectionTable.xreConnRetryAttempts` | readOnly | unsignedInt | Retry attempts recorded for this XRE connection entry. | +| 852 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.ConnectionTable.xreConnStatus` | readOnly | string | Current status of this XRE connection entry. | +| 853 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.ConnectionTable.xreConnURL` | readOnly | string | Connection URL used by this XRE connection entry. | +| 854 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreAvgCmdProcTime` | readOnly | int | Command processing time statistic reported by XRE. | +| 855 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreChannelMapId` | readOnly | string | Channel map identifier currently used by the XRE client. | +| 856 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreCommandCnt` | readOnly | unsignedInt | Count metric reported by the XRE client. | +| 857 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreControllerId` | readOnly | string | Controller identifier reported by the XRE client. | +| 858 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreEnable` | readWrite | boolean | Enables or disables the XRE client. | +| 859 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreErrorCnt` | readOnly | unsignedInt | Count metric reported by the XRE client. | +| 860 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreFlushLocalCache` | readWrite | boolean | Triggers an XRE local cache flush when set. | +| 861 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreGatewaySTBMAC` | readOnly | string | Gateway STB MAC address reported by the XRE client. | +| 862 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreGetTWPDiags` | readOnly | string | Diagnostic payload returned by XRE TWP diagnostics. | +| 863 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreLastURLAccessed` | readOnly | string | Last URL accessed by the XRE client. | +| 864 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreLastVideoUrl` | readOnly | string | Last video URL accessed by the XRE client. | +| 865 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreLogLevel` | readWrite | string | Logging level used by the XRE client. | +| 866 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreMaxCmdProcTime` | readOnly | int | Command processing time statistic reported by XRE. | +| 867 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreMinCmdProcTime` | readOnly | int | Command processing time statistic reported by XRE. | +| 868 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xrePlantId` | readOnly | string | Plant identifier reported by the XRE client. | +| 869 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreReceiverId` | readOnly | string | Receiver identifier reported by the XRE client. | +| 870 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreRefreshXreSession` | readWrite | boolean | Triggers XRE session refresh behavior. | +| 871 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreRefreshXreSessionWithRR` | readWrite | int | Controls refresh-with-RR behavior for the XRE session. | +| 872 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreSessionId` | readOnly | string | Active XRE session identifier reported by the client. | +| 873 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreSessionLastModTs` | readOnly | string | Timestamp of the last XRE session update. | +| 874 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreSessionUptime` | readOnly | string | Uptime of the current XRE session. | +| 875 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreStatus` | readOnly | string | Configuration or status value for the XRE client. | +| 876 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreTotAnimCnt` | readOnly | unsignedInt | Count metric reported by the XRE client. | +| 877 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreTotAppCnt` | readOnly | unsignedInt | Count metric reported by the XRE client. | +| 878 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreTotFlashCnt` | readOnly | unsignedInt | Count metric reported by the XRE client. | +| 879 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreTotFontCnt` | readOnly | unsignedInt | Count metric reported by the XRE client. | +| 880 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreTotHtmlTxtCnt` | readOnly | unsignedInt | Count metric reported by the XRE client. | +| 881 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreTotImgCnt` | readOnly | unsignedInt | Count metric reported by the XRE client. | +| 882 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreTotNineSliceImgCnt` | readOnly | unsignedInt | Count metric reported by the XRE client. | +| 883 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreTotRectCnt` | readOnly | unsignedInt | Count metric reported by the XRE client. | +| 884 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreTotSoundCnt` | readOnly | unsignedInt | Count metric reported by the XRE client. | +| 885 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreTotStyleshtCnt` | readOnly | unsignedInt | Count metric reported by the XRE client. | +| 886 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreTotTxtCnt` | readOnly | unsignedInt | Count metric reported by the XRE client. | +| 887 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreTotTxtIpCnt` | readOnly | unsignedInt | Count metric reported by the XRE client. | +| 888 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreTotVideoCnt` | readOnly | unsignedInt | Count metric reported by the XRE client. | +| 889 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreTotViewCnt` | readOnly | unsignedInt | Count metric reported by the XRE client. | +| 890 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreVersion` | readOnly | string | Version string reported by the XRE client. | +| 891 | `Device.X_COMCAST-COM_Xcalibur.Client.XRE.xreVodId` | readOnly | string | VOD identifier reported by the XRE client. | +| 892 | `Device.X_COMCAST-COM_Xcalibur.Client.xconfCheckNow` | readWrite | string | Triggers an immediate Xconf check for the Xcalibur client. | +| 893 | `Device.X_COMCAST-COM_Xcalibur.DevApp.devAppNumAps` | readOnly | unsignedInt | Number of DevApp application entries reported by the platform. | +| 894 | `Device.X_COMCAST-COM_Xcalibur.DevApp.devAppTable.{i}.devAppId` | readOnly | string | Application identifier for this DevApp entry. | +| 895 | `Device.X_COMCAST-COM_Xcalibur.DevApp.devAppTable.{i}.devAppRestartCapability` | readOnly | string | Restart capability reported for this DevApp entry. | +| 896 | `Device.X_COMCAST-COM_Xcalibur.TRM.trmGatewayDeviceFriendlyName` | readOnly | string | Gateway identification value reported by TRM. | +| 897 | `Device.X_COMCAST-COM_Xcalibur.TRM.trmGatewayMoCAIP` | readOnly | string | Gateway identification value reported by TRM. | +| 898 | `Device.X_COMCAST-COM_Xcalibur.TRM.trmGatewayMoCAMAC` | readOnly | string | Gateway identification value reported by TRM. | +| 899 | `Device.X_COMCAST-COM_Xcalibur.TRM.trmGatewaySTBMAC` | readOnly | string | Gateway identification value reported by TRM. | +| 900 | `Device.X_RDKCENTRAL-COM_T2.ReportProfiles` | readWrite | string | Telemetry 2.0 report profiles payload. | +| 901 | `Device.X_RDKCENTRAL-COM_T2.ReportProfilesMsgPack` | readWrite | string | Telemetry 2.0 report profiles payload. | +| 902 | `Device.X_RDK_WebPA_DNSText.URL` | readWrite | string | Bootstrap URL used to retrieve WebPA DNS text records. | +| 903 | `Device.X_RDK_WebPA_Server.URL` | readOnly | string | Current WebPA server URL from the bootstrap store. | +| 904 | `Device.X_RDK_WebPA_TokenServer.URL` | readOnly | string | Current WebPA token server URL from the bootstrap store. | \ No newline at end of file diff --git a/src/hostif/parodusClient/docs/parodus-module-analysis.md b/src/hostif/parodusClient/docs/parodus-module-analysis.md new file mode 100644 index 000000000..9db91d144 --- /dev/null +++ b/src/hostif/parodusClient/docs/parodus-module-analysis.md @@ -0,0 +1,426 @@ +# Parodus Module Analysis + +## Overview + +`tr69hostif` currently embeds the Parodus client directly as a compiled-in subsystem. This document explains why the integration is structured the way it is today, what problems that creates operationally, and what a separation into an independent module would look like. + +--- + +## 1. Why It Is the Way It Is Today + +### 1.1 Historical Context + +Parodus is the WebPA client gateway that connects RDK devices to the cloud-side management infrastructure over a persistent WebSocket. When WebPA was introduced into the RDK ecosystem, `tr69hostif` was already the resident TR-181 parameter manager. The shortest path to expose TR-181 parameters over WebPA was to embed the Parodus client library connection directly into `tr69hostif` so it could call `hostIf_GetMsgHandler()` and `hostIf_SetMsgHandler()` without any IPC. + +### 1.2 Current Architecture + +```mermaid +flowchart TB + subgraph tr69hostif process + MAIN[hostIf_main.cpp\nMain thread + GLib loop] + PARODUS_THREAD[libpd_client_mgr thread\nPARODUS_ENABLE compile flag] + WALDB[waldb\nXML data-model validator] + PAL[PAL layer\nwebpa_adapter\nwebpa_parameter\nwebpa_attribute\nwebpa_notification] + START_PARODUS[startParodus binary\nbuilt separately\nlaunched by system] + + MAIN -->|pthread_create| PARODUS_THREAD + PARODUS_THREAD --> PAL + PAL --> WALDB + PAL -->|hostIf_GetMsgHandler\nhostIf_SetMsgHandler| MAIN + end + + subgraph External + LIBPARODUS[libparodus.so\nexternal dependency] + PARODUS_DAEMON[parodus binary\nWebSocket gateway to cloud] + CLOUD[Cloud Management\nWebPA / XMiDT] + end + + PARODUS_THREAD -->|libparodus_init\nlibparodus_receive\nlibparodus_send| LIBPARODUS + LIBPARODUS -->|ZeroMQ tcp://127.0.0.1:6666| PARODUS_DAEMON + PARDOUS_DAEMON --- CLOUD + + START_PARODUS -->|v_secure_system backgroundrun| PARODUS_DAEMON +``` + +### 1.3 Component Inventory + +| Component | Where it lives | Role | +|---|---|---| +| `libpd.cpp` | `parodusClient/pal/` | Entry point for the Parodus IPC thread. Owns `libparodus_init`, receive loop, and `sendNotification`. | +| `webpa_adapter.cpp` | `parodusClient/pal/` | WRP message router. Calls `wdmp_parse_request` and dispatches GET/SET/GETATTR/SETATTR to `webpa_parameter` and `webpa_attribute`. | +| `webpa_parameter.cpp` | `parodusClient/pal/` | Translates WDMP GET/SET into `HOSTIF_MsgData_t` and calls `hostIf_GetMsgHandler()` / `hostIf_SetMsgHandler()`. | +| `webpa_attribute.cpp` | `parodusClient/pal/` | Translates WDMP GETATTR/SETATTR into notify-flag operations via `hostIf_GetAttributesMsgHandler`. | +| `webpa_notification.cpp` | `parodusClient/pal/` | Builds notification WRP events and calls `sendNotification()`. Reads notify config from `notify_webpa_cfg.json`. | +| `waldb.cpp` | `parodusClient/waldb/` | Parses the XML data model (`/tmp/data-model.xml`) to validate parameter names and resolve wildcard paths. Linked as `libwaldb.la` into the main binary. | +| `startParodus.cpp` | `parodusClient/startParodus/` | Separate binary. Collects device identity (MAC, serial, partner ID, firmware version) and launches the `parodus` daemon via `v_secure_system`. | + +### 1.4 Thread Lifecycle + +The Parodus subsystem is spawned from `hostIf_main.cpp` behind the `PARODUS_ENABLE` compile-time flag: + +```c +// hostIf_main.cpp:482 +if(0 == pthread_create(&parodus_init_tid, NULL, libpd_client_mgr, NULL)) +``` + +Inside `libpd_client_mgr`: + +1. `checkDataModelStatus()` validates the XML data model via `waldb`. +2. `connect_parodus()` calls `pthread_detach(pthread_self())` — **the thread detaches itself** — then retries `libparodus_init()` with exponential backoff until the parodus daemon is reachable over ZeroMQ. +3. Once connected, `registerNotifyCallback()` and `setInitialNotify()` configure change notifications. +4. `parodus_receive_wait()` runs a blocking receive loop, dispatching every `WRP_MSG_TYPE__REQ` to `processRequest()`. + +Because `connect_parodus()` detaches the thread, the main thread cannot `pthread_join(parodus_init_tid)` during shutdown. Any attempt to do so causes a crash (see the `pthread_detach_crash_fix` user memory note). + +### 1.5 startParodus Coupling + +`startParodus` is a separate compiled binary but lives inside the same source tree and build system. Its job is to read device identity parameters — many of which are TR-181 parameters — and launch the `parodus` daemon with them as command-line arguments. It reads several values via `getRFCParameter()` (serial number, boot time, server URL, token server URL) and reads partner ID directly from `/opt/www/authService/partnerId3.dat`, replicating the same PartnerId resolution logic that already exists in `XBSStore`. + + +## 2. Drawbacks and Issues with the Current Design +======= +### 1.6 Startup Sequence + +Two independent activities bring the full WebPA channel online. They are not directly coordinated; `libpd_client_mgr` retries until the parodus daemon is reachable regardless of how it was launched. + +```mermaid +sequenceDiagram + participant SYS as System / systemd + participant SP as startParodus binary + participant PD as parodus daemon + participant MAIN as hostIf_main.cpp + participant LPD as libpd_client_mgr thread + participant LIBP as libparodus.so + + SYS->>SP: launch startParodus + SP->>SP: read HW MAC from /tmp/.macAddress + SP->>SP: read PartnerId from partnerId3.dat + SP->>SP: read SerialNumber / BootTime via getRFCParameter() + SP->>SP: read WebPA URL / JWT / network interface from webpa_cfg.json + SP->>PD: v_secure_system backgroundrun /usr/bin/parodus --hw-mac=... --partner-id=... + PD-->>SP: daemon launched (background) + + MAIN->>MAIN: init profile handlers, HTTP server, RFC store + MAIN->>LPD: pthread_create(libpd_client_mgr) + LPD->>LPD: checkDataModelStatus() load /tmp/data-model.xml via waldb + LPD->>LPD: connect_parodus() → pthread_detach(self) + LPD->>LPD: get_parodus_url() from /etc/webpa_cfg.json + + loop exponential backoff until parodus responds + LPD->>LIBP: libparodus_init(&cfg) + LIBP->>PD: ZeroMQ connect tcp://127.0.0.1:6666 + PD-->>LIBP: accept or reject + LIBP-->>LPD: ret == 0 (success) or error + end + + LPD->>LPD: registerNotifyCallback() + LPD->>LPD: setInitialNotify() + LPD->>LPD: write /tmp/webpa/start_time + LPD->>LPD: enter parodus_receive_wait() loop +``` + +### 1.7 Inbound WRP Request Flow (Cloud GET / SET) + +This is the complete path from a cloud-originated WebPA GET or SET request to the TR-181 profile handler and back to the cloud. + +```mermaid +sequenceDiagram + participant CLOUD as Cloud / XMiDT + participant PD as parodus daemon + participant LIBP as libparodus.so + participant RW as parodus_receive_wait() + participant WA as webpa_adapter processRequest() + participant WP as webpa_parameter getValues / setValues + participant WALDB as waldb checkDataModelStatus + participant MSG as hostIf_GetMsgHandler / hostIf_SetMsgHandler + participant PROF as TR-181 Profile Handler + + CLOUD->>PD: WebSocket WRP REQ (GET or SET) + PD->>LIBP: deliver via ZeroMQ + LIBP-->>RW: libparodus_receive() returns wrp_msg + + RW->>WA: processRequest(payload, transaction_uuid) + WA->>WA: wdmp_parse_request() parse WDMP JSON + + alt GET request + WA->>WP: getValues(paramNames, count) + WP->>WALDB: checkDataModelStatus / wildcard expand + WALDB-->>WP: validated param list + WP->>MSG: hostIf_GetMsgHandler(HOSTIF_MsgData_t) + MSG->>PROF: profile handler get() + PROF-->>MSG: value in paramValue + MSG-->>WP: return OK / NOK + WP-->>WA: param_t array + else SET request + WA->>WP: setValues(paramVal, count) + WP->>MSG: hostIf_SetMsgHandler(HOSTIF_MsgData_t) with requestor=HOSTIF_SRC_WEBPA + MSG->>PROF: profile handler set() + PROF-->>MSG: faultCode + MSG-->>WP: return OK / NOK + WP-->>WA: WDMP_STATUS + end + + WA->>WA: wdmp_form_response() build JSON response + WA-->>RW: resPayload string + RW->>LIBP: libparodus_send(res_wrp_msg) + LIBP->>PD: ZeroMQ reply + PD->>CLOUD: WebSocket WRP response +``` + +**Key timing note:** `processRequest()` runs synchronously on the same thread as the receive loop. While `hostIf_GetMsgHandler()` is executing, no further WRP messages can be received from the parodus daemon. HAL calls inside profile handlers can take 100–500 ms on some device platforms, which causes visible WebPA latency. + +### 1.8 Notification Push Flow (Parameter Change to Cloud) + +When a TR-181 parameter that has been marked for WebPA notification changes, the change is pushed proactively to the cloud without waiting for a GET from the cloud. + +```mermaid +sequenceDiagram + participant PROF as TR-181 Profile Handler + participant NH as NotificationHandler + participant WN as webpa_notification.cpp + participant LPD as libpd.cpp sendNotification() + participant LIBP as libparodus.so + participant PD as parodus daemon + participant CLOUD as Cloud / XMiDT + + PROF->>NH: notifyCallback() on param change + NH->>WN: build notification JSON payload + WN->>WN: getNotifySource() → mac:device_mac + WN->>LPD: sendNotification(payload, source, destination) + + LPD->>LPD: build WRP_MSG_TYPE__EVENT struct + loop retry up to 3 times with exponential backoff + LPD->>LIBP: libparodus_send(notif_wrp_msg) + LIBP->>PD: ZeroMQ event message + PD-->>LIBP: send status + LIBP-->>LPD: sendStatus == 0 (success) or error + end + + PD->>CLOUD: WebSocket WRP EVENT push +``` + +Initial notification state is configured at startup by `setInitialNotify()`, which reads `notify_webpa_cfg.json` (checked from `/opt/` first, falling back to `/etc/`) to determine which parameters should have notifications enabled on connect. + +### 1.9 Threading Model + +#### Thread Inventory + +| Thread | Created by | Entry point | Detached? | Purpose | +|---|---|---|---|---| +| Main (GLib loop) | OS | `hostIf_main::main()` | No | Init, signal handling, profile router | +| Parodus IPC | `pthread_create` in `hostIf_main` | `libpd_client_mgr()` | Yes (self-detaches in `connect_parodus`) | libparodus connect, receive loop, notification send | + +#### Synchronization Primitives Used by the Parodus Subsystem + +| Primitive | Declared in | Purpose | +|---|---|---| +| `pthread_cond_t parodus_cond` | `libpd.cpp` (global) | Wakes the receive loop retry wait when `stop_parodus_recv_wait()` is called | +| `pthread_mutex_t parodus_lock` | `libpd.cpp` (global) | Guards `parodus_cond` during `pthread_cond_timedwait` in the error retry path | +| `std::mutex g_db_mutex` | `waldb.cpp` | Serializes access to the XML data model handle during `loadDataModel()` | + +#### Thread State Diagram + +```mermaid +stateDiagram-v2 + [*] --> Created : pthread_create in hostIf_main + Created --> DataModelLoad : libpd_client_mgr entry + DataModelLoad --> DataModelFail : checkDataModelStatus != 0 + DataModelFail --> [*] : return NULL + DataModelLoad --> Connecting : checkDataModelStatus == 0 + Connecting --> Connecting : libparodus_init failed → sleep backoff + Connecting --> Detached : pthread_detach(self) called inside connect_parodus + Detached --> Connected : libparodus_init ret == 0 + Connected --> ReceiveLoop : parodus_receive_wait entered + ReceiveLoop --> ReceiveLoop : receive and dispatch WRP messages + ReceiveLoop --> ErrorRetry : libparodus_receive returned non-zero + ErrorRetry --> ReceiveLoop : pthread_cond_timedwait timeout or signal + ReceiveLoop --> Shutdown : exit_parodus_recv == true + Shutdown --> [*] : libparodus_close_receiver + libparodus_shutdown +``` + +**Note on the Detached state:** once `connect_parodus()` calls `pthread_detach(pthread_self())`, the thread handle `parodus_init_tid` in `hostIf_main.cpp` becomes invalid for any join operation. The thread will run until `exit_parodus_recv` is set true via `stop_parodus_recv_wait()`. + +--- + +### 2.1 Thread Detachment Causes Crash-Risk on Shutdown + +`connect_parodus()` calls `pthread_detach(pthread_self())` at the start of its retry loop. The thread is therefore detached for its entire lifetime. The `parodus_init_tid` handle stored in `hostIf_main.cpp` is invalid for joining after that point. Any future refactor that adds `pthread_join(parodus_init_tid, NULL)` to the shutdown path will crash in `__pthread_clockjoin_ex`. + +### 2.2 Blocking Receive Loop Holds an Entire Thread Permanently + +`parodus_receive_wait()` is a `while(1)` loop that calls `libparodus_receive(libparodus_instance, &wrp_msg, 2000)`. If the parodus daemon becomes unreachable (network failure, daemon restart), the loop falls into a 5-second `pthread_cond_timedwait` retry cycle. The thread never exits cleanly and never participates in structured shutdown. + +The exit flag `exit_parodus_recv` is set by `stop_parodus_recv_wait()`, but that function is only called during normal daemon shutdown. If the receive call itself hangs (latent ZeroMQ socket behavior), the flag check is never reached. + +### 2.3 processRequest Is Synchronous and Blocks the Receive Thread + +`processRequest()` is called directly from the receive loop on the same Parodus thread. It calls through `webpa_parameter.cpp` → `hostIf_GetMsgHandler()` → concrete profile handlers, some of which make HAL calls that can take hundreds of milliseconds. During that time, no new WRP messages can be received. A slow HAL or a hung IARM call causes the entire WebPA channel to back up. + +### 2.4 waldb Is Linked Into the Main Binary + +`libwaldb.la` is linked directly into `tr69hostif`. This means the XML data-model XML is loaded into the same process address space and parsed at startup. The data model XML is large; loading it costs RSS memory even when the Parodus channel is not in use. If Parodus is not needed on a platform, the memory is still consumed because the library is unconditionally linked (even if `PARODUS_ENABLE` guards the thread creation, the library symbols are always resolved). + +### 2.5 Duplicate PartnerId Resolution in startParodus + +`startParodus.cpp` re-implements PartnerId reading from `/opt/www/authService/partnerId3.dat` and falls back to `getRFCParameter()` for `Device.DeviceInfo.X_RDKCENTRAL-COM_Syndication.PartnerId`. This duplicates the same logic that already exists in `Device_DeviceInfo.cpp::get_PartnerId_From_Script()` and `XBSStore`. There are now three independent code paths that each read PartnerId independently, each with their own fallback handling and file-open retry logic. + +### 2.6 Configuration Is Fragmented Across Multiple Files + +The Parodus subsystem reads configuration from at least four separate sources: + +| Parameter | Source | +|---|---| +| Parodus ZeroMQ URL | `/etc/webpa_cfg.json` or `/opt/webpa_cfg.json` | +| Client ZeroMQ URL | `/etc/webpa_cfg.json` or `/opt/webpa_cfg.json` | +| WebPA server IP | `getRFCParameter("Device.X_RDK_WebPA_Server.URL")` | +| Notification config | `/etc/notify_webpa_cfg.json` or `/opt/notify_webpa_cfg.json` | +| JWT key path | Hardcoded `/etc/ssl/certs/webpa-rs256.pem` | +| CRUD config | Hardcoded `/opt/secure/parodus_cfg.json` | +| Partner ID | File → RFC parameter fallback (duplicated) | + +There is no single configuration object that a test or integration environment can substitute cleanly. + +### 2.7 No Independent Testability + +Because the PAL layer calls `hostIf_GetMsgHandler()` / `hostIf_SetMsgHandler()` directly (function calls into the same process), it is impossible to unit-test the Parodus request dispatch path without bringing up the full `tr69hostif` subsystem. The unit tests in `parodusClient/gtest/` stub out waldb and the IPC layer but cannot test a real parameter GET through the Parodus path without the entire profile manager being initialized. + +### 2.8 Build Flag Inconsistency + +Some platform builds define `PARODUS_ENABLE` to include the receive thread but do not define `WEB_CONFIG_ENABLED` or `WEBCONFIG_LITE_ENABLE`, leaving the startParodus binary unused but still compiled. The compile-time flag guards only the thread creation, not the library linkage, which means object files and their static data are always included. + +--- + +## 3. Potential Solution: Separating Parodus as an Independent Module + +### 3.1 Target Architecture + +The core idea is to decouple the Parodus client from the `tr69hostif` process entirely. Instead of calling `hostIf_GetMsgHandler()` directly, the Parodus module communicates with `tr69hostif` through the existing RBUS or HTTP server interface. + +```mermaid +flowchart TB + subgraph tr69hostif process + MAIN[hostIf_main\nTR-181 parameter store] + RBUS[RBUS provider\nor HTTP server] + MAIN --> RBUS + end + + subgraph parodus-client process NEW + PARODUSMGR[Parodus client manager] + WALDB_STANDALONE[waldb\nstandalone library] + PAL_STANDALONE[PAL layer\nwebpa_adapter\nwebpa_parameter\nwebpa_attribute] + START_P[startParodus\ndevice identity collector] + + PARODUSMGR --> PAL_STANDALONE + PAL_STANDALONE --> WALDB_STANDALONE + START_P --> PARODUSMGR + end + + subgraph External + LIBPARODUS[libparodus.so] + PARODUS_DAEMON[parodus binary] + CLOUD[Cloud Management] + end + + PAL_STANDALONE -->|RBUS get/set\nor HTTP REST| RBUS + PARODUSMGR -->|libparodus IPC| LIBPARODUS + LIBPARODUS -->|ZeroMQ| PARODUS_DAEMON + PARODUS_DAEMON --- CLOUD +``` + +### 3.2 What Changes + +**Replace direct function calls with IPC:** + +`webpa_parameter.cpp` currently calls `hostIf_GetMsgHandler()` and `hostIf_SetMsgHandler()` directly. In the separated design, those calls are replaced with RBUS `rbusValue_Get` / `rbusValue_Set` calls, or with HTTP REST calls to `tr69hostif`'s HTTP server. The PAL layer becomes protocol-agnostic. + +**Move waldb out of tr69hostif linkage:** + +`libwaldb.la` should be a dependency of the parodus-client process only. It is removed from `tr69hostif_LDADD`. This reduces the resident memory of `tr69hostif` on platforms that do not use WebPA. + +**Consolidate PartnerId reading:** + +`startParodus.cpp` should query PartnerId via a single TR-181 GET (`Device.DeviceInfo.X_RDKCENTRAL-COM_Syndication.PartnerId`) through the IPC interface instead of reading the file directly. `tr69hostif` already owns the canonical resolution path. + +**Give the thread a clean shutdown path:** + +Remove `pthread_detach(pthread_self())` from `connect_parodus()`. The calling context — now the parodus-client process's own `main()` — can manage the thread lifecycle and call `pthread_join` cleanly. + +**Unify configuration loading:** + +All Parodus configuration is consolidated into a single structure loaded from `/etc/parodus_client.json` (or the existing `webpa_cfg.json` extended with the missing keys). No more fragmented reads across four files. + +### 3.3 Interface Contract + +The separated parodus-client module needs two capabilities from `tr69hostif`: + +| Need | Provided by | +|---|---| +| GET any TR-181 parameter | RBUS `rbusValue_Get` or HTTP GET `/tr181?param=...` | +| SET any TR-181 parameter | RBUS `rbusValue_Set` or HTTP POST `/tr181` | +| Change notifications (push to cloud) | RBUS event subscription or `tr69hostif` notification callback | + +No startup ordering dependency is required: the parodus-client retries until `tr69hostif` is reachable, which is the same behavior `connect_parodus()` already implements for the parodus daemon. + +### 3.4 Transition Path + +A clean incremental migration is possible without rewriting everything at once: + +1. **Phase 1 — Isolate the PAL layer from tr69hostif linkage.** Introduce an abstract `IParamAccessor` interface in `webpa_parameter.cpp`. The current implementation calls `hostIf_GetMsgHandler()` directly. Compile-time injection (or link-time injection) can swap in an RBUS or HTTP implementation without changing the PAL API. Unit tests can use a mock implementation. + +2. **Phase 2 — Remove waldb from tr69hostif link dependencies.** Move `libwaldb.la` out of `tr69hostif_LDADD`. Update the waldb `Makefile.am` to produce a shared or static library installable independently. + +3. **Phase 3 — Split the startParodus binary into its own deliverable.** Give it its own `configure.ac` or package. The binary reads device identity from `tr69hostif` via RBUS at startup rather than duplicating file reads. + +4. **Phase 4 — Move the parodus thread into the standalone process.** The thread entry point `libpd_client_mgr` becomes `main()`. The `PARODUS_ENABLE` guard in `hostIf_main.cpp` is removed entirely. + + +### 3.5 Target Startup Sequence After Separation + +```mermaid +sequenceDiagram + participant SYS as systemd + participant TR69 as tr69hostif process + participant PCC as parodus-client process + participant PD as parodus daemon + participant CLOUD as Cloud / XMiDT + + SYS->>TR69: start (existing service) + TR69->>TR69: init profile handlers, RFC store, RBUS provider + TR69-->>SYS: READY (sd_notify) + + SYS->>PCC: start parodus-client service (new) + PCC->>PCC: read device identity via RBUS from tr69hostif + PCC->>PD: launch parodus daemon with collected args + PCC->>PCC: libparodus_init retry loop + PD-->>PCC: ZeroMQ ready + + PCC->>PCC: enter receive loop + CLOUD->>PD: WebSocket WRP REQ + PD->>PCC: ZeroMQ deliver + PCC->>TR69: RBUS get/set TR-181 parameter + TR69-->>PCC: value or fault + PCC->>PD: ZeroMQ reply + PD->>CLOUD: WebSocket WRP response +``` + +### 3.6 Benefits of Separation + +| Concern | Current | After Separation | +|---|---|---| +| Memory footprint of tr69hostif | waldb + PAL always linked | Only TR-181 profile code | +| Parodus crash impact | Crash in parodus thread crashes tr69hostif (same process) | Isolated; tr69hostif continues | +| Independent restartability | Impossible; requires full tr69hostif restart | parodus-client can restart independently | +| Unit testability | Requires full tr69hostif profile manager | PAL layer testable with mock IParamAccessor | +| PartnerId reading | Three independent implementations | Single source: tr69hostif TR-181 parameter | +| Thread shutdown | Detached; join not possible | Joinable; clean shutdown | +| Build reduction for non-WebPA platforms | PAL object files always compiled | Separate package; omit from build entirely | + +--- + +## See Also + +- [System Overview](overview.md) +- [Threading Model](threading-model.md) +- [Data Flow](data-flow.md) +- [Partner Defaults Workflow](partner-defaults-workflow.md) +- [Public API](../api/public-api.md) diff --git a/src/unittest/stubs/dsAudioSettings.h b/src/unittest/stubs/dsAudioSettings.h new file mode 100644 index 000000000..99403fd2e --- /dev/null +++ b/src/unittest/stubs/dsAudioSettings.h @@ -0,0 +1,65 @@ +/* + * dsAudioSettings.h — Native-build stub for tr69hostif L2/coverage builds. + * + * Mainline devicesettings rpc/srv/dsAudioConfig.c includes dsAudioSettings.h and + * uses the kConfigs / kPorts tables defined here. If dsAudioConfig.h (or another + * header) sets the _DS_AUDIOOUTPUTPORTSETTINGS_H guard before the real rdkvhal + * header is reached, kConfigs and kPorts become invisible. Copying this file over + * the cloned rdkvhal-devicesettings-raspberrypi4/dsAudioSettings.h guarantees the + * tables are always present regardless of include order. + * + * Content mirrors rdkvhal-devicesettings-raspberrypi4/dsAudioSettings.h (main branch). + * Type definitions (dsAudioTypeConfig_t, dsAudioPortConfig_t, etc.) come from + * rdk-halif-device_settings/include/dsAVDTypes.h via dsTypes.h / dsUtl.h. + */ +#ifndef _DS_AUDIOOUTPUTPORTSETTINGS_H +#define _DS_AUDIOOUTPUTPORTSETTINGS_H + +#include "dsUtl.h" +#include "dsAVDTypes.h" + +/* Supported configurations for a single HDMI audio port */ +static const dsAudioPortType_t kSupportedPortTypes[] = { + dsAUDIOPORT_TYPE_HDMI +}; + +static const dsAudioEncoding_t kSupportedHDMIEncodings[] = { + dsAUDIO_ENC_PCM, dsAUDIO_ENC_AC3 +}; + +static const dsAudioCompression_t kSupportedHDMICompressions[] = { + dsAUDIO_CMP_NONE, dsAUDIO_CMP_LIGHT, dsAUDIO_CMP_MEDIUM, dsAUDIO_CMP_HEAVY, +}; + +static const dsAudioStereoMode_t kSupportedHDMIStereoModes[] = { + dsAUDIO_STEREO_STEREO, dsAUDIO_STEREO_SURROUND, +}; + +static const dsAudioTypeConfig_t kConfigs[] = { + { + /* .typeId = */ dsAUDIOPORT_TYPE_HDMI, + /* .name = */ "HDMI", + /* .numSupportedCompressions = */ dsUTL_DIM(kSupportedHDMICompressions), + /* .compressions = */ kSupportedHDMICompressions, + /* .numSupportedEncodings = */ dsUTL_DIM(kSupportedHDMIEncodings), + /* .encodings = */ kSupportedHDMIEncodings, + /* .numSupportedStereoModes = */ dsUTL_DIM(kSupportedHDMIStereoModes), + /* .stereoModes = */ kSupportedHDMIStereoModes, + } +}; + +static const dsVideoPortPortId_t connectedVOPs[dsAUDIOPORT_TYPE_MAX][dsVIDEOPORT_TYPE_MAX] = { + { /* VOPs connected to LR Audio — none */ }, + { /* VOPs connected to HDMI Audio */ + { dsVIDEOPORT_TYPE_HDMI, 0 }, + } +}; + +static const dsAudioPortConfig_t kPorts[] = { + { + /* .id = */ { dsAUDIOPORT_TYPE_HDMI, 0 }, + /* .connectedVOPs =*/ connectedVOPs[dsAUDIOPORT_TYPE_HDMI], + } +}; + +#endif /* _DS_AUDIOOUTPUTPORTSETTINGS_H */ diff --git a/src/unittest/stubs/dsVideoDeviceSettings.h b/src/unittest/stubs/dsVideoDeviceSettings.h new file mode 100644 index 000000000..d09742f82 --- /dev/null +++ b/src/unittest/stubs/dsVideoDeviceSettings.h @@ -0,0 +1,38 @@ +/* + * dsVideoDeviceSettings.h — Native-build stub for tr69hostif L2/coverage builds. + * + * The rdkvhal-devicesettings-raspberrypi4 version wraps kConfigs inside + * an anonymous namespace {} placed inside extern "C" {}. GCC does not + * handle this combination correctly when the .c translation unit is compiled + * as C, causing 'kConfigs' was not declared in this scope at the call site + * in dsVideoDeviceConfig.c. cov_build.sh copies this stub over the cloned + * rdkvhal copy so the tables are always visible at file scope. + * + * Content mirrors rdkvhal-devicesettings-raspberrypi4/dsVideoDeviceSettings.h + * (main branch) without the anonymous namespace. + */ +#ifndef _DS_VIDEODEVICESETTINGS_H_ +#define _DS_VIDEODEVICESETTINGS_H_ + +#include "dsUtl.h" +#include "dsVideoDeviceTypes.h" + +static const dsVideoZoom_t kSupportedDFCs[] = { + dsVIDEO_ZOOM_NONE, + dsVIDEO_ZOOM_FULL, + dsVIDEO_ZOOM_PLATFORM, +}; + +static const dsVideoZoom_t kDefaultDFC = dsVIDEO_ZOOM_FULL; + +static const int kNumVideoDevices = 1; + +static const dsVideoConfig_t kConfigs[] = { + { + /* .numSupportedDFCs = */ dsUTL_DIM(kSupportedDFCs), + /* .supportedDFCs = */ kSupportedDFCs, + /* .defaultDFC = */ dsVIDEO_ZOOM_FULL, + }, +}; + +#endif /* _DS_VIDEODEVICESETTINGS_H_ */ diff --git a/src/unittest/stubs/dsVideoPortSettings.h b/src/unittest/stubs/dsVideoPortSettings.h new file mode 100644 index 000000000..6009eb8ac --- /dev/null +++ b/src/unittest/stubs/dsVideoPortSettings.h @@ -0,0 +1,46 @@ +/* + * dsVideoPortSettings.h — Native-build stub for tr69hostif L2/coverage builds. + * + * Same guard-collision pattern as dsAudioSettings.h / dsVideoResolutionSettings.h: + * if any transitively-included header sets _DS_VIDEOOUTPUTPORTSETTINGS_H_ before + * the rdkvhal-devicesettings-raspberrypi4 version is reached, kConfigs and kPorts + * become undeclared in dsVideoPortConfig.c. cov_build.sh copies this file over + * the cloned rdkvhal copy to guarantee the tables are always defined. + * + * Content mirrors rdkvhal-devicesettings-raspberrypi4/dsVideoPortSettings.h (main branch). + */ +#ifndef _DS_VIDEOOUTPUTPORTSETTINGS_H_ +#define _DS_VIDEOOUTPUTPORTSETTINGS_H_ + +#include "dsAVDTypes.h" +#include "dsUtl.h" +#include "dsVideoResolutionSettings.h" + +static const dsVideoPortType_t kSupportedPortTypes[] = { + dsVIDEOPORT_TYPE_HDMI +}; + +static const dsVideoPortTypeConfig_t kConfigs[] = { + { + /* .typeId = */ dsVIDEOPORT_TYPE_HDMI, + /* .name = */ "HDMI", + /* .dtcpSupported = */ false, + /* .hdcpSupported = */ false, + /* .restrictedResolution = */ -1, + /* .numSupportedResolutions = */ dsUTL_DIM(kResolutions), + /* .supportedResolutions = */ kResolutions, + }, +}; + +static const dsVideoPortPortConfig_t kPorts[] = { + { + /* .id = */ { dsVIDEOPORT_TYPE_HDMI, 0 }, + /* .connectedAOP = */ { dsAUDIOPORT_TYPE_HDMI, 0 }, + /* .defaultResolution = */ "720p60", + }, +}; + +/* Index into kResolutions[] for the default resolution ("720p60" == index 5). */ +static const int kDefaultResIndex = 5; + +#endif /* _DS_VIDEOOUTPUTPORTSETTINGS_H_ */ diff --git a/src/unittest/stubs/dsVideoResolutionSettings.h b/src/unittest/stubs/dsVideoResolutionSettings.h new file mode 100644 index 000000000..fc1aa5edb --- /dev/null +++ b/src/unittest/stubs/dsVideoResolutionSettings.h @@ -0,0 +1,48 @@ +/* + * dsVideoResolutionSettings.h — Native-build stub for tr69hostif L2/coverage builds. + * + * In mainline rdk-halif-device_settings the kResolutions table was moved to + * platform-specific HAL implementation files and is no longer exported through + * this header. This stub provides the array so that Components_HDMI.cpp compiles + * when building natively for test/coverage purposes without real hardware. + * + * The entry layout matches dsVideoPortResolution_t as defined in dsAVDTypes.h: + * char name[32], dsVideoResolution_t pixelResolution, dsVideoAspectRatio_t aspectRatio, + * dsVideoStereoScopicMode_t stereoScopicMode, dsVideoFrameRate_t frameRate, bool interlaced + */ +#ifndef _DS_VIDEO_RESOLUTION_SETTINGS_H_ +#define _DS_VIDEO_RESOLUTION_SETTINGS_H_ + +#include "dsAVDTypes.h" + +/* Scan-mode convenience macros used by both kResolutions[] entries and + * devicesettings ds/ C++ sources (e.g. videoOutputPortConfig.cpp). */ +#ifndef _PROGRESSIVE +#define _PROGRESSIVE false +#endif +#ifndef _INTERLACED +#define _INTERLACED true +#endif + +static dsVideoPortResolution_t kResolutions[] = { + /* name pixelResolution aspectRatio stereoScopicMode frameRate interlaced */ + {"480i60", dsVIDEO_PIXELRES_720x480, dsVIDEO_ASPECT_RATIO_4x3, dsVIDEO_SSMODE_2D, dsVIDEO_FRAMERATE_60, true }, + {"480p60", dsVIDEO_PIXELRES_720x480, dsVIDEO_ASPECT_RATIO_4x3, dsVIDEO_SSMODE_2D, dsVIDEO_FRAMERATE_60, false }, + {"576i50", dsVIDEO_PIXELRES_720x576, dsVIDEO_ASPECT_RATIO_4x3, dsVIDEO_SSMODE_2D, dsVIDEO_FRAMERATE_50, true }, + {"576p50", dsVIDEO_PIXELRES_720x576, dsVIDEO_ASPECT_RATIO_4x3, dsVIDEO_SSMODE_2D, dsVIDEO_FRAMERATE_50, false }, + {"720p50", dsVIDEO_PIXELRES_1280x720, dsVIDEO_ASPECT_RATIO_16x9, dsVIDEO_SSMODE_2D, dsVIDEO_FRAMERATE_50, false }, + {"720p60", dsVIDEO_PIXELRES_1280x720, dsVIDEO_ASPECT_RATIO_16x9, dsVIDEO_SSMODE_2D, dsVIDEO_FRAMERATE_60, false }, + {"1080i50", dsVIDEO_PIXELRES_1920x1080,dsVIDEO_ASPECT_RATIO_16x9, dsVIDEO_SSMODE_2D, dsVIDEO_FRAMERATE_50, true }, + {"1080i60", dsVIDEO_PIXELRES_1920x1080,dsVIDEO_ASPECT_RATIO_16x9, dsVIDEO_SSMODE_2D, dsVIDEO_FRAMERATE_60, true }, + {"1080p24", dsVIDEO_PIXELRES_1920x1080,dsVIDEO_ASPECT_RATIO_16x9, dsVIDEO_SSMODE_2D, dsVIDEO_FRAMERATE_24, false }, + {"1080p25", dsVIDEO_PIXELRES_1920x1080,dsVIDEO_ASPECT_RATIO_16x9, dsVIDEO_SSMODE_2D, dsVIDEO_FRAMERATE_25, false }, + {"1080p30", dsVIDEO_PIXELRES_1920x1080,dsVIDEO_ASPECT_RATIO_16x9, dsVIDEO_SSMODE_2D, dsVIDEO_FRAMERATE_30, false }, + {"1080p50", dsVIDEO_PIXELRES_1920x1080,dsVIDEO_ASPECT_RATIO_16x9, dsVIDEO_SSMODE_2D, dsVIDEO_FRAMERATE_50, false }, + {"1080p60", dsVIDEO_PIXELRES_1920x1080,dsVIDEO_ASPECT_RATIO_16x9, dsVIDEO_SSMODE_2D, dsVIDEO_FRAMERATE_60, false }, + {"2160p24", dsVIDEO_PIXELRES_3840x2160,dsVIDEO_ASPECT_RATIO_16x9, dsVIDEO_SSMODE_2D, dsVIDEO_FRAMERATE_24, false }, + {"2160p30", dsVIDEO_PIXELRES_3840x2160,dsVIDEO_ASPECT_RATIO_16x9, dsVIDEO_SSMODE_2D, dsVIDEO_FRAMERATE_30, false }, + {"2160p50", dsVIDEO_PIXELRES_3840x2160,dsVIDEO_ASPECT_RATIO_16x9, dsVIDEO_SSMODE_2D, dsVIDEO_FRAMERATE_50, false }, + {"2160p60", dsVIDEO_PIXELRES_3840x2160,dsVIDEO_ASPECT_RATIO_16x9, dsVIDEO_SSMODE_2D, dsVIDEO_FRAMERATE_60, false }, +}; + +#endif /* _DS_VIDEO_RESOLUTION_SETTINGS_H_ */ diff --git a/src/unittest/stubs/rfcapi.h b/src/unittest/stubs/rfcapi.h index b46c45c41..9671d3b57 100644 --- a/src/unittest/stubs/rfcapi.h +++ b/src/unittest/stubs/rfcapi.h @@ -22,7 +22,6 @@ #include #include -#include "Device_DeviceInfo.h" #define RFCVAR_FILE "/opt/secure/RFC/rfcVariable.ini" #define TR181STORE_FILE "/opt/secure/RFC/tr181store.ini" diff --git a/src/unittest/stubs/telemetry_busmessage_sender.h b/src/unittest/stubs/telemetry_busmessage_sender.h new file mode 100644 index 000000000..7e86d05d0 --- /dev/null +++ b/src/unittest/stubs/telemetry_busmessage_sender.h @@ -0,0 +1,24 @@ +/* + * telemetry_busmessage_sender.h — Native-build stub for tr69hostif L2/coverage builds. + * + * The real header is part of the telemetry2 component which is not built in the + * native/container test environment. All APIs are stubbed as no-ops so that + * devicesettings rpc/srv compiles without a telemetry2 install. + */ +#ifndef _TELEMETRY_BUSMESSAGE_SENDER_H_ +#define _TELEMETRY_BUSMESSAGE_SENDER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +static inline int t2_init(const char *component) { (void)component; return 0; } +static inline int t2_event_s(const char *marker, const char *value) { (void)marker; (void)value; return 0; } +static inline int t2_event_d(const char *marker, double value) { (void)marker; (void)value; return 0; } +static inline int t2_event_f(const char *marker, double value) { (void)marker; (void)value; return 0; } + +#ifdef __cplusplus +} +#endif + +#endif /* _TELEMETRY_BUSMESSAGE_SENDER_H_ */ diff --git a/src/unittest/stubs/telemetry_msgsender_stub.c b/src/unittest/stubs/telemetry_msgsender_stub.c new file mode 100644 index 000000000..4d80954cd --- /dev/null +++ b/src/unittest/stubs/telemetry_msgsender_stub.c @@ -0,0 +1,16 @@ +/* + * telemetry_msgsender_stub.c — Stub shared library for tr69hostif L2/coverage builds. + * + * devicesettings rpc/srv links against -ltelemetry_msgsender (hardcoded in + * libdshalsrv_la_LIBADD). The real library belongs to the telemetry2 component + * which is not present in the native/container build environment. + * + * All functions are no-ops that satisfy the linker without pulling in telemetry2. + * Because the header declares these as static inline, every TU already has inline + * copies; these exported symbols are only needed for the shared-library link step. + */ + +int t2_init(const char *component) { (void)component; return 0; } +int t2_event_s(const char *marker, const char *value) { (void)marker; (void)value; return 0; } +int t2_event_d(const char *marker, double value) { (void)marker; (void)value; return 0; } +int t2_event_f(const char *marker, double value) { (void)marker; (void)value; return 0; } From 885b056711b86cbca3ac458dfd0b824d39f228c8 Mon Sep 17 00:00:00 2001 From: madhubabutt <114217841+madhubabutt@users.noreply.github.com> Date: Fri, 1 May 2026 19:22:17 +0530 Subject: [PATCH 2/2] RDK-60108 Refactor and Hardening of Thunder Plugin Interaction for tr69hostif Module (#446) Co-authored-by: mtirum011 Co-authored-by: nhanasi --- docs/api/thunder-plugin-interfaces.md | 37 +- run_l2.sh | 1 - src/hostif/docs/README.md | 3 +- src/hostif/include/hostIf_utils.h | 113 +++- .../profiles/DeviceInfo/Device_DeviceInfo.cpp | 479 +++------------ src/hostif/profiles/wifi/Device_WiFi.cpp | 97 +-- .../profiles/wifi/Device_WiFi_EndPoint.cpp | 207 +++---- .../profiles/wifi/Device_WiFi_EndPoint.h | 2 +- .../wifi/Device_WiFi_EndPoint_Security.cpp | 56 +- src/hostif/profiles/wifi/Device_WiFi_SSID.cpp | 409 ++++++------- src/hostif/profiles/wifi/Device_WiFi_SSID.h | 26 +- src/hostif/src/gtest/gtest_src.cpp | 174 +++++- src/hostif/src/hostIf_utils.cpp | 565 ++++++++++++++++-- 13 files changed, 1207 insertions(+), 962 deletions(-) diff --git a/docs/api/thunder-plugin-interfaces.md b/docs/api/thunder-plugin-interfaces.md index 7768605bb..c84d1669b 100644 --- a/docs/api/thunder-plugin-interfaces.md +++ b/docs/api/thunder-plugin-interfaces.md @@ -34,16 +34,14 @@ walks the response tree, validates result fields, and maps those fields into `HO flowchart TD A[TR-181 GET or SET handler] --> B[Build JSON-RPC request string inline] B --> C[getJsonRPCData in hostIf_utils.cpp] - C --> D[get_security_token] - D --> E[WPEFrameworkSecurityUtility] - C --> F[libcurl POST to /jsonrpc] - F --> G[Thunder plugin org.rdk.*] - G --> H[Raw JSON response string] - H --> I[cJSON_Parse inside handler] - I --> J[result lookup] - J --> K[field lookup and type checks] - K --> L[Convert to TR-181 output type] - L --> M[Populate HOSTIF_MsgData_t] + C --> D[libcurl POST to /jsonrpc] + D --> E[Thunder plugin org.rdk.*] + E --> F[Raw JSON response string] + F --> G[cJSON_Parse inside handler] + G --> H[result lookup] + H --> I[field lookup and type checks] + I --> J[Convert to TR-181 output type] + J --> K[Populate HOSTIF_MsgData_t] I -. duplicated across handlers .-> N[Repeated parse/validation code] K -. inconsistent checks .-> N @@ -74,7 +72,7 @@ not the transport alone, but the handler-local parsing contract. Key observations from the current implementation: -- `getJsonRPCData()` already centralizes token retrieval, headers, timeout setup, and `curl_easy_perform()`. +- `getJsonRPCData()` centralizes the HTTP transport setup (JSON content type header, timeouts, `curl_easy_perform()`), but does not add an `Authorization` header. - The current curl write callback is also part of the transport contract and should be normalized during the refactor, so the common helper owns response buffering with the expected libcurl callback shape. - Response parsing is duplicated per handler, so fixes to JSON validation have to be repeated in many files. - Some handlers use weak response checks such as `if(response.c_str())`, which is always non-null for a `std::string`; the real intent should be an emptiness check. @@ -100,7 +98,7 @@ flowchart TD A[TR-181 handler] --> B[Common Thunder helper API] B --> C[Build request object] C --> D[getJsonRPCData or successor transport helper] - D --> E[libcurl + token + timeouts] + D --> E[libcurl + Content-Type + timeouts] E --> F[Thunder JSON-RPC endpoint] F --> G[Raw response] G --> H[Central cJSON_Parse] @@ -159,14 +157,13 @@ All calls follow JSON-RPC 2.0: ### Authentication -Every request carries a Bearer token in the `Authorization` header: +Current implementation sends only the JSON content type header: ``` -Authorization: Bearer Content-Type: application/json ``` -The token is fetched at call time via `get_security_token()` (same file). +`getJsonRPCData()` currently does not fetch or attach a Bearer token. ### Core Helper Function @@ -177,10 +174,9 @@ string getJsonRPCData(std::string postData); **Behaviour:** -1. Calls `get_security_token()` and builds the Authorization header. -2. Initialises a `CURL` handle via `curl_easy_init()`. -3. Sets `CURLOPT_POST`, `CURLOPT_POSTFIELDS`, `CURLOPT_HTTPHEADER`, - `CURLOPT_WRITEFUNCTION` / `CURLOPT_WRITEDATA`. +1. Initialises a `CURL` handle via `curl_easy_init()`. +2. Appends `Content-Type: application/json` and sets `CURLOPT_HTTPHEADER`. +3. Sets `CURLOPT_POST`, `CURLOPT_POSTFIELDS`, `CURLOPT_WRITEFUNCTION` / `CURLOPT_WRITEDATA`. 4. Sets `CURLOPT_CONNECTTIMEOUT = 5 s`, `CURLOPT_TIMEOUT = 10 s`. 5. Calls `curl_easy_perform()` and returns the raw response string. 6. On failure returns an empty string; callers must check before parsing. @@ -554,9 +550,8 @@ sequenceDiagram participant Plugin as org.rdk.* Plugin Profile->>Utils: postData JSON string - Utils->>Utils: get_security_token() Utils->>Curl: curl_easy_init() - Utils->>Curl: setopt (URL, POST, headers, timeout) + Utils->>Curl: setopt (URL, POST, Content-Type header, timeout) Curl->>Thunder: HTTP POST /jsonrpc Thunder->>Plugin: dispatch method Plugin-->>Thunder: JSON result diff --git a/run_l2.sh b/run_l2.sh index b9610cc2a..553d421e7 100644 --- a/run_l2.sh +++ b/run_l2.sh @@ -68,4 +68,3 @@ pytest --json-report --json-report-summary --json-report-file $RESULT_DIR/bootup pytest --json-report --json-report-summary --json-report-file $RESULT_DIR/handlers_communications.json test/functional-tests/tests/test_handlers_communications.py pytest --json-report --json-report-summary --json-report-file $RESULT_DIR/deviceip.json test/functional-tests/tests/tr69hostif_deviceip.py pytest --json-report --json-report-summary --json-report-file $RESULT_DIR/webpa.json test/functional-tests/tests/tr69hostif_webpa.py - diff --git a/src/hostif/docs/README.md b/src/hostif/docs/README.md index 01528f631..34c3e5231 100644 --- a/src/hostif/docs/README.md +++ b/src/hostif/docs/README.md @@ -316,8 +316,7 @@ This file provides all type-neutral helpers used across the subsystems. |----------|---------| | `matchComponent()` | Prefix and instance-number parsing for TR-181 paths | | `triggerResetScript()` | Executes cold / factory / warehouse / customer reset scripts | -| `getJsonRPCData()` | `libcurl` POST to WPEFramework JSON-RPC endpoint with Bearer token | -| `get_security_token()` | Calls `/usr/bin/WPEFrameworkSecurityUtility` via popen, parses JWT token | +| `getJsonRPCData()` | `libcurl` POST to WPEFramework JSON-RPC endpoint using the current request/auth configuration | | `getCurrentTime()` / `timeValDiff()` | Wall-clock timing for request duration logging | | `setLegacyRFCEnabled()` / `legacyRFCEnabled()` | Runtime flag for legacy vs new HTTP server mode | | `getBSUpdateEnum()` | Maps "rfcUpdate" / "allUpdate" / "default" strings to `HostIf_Source_Type_t` | diff --git a/src/hostif/include/hostIf_utils.h b/src/hostif/include/hostIf_utils.h index 179aa5760..5420c96c1 100755 --- a/src/hostif/include/hostIf_utils.h +++ b/src/hostif/include/hostIf_utils.h @@ -36,6 +36,7 @@ #include "hostIf_main.h" #include "hostIf_tr69ReqHandler.h" #include +#include "cJSON.h" #define REBOOT_SCR "backgroundrun sh /rebootNow.sh -s hostIf_utils" #define SCR_PATH "/lib/rdk" @@ -171,18 +172,118 @@ bool isNtpTimeFilePresent(); unsigned long get_system_manageble_ntp_time(); unsigned long get_device_manageble_time(); -/** - * This function retrieves the security token for Thunder. - * @return A string containing the security token or an empty string. - */ -std::string get_security_token(); - /** * This function makes jsonrpc call and returns the result. * @return A string contiaining the jsonrpc call result. */ string getJsonRPCData(std::string postData); +/** + * Invoke a Thunder JSON-RPC method and return the complete response payload. + * + * @param[in] method Thunder method name, for example org.rdk.AuthService.getExperience. + * @param[in] paramsJson JSON object string for params, pass empty string when params are not required. + * @param[out] response Full JSON response payload from Thunder. + * + * @return true on transport success with non-empty payload, false otherwise. + */ +bool invokeThunderPluginMethod(const std::string& method, const std::string& paramsJson, std::string& response); + +/** + * Invoke a Thunder JSON-RPC method and extract a string field from result object. + */ +bool invokeThunderPluginMethodAndExtractStringField(const std::string& method, + const std::string& paramsJson, const std::string& fieldName, std::string& value); + +/** + * Invoke a Thunder JSON-RPC method and extract a numeric field from result object. + */ +bool invokeThunderPluginMethodAndExtractNumberField(const std::string& method, + const std::string& paramsJson, const std::string& fieldName, int& value); + +/** + * Invoke a Thunder JSON-RPC method and extract a boolean field from result object. + * Accepts both JSON booleans and numeric 0/1 values. + */ +bool invokeThunderPluginMethodAndExtractBoolField(const std::string& method, + const std::string& paramsJson, const std::string& fieldName, bool& value); + +/** + * Parse and validate a JSON-RPC response and extract a string field from result object. + * Also handles arrays and objects by serializing them to a JSON string. + */ +bool thunderExtractResultStringField(const std::string& response, const char* fieldName, std::string& value); + +/** + * Parse and validate a JSON-RPC response and extract a numeric field from result object. + */ +bool thunderExtractResultNumberField(const std::string& response, const char* fieldName, int& value); + +/** + * Parse and validate a JSON-RPC response and extract a boolean field from result object. + * Accepts both JSON booleans and numeric 0/1 values. + */ +bool thunderExtractResultBoolField(const std::string& response, const char* fieldName, bool& value); + +/** + * Intended for non-negative numeric values (for example, Unix timestamps) that fit in + * unsigned long. Since JSON numbers may be represented internally as floating-point values, + * very large integers can lose precision and values outside the target range are not safe. + */ +bool invokeThunderPluginMethodAndExtractULongField(const std::string& method, + const std::string& paramsJson, const std::string& fieldName, unsigned long& value); + +/** + * Parse and validate a JSON-RPC response and extract an unsigned long numeric field from result object. + */ +bool thunderExtractResultULongField(const std::string& response, const char* fieldName, unsigned long& value); + +/** + * Parse Thunder response, locate an object in result[arrayFieldName] where matchKey == matchValue, + * and read a string field from that object. + */ +bool readThunderArrayItemByKey(const std::string& response, + const char* arrayFieldName, + const char* matchKey, + const char* matchValue, + const char* fieldName, + std::string& value); + +/** + * Parse Thunder response, locate an object in result[arrayFieldName] where matchKey == matchValue, + * and read a boolean field from that object. Accepts both JSON booleans and numeric 0/1 values. + */ +bool readThunderArrayItemByKey(const std::string& response, + const char* arrayFieldName, + const char* matchKey, + const char* matchValue, + const char* fieldName, + bool& value); + +/** + * Extract string values from a cJSON array and concatenate them with a delimiter. + * @param[in] arrayObj The cJSON array object to process. + * @param[in] delimiter The string to use as separator between array elements. + * @param[out] value The resulting concatenated string. + * @return true if successful, false if arrayObj is not a valid array. + */ +bool extractThunderStringArrayAsDelimitedString(cJSON* arrayObj, const std::string& delimiter, std::string& value); + +/** + * Invoke a Thunder JSON-RPC method and extract a result array field as a delimited string. + * Example: ["A","B"] with delimiter "_" becomes "A_B". + */ +bool invokeThunderPluginMethodAndExtractDelimitedStringArrayField(const std::string& method, + const std::string& paramsJson, const std::string& fieldName, + const std::string& delimiter, std::string& value); + +/** + * Invoke a Thunder JSON-RPC method and extract the top-level "result" field as a plain string. + * Use this when the response shape is {"result": "VALUE"} rather than {"result": {"field": "VALUE"}}. + */ +bool invokeThunderPluginMethodAndExtractScalarStringResult(const std::string& method, + const std::string& paramsJson, std::string& value); + #endif /* HOSTIF_UTILS_H_*/ diff --git a/src/hostif/profiles/DeviceInfo/Device_DeviceInfo.cpp b/src/hostif/profiles/DeviceInfo/Device_DeviceInfo.cpp index 37ded3ce1..a85ff4113 100644 --- a/src/hostif/profiles/DeviceInfo/Device_DeviceInfo.cpp +++ b/src/hostif/profiles/DeviceInfo/Device_DeviceInfo.cpp @@ -1288,92 +1288,24 @@ string hostIf_DeviceInfo::getEstbIp() retAddr=param.activeIfaceIpaddr; } #else - std::string postData = "{\"jsonrpc\":\"2.0\",\"id\":\"42\",\"method\": \"org.rdk.NetworkManager.GetPrimaryInterface\"}"; - - string response = getJsonRPCData(std::move(postData)); - if(response.c_str()) + if (!invokeThunderPluginMethodAndExtractStringField("org.rdk.NetworkManager.GetPrimaryInterface", "", "interface", ifc)) { - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: curl response string = %s\n", __FUNCTION__, response.c_str()); - cJSON* root = cJSON_Parse(response.c_str()); - if(root) - { - cJSON* jsonObj = cJSON_GetObjectItem(root, "result"); - - if (jsonObj) - { - cJSON *IpAddrObj = cJSON_GetObjectItem(jsonObj, "interface"); - if (IpAddrObj && IpAddrObj->valuestring) - { - // ASSIGN TO OP HERE - ifc = IpAddrObj->valuestring; - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] No interface in the output from Thunder plugin\n", __FUNCTION__); - cJSON_Delete(root); - return retAddr; - } - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error, no \"result\" in the output from Thunder plugin\n", __FUNCTION__); - cJSON_Delete(root); - return retAddr; - } - cJSON_Delete(root); - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: json parse error\n", __FUNCTION__); - } - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: getJsonRPCData failed\n", __FUNCTION__); + RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] failed to fetch interface from NetworkManager\n", __FUNCTION__); + return retAddr; } - postData = "{\"jsonrpc\":\"2.0\",\"id\":\"42\",\"method\": \"org.rdk.NetworkManager.GetIPSettings\", \"params\" : { \"interface\" : \"" + ifc + "\"}}"; - response = getJsonRPCData(std::move(postData)); - if(response.c_str()) + std::string paramsJson = "{\"interface\":\"" + ifc + "\"}"; + if (invokeThunderPluginMethodAndExtractStringField("org.rdk.NetworkManager.GetIPSettings", paramsJson, "ipaddress", retAddr)) { - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: curl response string = %s\n", __FUNCTION__, response.c_str()); - cJSON* root = cJSON_Parse(response.c_str()); - if(root) - { - cJSON* jsonObj = cJSON_GetObjectItem(root, "result"); - - if (jsonObj) - { - cJSON *IpAddrObj = cJSON_GetObjectItem(jsonObj, "ipaddress"); - if (IpAddrObj && IpAddrObj->valuestring) - { - //ASSIGN TO OP HERE - retAddr = IpAddrObj->valuestring; - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] No IP in the output from Thunder plugin\n", __FUNCTION__); - cJSON_Delete(root); - return retAddr; - } - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error, no \"result\" in the output from Thunder plugin\n", __FUNCTION__); - cJSON_Delete(root); - return retAddr; - } - cJSON_Delete(root); - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: json parse error\n", __FUNCTION__); - } + RDK_LOG (RDK_LOG_DEBUG, LOG_TR69HOSTIF, "[%s] successfully fetched ipaddress from NetworkManager\n", __FUNCTION__); + return retAddr; } else { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: getJsonRPCData failed\n", __FUNCTION__); + RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] failed to fetch ipaddress from NetworkManager\n", __FUNCTION__); + return retAddr; } + #endif ////Legacy way of getting estb ip. #else @@ -2720,91 +2652,23 @@ int hostIf_DeviceInfo::set_Device_DeviceInfo_X_RDKCENTRAL_COM_Syndication_Partne { if( n_PartnerId.compare(current_PartnerId) ) { - CURL *curl = curl_easy_init(); bool upload_flag = false; - std::string postData; - std::string tokenheader; + bool success = false; + std::string paramsJson = "{ \"partnerId\" : \"" + n_PartnerId + "\"}"; - if(curl) + RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s] call plugin to set partner ID.. with New PartnerId = %s \n", __FUNCTION__, n_PartnerId.c_str()); + if (invokeThunderPluginMethodAndExtractBoolField("org.rdk.AuthService.setPartnerId", paramsJson, "success", success) && success) { - /* We have different partner IDs - * set the partnerId using setpartnerid() */ - long http_code = 0; - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s] call curl to set partner ID.. with New PartnerId = %s \n", __FUNCTION__, n_PartnerId.c_str()); - - std::string sToken = get_security_token(); - - tokenheader = "Authorization: Bearer " + sToken; - - postData = "{\"jsonrpc\":\"2.0\",\"id\":\"3\",\"method\": \"org.rdk.AuthService.setPartnerId\", \"params\" : { \"partnerId\" : \""; - postData += n_PartnerId; - postData += "\"}}"; - - struct curl_slist *list = NULL; - - list = curl_slist_append(list, tokenheader.c_str()); - list = curl_slist_append(list, "Content-Type: application/json"); - - if(curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list) != CURLE_OK) { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s:%d] curl setup failed for CURLOPT_HTTPHEADER\n", __FUNCTION__, __LINE__); - curl_easy_cleanup(curl); - curl_slist_free_all(list); - return NOK; - } - if(curl_easy_setopt(curl, CURLOPT_POST, 1L) != CURLE_OK) { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s:%d]: curl setup failed for CURLOPT_POST\n", __FUNCTION__, __LINE__); - curl_easy_cleanup(curl); - curl_slist_free_all(list); - return NOK; - } - if(curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)postData.length()) != CURLE_OK) { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s:%d]: curl setup failed for CURLOPT_POSTFIELDSIZE\n", __FUNCTION__, __LINE__); - curl_easy_cleanup(curl); - curl_slist_free_all(list); - return NOK; - } - if(curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData.c_str()) != CURLE_OK) { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s:%d]: curl setup failed for CURLOPT_POSTFIELDS\n", __FUNCTION__, __LINE__); - curl_easy_cleanup(curl); - curl_slist_free_all(list); - return NOK; - } - if(curl_easy_setopt(curl, CURLOPT_URL, JSONRPC_URL) != CURLE_OK) { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s:%d]: curl setup failed for CURLOPT_URL\n", __FUNCTION__, __LINE__); - curl_easy_cleanup(curl); - curl_slist_free_all(list); - return NOK; - } - - CURLcode res = curl_easy_perform(curl); - - if ( res == CURLE_OK ) - { - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); - RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s] curl response : %d http response code: %ld\n", __FUNCTION__, res, http_code); - } - - curl_easy_cleanup(curl); - curl_slist_free_all(list); - - if( res == CURLE_OK && http_code == HTTP_OK ) - { - upload_flag = true; - RDK_LOG(RDK_LOG_INFO,LOG_TR69HOSTIF,"[%s] PartnerID uploaded using Curl Success \n",__FUNCTION__); - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] curl returned with error : %d http response code: %ld\n",\ - __FUNCTION__, res, http_code); - return NOK; - } + upload_flag = true; + RDK_LOG(RDK_LOG_INFO,LOG_TR69HOSTIF,"[%s] PartnerID uploaded using AuthService plugin call success \n",__FUNCTION__); } - else { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] curl init failed\n", __FUNCTION__); + else + { + RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] setPartnerId plugin request failed for value %s\n", __FUNCTION__, n_PartnerId.c_str()); return NOK; } - - /* Reload the bootstrap config if CURLE_OK */ + + /* Reload the bootstrap config if CURLE_OK */ int ret=NOK; if (upload_flag) @@ -3158,34 +3022,21 @@ int hostIf_DeviceInfo::set_xOpsReverseSshTrigger(HOSTIF_MsgData_t *stMsgData) { RDK_LOG(RDK_LOG_TRACE1,LOG_TR69HOSTIF,"[%s] Entering... \n",__FUNCTION__); #ifdef PRIVACYMODES_CONTROL - string privacyModeValue; - string queryJsonPrivacy = "{\"jsonrpc\":\"2.0\",\"id\":\"3\",\"method\": \"org.rdk.System.getPrivacyMode\" }"; - string response = getJsonRPCData(queryJsonPrivacy); - //string response = '{"jsonrpc":"2.0","id":3,"result":{"privacyMode":"SHARE","success":true}}'; - if(response.c_str()) - { - cJSON* root = cJSON_Parse(response.c_str()); - if(root) + string privacyModeValue; + + if (invokeThunderPluginMethodAndExtractScalarStringResult("org.rdk.UserSettings.getPrivacyMode", "", privacyModeValue)) + { + RDK_LOG(RDK_LOG_INFO,LOG_TR69HOSTIF,"%s: PrivacyMode is %s\n", __FUNCTION__, privacyModeValue.c_str()); + if (privacyModeValue.compare("DO_NOT_SHARE") == 0) { - cJSON* jsonObj = cJSON_GetObjectItem(root, "result"); - if (jsonObj){ - cJSON* privacyMode = cJSON_GetObjectItem(jsonObj, "privacyMode"); - if(privacyMode){ - privacyModeValue = privacyMode->valuestring; - RDK_LOG(RDK_LOG_INFO,LOG_TR69HOSTIF,"%s: PrivacyMode is %s\n", __FUNCTION__, privacyModeValue.c_str()); - if (privacyModeValue.compare("DO_NOT_SHARE") == 0){ - RDK_LOG(RDK_LOG_INFO,LOG_TR69HOSTIF,"%s: Revssh is disabled\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - } - } - cJSON_Delete(root); - } - else{ - RDK_LOG(RDK_LOG_INFO,LOG_TR69HOSTIF,"%s: Response from the rdkservices is not valid \n", __FUNCTION__); + RDK_LOG(RDK_LOG_INFO,LOG_TR69HOSTIF,"%s: Revssh is disabled\n", __FUNCTION__); + return NOK; } - } + } + else + { + RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: Failed to get privacy mode from UserSettings.getPrivacyMode\n", __FUNCTION__); + } #endif string inputStr(stMsgData->paramValue); const string startShorts = "start shorts"; @@ -3259,63 +3110,14 @@ int hostIf_DeviceInfo::set_xOpsReverseSshTrigger(HOSTIF_MsgData_t *stMsgData) */ int hostIf_DeviceInfo::get_Device_DeviceInfo_MigrationPreparer_MigrationReady(HOSTIF_MsgData_t * stMsgData, bool *pChanged) { - std::string response; - std::string postData; std::string value; - int i = 0; RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: call curl to get Components that are Ready..\n", __FUNCTION__); - postData = "{\"jsonrpc\":\"2.0\",\"id\":\"3\",\"method\": \"org.rdk.MigrationPreparer.getComponentReadiness\" }"; - response = getJsonRPCData(std::move(postData)); - - if(response.c_str()) - { - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: curl response string = %s\n", __FUNCTION__, response.c_str()); - cJSON* root = cJSON_Parse(response.c_str()); - if(root) - { - cJSON* jsonObj = cJSON_GetObjectItem(root, "result"); - if (jsonObj) - { - cJSON *ComponentList_obj = cJSON_GetObjectItem(jsonObj, "ComponentList"); - if (ComponentList_obj != NULL && cJSON_IsArray(ComponentList_obj)) - { - int ComponentList_obj_count = cJSON_GetArraySize(ComponentList_obj); - for ( ; i < ComponentList_obj_count-1; i++) - { - cJSON *Component = cJSON_GetArrayItem(ComponentList_obj, i); - if (cJSON_IsString(Component)) - { - printf(" - %s\n", Component->valuestring); - value = value + Component->valuestring + "_"; - } - } - cJSON *Component = cJSON_GetArrayItem(ComponentList_obj, i); - value = value + Component->valuestring ; - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] componentList is not present \n", __FUNCTION__); - return NOK; - } - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error, no \"result\" in the output from Thunder plugin\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - cJSON_Delete(root); - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: json parse error\n", __FUNCTION__); - } - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: curl init failed\n", __FUNCTION__); + if (!invokeThunderPluginMethodAndExtractDelimitedStringArrayField( + "org.rdk.MigrationPreparer.getComponentReadiness", "", "ComponentList", "_", value)) { + RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] Failed to get/parse ComponentList\n", __FUNCTION__); + return NOK; } stMsgData->paramtype = hostIf_StringType; @@ -4203,54 +4005,21 @@ int hostIf_DeviceInfo::get_xRDKCentralComRFC(HOSTIF_MsgData_t *stMsgData) int hostIf_DeviceInfo::get_xRDKCentralComRFCAccountId(HOSTIF_MsgData_t *stMsgData) { int ret=NOK; - std::string postData = "{\"jsonrpc\":\"2.0\",\"id\":\"3\",\"method\": \"org.rdk.AuthService.getServiceAccountId\" }"; RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: call curl to get Account ID..\n", __FUNCTION__); - - string response = getJsonRPCData(std::move(postData)); - if(response.c_str()) - { - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: curl response string = %s\n", __FUNCTION__, response.c_str()); - cJSON* root = cJSON_Parse(response.c_str()); - if(root) - { - cJSON* jsonObj = cJSON_GetObjectItem(root, "result"); - - if (jsonObj) - { - cJSON *accountIdObj = cJSON_GetObjectItem(jsonObj, "serviceAccountId"); + std::string serviceAccountId; - if (accountIdObj && accountIdObj->type == cJSON_String && accountIdObj->valuestring) - { - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "Found serviceAccountId value = %s\n", accountIdObj->valuestring); - putValue(stMsgData, accountIdObj->valuestring); - stMsgData->faultCode = fcNoFault; - ret = OK; - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error, no \"serviceAccountId\" in the output from Thunder plugin\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error, no \"result\" in the output from Thunder plugin\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - cJSON_Delete(root); - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: json parse error\n", __FUNCTION__); - } + if (invokeThunderPluginMethodAndExtractStringField("org.rdk.AuthService.getServiceAccountId", "", "serviceAccountId", serviceAccountId)) + { + RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "Found serviceAccountId value = %s\n", serviceAccountId.c_str()); + putValue(stMsgData, serviceAccountId); + stMsgData->faultCode = fcNoFault; + ret = OK; } else { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: curl init failed\n", __FUNCTION__); - } + RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: failed to fetch serviceAccountId\n", __FUNCTION__); + } return ret; } @@ -5388,52 +5157,18 @@ int hostIf_DeviceInfo::set_xOpsRPCRebootPendingNotification(HOSTIF_MsgData_t *st int hostIf_DeviceInfo::get_HotelCheckoutLastResetTime(HOSTIF_MsgData_t* stMsgData) { - std::string postData = "{\"jsonrpc\":\"2.0\",\"id\":\"3\",\"method\": \"org.rdk.Account.getLastCheckoutResetTime\" }"; - string resp = getJsonRPCData(std::move(postData)); - if (resp.empty()) - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] Empty output from Thunder call\n", __FUNCTION__); - return NOK; - } + unsigned long value = 0; - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s] curl response string = %s\n", __FUNCTION__, resp.c_str()); - - cJSON* root = cJSON_Parse(resp.c_str()); - - if(root) + if (invokeThunderPluginMethodAndExtractULongField("org.rdk.Account.getLastCheckoutResetTime", "", "resetTime", value)) { - cJSON* jsonObj = cJSON_GetObjectItem(root, "result"); - if (jsonObj) - { - cJSON *resetTimeObj = cJSON_GetObjectItem(jsonObj, "resetTime"); - - if (resetTimeObj && resetTimeObj->type == cJSON_Number) - { - unsigned long value = (unsigned long)resetTimeObj->valuedouble; - put_ulong(stMsgData->paramValue, value); - stMsgData->paramtype = hostIf_UnsignedLongType; - stMsgData->paramLen = sizeof(unsigned long); - } - else - { - RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] No resetTime in the output from Thunder plugin\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - } - else - { - RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error, no \"result\" in the output from Thunder plugin\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - - cJSON_Delete(root); + put_ulong(stMsgData->paramValue, value); + stMsgData->paramtype = hostIf_UnsignedLongType; + stMsgData->paramLen = sizeof(unsigned long); } else { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error\n", __FUNCTION__); + RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] Failed to extract resetTime from Account.getLastCheckoutResetTime\n", __FUNCTION__); return NOK; } @@ -5442,65 +5177,26 @@ int hostIf_DeviceInfo::get_HotelCheckoutLastResetTime(HOSTIF_MsgData_t* stMsgDat int hostIf_DeviceInfo::get_HotelCheckoutStatus(HOSTIF_MsgData_t* stMsgData) { - std::string postData = "{\"jsonrpc\":\"2.0\",\"id\":\"3\",\"method\": \"org.rdk.Account.getLastCheckoutResetTime\" }"; - - string resp = getJsonRPCData(std::move(postData)); - if (resp.empty()) - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] Empty outpu from Thunder call\n", __FUNCTION__); - return NOK; - } - - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s] curl response string = %s\n", __FUNCTION__, resp.c_str()); - - cJSON* root = cJSON_Parse(resp.c_str()); stMsgData->paramtype = hostIf_StringType; - if(root) + unsigned long value = 0; + if (!invokeThunderPluginMethodAndExtractULongField("org.rdk.Account.getLastCheckoutResetTime", "", "resetTime", value)) { - cJSON* jsonObj = cJSON_GetObjectItem(root, "result"); - if (jsonObj) - { - cJSON *resetTimeObj = cJSON_GetObjectItem(jsonObj, "resetTime"); - - if (resetTimeObj && resetTimeObj->type == cJSON_Number) - { - unsigned long value = (unsigned long)resetTimeObj->valuedouble; - - if (value > 0) - { - snprintf(stMsgData->paramValue, TR69HOSTIFMGR_MAX_PARAM_LEN, "%s", "success"); - } - else - { - snprintf(stMsgData->paramValue, TR69HOSTIFMGR_MAX_PARAM_LEN, "%s", "unknown"); - } - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] No resetTime in the output from Thunder call\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] No result from Thunder call\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - - stMsgData->paramLen = strlen(stMsgData->paramValue); + RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] Failed to extract resetTime from Account.getLastCheckoutResetTime\n", __FUNCTION__); + return NOK; + } - cJSON_Delete(root); + if (value > 0) + { + snprintf(stMsgData->paramValue, TR69HOSTIFMGR_MAX_PARAM_LEN, "%s", "success"); } else { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error\n", __FUNCTION__); - return NOK; + snprintf(stMsgData->paramValue, TR69HOSTIFMGR_MAX_PARAM_LEN, "%s", "unknown"); } + stMsgData->paramLen = strlen(stMsgData->paramValue); return OK; } @@ -5615,48 +5311,15 @@ void hostIf_DeviceInfo::systemMgmtTimePathMonitorThr() int hostIf_DeviceInfo::get_X_RDKCENTRAL_COM_experience( HOSTIF_MsgData_t *stMsgData) { string experience = ""; - std::string postData = "{\"jsonrpc\":\"2.0\",\"id\":\"3\",\"method\": \"org.rdk.AuthService.getExperience\" }"; - - string resp = getJsonRPCData(std::move(postData)); - if(resp.c_str()) - { - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s] curl response string = %s\n", __FUNCTION__, resp.c_str()); - - cJSON* root = cJSON_Parse(resp.c_str()); - if(root) - { - cJSON* jsonObj = cJSON_GetObjectItem(root, "result"); - - if (jsonObj) - { - cJSON *experienceObj = cJSON_GetObjectItem(jsonObj, "experience"); - if(experienceObj && experienceObj->type == cJSON_String && experienceObj->valuestring && (strlen(experienceObj->valuestring) > 0)) - { - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s]The parameter [%s] value is [%s].\n", __FUNCTION__, stMsgData->paramName, experienceObj->valuestring); - experience = experienceObj->valuestring; - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error, no \"experience\" in the output from Thunder plugin\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error, no \"result\" in the output from Thunder plugin\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - - cJSON_Delete(root); - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error\n", __FUNCTION__); - return NOK; - } + if (invokeThunderPluginMethodAndExtractStringField("org.rdk.AuthService.getExperience", "", "experience", experience)) + { + RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s]The parameter [%s] value is [%s].\n", __FUNCTION__, stMsgData->paramName, experience.c_str()); + } + else + { + RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] failed to fetch experience from AuthService\n", __FUNCTION__); + return NOK; } if(!experience.empty()) { diff --git a/src/hostif/profiles/wifi/Device_WiFi.cpp b/src/hostif/profiles/wifi/Device_WiFi.cpp index a1fd34d18..bf683ed8e 100644 --- a/src/hostif/profiles/wifi/Device_WiFi.cpp +++ b/src/hostif/profiles/wifi/Device_WiFi.cpp @@ -337,53 +337,26 @@ int hostIf_WiFi::get_Device_WiFi_EnableWiFi(HOSTIF_MsgData_t *stMsgData) { LOG_ENTRY_EXIT; - std::string postData = "{\"jsonrpc\":\"2.0\",\"id\":\"42\",\"method\": \"org.rdk.NetworkManager.GetAvailableInterfaces\"}"; - string response = getJsonRPCData(std::move(postData)); + std::string response; + if (!invokeThunderPluginMethod("org.rdk.NetworkManager.GetAvailableInterfaces", "", response)) + { + RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: failed to fetch interfaces from NetworkManager.GetAvailableInterfaces\n", __FUNCTION__); + return NOK; + } - if(response.c_str()) + bool enabled = false; + if (readThunderArrayItemByKey(response, "interfaces", "type", "WIFI", "enabled", enabled)) { - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: curl response string = %s\n", __FUNCTION__, response.c_str()); - cJSON* root = cJSON_Parse(response.c_str()); - if(root) - { - cJSON* jsonObj = cJSON_GetObjectItem(root, "result"); - - if (jsonObj) - { - cJSON *interfaces = cJSON_GetObjectItem(jsonObj, "interfaces"); - cJSON *interface = nullptr, *interfaceType; - for (int i = 0; i < cJSON_GetArraySize(interfaces); i++) { - interface = cJSON_GetArrayItem(interfaces, i); - interfaceType = cJSON_GetObjectItem(interface, "type"); - if (strcmp(interfaceType->valuestring, "WIFI") == 0) - break; - } - - //ASSIGN TO OP HERE - cJSON *result = cJSON_GetObjectItem(interface, "enabled"); - put_boolean(stMsgData->paramValue, result->type); - stMsgData->paramtype = hostIf_BooleanType; - stMsgData->paramLen=1; - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error, no \"result\" in the output from Thunder plugin\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - cJSON_Delete(root); - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: json parse error\n", __FUNCTION__); - return NOK; - } + put_boolean(stMsgData->paramValue, enabled); + stMsgData->paramtype = hostIf_BooleanType; + stMsgData->paramLen = 1; } else { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: getJsonRPCData() failed\n", __FUNCTION__); - return NOK; + RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Invalid or missing enabled for WIFI interface\n", __FUNCTION__); + return NOK; } + return OK; } #endif @@ -426,6 +399,7 @@ int hostIf_WiFi::set_Device_WiFi_EnableWiFi(HOSTIF_MsgData_t *stMsgData) int hostIf_WiFi::set_Device_WiFi_EnableWiFi(HOSTIF_MsgData_t *stMsgData) { LOG_ENTRY_EXIT; + string paramsJson; if (stMsgData->paramtype != hostIf_BooleanType) { @@ -434,45 +408,28 @@ int hostIf_WiFi::set_Device_WiFi_EnableWiFi(HOSTIF_MsgData_t *stMsgData) return NOK; } - std::string postData; if(get_boolean(stMsgData->paramValue)) { - postData = "{\"jsonrpc\":\"2.0\",\"id\":\"42\",\"method\": \"org.rdk.NetworkManager.EnableInterface\", \"params\" : { \"type\" : \"WIFI\"}}"; + paramsJson = "{\"interface\": \"wlan0\", \"enabled\": true}"; } else { - postData = "{\"jsonrpc\":\"2.0\",\"id\":\"42\",\"method\": \"org.rdk.NetworkManager.DisableInterface\", \"params\" : { \"type\" : \"WIFI\"}}"; - } + paramsJson = "{\"interface\": \"wlan0\", \"enabled\": false}"; + } - string response = getJsonRPCData(std::move(postData)); - if(response.c_str()) + bool result = false; + if (invokeThunderPluginMethodAndExtractBoolField("org.rdk.NetworkManager.SetInterfaceState", paramsJson, "success", result)) { - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: curl response string = %s\n", __FUNCTION__, response.c_str()); - cJSON* root = cJSON_Parse(response.c_str()); - if(root) - { - cJSON* jsonObj = cJSON_GetObjectItem(root, "result"); - - if (jsonObj) - { - cJSON *CheckResultObj = cJSON_GetObjectItem(jsonObj, "success"); - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: Result of Set operation = %s\n", __FUNCTION__, cJSON_IsTrue(CheckResultObj) ? "true" : "false"); - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error, no \"result\" in the output from Thunder plugin\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - cJSON_Delete(root); - } - else + RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: Result of Set operation = %s\n", + __FUNCTION__, result ? "true" : "false"); + if (!result) { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: json parse error\n", __FUNCTION__); - return NOK; + RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: WiFi SetInterfaceState rejected by Thunder\n", __FUNCTION__); + stMsgData->faultCode = fcRequestDenied; + return NOK; } } else { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: getJsonRPCData() failed\n", __FUNCTION__); + RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: WiFi SetInterfaceState call failed\n", __FUNCTION__); return NOK; } return OK; diff --git a/src/hostif/profiles/wifi/Device_WiFi_EndPoint.cpp b/src/hostif/profiles/wifi/Device_WiFi_EndPoint.cpp index 66dec1222..5a5b89f0b 100644 --- a/src/hostif/profiles/wifi/Device_WiFi_EndPoint.cpp +++ b/src/hostif/profiles/wifi/Device_WiFi_EndPoint.cpp @@ -49,6 +49,16 @@ extern "C" { #include "hostIf_utils.h" #endif +enum WiFiEndPointFetchMask { + WIFI_ENDPOINT_FETCH_AVAILABLE_INTERFACES = 1 << 0, + WIFI_ENDPOINT_FETCH_CONNECTED_SSID = 1 << 1 +}; + +#ifndef RDKV_NM +static time_t endPointInterfacesFetchTime = 0; +static time_t endPointConnectedSsidFetchTime = 0; +#endif + GHashTable* hostIf_WiFi_EndPoint::ifHash = NULL; hostIf_WiFi_EndPoint* hostIf_WiFi_EndPoint::getInstance(int dev_id) @@ -135,7 +145,7 @@ hostIf_WiFi_EndPoint::hostIf_WiFi_EndPoint (int dev_id) : int hostIf_WiFi_EndPoint::get_Device_WiFi_EndPoint_Enable (HOSTIF_MsgData_t *stMsgData) { LOG_ENTRY_EXIT; - if (OK != refreshCache ()) + if (OK != refreshCache (WIFI_ENDPOINT_FETCH_AVAILABLE_INTERFACES)) return NOK; RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s] Enable = [%d]\n", __FUNCTION__, Enable); put_int (stMsgData->paramValue, Enable); @@ -153,7 +163,7 @@ int hostIf_WiFi_EndPoint::get_Device_WiFi_EndPoint_Status (HOSTIF_MsgData_t *stM { errno_t rc = -1; LOG_ENTRY_EXIT; - if (OK != refreshCache ()) + if (OK != refreshCache (WIFI_ENDPOINT_FETCH_AVAILABLE_INTERFACES)) return NOK; RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s] Status = [%s]\n", __FUNCTION__, Status); rc=strcpy_s (stMsgData->paramValue,sizeof(stMsgData->paramValue), Status); @@ -170,7 +180,7 @@ int hostIf_WiFi_EndPoint::get_Device_WiFi_EndPoint_Alias (HOSTIF_MsgData_t *stMs { errno_t rc = -1; LOG_ENTRY_EXIT; - if (OK != refreshCache ()) + if (OK != refreshCache (0)) return NOK; RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s] Alias = [%s]\n", __FUNCTION__, Alias); rc=strcpy_s (stMsgData->paramValue,sizeof(stMsgData->paramValue), Alias); @@ -226,7 +236,7 @@ int hostIf_WiFi_EndPoint::get_Device_WiFi_EndPoint_ProfileNumberOfEntries (HOSTI int hostIf_WiFi_EndPoint::get_Device_WiFi_EndPoint_Stats_LastDataDownlinkRate (HOSTIF_MsgData_t *stMsgData) { LOG_ENTRY_EXIT; - if (OK != refreshCache ()) + if (OK != refreshCache (0)) return NOK; RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s] Stats.LastDataDownlinkRate = [%lu]\n", __FUNCTION__, stats.LastDataDownlinkRate); put_int (stMsgData->paramValue, stats.LastDataDownlinkRate); @@ -238,7 +248,7 @@ int hostIf_WiFi_EndPoint::get_Device_WiFi_EndPoint_Stats_LastDataDownlinkRate (H int hostIf_WiFi_EndPoint::get_Device_WiFi_EndPoint_Stats_LastDataUplinkRate (HOSTIF_MsgData_t *stMsgData) { LOG_ENTRY_EXIT; - if (OK != refreshCache ()) + if (OK != refreshCache (0)) return NOK; RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s] Stats.LastDataUplinkRate = [%lu]\n", __FUNCTION__, stats.LastDataUplinkRate); put_int (stMsgData->paramValue, stats.LastDataUplinkRate); @@ -250,7 +260,7 @@ int hostIf_WiFi_EndPoint::get_Device_WiFi_EndPoint_Stats_LastDataUplinkRate (HOS int hostIf_WiFi_EndPoint::get_Device_WiFi_EndPoint_Stats_SignalStrength (HOSTIF_MsgData_t *stMsgData) { LOG_ENTRY_EXIT; - if (OK != refreshCache ()) + if (OK != refreshCache (WIFI_ENDPOINT_FETCH_CONNECTED_SSID)) return NOK; RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s] Stats.SignalStrength = [%d]\n", __FUNCTION__, stats.SignalStrength); put_int (stMsgData->paramValue, stats.SignalStrength); @@ -262,7 +272,7 @@ int hostIf_WiFi_EndPoint::get_Device_WiFi_EndPoint_Stats_SignalStrength (HOSTIF_ int hostIf_WiFi_EndPoint::get_Device_WiFi_EndPoint_Stats_Retransmissions (HOSTIF_MsgData_t *stMsgData) { LOG_ENTRY_EXIT; - if (OK != refreshCache ()) + if (OK != refreshCache (0)) return NOK; RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s] Stats.Retransmissions = [%lu]\n", __FUNCTION__, stats.Retransmissions); put_int (stMsgData->paramValue, stats.Retransmissions); @@ -275,8 +285,9 @@ int hostIf_WiFi_EndPoint::get_Device_WiFi_EndPoint_Stats_Retransmissions (HOSTIF * @brief Refreshes the cache of Device.WiFi.EndPoint. parameters */ #ifdef RDKV_NM -int hostIf_WiFi_EndPoint::refreshCache() +int hostIf_WiFi_EndPoint::refreshCache(unsigned int fetchMask) { + (void)fetchMask; LOG_ENTRY_EXIT; static time_t time_of_last_successful_query = 0; static int last_call_status = NOK; @@ -323,7 +334,7 @@ int hostIf_WiFi_EndPoint::refreshCache() return OK; } #else -int hostIf_WiFi_EndPoint::refreshCache() +int hostIf_WiFi_EndPoint::refreshCache(unsigned int fetchMask) { LOG_ENTRY_EXIT; @@ -333,146 +344,94 @@ int hostIf_WiFi_EndPoint::refreshCache() std::lock_guard lg (m); - // Using a 1-second cache. - if ((last_call_status == OK ) && (time (0) <= time_of_last_successful_query + 1)) + time_t now = time(0); + unsigned int refreshMask = 0; + + // Using a 1-second cache per data source group. + if (((fetchMask & WIFI_ENDPOINT_FETCH_AVAILABLE_INTERFACES) != 0) && (now > endPointInterfacesFetchTime + 1)) + { + refreshMask |= WIFI_ENDPOINT_FETCH_AVAILABLE_INTERFACES; + } + + if (((fetchMask & WIFI_ENDPOINT_FETCH_CONNECTED_SSID) != 0) && (now > endPointConnectedSsidFetchTime + 1)) + { + refreshMask |= WIFI_ENDPOINT_FETCH_CONNECTED_SSID; + } + + if ((refreshMask == 0) && (fetchMask == 0)) { - RDK_LOG (RDK_LOG_DEBUG, LOG_TR69HOSTIF, "[%s] Cache not stale. last call status is SUCCESS, Refresh not required.\n", __FUNCTION__); return OK; } - - std::string postData = "{\"jsonrpc\":\"2.0\",\"id\":\"42\",\"method\": \"org.rdk.NetworkManager.1.GetAvailableInterfaces\"}"; + if ((last_call_status == OK ) && (refreshMask == 0) && (now <= time_of_last_successful_query + 1)) + { + RDK_LOG (RDK_LOG_DEBUG, LOG_TR69HOSTIF, "[%s] Cache not stale. last call status is SUCCESS, Refresh not required.\n", __FUNCTION__); + return OK; + } - string response = getJsonRPCData(std::move(postData)); - if(!response.empty()) + if ((refreshMask & WIFI_ENDPOINT_FETCH_AVAILABLE_INTERFACES) != 0) { - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: curl response string = %s\n", __FUNCTION__, response.c_str()); - cJSON* root = cJSON_Parse(response.c_str()); - if(root) - { - cJSON* jsonObj = cJSON_GetObjectItem(root, "result"); - - if (jsonObj) - { - cJSON *interfaces = cJSON_GetObjectItem(jsonObj, "interfaces"); - cJSON *interface = nullptr, *interfaceType = nullptr; - - if (!cJSON_IsArray(interfaces)) - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] WifiState result missing interfaces array\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - - for (int i = 0; i < cJSON_GetArraySize(interfaces); i++) { - interface = cJSON_GetArrayItem(interfaces, i); - if (!cJSON_IsObject(interface)) { - interface = nullptr; - continue; - } - interfaceType = cJSON_GetObjectItem(interface, "type"); - if (cJSON_IsString(interfaceType) && interfaceType->valuestring && (strcmp(interfaceType->valuestring, "WIFI") == 0)) - break; - interface = nullptr; - } - - if (!interface) - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] WIFI interface not found\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - - //ASSIGN TO OP HERE - cJSON *result = cJSON_GetObjectItem(interface, "enabled"); - if (cJSON_IsBool(result)) + std::string response; + if (!invokeThunderPluginMethod("org.rdk.NetworkManager.1.GetAvailableInterfaces", "", response)) { - Enable = cJSON_IsTrue(result); + RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] org.rdk.NetworkManager.1.GetAvailableInterfaces call failed\n", __FUNCTION__); + return NOK; } - else if (cJSON_IsNumber(result)) + + if (!readThunderArrayItemByKey(response, "interfaces", "type", "WIFI", "enabled", Enable)) { - Enable = (0 != result->valueint); + RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] Failed to extract WIFI interface enabled state\n", __FUNCTION__); + return NOK; } - else + + if (Enable) { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] WIFI interface missing valid enabled field\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; + strncpy(Status, "Enabled", BUFF_LENGTH_64); } - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error, no \"result\" in the output from Thunder plugin\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - cJSON_Delete(root); - } else { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: json parse error\n", __FUNCTION__); - return NOK; + strncpy(Status, "Disabled", BUFF_LENGTH_64); } + Status[BUFF_LENGTH_64 - 1] = '\0'; } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: getJsonRPCData() failed or returned empty response\n", __FUNCTION__); - return NOK; - } - - postData = "{\"jsonrpc\":\"2.0\",\"id\":\"42\",\"method\": \"org.rdk.NetworkManager.GetConnectedSSID\"}"; - response = getJsonRPCData(postData); - if(!response.empty()) + if ((refreshMask & WIFI_ENDPOINT_FETCH_CONNECTED_SSID) != 0) { - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: curl response string = %s\n", __FUNCTION__, response.c_str()); - cJSON* root = cJSON_Parse(response.c_str()); - if(root) + std::string connectedSsidResponse; + if (!invokeThunderPluginMethod("org.rdk.NetworkManager.GetConnectedSSID", "", connectedSsidResponse)) { - cJSON* jsonObj = cJSON_GetObjectItem(root, "result"); - - if (jsonObj) - { - cJSON *ssid = cJSON_GetObjectItem(jsonObj, "ssid"); - cJSON *strength = cJSON_GetObjectItem(jsonObj, "strength"); - if (!(cJSON_IsString(ssid) && ssid->valuestring)) - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] ConnectedSSID result missing valid ssid\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - if (!cJSON_IsNumber(strength)) - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] ConnectedSSID result missing numeric strength\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - //ASSIGN TO OP HERE - strncpy (SSIDReference, ssid->valuestring, BUFF_LENGTH_256); - SSIDReference[BUFF_LENGTH_256 - 1] = '\0'; - stats.SignalStrength = strength->valueint; - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: strength = %d\n", __FUNCTION__, stats.SignalStrength); - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error, no \"result\" in the output from Thunder plugin\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - cJSON_Delete(root); + RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] Failed to invoke GetConnectedSSID\n", __FUNCTION__); + return NOK; } - else + + std::string connectedSsid; + if (!thunderExtractResultStringField(connectedSsidResponse, "ssid", connectedSsid)) + { + RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] Failed to extract SSID from GetConnectedSSID\n", __FUNCTION__); + return NOK; + } + strncpy(SSIDReference, connectedSsid.c_str(), BUFF_LENGTH_256); + SSIDReference[BUFF_LENGTH_256 - 1] = '\0'; + + int strength = 0; + if (!thunderExtractResultNumberField(connectedSsidResponse, "strength", strength)) { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: json parse error\n", __FUNCTION__); + RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] Failed to extract signal strength from GetConnectedSSID\n", __FUNCTION__); return NOK; } + stats.SignalStrength = strength; + RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: strength = %d\n", __FUNCTION__, stats.SignalStrength); } - else + + time_of_last_successful_query = now; + if ((refreshMask & WIFI_ENDPOINT_FETCH_AVAILABLE_INTERFACES) != 0) { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: getJsonRPCData() failed or returned empty response\n", __FUNCTION__); - return NOK; + endPointInterfacesFetchTime = now; + } + if ((refreshMask & WIFI_ENDPOINT_FETCH_CONNECTED_SSID) != 0) + { + endPointConnectedSsidFetchTime = now; } - time_of_last_successful_query = time (0); //strncpy (Alias, param.data.endPointInfo.alias, BUFF_LENGTH_64); //strncpy (ProfileReference, param.data.endPointInfo.ProfileReference, BUFF_LENGTH_256); @@ -480,7 +439,7 @@ int hostIf_WiFi_EndPoint::refreshCache() RDK_LOG (RDK_LOG_DEBUG, LOG_TR69HOSTIF, "[%s] Cache refreshed.\n", __FUNCTION__); - if (false == Enable) // "Disabled" endpoint + if (((fetchMask & WIFI_ENDPOINT_FETCH_AVAILABLE_INTERFACES) != 0) && (false == Enable)) // "Disabled" endpoint { RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] EndPoint is disabled\n", __FUNCTION__); last_call_status = NOK; diff --git a/src/hostif/profiles/wifi/Device_WiFi_EndPoint.h b/src/hostif/profiles/wifi/Device_WiFi_EndPoint.h index 89cd190d0..e1c68fab9 100644 --- a/src/hostif/profiles/wifi/Device_WiFi_EndPoint.h +++ b/src/hostif/profiles/wifi/Device_WiFi_EndPoint.h @@ -66,7 +66,7 @@ class hostIf_WiFi_EndPoint { hostIf_WiFi_EndPoint(int dev_id); ~hostIf_WiFi_EndPoint() {}; - int refreshCache (); + int refreshCache (unsigned int fetchMask); public: static class hostIf_WiFi_EndPoint *getInstance(int dev_id); diff --git a/src/hostif/profiles/wifi/Device_WiFi_EndPoint_Security.cpp b/src/hostif/profiles/wifi/Device_WiFi_EndPoint_Security.cpp index 030659a96..3be982266 100644 --- a/src/hostif/profiles/wifi/Device_WiFi_EndPoint_Security.cpp +++ b/src/hostif/profiles/wifi/Device_WiFi_EndPoint_Security.cpp @@ -159,56 +159,20 @@ int hostIf_WiFi_EndPoint_Security::get_hostIf_WiFi_EndPoint_Security_ModesEnable return retVal; } - std::string postData = "{\"jsonrpc\":\"2.0\",\"id\":\"42\",\"method\": \"org.rdk.NetworkManager.GetConnectedSSID\"}"; - - string response = getJsonRPCData(std::move(postData)); - if(response.c_str()) + int security = 0; + if (invokeThunderPluginMethodAndExtractNumberField("org.rdk.NetworkManager.GetConnectedSSID", "", "security", security)) { - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: curl response string = %s\n", __FUNCTION__, response.c_str()); - cJSON* root = cJSON_Parse(response.c_str()); - if(root) - { - cJSON* jsonObj = cJSON_GetObjectItem(root, "result"); - - if (jsonObj) - { - cJSON *securityObj = cJSON_GetObjectItem(jsonObj, "security"); - - //ASSIGN TO OP HERE - if (securityObj && cJSON_IsNumber(securityObj)) - { - put_int(stMsgData->paramValue,securityObj->valueint); - stMsgData->paramtype = hostIf_IntegerType; - stMsgData->paramLen = sizeof(int); - - RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s] WiFi Security Mode : %d\n",__FUNCTION__, securityObj->valueint); - retVal = OK; - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error, missing/invalid \"security\" in result\n", __FUNCTION__); - retVal = NOK; - } - - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error, no \"result\" in the output from Thunder plugin\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - cJSON_Delete(root); - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: json parse error\n", __FUNCTION__); - return NOK; - } + put_int(stMsgData->paramValue, security); + stMsgData->paramtype = hostIf_IntegerType; + stMsgData->paramLen = sizeof(int); + + RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF, "[%s] WiFi Security Mode : %d\n",__FUNCTION__, security); + retVal = OK; } else { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: getJsonRPCData() failed\n", __FUNCTION__); - return NOK; + RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: failed to fetch security from NetworkManager.GetConnectedSSID\n", __FUNCTION__); + return NOK; } RDK_LOG(RDK_LOG_TRACE1,LOG_TR69HOSTIF,"[%s:%s] Exiting..\n", __FUNCTION__, __FILE__); return retVal; diff --git a/src/hostif/profiles/wifi/Device_WiFi_SSID.cpp b/src/hostif/profiles/wifi/Device_WiFi_SSID.cpp index 1bcfa97d8..8c69a4889 100644 --- a/src/hostif/profiles/wifi/Device_WiFi_SSID.cpp +++ b/src/hostif/profiles/wifi/Device_WiFi_SSID.cpp @@ -54,6 +54,12 @@ extern "C" { static time_t firstExTime = 0; +#ifndef RDKV_NM +static time_t connectedSsidFetchTime = 0; +static time_t availableInterfacesFetchTime = 0; +static time_t wifiStateFetchTime = 0; +#endif + GHashTable* hostIf_WiFi_SSID::ifHash = NULL; hostIf_WiFi_SSID* hostIf_WiFi_SSID::getInstance(int dev_id) @@ -132,8 +138,9 @@ hostIf_WiFi_SSID::hostIf_WiFi_SSID(int dev_id): memset(SSID,0, sizeof(SSID)); //CID:103108 - OVERRUN } #ifdef RDKV_NM -int hostIf_WiFi_SSID::get_Device_WiFi_SSID_Fields(int ssidIndex) +int hostIf_WiFi_SSID::get_Device_WiFi_SSID_Fields(int ssidIndex, unsigned int fetchMask) { + (void)fetchMask; errno_t rc = -1; IARM_Result_t retVal = IARM_RESULT_SUCCESS; IARM_BUS_WiFi_DiagsPropParam_t param = {0}; @@ -186,7 +193,7 @@ int hostIf_WiFi_SSID::get_Device_WiFi_SSID_Fields(int ssidIndex) } } #else -int hostIf_WiFi_SSID::get_Device_WiFi_SSID_Fields(int ssidIndex) +int hostIf_WiFi_SSID::get_Device_WiFi_SSID_Fields(int ssidIndex, unsigned int fetchMask) { errno_t rc = -1; RDK_LOG(RDK_LOG_TRACE1,LOG_TR69HOSTIF,"[%s:%s] Entering..\n", __FUNCTION__, __FILE__); @@ -194,256 +201,145 @@ int hostIf_WiFi_SSID::get_Device_WiFi_SSID_Fields(int ssidIndex) hostIf_WiFi_SSID *pDev = hostIf_WiFi_SSID::getInstance(dev_id); if (pDev) { - std::string postData = "{\"jsonrpc\":\"2.0\",\"id\":\"42\",\"method\": \"org.rdk.NetworkManager.GetConnectedSSID\"}"; - string response = getJsonRPCData(std::move(postData)); - if (response.empty()) - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Empty response received from NetworkManager.GetConnectedSSID JSON-RPC request\n", __FUNCTION__); - return NOK; - } - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: curl response string = %s\n", __FUNCTION__, response.c_str()); - cJSON* root = cJSON_Parse(response.c_str()); - if(root) + if ((fetchMask & WIFI_SSID_FETCH_CONNECTED_SSID) != 0) { - cJSON* jsonObj = cJSON_GetObjectItem(root, "result"); + std::string ssidResponse; + if (!invokeThunderPluginMethod("org.rdk.NetworkManager.GetConnectedSSID", "", ssidResponse)) + { + RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: failed to invoke NetworkManager.GetConnectedSSID\n", __FUNCTION__); + return NOK; + } - if (jsonObj) + std::string bssid; + if (!thunderExtractResultStringField(ssidResponse, "bssid", bssid)) { - cJSON *bssid = cJSON_GetObjectItem(jsonObj, "bssid"); - cJSON *ssid = cJSON_GetObjectItem(jsonObj, "ssid"); + RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: failed to fetch bssid from NetworkManager.GetConnectedSSID\n", __FUNCTION__); + return NOK; + } - if (!bssid || !cJSON_IsString(bssid) || !bssid->valuestring) - { - RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Invalid or missing BSSID\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } + std::string ssid; + if (!thunderExtractResultStringField(ssidResponse, "ssid", ssid)) + { + RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: failed to fetch ssid from NetworkManager.GetConnectedSSID\n", __FUNCTION__); + return NOK; + } - if (!ssid || !cJSON_IsString(ssid) || !ssid->valuestring) - { - RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Invalid or missing SSID\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - //ASSIGN TO OP HERE - rc=strcpy_s(BSSID,sizeof(BSSID),bssid->valuestring); - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: BSSID = %s \n", __FUNCTION__, BSSID); - if(rc!=EOK) - { - ERR_CHK(rc); - } - rc=strcpy_s(SSID,sizeof(SSID),ssid->valuestring); - if(rc!=EOK) - { - ERR_CHK(rc); - } - rc = strcpy_s(name, sizeof(name), ssid->valuestring); - if (rc != EOK) - { - ERR_CHK(rc); - } + //ASSIGN TO OP HERE + rc=strcpy_s(BSSID,sizeof(BSSID),bssid.c_str()); + RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: BSSID = %s \n", __FUNCTION__, BSSID); + if(rc!=EOK) + { + ERR_CHK(rc); } - else + rc=strcpy_s(SSID,sizeof(SSID),ssid.c_str()); + RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: SSID = %s \n", __FUNCTION__, SSID); + if(rc!=EOK) { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error, no \"result\" in the output from Thunder plugin\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; + ERR_CHK(rc); + } + rc = strcpy_s(name, sizeof(name), ssid.c_str()); + if (rc != EOK) + { + ERR_CHK(rc); } - cJSON_Delete(root); - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: json parse error\n", __FUNCTION__); - return NOK; } - postData = "{\"jsonrpc\":\"2.0\",\"id\":\"42\",\"method\": \"org.rdk.NetworkManager.GetAvailableInterfaces\"}"; - response = getJsonRPCData(postData); - - if(!response.empty()) + if ((fetchMask & WIFI_SSID_FETCH_AVAILABLE_INTERFACES) != 0) { - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: curl response string = %s\n", __FUNCTION__, response.c_str()); - cJSON* root = cJSON_Parse(response.c_str()); - if(root) + std::string response; + if (invokeThunderPluginMethod("org.rdk.NetworkManager.GetAvailableInterfaces", "", response)) { - cJSON* jsonObj = cJSON_GetObjectItem(root, "result"); - - if (jsonObj) + std::string macAddressValue; + if (readThunderArrayItemByKey(response, "interfaces", "type", "WIFI", "mac", macAddressValue)) { - cJSON *interfaces = cJSON_GetObjectItem(jsonObj, "interfaces"); - cJSON *interface = NULL; - cJSON *interfaceType = NULL; - - if (!cJSON_IsArray(interfaces)) - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Invalid or missing interfaces array\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - - for (int i = 0; i < cJSON_GetArraySize(interfaces); i++) - { - interface = cJSON_GetArrayItem(interfaces, i); - if (!cJSON_IsObject(interface)) - { - interface = NULL; - continue; - } - interfaceType = cJSON_GetObjectItem(interface, "type"); - if (cJSON_IsString(interfaceType) && interfaceType->valuestring && (strcmp(interfaceType->valuestring, "WIFI") == 0)) - { - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: Found WiFi Interface\n", __FUNCTION__); - break; - } - interface = NULL; - } - - if (!interface) - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: WIFI interface not found\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - //ASSIGN TO OP HERE - cJSON *result = cJSON_GetObjectItem(interface, "mac"); - if (!cJSON_IsString(result) || !result->valuestring) - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Invalid or missing mac\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - rc = strcpy_s(MACAddress, sizeof(MACAddress), result->valuestring); - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: MACAddress = %s \n", __FUNCTION__, MACAddress); - if (rc != EOK) - { - ERR_CHK(rc); - } - cJSON *isEnabled = cJSON_GetObjectItem(interface, "enabled"); - if (cJSON_IsBool(isEnabled)) - { - enable = cJSON_IsTrue(isEnabled); - } - else if (cJSON_IsNumber(isEnabled)) - { - enable = (0 != isEnabled->valueint); - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Invalid or missing enabled\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: ENABLE = %d \n", __FUNCTION__, enable); + RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: Found WiFi Interface\n", __FUNCTION__); } else { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error, no \"result\" in the output from Thunder plugin\n", __FUNCTION__); - cJSON_Delete(root); + RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: WIFI interface not found\n", __FUNCTION__); return NOK; } - cJSON_Delete(root); - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: json parse error\n", __FUNCTION__); - return NOK; - } - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Empty response received from NetworkManager.GetAvailableInterfaces JSON-RPC request\n", __FUNCTION__); - return NOK; - } - - postData = "{\"jsonrpc\":\"2.0\",\"id\":\"42\",\"method\": \"org.rdk.NetworkManager.GetWifiState\"}"; - response = getJsonRPCData(std::move(postData)); - if(!response.empty()) - { - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: curl response string = %s\n", __FUNCTION__, response.c_str()); - cJSON* root = cJSON_Parse(response.c_str()); - if(root) - { - cJSON* jsonObj = cJSON_GetObjectItem(root, "result"); + rc = strcpy_s(MACAddress, sizeof(MACAddress), macAddressValue.c_str()); + RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: MACAddress = %s \n", __FUNCTION__, MACAddress); + if (rc != EOK) + { + ERR_CHK(rc); + } - if (jsonObj) + if (!readThunderArrayItemByKey(response, "interfaces", "type", "WIFI", "enabled", enable)) { - cJSON *state = cJSON_GetObjectItem(jsonObj, "state"); - if (!state || !cJSON_IsNumber(state)) - { - RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error, \"state\" field missing or not a number\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - int res = state->valueint; - switch (res) { - case 0: - rc=strcpy_s(status,sizeof(status),"UNINSTALLED"); - break; - case 1: - rc=strcpy_s(status,sizeof(status),"DISABLED"); - break; - case 2: - rc=strcpy_s(status,sizeof(status),"DISCONNECTED"); - break; - case 3: - rc=strcpy_s(status,sizeof(status),"PAIRING"); - break; - case 4: - rc=strcpy_s(status,sizeof(status),"CONNECTING"); - break; - case 5: - rc=strcpy_s(status,sizeof(status),"CONNECTED"); - break; - case 6: - rc=strcpy_s(status,sizeof(status),"SSID_NOT_FOUND"); - break; - case 7: - rc=strcpy_s(status,sizeof(status),"SSID_CHANGED"); - break; - case 8: - rc=strcpy_s(status,sizeof(status),"CONNECTION_LOST"); - break; - case 9: - rc=strcpy_s(status,sizeof(status),"CONNECTION_FAILED"); - break; - case 10: - rc=strcpy_s(status,sizeof(status),"CONNECTION_INTERRUPTED"); - break; - case 11: - rc=strcpy_s(status,sizeof(status),"INVALID_CREDENTIALS"); - break; - case 12: - rc=strcpy_s(status,sizeof(status),"AUTHENTICATION_FAILED"); - break; - case 13: - rc=strcpy_s(status,sizeof(status),"ERROR"); - break; - } - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: STATUS = %s \n", __FUNCTION__, status); - if(rc!=EOK) - { - ERR_CHK(rc); - } - } - else - { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error, no \"result\" in the output from Thunder plugin\n", __FUNCTION__); - cJSON_Delete(root); - return NOK; - } - cJSON_Delete(root); - } + RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Invalid or missing enabled for WIFI interface\n", __FUNCTION__); + return NOK; + } + + RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: ENABLE = %d \n", __FUNCTION__, enable); + } else { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: json parse error\n", __FUNCTION__); + RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: failed to fetch interfaces from NetworkManager.GetAvailableInterfaces\n", __FUNCTION__); return NOK; } - } - else + } + + if ((fetchMask & WIFI_SSID_FETCH_WIFI_STATE) != 0) { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Empty response received from NetworkManager.GetWifiState JSON-RPC request\n", __FUNCTION__); - return NOK; + int res = 0; + if (!invokeThunderPluginMethodAndExtractNumberField("org.rdk.NetworkManager.GetWifiState", "", "state", res)) + { + RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: failed to fetch state from NetworkManager.GetWifiState\n", __FUNCTION__); + return NOK; + } + + switch (res) { + case 0: + rc=strcpy_s(status,sizeof(status),"UNINSTALLED"); + break; + case 1: + rc=strcpy_s(status,sizeof(status),"DISABLED"); + break; + case 2: + rc=strcpy_s(status,sizeof(status),"DISCONNECTED"); + break; + case 3: + rc=strcpy_s(status,sizeof(status),"PAIRING"); + break; + case 4: + rc=strcpy_s(status,sizeof(status),"CONNECTING"); + break; + case 5: + rc=strcpy_s(status,sizeof(status),"CONNECTED"); + break; + case 6: + rc=strcpy_s(status,sizeof(status),"SSID_NOT_FOUND"); + break; + case 7: + rc=strcpy_s(status,sizeof(status),"SSID_CHANGED"); + break; + case 8: + rc=strcpy_s(status,sizeof(status),"CONNECTION_LOST"); + break; + case 9: + rc=strcpy_s(status,sizeof(status),"CONNECTION_FAILED"); + break; + case 10: + rc=strcpy_s(status,sizeof(status),"CONNECTION_INTERRUPTED"); + break; + case 11: + rc=strcpy_s(status,sizeof(status),"INVALID_CREDENTIALS"); + break; + case 12: + rc=strcpy_s(status,sizeof(status),"AUTHENTICATION_FAILED"); + break; + case 13: + rc=strcpy_s(status,sizeof(status),"ERROR"); + break; + } + RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: STATUS = %s \n", __FUNCTION__, status); + if(rc!=EOK) + { + ERR_CHK(rc); + } } firstExTime = time (NULL); @@ -458,18 +354,63 @@ int hostIf_WiFi_SSID::get_Device_WiFi_SSID_Fields(int ssidIndex) } #endif -void hostIf_WiFi_SSID::checkWifiSSIDFetch(int ssidIndex) +void hostIf_WiFi_SSID::checkWifiSSIDFetch(int ssidIndex, unsigned int fetchMask) { int ret = NOK; time_t currExTime = time (NULL); +#ifdef RDKV_NM if ((currExTime - firstExTime ) > QUERY_INTERVAL) { - ret = get_Device_WiFi_SSID_Fields(ssidIndex); + ret = get_Device_WiFi_SSID_Fields(ssidIndex, fetchMask); + if( OK != ret) + { + RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"[%s:%s] Failed to fetch : %d.\n", __FILE__, __FUNCTION__, ret); + } + } +#else + unsigned int refreshMask = 0; + + if (((fetchMask & WIFI_SSID_FETCH_CONNECTED_SSID) != 0) && ((currExTime - connectedSsidFetchTime) > QUERY_INTERVAL)) + { + refreshMask |= WIFI_SSID_FETCH_CONNECTED_SSID; + } + + if (((fetchMask & WIFI_SSID_FETCH_AVAILABLE_INTERFACES) != 0) && ((currExTime - availableInterfacesFetchTime) > QUERY_INTERVAL)) + { + refreshMask |= WIFI_SSID_FETCH_AVAILABLE_INTERFACES; + } + + if (((fetchMask & WIFI_SSID_FETCH_WIFI_STATE) != 0) && ((currExTime - wifiStateFetchTime) > QUERY_INTERVAL)) + { + refreshMask |= WIFI_SSID_FETCH_WIFI_STATE; + } + + if (refreshMask != 0) + { + ret = get_Device_WiFi_SSID_Fields(ssidIndex, refreshMask); if( OK != ret) { RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"[%s:%s] Failed to fetch : %d.\n", __FILE__, __FUNCTION__, ret); } + else + { + if ((refreshMask & WIFI_SSID_FETCH_CONNECTED_SSID) != 0) + { + connectedSsidFetchTime = currExTime; + } + + if ((refreshMask & WIFI_SSID_FETCH_AVAILABLE_INTERFACES) != 0) + { + availableInterfacesFetchTime = currExTime; + } + + if ((refreshMask & WIFI_SSID_FETCH_WIFI_STATE) != 0) + { + wifiStateFetchTime = currExTime; + } + } } +#endif } int hostIf_WiFi_SSID::get_Device_WiFi_SSID_Enable(HOSTIF_MsgData_t *stMsgData ) @@ -477,7 +418,7 @@ int hostIf_WiFi_SSID::get_Device_WiFi_SSID_Enable(HOSTIF_MsgData_t *stMsgData ) int ssidIndex=1; int ret=OK; RDK_LOG(RDK_LOG_TRACE1,LOG_TR69HOSTIF,"[%s:%s] Entering..\n", __FUNCTION__, __FILE__); - checkWifiSSIDFetch(ssidIndex); + checkWifiSSIDFetch(ssidIndex, WIFI_SSID_FETCH_AVAILABLE_INTERFACES); put_boolean(stMsgData->paramValue, enable); stMsgData->paramtype = hostIf_BooleanType; stMsgData->paramLen=1; @@ -496,7 +437,7 @@ int hostIf_WiFi_SSID::get_Device_WiFi_SSID_Status(HOSTIF_MsgData_t *stMsgData ) int ssidIndex=1; RDK_LOG(RDK_LOG_TRACE1,LOG_TR69HOSTIF,"[%s:%s] Entering..\n", __FUNCTION__, __FILE__); - checkWifiSSIDFetch(ssidIndex); + checkWifiSSIDFetch(ssidIndex, WIFI_SSID_FETCH_WIFI_STATE); stMsgData->paramtype = hostIf_StringType; stMsgData->paramLen = strlen(status); snprintf(stMsgData->paramValue, TR69HOSTIFMGR_MAX_PARAM_LEN, status); @@ -519,7 +460,7 @@ int hostIf_WiFi_SSID::get_Device_WiFi_SSID_Name(HOSTIF_MsgData_t *stMsgData ) { int ssidIndex=1; RDK_LOG(RDK_LOG_TRACE1,LOG_TR69HOSTIF,"[%s:%s] Entering..\n", __FUNCTION__, __FILE__); - checkWifiSSIDFetch(ssidIndex); + checkWifiSSIDFetch(ssidIndex, WIFI_SSID_FETCH_CONNECTED_SSID); snprintf(stMsgData->paramValue, TR69HOSTIFMGR_MAX_PARAM_LEN, name); stMsgData->paramtype = hostIf_StringType; stMsgData->paramLen = strlen(name); @@ -548,7 +489,7 @@ int hostIf_WiFi_SSID::hostIf_WiFi_SSID::get_Device_WiFi_SSID_BSSID(HOSTIF_MsgDat int ssidIndex=1; int ret=OK; RDK_LOG(RDK_LOG_TRACE1,LOG_TR69HOSTIF,"[%s:%s] Entering..\n", __FUNCTION__, __FILE__); - checkWifiSSIDFetch(ssidIndex); + checkWifiSSIDFetch(ssidIndex, WIFI_SSID_FETCH_CONNECTED_SSID); snprintf(stMsgData->paramValue, TR69HOSTIFMGR_MAX_PARAM_LEN, BSSID); stMsgData->paramtype = hostIf_StringType; stMsgData->paramLen = strlen(BSSID); @@ -562,7 +503,7 @@ int hostIf_WiFi_SSID::hostIf_WiFi_SSID::get_Device_WiFi_SSID_MACAddress(HOSTIF_M int ssidIndex=1; int ret=OK; RDK_LOG(RDK_LOG_TRACE1,LOG_TR69HOSTIF,"[%s:%s] Entering..\n", __FUNCTION__, __FILE__); - checkWifiSSIDFetch(ssidIndex); + checkWifiSSIDFetch(ssidIndex, WIFI_SSID_FETCH_AVAILABLE_INTERFACES); snprintf(stMsgData->paramValue, TR69HOSTIFMGR_MAX_PARAM_LEN, MACAddress); stMsgData->paramtype = hostIf_StringType; stMsgData->paramLen = strlen(MACAddress); @@ -575,7 +516,7 @@ int hostIf_WiFi_SSID::get_Device_WiFi_SSID_SSID(HOSTIF_MsgData_t *stMsgData ) int ssidIndex=1; int ret=OK; RDK_LOG(RDK_LOG_TRACE1,LOG_TR69HOSTIF,"[%s:%s] Entering..\n", __FUNCTION__, __FILE__); - checkWifiSSIDFetch(ssidIndex); + checkWifiSSIDFetch(ssidIndex, WIFI_SSID_FETCH_CONNECTED_SSID); snprintf(stMsgData->paramValue,TR69HOSTIFMGR_MAX_PARAM_LEN, SSID); stMsgData->paramtype = hostIf_StringType; stMsgData->paramLen = strlen(SSID); diff --git a/src/hostif/profiles/wifi/Device_WiFi_SSID.h b/src/hostif/profiles/wifi/Device_WiFi_SSID.h index f8e3db1ec..3fdd1b813 100644 --- a/src/hostif/profiles/wifi/Device_WiFi_SSID.h +++ b/src/hostif/profiles/wifi/Device_WiFi_SSID.h @@ -62,6 +62,28 @@ #include "hostIf_updateHandler.h" #include "Device_WiFi.h" +/* + * Fetch mask uses bit flags (1, 2, 4) so callers can request multiple + * independent Thunder data groups in one refresh call using bitwise OR. + * + * Example: + * mask = WIFI_SSID_FETCH_CONNECTED_SSID | WIFI_SSID_FETCH_WIFI_STATE; + * if (mask & WIFI_SSID_FETCH_CONNECTED_SSID) { ... } + * if (mask & WIFI_SSID_FETCH_WIFI_STATE) { ... } + * + * Sequential enum values (0, 1, 2) are not suitable here because: + * - 0 cannot behave as a settable flag. + * - OR-combined results become ambiguous for membership checks. + * + * This flag-based design is required for selective refresh and avoids + * unnecessary RPC calls for unrelated parameters. + */ +enum WiFiSSIDFetchMask { + WIFI_SSID_FETCH_CONNECTED_SSID = 1 << 0, + WIFI_SSID_FETCH_AVAILABLE_INTERFACES = 1 << 1, + WIFI_SSID_FETCH_WIFI_STATE = 1 << 2 +}; + /** @defgroup TR_069_DEVICE_WIFI_API TR-069 Device.WiFi object API. * @ingroup TR_069_API * @@ -105,8 +127,8 @@ class hostIf_WiFi_SSID { static GList* getAllInstances(); static void closeInstance(hostIf_WiFi_SSID *); static void closeAllInstances(); - int get_Device_WiFi_SSID_Fields(int ssidIndex); - void checkWifiSSIDFetch(int radioIndex); + int get_Device_WiFi_SSID_Fields(int ssidIndex, unsigned int fetchMask); + void checkWifiSSIDFetch(int radioIndex, unsigned int fetchMask); bool enable; char status[BUFF_LENGTH_64]; diff --git a/src/hostif/src/gtest/gtest_src.cpp b/src/hostif/src/gtest/gtest_src.cpp index 639b3f0a8..9d9a22981 100644 --- a/src/hostif/src/gtest/gtest_src.cpp +++ b/src/hostif/src/gtest/gtest_src.cpp @@ -361,12 +361,6 @@ TEST(srcTest, getResetState) EXPECT_EQ(state, FactoryReset); } -TEST(srcTest, get_security_token) -{ - std::string token = get_security_token(); - EXPECT_EQ(token, ""); -} - TEST(srcTest, putBoolValue) { HOSTIF_MsgData_t param = { 0 }; @@ -456,6 +450,174 @@ TEST(srcTest, getStringValue) EXPECT_EQ(value, "true"); } +TEST(srcTest, invokeThunderPluginMethodEmptyMethod) +{ + std::string response = "stale"; + EXPECT_FALSE(invokeThunderPluginMethod("", "", response)); + EXPECT_TRUE(response.empty()); +} + +TEST(srcTest, thunderExtractResultStringFieldSuccess) +{ + const std::string response = "{\"jsonrpc\":\"2.0\",\"id\":\"3\",\"result\":{\"ssid\":\"HomeWiFi\"}}"; + std::string value; + EXPECT_TRUE(thunderExtractResultStringField(response, "ssid", value)); + EXPECT_EQ(value, "HomeWiFi"); +} + +TEST(srcTest, thunderExtractResultStringFieldInvalidJson) +{ + const std::string response = "{\"result\":{\"ssid\":\"HomeWiFi\"}"; + std::string value; + EXPECT_FALSE(thunderExtractResultStringField(response, "ssid", value)); +} + +TEST(srcTest, thunderExtractResultStringFieldMissingResult) +{ + const std::string response = "{\"jsonrpc\":\"2.0\",\"id\":\"3\",\"params\":{\"ssid\":\"HomeWiFi\"}}"; + std::string value; + EXPECT_FALSE(thunderExtractResultStringField(response, "ssid", value)); +} + +TEST(srcTest, thunderExtractResultStringFieldWithErrorObject) +{ + const std::string response = "{\"jsonrpc\":\"2.0\",\"id\":\"3\",\"error\":{\"code\":-32000,\"message\":\"Plugin call failed\"}}"; + std::string value; + EXPECT_FALSE(thunderExtractResultStringField(response, "ssid", value)); +} + +TEST(srcTest, thunderExtractResultStringFieldWrongType) +{ + const std::string response = "{\"jsonrpc\":\"2.0\",\"id\":\"3\",\"result\":{\"ssid\":123}}"; + std::string value; + EXPECT_FALSE(thunderExtractResultStringField(response, "ssid", value)); +} + +TEST(srcTest, thunderExtractResultNumberFieldSuccess) +{ + const std::string response = "{\"result\":{\"strength\":75}}"; + int value = 0; + EXPECT_TRUE(thunderExtractResultNumberField(response, "strength", value)); + EXPECT_EQ(value, 75); +} + +TEST(srcTest, thunderExtractResultNumberFieldWrongType) +{ + const std::string response = "{\"result\":{\"strength\":\"strong\"}}"; + int value = 0; + EXPECT_FALSE(thunderExtractResultNumberField(response, "strength", value)); +} + +TEST(srcTest, thunderExtractResultBoolFieldAcceptsBoolAndNumber) +{ + bool boolValue = false; + EXPECT_TRUE(thunderExtractResultBoolField("{\"result\":{\"enabled\":true}}", "enabled", boolValue)); + EXPECT_TRUE(boolValue); + + bool numericValue = false; + EXPECT_TRUE(thunderExtractResultBoolField("{\"result\":{\"enabled\":0}}", "enabled", numericValue)); + EXPECT_FALSE(numericValue); +} + +TEST(srcTest, thunderExtractResultBoolFieldWrongType) +{ + const std::string response = "{\"result\":{\"enabled\":\"yes\"}}"; + bool value = false; + EXPECT_FALSE(thunderExtractResultBoolField(response, "enabled", value)); +} + +TEST(srcTest, thunderExtractResultULongFieldSuccessAndWrongType) +{ + unsigned long goodValue = 0; + EXPECT_TRUE(thunderExtractResultULongField("{\"result\":{\"uptime\":123456}}", "uptime", goodValue)); + EXPECT_EQ(goodValue, 123456UL); + + unsigned long badValue = 0; + EXPECT_FALSE(thunderExtractResultULongField("{\"result\":{\"uptime\":\"123456\"}}", "uptime", badValue)); +} + +TEST(srcTest, extractThunderStringArrayAsDelimitedStringSuccess) +{ + cJSON* arrayObj = cJSON_Parse("[\"wlan0\",\"wlan1\"]"); + ASSERT_NE(arrayObj, nullptr); + + std::string value; + EXPECT_TRUE(extractThunderStringArrayAsDelimitedString(arrayObj, "_", value)); + EXPECT_EQ(value, "wlan0_wlan1"); + + cJSON_Delete(arrayObj); +} + +TEST(srcTest, extractThunderStringArrayAsDelimitedStringInvalidInput) +{ + cJSON* notArrayObj = cJSON_Parse("{\"iface\":\"wlan0\"}"); + ASSERT_NE(notArrayObj, nullptr); + + std::string value; + EXPECT_FALSE(extractThunderStringArrayAsDelimitedString(notArrayObj, "_", value)); + + cJSON_Delete(notArrayObj); +} + +TEST(srcTest, readThunderArrayItemByKeyStringSuccess) +{ + const std::string response = + "{\"result\":{\"interfaces\":[{\"name\":\"wlan0\",\"type\":\"WIFI\",\"ssid\":\"HomeWiFi\"},{\"name\":\"eth0\",\"type\":\"ETHERNET\",\"ssid\":\"HomeWiFi\"}]}}"; + + std::string value; + EXPECT_TRUE(readThunderArrayItemByKey(response, "interfaces", "type", "WIFI", "ssid", value)); + EXPECT_EQ(value, "HomeWiFi"); +} + +TEST(srcTest, readThunderArrayItemByKeyStringMissingArray) +{ + const std::string response = "{\"result\":{\"ifaces\":[]}}"; + std::string value; + EXPECT_FALSE(readThunderArrayItemByKey(response, "interfaces", "type", "WIFI", "ssid", value)); +} + +TEST(srcTest, readThunderArrayItemByKeyStringNoMatchingItem) +{ + const std::string response = + "{\"result\":{\"interfaces\":[{\"name\":\"eth0\",\"type\":\"ETHERNET\",\"ssid\":\"HomeWiFi\"}]}}"; + + std::string value; + EXPECT_FALSE(readThunderArrayItemByKey(response, "interfaces", "type", "WIFI", "ssid", value)); +} + +TEST(srcTest, readThunderArrayItemByKeyStringWrongFieldType) +{ + const std::string response = + "{\"result\":{\"interfaces\":[{\"name\":\"wlan0\",\"type\":\"WIFI\",\"ssid\":123}]}}"; + + std::string value; + EXPECT_FALSE(readThunderArrayItemByKey(response, "interfaces", "type", "WIFI", "ssid", value)); +} + +TEST(srcTest, readThunderArrayItemByKeyBoolAcceptsBoolAndNumber) +{ + const std::string boolResponse = + "{\"result\":{\"interfaces\":[{\"type\":\"WIFI\",\"enabled\":true}]}}"; + bool boolValue = false; + EXPECT_TRUE(readThunderArrayItemByKey(boolResponse, "interfaces", "type", "WIFI", "enabled", boolValue)); + EXPECT_TRUE(boolValue); + + const std::string numberResponse = + "{\"result\":{\"interfaces\":[{\"type\":\"WIFI\",\"enabled\":0}]}}"; + bool numberValue = true; + EXPECT_TRUE(readThunderArrayItemByKey(numberResponse, "interfaces", "type", "WIFI", "enabled", numberValue)); + EXPECT_FALSE(numberValue); +} + +TEST(srcTest, readThunderArrayItemByKeyBoolWrongType) +{ + const std::string response = + "{\"result\":{\"interfaces\":[{\"type\":\"WIFI\",\"enabled\":\"yes\"}]}}"; + + bool value = false; + EXPECT_FALSE(readThunderArrayItemByKey(response, "interfaces", "type", "WIFI", "enabled", value)); +} + GTEST_API_ int main(int argc, char *argv[]){ char testresults_fullfilepath[GTEST_REPORT_FILEPATH_SIZE]; char buffer[GTEST_REPORT_FILEPATH_SIZE]; diff --git a/src/hostif/src/hostIf_utils.cpp b/src/hostif/src/hostIf_utils.cpp index 68627f913..9bd7377a8 100644 --- a/src/hostif/src/hostIf_utils.cpp +++ b/src/hostif/src/hostIf_utils.cpp @@ -518,42 +518,6 @@ unsigned long get_device_manageble_time() return epoch_time; } -std::string get_security_token() { - std::string sToken = ""; - char pSecurityOutput[256] = {0}; - FILE *pSecurity = v_secure_popen("r", "/usr/bin/WPEFrameworkSecurityUtility"); - if(pSecurity) { - if (fgets(pSecurityOutput, 256, pSecurity) != NULL) { - cJSON* root = cJSON_Parse(pSecurityOutput); - if (root) { - cJSON *res = cJSON_GetObjectItem(root, "success"); - if(cJSON_IsTrue(res) == 1) { - cJSON* token = cJSON_GetObjectItem(root, "token"); - if (token != NULL && token->type == cJSON_String && token->valuestring != NULL) { - RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: Security Token retrieved successfully\n", __FUNCTION__); - sToken = token->valuestring; - } - } - else { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF,"%s: Security Token retrieval failed!\n", __FUNCTION__); - } - cJSON_Delete(root); - } - else { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error\n", __FUNCTION__); - } - } - v_secure_pclose(pSecurity); - } - - else { - RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF,"%s: Failed to open security utility\n", __FUNCTION__); - } - - - return sToken; -} - size_t static writeCurlResponse(void *ptr, size_t size, size_t nmemb, string stream); size_t static writeCurlResponse(void *ptr, size_t size, size_t nmemb, string stream) { @@ -565,17 +529,12 @@ size_t static writeCurlResponse(void *ptr, size_t size, size_t nmemb, string str string getJsonRPCData(std::string postData) { - std::string tokenheader; string response; CURL *curl = curl_easy_init(); if(curl) { - std::string sToken = get_security_token(); - tokenheader = "Authorization: Bearer " + sToken; - struct curl_slist *list = NULL; - list = curl_slist_append(list, tokenheader.c_str()); list = curl_slist_append(list, "Content-Type: application/json"); if(curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list) != CURLE_OK){ @@ -643,6 +602,530 @@ string getJsonRPCData(std::string postData) } } +static bool parseThunderResultObject(const std::string& response, cJSON** rootOut, cJSON** resultOut) +{ + if ((rootOut == NULL) || (resultOut == NULL)) + { + return false; + } + + *rootOut = NULL; + *resultOut = NULL; + + if (response.empty()) + { + RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Empty Thunder response payload\n", __FUNCTION__); + return false; + } + + cJSON* root = cJSON_Parse(response.c_str()); + if (root == NULL) + { + const char* errPtr = cJSON_GetErrorPtr(); + RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Failed to parse Thunder response JSON near: [%s]\n", + __FUNCTION__, errPtr ? errPtr : "unknown"); + return false; + } + + cJSON* errorObj = cJSON_GetObjectItem(root, "error"); + if (cJSON_IsObject(errorObj)) + { + cJSON* errorCode = cJSON_GetObjectItem(errorObj, "code"); + cJSON* errorMessage = cJSON_GetObjectItem(errorObj, "message"); + RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, + "%s: Thunder returned error code=%d message=%s\n", + __FUNCTION__, + cJSON_IsNumber(errorCode) ? errorCode->valueint : -1, + (cJSON_IsString(errorMessage) && errorMessage->valuestring) ? errorMessage->valuestring : "unknown"); + cJSON_Delete(root); + return false; + } + + cJSON* resultObj = cJSON_GetObjectItem(root, "result"); + if (!cJSON_IsObject(resultObj)) + { + RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error, no \"result\" in the output from Thunder plugin\n", __FUNCTION__); + cJSON_Delete(root); + return false; + } + + *rootOut = root; + *resultOut = resultObj; + return true; +} + +bool invokeThunderPluginMethod(const std::string& method, const std::string& paramsJson, std::string& response) +{ + response.clear(); + + if (method.empty()) + { + RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: method name is empty\n", __FUNCTION__); + return false; + } + + std::string postData = "{\"jsonrpc\":\"2.0\",\"id\":\"3\",\"method\": \"" + method + "\""; + if (!paramsJson.empty()) + { + postData += ", \"params\" : " + paramsJson; + } + postData += "}"; + + response = getJsonRPCData(std::move(postData)); + if (response.empty()) + { + RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: getJsonRPCData failed\n", __FUNCTION__); + return false; + } + + RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: curl response string = %s\n", __FUNCTION__, response.c_str()); + return true; +} + +bool thunderExtractResultStringField(const std::string& response, const char* fieldName, std::string& value) +{ + value.clear(); + + if (fieldName == NULL) + { + return false; + } + + cJSON* root = NULL; + cJSON* resultObj = NULL; + if (!parseThunderResultObject(response, &root, &resultObj)) + { + return false; + } + + cJSON* fieldObj = cJSON_GetObjectItem(resultObj, fieldName); + bool ok = false; + if (cJSON_IsString(fieldObj) && (fieldObj->valuestring != NULL)) + { + value = fieldObj->valuestring; + ok = true; + } + else if (cJSON_IsArray(fieldObj) || cJSON_IsObject(fieldObj)) + { + char* serialized = cJSON_PrintUnformatted(fieldObj); + if (serialized != NULL) + { + value = serialized; + cJSON_free(serialized); + ok = !value.empty(); + } + + if (!ok) + { + RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] failed to serialize \"%s\" from Thunder result\n", __FUNCTION__, fieldName); + } + } + else + { + RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error, no \"%s\" in the output from Thunder plugin\n", __FUNCTION__, fieldName); + } + + cJSON_Delete(root); + return ok; +} + + +bool thunderExtractResultNumberField(const std::string& response, const char* fieldName, int& value) +{ + value = 0; + + if (fieldName == NULL) + { + return false; + } + + cJSON* root = NULL; + cJSON* resultObj = NULL; + if (!parseThunderResultObject(response, &root, &resultObj)) + { + return false; + } + + cJSON* fieldObj = cJSON_GetObjectItem(resultObj, fieldName); + bool ok = false; + if (cJSON_IsNumber(fieldObj)) + { + value = fieldObj->valueint; + ok = true; + } + else + { + RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error, missing/invalid \"%s\" in result\n", __FUNCTION__, fieldName); + } + + cJSON_Delete(root); + return ok; +} + +bool thunderExtractResultBoolField(const std::string& response, const char* fieldName, bool& value) +{ + value = false; + + if (fieldName == NULL) + { + return false; + } + + cJSON* root = NULL; + cJSON* resultObj = NULL; + if (!parseThunderResultObject(response, &root, &resultObj)) + { + return false; + } + + cJSON* fieldObj = cJSON_GetObjectItem(resultObj, fieldName); + bool ok = false; + + if (cJSON_IsBool(fieldObj)) + { + value = cJSON_IsTrue(fieldObj); + ok = true; + } + else if (cJSON_IsNumber(fieldObj)) + { + value = (fieldObj->valueint != 0); + ok = true; + } + + if (!ok) + { + RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Missing/invalid bool field %s in Thunder result\n", __FUNCTION__, fieldName); + } + + cJSON_Delete(root); + return ok; +} + +bool thunderExtractResultULongField(const std::string& response, const char* fieldName, unsigned long& value) +{ + value = 0; + + if (fieldName == NULL) + { + return false; + } + + cJSON* root = NULL; + cJSON* resultObj = NULL; + if (!parseThunderResultObject(response, &root, &resultObj)) + { + return false; + } + + cJSON* fieldObj = cJSON_GetObjectItem(resultObj, fieldName); + bool ok = false; + if (cJSON_IsNumber(fieldObj)) + { + value = (unsigned long)fieldObj->valuedouble; + ok = true; + } + else + { + RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Missing/invalid unsigned long field %s in Thunder result\n", __FUNCTION__, fieldName); + } + + cJSON_Delete(root); + return ok; +} + +bool invokeThunderPluginMethodAndExtractStringField(const std::string& method, + const std::string& paramsJson, const std::string& fieldName, std::string& value) +{ + std::string response; + + if (!invokeThunderPluginMethod(method, paramsJson, response)) { + return false; + } + + if (!thunderExtractResultStringField(response, fieldName.c_str(), value)) { + return false; + } + + return true; +} + +bool invokeThunderPluginMethodAndExtractNumberField(const std::string& method, + const std::string& paramsJson, const std::string& fieldName, int& value) +{ + std::string response; + + if (!invokeThunderPluginMethod(method, paramsJson, response)) { + return false; + } + + if (!thunderExtractResultNumberField(response, fieldName.c_str(), value)) { + return false; + } + + return true; +} + +bool invokeThunderPluginMethodAndExtractBoolField(const std::string& method, + const std::string& paramsJson, const std::string& fieldName, bool& value) +{ + std::string response; + + if (!invokeThunderPluginMethod(method, paramsJson, response)) { + return false; + } + + if (!thunderExtractResultBoolField(response, fieldName.c_str(), value)) { + return false; + } + + return true; +} + +bool readThunderArrayItemByKey(const std::string& response, + const char* arrayFieldName, + const char* matchKey, + const char* matchValue, + const char* fieldName, + std::string& value) +{ + value.clear(); + + if ((arrayFieldName == NULL) || (matchKey == NULL) || (matchValue == NULL) || (fieldName == NULL)) + { + return false; + } + + cJSON* root = NULL; + cJSON* resultObj = NULL; + if (!parseThunderResultObject(response, &root, &resultObj)) + { + return false; + } + + cJSON* arrayObj = cJSON_GetObjectItem(resultObj, arrayFieldName); + if (!cJSON_IsArray(arrayObj)) + { + RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Missing/invalid array field %s in Thunder result\n", __FUNCTION__, arrayFieldName); + cJSON_Delete(root); + return false; + } + + bool ok = false; + for (int i = 0; i < cJSON_GetArraySize(arrayObj); i++) + { + cJSON* itemObj = cJSON_GetArrayItem(arrayObj, i); + if (!cJSON_IsObject(itemObj)) + { + continue; + } + + cJSON* matchObj = cJSON_GetObjectItem(itemObj, matchKey); + if (!cJSON_IsString(matchObj) || (matchObj->valuestring == NULL) || (strcmp(matchObj->valuestring, matchValue) != 0)) + { + continue; + } + + cJSON* fieldObj = cJSON_GetObjectItem(itemObj, fieldName); + if (cJSON_IsString(fieldObj) && fieldObj->valuestring) + { + value = fieldObj->valuestring; + ok = true; + } + else if (cJSON_IsArray(fieldObj) || cJSON_IsObject(fieldObj)) + { + char* serialized = cJSON_PrintUnformatted(fieldObj); + if (serialized != NULL) + { + value = serialized; + cJSON_free(serialized); + ok = !value.empty(); + } + } + + break; + } + + if (!ok) + { + RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, + "%s: Missing/invalid field %s for %s=%s in array %s\n", + __FUNCTION__, fieldName, matchKey, matchValue, arrayFieldName); + } + + cJSON_Delete(root); + return ok; +} + +bool readThunderArrayItemByKey(const std::string& response, + const char* arrayFieldName, + const char* matchKey, + const char* matchValue, + const char* fieldName, + bool& value) +{ + value = false; + + if ((arrayFieldName == NULL) || (matchKey == NULL) || (matchValue == NULL) || (fieldName == NULL)) + { + return false; + } + + cJSON* root = NULL; + cJSON* resultObj = NULL; + if (!parseThunderResultObject(response, &root, &resultObj)) + { + return false; + } + + cJSON* arrayObj = cJSON_GetObjectItem(resultObj, arrayFieldName); + if (!cJSON_IsArray(arrayObj)) + { + RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Missing/invalid array field %s in Thunder result\n", __FUNCTION__, arrayFieldName); + cJSON_Delete(root); + return false; + } + + bool ok = false; + for (int i = 0; i < cJSON_GetArraySize(arrayObj); i++) + { + cJSON* itemObj = cJSON_GetArrayItem(arrayObj, i); + if (!cJSON_IsObject(itemObj)) + { + continue; + } + + cJSON* matchObj = cJSON_GetObjectItem(itemObj, matchKey); + if (!cJSON_IsString(matchObj) || (matchObj->valuestring == NULL) || (strcmp(matchObj->valuestring, matchValue) != 0)) + { + continue; + } + + cJSON* fieldObj = cJSON_GetObjectItem(itemObj, fieldName); + if (cJSON_IsBool(fieldObj)) + { + value = cJSON_IsTrue(fieldObj); + ok = true; + } + else if (cJSON_IsNumber(fieldObj)) + { + value = (fieldObj->valueint != 0); + ok = true; + } + + break; + } + + if (!ok) + { + RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, + "%s: Missing/invalid bool field %s for %s=%s in array %s\n", + __FUNCTION__, fieldName, matchKey, matchValue, arrayFieldName); + } + + cJSON_Delete(root); + return ok; +} + +bool invokeThunderPluginMethodAndExtractULongField(const std::string& method, + const std::string& paramsJson, const std::string& fieldName, unsigned long& value) +{ + std::string response; + + if (!invokeThunderPluginMethod(method, paramsJson, response)) { + return false; + } + + if (!thunderExtractResultULongField(response, fieldName.c_str(), value)) { + return false; + } + + return true; +} + +bool extractThunderStringArrayAsDelimitedString(cJSON* arrayObj, const std::string& delimiter, std::string& value) +{ + value.clear(); + + if (!cJSON_IsArray(arrayObj)) + { + RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Input is not a valid cJSON array\n", __FUNCTION__); + return false; + } + + int arraySize = cJSON_GetArraySize(arrayObj); + if (arraySize <= 0) + { + return true; // Empty array is valid, return empty string + } + + for (int i = 0; i < arraySize; i++) + { + cJSON* item = cJSON_GetArrayItem(arrayObj, i); + if (cJSON_IsString(item) && item->valuestring) + { + if (i > 0) + { + value += delimiter; + } + value += item->valuestring; + } + } + + return true; +} + +bool invokeThunderPluginMethodAndExtractDelimitedStringArrayField(const std::string& method, + const std::string& paramsJson, const std::string& fieldName, + const std::string& delimiter, std::string& value) +{ + value.clear(); + + std::string response; + if (!invokeThunderPluginMethod(method, paramsJson, response)) { + return false; + } + + cJSON* root = NULL; + cJSON* resultObj = NULL; + if (!parseThunderResultObject(response, &root, &resultObj)) { + return false; + } + + cJSON* arrayObj = cJSON_GetObjectItem(resultObj, fieldName.c_str()); + const bool ok = extractThunderStringArrayAsDelimitedString(arrayObj, delimiter, value); + cJSON_Delete(root); + return ok; +} + +bool invokeThunderPluginMethodAndExtractScalarStringResult(const std::string& method, + const std::string& paramsJson, std::string& value) +{ + value.clear(); + + std::string response; + if (!invokeThunderPluginMethod(method, paramsJson, response)) { + return false; + } + + cJSON* root = cJSON_Parse(response.c_str()); + if (root == NULL) { + RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: json parse error for method %s\n", __FUNCTION__, method.c_str()); + return false; + } + + cJSON* resultObj = cJSON_GetObjectItem(root, "result"); + bool ok = false; + if (cJSON_IsString(resultObj) && (resultObj->valuestring != NULL)) { + value = resultObj->valuestring; + ok = true; + } else { + RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Missing/invalid scalar string result for method %s\n", __FUNCTION__, method.c_str()); + } + + cJSON_Delete(root); + return ok; +} + #ifdef GTEST_ENABLE size_t (*getWriteCurlResponse(void))(void *ptr, size_t size, size_t nmemb, std::string stream) { return &writeCurlResponse;