From 6342f271a66978006023c15e0a5e52ab05133c44 Mon Sep 17 00:00:00 2001 From: Gene Gallagher <129112619+egalla204@users.noreply.github.com> Date: Wed, 5 Nov 2025 18:00:16 -0500 Subject: [PATCH 01/39] RDKEMW-10164: update CHANGELOG for release v1.1.5 (#139) --- CHANGELOG.md | 218 +++++++++++++++++++++++++-------------------------- 1 file changed, 105 insertions(+), 113 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9eed8a53..ef1e336b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,140 +1,130 @@ -# Changelog +### Changelog -All notable changes to this project will be documented in this file. +All notable changes to this project will be documented in this file. Dates are displayed in UTC. -* Each RDK Service has a CHANGELOG file that contains all changes done so far. When version is updated, add a entry in the CHANGELOG.md at the top with user friendly information on what was changed with the new version. Please don't mention JIRA tickets in CHANGELOG. +Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). -* Please Add entry in the CHANGELOG for each version change and indicate the type of change with these labels: - * **Added** for new features. - * **Changed** for changes in existing functionality. - * **Deprecated** for soon-to-be removed features. - * **Removed** for now removed features. - * **Fixed** for any bug fixes. - * **Security** in case of vulnerabilities. -* Changes in CHANGELOG should be updated when commits are added to the main or release branches. There should be one CHANGELOG entry per JIRA Ticket. This is not enforced on sprint branches since there could be multiple changes for the same JIRA ticket during development. + -* In the future, generate this file by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [1.1.5](https://github.com/rdkcentral/control/compare/1.1.4...1.1.5) -## [1.1.4] - 2025-09-17 +> 5 November 2025 -### Changed -- move certselector logic into ctrlm-main repo (#102) -- use version/branch from recipe (#109) +- RDKEMW-9924 : ctrlm RF4CE upgrade skipped when BLE enabled [`#137`](https://github.com/rdkcentral/control/pull/137) +- RDKEMW-7225: BLE pairing retries [`#126`](https://github.com/rdkcentral/control/pull/126) +- RDKEMW-8929: Refactor ctrlm_voice_ipc_t to inherit ctrlm_ipc_iarm_t [`#129`](https://github.com/rdkcentral/control/pull/129) +- Update CODEOWNERS [`#130`](https://github.com/rdkcentral/control/pull/130) +- RDKEMW-8815: only return SUCCESS for autolookup if it found at least 1 code. [`#125`](https://github.com/rdkcentral/control/pull/125) +- Deploy fossid_integration_stateless_diffscan_target_repo action [`#121`](https://github.com/rdkcentral/control/pull/121) +- Deploy cla action [`#74`](https://github.com/rdkcentral/control/pull/74) +- RDKEMW-8354: ctrlm-main crash while holding standby during OTA [`#115`](https://github.com/rdkcentral/control/pull/115) +- RDKEMW-8133: Optional param name for voiceSessionRequest [`#108`](https://github.com/rdkcentral/control/pull/108) -### Added -- update AMC APP key mapping (#98) +#### [1.1.4](https://github.com/rdkcentral/control/compare/1.1.3...1.1.4) -### Fixed -- getNetStatus call time out due to SAT download retries (#97) -- remove device from bluez during factory reset (#100) -- Missing Thunder cflags in ctrlm implemenation (#103) +> 18 September 2025 -### Removed -- remove ctrlm compile flags (#104) -- remove ctrlm build flags - CPC, DUNFELL (#105) -- remove ctrlm build flags - RF4CE_PACKET_ANALYSIS (#107) -- remove ctrlm build flags - DISABLE_BLE_VOICE (#106) +- RDKEMW-8349 : ctrlm release v1.1.4 [`#113`](https://github.com/rdkcentral/control/pull/113) +- RDKEMW-7979 : use version/branch from recipe [`#109`](https://github.com/rdkcentral/control/pull/109) +- RDKEMW-7122 : Missing Thunder cflags in ctrlm implementation [`#103`](https://github.com/rdkcentral/control/pull/103) +- RDKEMW-7772 : remove ctrlm build flags - DISABLE_BLE_VOICE [`#106`](https://github.com/rdkcentral/control/pull/106) +- RDKEMW-7834 : remove ctrlm build flags - RF4CE_PACKET_ANALYSIS [`#107`](https://github.com/rdkcentral/control/pull/107) +- RDKEMW-7694 : remove ctrlm build flags - CPC, DUNFELL [`#105`](https://github.com/rdkcentral/control/pull/105) +- RDKEMW-7573 : remove ctrlm compile flags [`#104`](https://github.com/rdkcentral/control/pull/104) +- RDKEMW-7333: remove device from bluez during factory reset [`#100`](https://github.com/rdkcentral/control/pull/100) +- RDKEMW-6767: getNetStatus call time out due to SAT download retries [`#97`](https://github.com/rdkcentral/control/pull/97) +- RDKEMW-3409 : move certselector logic into ctrlm-main repo [`#102`](https://github.com/rdkcentral/control/pull/102) +- RDKEMW-7174 : update AMC APP key mapping [`#98`](https://github.com/rdkcentral/control/pull/98) -## [1.1.3] - 2025-08-19 +#### [1.1.3](https://github.com/rdkcentral/control/compare/1.1.2...1.1.3) -### Changed -- Modify Remote Control plugin for RF4CE support (#80) -- Mac address fetch (#92) +> 19 August 2025 -### Added -- Runtime detection of ASB (#96) +- RDKEMW-7232: update CHANGELOG for controlMgr release v1.1.3 [`#99`](https://github.com/rdkcentral/control/pull/99) +- RDKEMW-5576: ctrlm mac address fetch [`#92`](https://github.com/rdkcentral/control/pull/92) +- RDKEMW-4309 : Modify Remote Control plugin for RF4CE support [`#80`](https://github.com/rdkcentral/control/pull/80) +- RDKEMW-5604 : runtime detection of ASB [`#96`](https://github.com/rdkcentral/control/pull/96) -## [1.1.2] - 2025-08-04 +#### [1.1.2](https://github.com/rdkcentral/control/compare/1.1.1...1.1.2) -### Changed -- use HdmiCecSource instead of deprecated HdmiCec (#93) -- update key code mapping (#91) -- stop BLE audio stream on the RCU when server ends session early (#76) +> 18 August 2025 -### Added -- BLE network discovery (#94) -- try to load VL provided IRDB, upon failure fallback to existing IRDB in MW (#79) -- print raw EDID data at debug log level +- RDKEMW-6034: update CHANGELOG for controlMgr release v1.1.2 [`#95`](https://github.com/rdkcentral/control/pull/95) +- RDKEMW-6538: use HdmiCecSource instead of deprecated HdmiCec [`#93`](https://github.com/rdkcentral/control/pull/93) +- RDKEMW-6383 : update key code mapping [`#91`](https://github.com/rdkcentral/control/pull/91) +- RDKEMW-3797 : BLE network discovery [`#94`](https://github.com/rdkcentral/control/pull/94) +- RDKEMW-6195: try to load VL provided IRDB, upon failure fallback to existing IRDB in MW [`#79`](https://github.com/rdkcentral/control/pull/79) +- RDKEMW-5714: Voice not initiated in ctrlm-main [`#81`](https://github.com/rdkcentral/control/pull/81) +- RDKEMW-6884: Logs indicate missing receiver ID [`#85`](https://github.com/rdkcentral/control/pull/85) +- RDKEMW-5413 : Remove RF4CE HAL from the middleware layer [`#75`](https://github.com/rdkcentral/control/pull/75) +- RDKEMW-5506 : stop BLE audio stream on the RCU when server ends session early [`#76`](https://github.com/rdkcentral/control/pull/76) +- RDKEMW-3965: print raw EDID data at debug log level [`447ae08`](https://github.com/rdkcentral/control/commit/447ae0826d15351fa97ccb12b3b18f435ff40089) -### Fixed -- Voice not initiated due to voice key not initialized to default value - -### Removed -- remove receiver ID, its no longer used (#85) -- Remove RF4CE HAL from the middleware layer (#75) +#### [1.1.1](https://github.com/rdkcentral/control/compare/1.1.0...1.1.1) - +> 30 June 2025 -## [1.1.1] - 2025-06-25 +- RDKEMW-4913: ctrlm release v1.1.1 [`#77`](https://github.com/rdkcentral/control/pull/77) +- RDKEMW-4788: use HDMI Input plugin RDKV and AVInput RDKE [`#67`](https://github.com/rdkcentral/control/pull/67) +- RDKEMW-5247 : BLE audio pipe size too small [`#68`](https://github.com/rdkcentral/control/pull/68) +- RDKEMW-3411 : receive RF4CE IR binding key codes over IR input device [`#69`](https://github.com/rdkcentral/control/pull/69) +- RDKEMW-3563: Enable ASB [`#63`](https://github.com/rdkcentral/control/pull/63) +- RDKEMW-3119: Control Manager to use Power Manager Thunder Plugin [`07c1d22`](https://github.com/rdkcentral/control/commit/07c1d222b5d99849713a4db8dcef3bd847380f4b) -### Changed -- Use the deprecated HDMI Input plugin instead of the new AV Input plugin if compile flag is set +#### [1.1.0](https://github.com/rdkcentral/control/compare/1.0.10...1.1.0) -### Fixed -- BLE audio pipe size too small, set minimum size -- enable RF4CE Advanced Secure Binding (ASB) +> 30 June 2025 -### Added -- receive RF4CE IR binding key codes over IR input device -- use new Power Manager Thunder Plugin for power state events, switch to deprecated IARM interface with compile flag - +- RDKEMW-4793: ctrlm release v1.1.0 [`#61`](https://github.com/rdkcentral/control/pull/61) +- RDKEMW-3408: [ctrlm] refactor interface to ctrlm IR Database for Vendor layer integration [`#18`](https://github.com/rdkcentral/control/pull/18) +- RDKEMW-3798 : RF4CE network discovery [`#53`](https://github.com/rdkcentral/control/pull/53) +- RDKEMW-3410 : Default BLE controller type list [`#29`](https://github.com/rdkcentral/control/pull/29) +- RDKEMW-4381: ctrlm crash during OTA interrupted by unpair or reset [`#54`](https://github.com/rdkcentral/control/pull/54) -## [1.1.0] - 2025-05-30 +#### [1.0.10](https://github.com/rdkcentral/control/compare/1.0.9...1.0.10) -### Changed -- move thunder and IARM dependencies from irdb to ctrlm -- load irdb library as a plugin with dlopen -- use AVInput instead of HDMI Input thunder plugin for HDMI Infoframes +> 4 June 2025 -### Added -- new interface to ctrlm IRDB -- Default BLE controller type list -- RF4CE network discovery at runtime instead of compile time +- RDKEMW-4424: update CHANGELOG for release 1.0.10 [`#55`](https://github.com/rdkcentral/control/pull/55) +- RDKEMW-3916: ctrlm crash from main queue msgs getting to networks prior to initialization [`#38`](https://github.com/rdkcentral/control/pull/38) +- RDKEMW-4146: ctrlm support both old and new deviceType [`#48`](https://github.com/rdkcentral/control/pull/48) +- RDKEMW-3918 : Control manager crashes on rapid MIC button presses [`#42`](https://github.com/rdkcentral/control/pull/42) +- RDK-56578 : Changed deviceType from tv to IpTv. [`#34`](https://github.com/rdkcentral/control/pull/34) +- RDKEMW-3609 : extend adpcm frame info [`#28`](https://github.com/rdkcentral/control/pull/28) +- RDKEMW-3916: IARM calls registered too early [`ae82b1e`](https://github.com/rdkcentral/control/commit/ae82b1e66f70d6f621eb3c680b7bf870379bd84c) +- RDKEMW-3835 - [Logging] Add Invalid firmware version OTA error code (0x8) mapping in ctrlmgr logs [`80e4d59`](https://github.com/rdkcentral/control/commit/80e4d59e841f3e9744fc6d3dd92b8bccec26c3ea) -### Fixed -- crash during OTA interrupted by unpair or reset +#### [1.0.9](https://github.com/rdkcentral/control/compare/1.0.8...1.0.9) +> 7 May 2025 -## [1.0.10] - 2025-05-16 +- update CHANGELOG for controlMgr release 1.0.9 [`#35`](https://github.com/rdkcentral/control/pull/35) +- RDKEMW-3737:Upgrading the halif-headers as iarmmgr [`#30`](https://github.com/rdkcentral/control/pull/30) +- RDKEMW-3564 : Audio samples is always reported as 0 for FFV sessions [`2920c1a`](https://github.com/rdkcentral/control/commit/2920c1a455d1e1afe1d095c0b09fd841a305974d) +- RDKEMW-3605: Remove 'volatile' type qualifier of "binding_in_progress" [`a7d2310`](https://github.com/rdkcentral/control/commit/a7d23104a3b961a26621a1c688ba775c3fe2ad3f) -### Changed -- ctrlm crash from main queue msgs getting to networks prior to initialization -- ctrlm support both old and new deviceType -- Control manager crashes on rapid MIC button presses -- [Logging] Add Invalid firmware version OTA error code (0x8) mapping in ctrlmgr logs -- Changed deviceType from tv to IpTv. -- Extend adpcm frame info. +#### [1.0.8](https://github.com/rdkcentral/control/compare/1.0.7...1.0.8) +> 28 April 2025 -## [1.0.9] - 2025-04-28 +- update CHANGELOG for controlMgr release 1.0.8 [`#25`](https://github.com/rdkcentral/control/pull/25) +- RDKEMW-3276: common udev node and provide list of possible names for IR input device discovery [`#20`](https://github.com/rdkcentral/control/pull/20) -### Changed -- Audio samples is always reported as 0 for FFV sessions -- Remove 'volatile' type qualifier of "binding_in_progress" -- Upgrading the halif-headers as iarmmgr +#### [1.0.7](https://github.com/rdkcentral/control/compare/1.0.6...1.0.7) +> 10 April 2025 -## [1.0.8] - 2025-04-15 - -### Changed -- use list of all possible names for IR input device discovery instead of product specific config - - -## [1.0.7] - 2025-03-31 - -### Changed +- XCTRL-400: add irdb stub implementation if ctrlm-hal-irdb lib does not exist [`#17`](https://github.com/rdkcentral/control/pull/17) +- Merge pull request #14 from rdkcentral/feature/XCTRL-400_rdkv_code_sy… [`#16`](https://github.com/rdkcentral/control/pull/16) +- XCTRL-400: RDKE Release 2025-03-31 (ctrlm v1.0.7) [`#14`](https://github.com/rdkcentral/control/pull/14) - Rationalize Voice Logging - move auth from ctrlm-cpc to ctrlm-main - Add ctrlm HAL certificate interace - Remove irMgr dependencies in controlMgr - create HAL interface for platform specific IRDBs - -### Added - BLE audio stream end time telemetry - voice stream telemetry in single line/event - -### Fixed - Type-Z OTA bug - Remote type changed to type-Z early - controlMgr maintenance time crash at onInitializedTimer @@ -145,28 +135,35 @@ All notable changes to this project will be documented in this file. - Logline error event rcu firmware status -## [1.0.6] - 2025-03-18 +#### [1.0.6](https://github.com/rdkcentral/control/compare/1.0.5...1.0.6) -### Added +> 18 March 2025 + +- RDKEMW-1397: IR input device name move to config file [`#1`](https://github.com/rdkcentral/control/pull/1) +- RDKEMW-1783: controlMgr crash at onInitializedTimer when going to dee… [`#11`](https://github.com/rdkcentral/control/pull/11) - custom target to build ctrlm config file only - additional config override file that can be provided by vendor layer +#### [1.0.5](https://github.com/rdkcentral/control/compare/1.0.4...1.0.5) + +> 25 February 2025 -## [1.0.5] - 2025-02-24 +- RDKEMW-1783: controlMgr crash at onInitializedTimer when going to deepsleep [`#10`](https://github.com/rdkcentral/control/pull/10) -### Changed -- crash at onInitializedTimer when going to deepsleep +#### [1.0.4](https://github.com/rdkcentral/control/compare/1.0.3...1.0.4) +> 25 February 2025 -## [1.0.4] - 2025-02-20 +- RDKEMW-1890: Remove irMgr dependencies in controlMgr [`#6`](https://github.com/rdkcentral/control/pull/6) -### Changed -- removed references to deprecated irMgr component +#### 1.0.3 -## [1.0.3] - 2025-02-07 +> 13 February 2025 -### Changed +- XCTRL-379: CTRLM RDKE Release 2025-02-07 [`#4`](https://github.com/rdkcentral/control/pull/4) +- XCTRL-379: CTRLM RDKE Release 2025-02-07 [`#3`](https://github.com/rdkcentral/control/pull/3) +- Import of source (develop) [`83e2f7b`](https://github.com/rdkcentral/control/commit/83e2f7bd1f5a179b47e0278f49e17466f4b1c457) - check that a file descriptor is valid before FD_SET() - standardize use of singleton pattern ctrlm - speed up BLE auto pairing and surface failures immediately @@ -176,16 +173,13 @@ All notable changes to this project will be documented in this file. - remove legacy url_vrex config field - Add ctrlm Support for XRA BLE key - QAM - ControlMgr crash pairWithMacHash when going to deepsleep - -### Added - RemoteControl plugin methods to pair and unpair targetted RCU devices based on MAC - RemoteControl plugin methods to trigger RCU firmware upgrade and report status of upgrade - ctrlm-factory added to this repo, its no longer a separate repo +#### 1.0.2 -## [1.0.2] - 2024-12-06 - -### Changed +> 6 December 2024 - ctrlm IR uinput device match exact name, simplify IR-initiated BLE pairing event handling - Check for Invalid avDevType - move stop audio stream to separate non iarm related function @@ -194,7 +188,5 @@ All notable changes to this project will be documented in this file. - Detect the platform type (TV vs STB) using DeviceInfo plugin - IR keypresses use same PII mask variable as Voice - fix "last wakeup key code" not received, along with defering gdbus proxy calls for characteristics until they are needed. - -### Added - unit test function to set IR protocol support characteristic on RCU - Added Alexa voice service support in SDT endpoint, along with async voice message support From 47055905f3409ff0e4b53652c14f59268fe6bee5 Mon Sep 17 00:00:00 2001 From: dwolaver <44593664+dwolaver@users.noreply.github.com> Date: Thu, 13 Nov 2025 10:14:03 -0500 Subject: [PATCH 02/39] RDKEMW-10311 : RF4CE update key mapping (#140) --- src/input_event/ctrlm_input_event_writer.h | 3 ++- src/rf4ce/ctrlm_rf4ce_network.cpp | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/input_event/ctrlm_input_event_writer.h b/src/input_event/ctrlm_input_event_writer.h index 54d7c51d..c05876e0 100644 --- a/src/input_event/ctrlm_input_event_writer.h +++ b/src/input_event/ctrlm_input_event_writer.h @@ -66,7 +66,7 @@ const std::map ctrlm_key_to_linux_map {CTRLM_KEY_CODE_CH_DOWN, linux_ui_code_values_t(KEY_PAGEDOWN, 0x59, KEY_LEFTCTRL)}, {CTRLM_KEY_CODE_LAST, linux_ui_code_values_t(KEY_ESC, 0x0, KEY_LEFTCTRL)}, {CTRLM_KEY_CODE_INPUT_SELECT, linux_ui_code_values_t(KEY_F15, 0x0, KEY_RESERVED)}, - {CTRLM_KEY_CODE_INFO, linux_ui_code_values_t(KEY_F9, 0xcb, KEY_LEFTCTRL)}, + {CTRLM_KEY_CODE_INFO, linux_ui_code_values_t(KEY_F20, 0x0, KEY_RESERVED)}, {CTRLM_KEY_CODE_VOL_UP, linux_ui_code_values_t(KEY_KPPLUS, 0x0, KEY_RESERVED)}, {CTRLM_KEY_CODE_VOL_DOWN, linux_ui_code_values_t(KEY_KPMINUS, 0x0, KEY_RESERVED)}, {CTRLM_KEY_CODE_MUTE, linux_ui_code_values_t(KEY_KPASTERISK, 0x0, KEY_RESERVED)}, @@ -86,6 +86,7 @@ const std::map ctrlm_key_to_linux_map {CTRLM_KEY_CODE_OCAP_C, linux_ui_code_values_t(KEY_RESERVED, 0x0, KEY_RESERVED)}, {CTRLM_KEY_CODE_OCAP_D, linux_ui_code_values_t(KEY_RESERVED, 0x0, KEY_RESERVED)}, {CTRLM_KEY_CODE_ASTERISK, linux_ui_code_values_t(KEY_F14, 0x0, KEY_RESERVED)}, + {CTRLM_KEY_CODE_PUSH_TO_TALK, linux_ui_code_values_t(KEY_F8, 0x0, KEY_RESERVED)} }; enum class key_stroke { diff --git a/src/rf4ce/ctrlm_rf4ce_network.cpp b/src/rf4ce/ctrlm_rf4ce_network.cpp index f01c52d5..de5a22ff 100644 --- a/src/rf4ce/ctrlm_rf4ce_network.cpp +++ b/src/rf4ce/ctrlm_rf4ce_network.cpp @@ -3660,6 +3660,11 @@ void ctrlm_obj_network_rf4ce_t::ind_process_voice_session_request(void *data, in device_type = CTRLM_VOICE_DEVICE_FF; } + if(device_type == CTRLM_VOICE_DEVICE_PTT) { + // Send voice key down event since the session was requested + process_event_key(dqm->controller_id, CTRLM_KEY_STATUS_DOWN, CTRLM_KEY_CODE_PUSH_TO_TALK); + } + bool command_status = (controller_type == RF4CE_CONTROLLER_TYPE_XR11 || controller_type == RF4CE_CONTROLLER_TYPE_XR19) ? true : false; @@ -3842,6 +3847,11 @@ void ctrlm_obj_network_rf4ce_t::ind_process_voice_session_request(void *data, in property.state = CTRLM_HAL_FREQUENCY_AGILITY_ENABLE; ctrlm_network_property_set(network_id_get(), CTRLM_HAL_NETWORK_PROPERTY_FREQUENCY_AGILITY, (void *)&property, sizeof(property)); } + + if(device_type == CTRLM_VOICE_DEVICE_PTT) { + // Send voice key up event since the session was not accepted + process_event_key(dqm->controller_id, CTRLM_KEY_STATUS_UP, CTRLM_KEY_CODE_PUSH_TO_TALK); + } } if(dqm->status != VOICE_SESSION_RESPONSE_AVAILABLE && dqm->status != VOICE_SESSION_RESPONSE_AVAILABLE_SKIP_CHAN_CHECK) { // Session was aborted @@ -3937,6 +3947,17 @@ void ctrlm_obj_network_rf4ce_t::ind_process_voice_session_stop(void *data, int s g_assert(dqm); g_assert(size == sizeof(ctrlm_main_queue_msg_voice_session_stop_t)); + if(!controller_exists(dqm->controller_id)) { + XLOGD_INFO("invalid controller id (%u)", dqm->controller_id); + return; + } + + ctrlm_rf4ce_controller_type_t controller_type = controllers_[dqm->controller_id]->controller_type_get(); + if(!ctrlm_is_voice_assistant((ctrlm_rcu_controller_type_t) controller_type)) { + // Send voice key up event since the session stop was received + process_event_key(dqm->controller_id, CTRLM_KEY_STATUS_UP, CTRLM_KEY_CODE_PUSH_TO_TALK); + } + // Check adjacent key press if(CTRLM_VOICE_SESSION_END_REASON_OTHER_KEY_PRESSED == dqm->session_end_reason && true == is_key_adjacent(dqm->controller_id, dqm->key_code)) { dqm->session_end_reason = CTRLM_VOICE_SESSION_END_REASON_ADJACENT_KEY_PRESSED; From 07c0c95bb7591d17119c48227b54565d10dbd49f Mon Sep 17 00:00:00 2001 From: Kelvin Lu <119349872+klu339@users.noreply.github.com> Date: Mon, 17 Nov 2025 08:46:47 -0500 Subject: [PATCH 03/39] Revert "RDKEMW-8929 (#129)" (#145) This reverts commit b47d6f80fb75d1e00a647cc1802ae170272373a5. --- include/ctrlm_ipc_voice.h | 8 +- src/ipc/ctrlm_ipc_iarm.cpp | 44 +++++++-- src/ipc/ctrlm_ipc_iarm.h | 23 +---- src/ipc/ctrlm_rcp_ipc_event.cpp | 17 ++-- src/ipc/ctrlm_rcp_ipc_event.h | 16 ++-- src/ipc/ctrlm_rcp_ipc_iarm_thunder.cpp | 30 ++++++- src/voice/ipc/ctrlm_voice_ipc.h | 5 +- src/voice/ipc/ctrlm_voice_ipc_iarm_legacy.cpp | 25 ++++-- .../ipc/ctrlm_voice_ipc_iarm_thunder.cpp | 90 ++++++++++++++++--- 9 files changed, 187 insertions(+), 71 deletions(-) diff --git a/include/ctrlm_ipc_voice.h b/include/ctrlm_ipc_voice.h index 270b92d9..d5a58bc0 100644 --- a/include/ctrlm_ipc_voice.h +++ b/include/ctrlm_ipc_voice.h @@ -304,11 +304,11 @@ typedef struct { // IARM Event JSON // This structure is used for the following calls: -// CTRLM_VOICE_IARM_EVENT_SESSION_BEGIN_JSON -// CTRLM_VOICE_IARM_EVENT_STREAM_BEGIN_JSON +// CTRLM_VOICE_IARM_EVENT_SESSION_BEGIN_JSON +// CTRLM_VOICE_IARM_EVENT_STREAM_BEGIN_JSON // CTRLM_VOICE_IARM_EVENT_SERVER_MESSAGE_JSON -// CTRLM_VOICE_IARM_EVENT_STREAM_END_JSON -// CTRLM_VOICE_IARM_EVENT_SESSION_END_JSON +// CTRLM_VOICE_IARM_EVENT_STREAM_END_JSON +// CTRLM_VOICE_IARM_EVENT_SESSION_END_JSON // // The payload MUST be a NULL terminated JSON String. typedef struct { diff --git a/src/ipc/ctrlm_ipc_iarm.cpp b/src/ipc/ctrlm_ipc_iarm.cpp index 6d960196..b8d16842 100644 --- a/src/ipc/ctrlm_ipc_iarm.cpp +++ b/src/ipc/ctrlm_ipc_iarm.cpp @@ -35,12 +35,44 @@ bool ctrlm_ipc_iarm_t::register_iarm_call(const char *call, IARM_BusCall_t handl return(ret); } -bool ctrlm_ipc_iarm_t::broadcast_iarm_event_legacy(const char *bus_name, int event, void *data, size_t data_size) const { - bool ret = true; - IARM_Result_t result = IARM_Bus_BroadcastEvent(bus_name, event, data, data_size); - if(IARM_RESULT_SUCCESS != result) { - XLOGD_ERROR("IARM Bus Error!"); - ret = false; +bool ctrlm_ipc_iarm_t::broadcast_iarm_event(const char *bus_name, int event, json_t* event_data) const +{ + bool ret = false; + if(!event_data) { + return(ret); } + + char *payload_str = json_dumps(event_data, JSON_COMPACT); + + if(payload_str != NULL) { + size_t str_size = strlen(payload_str) + 1; + size_t size = sizeof(ctrlm_main_iarm_event_json_t) + str_size; + + ctrlm_main_iarm_event_json_t *data = (ctrlm_main_iarm_event_json_t *)calloc(1, size); + if (data == NULL) { + XLOGD_ERROR("failed to allocate memory for the IARM event, so cannot broadcast...."); + } else { + + data->api_revision = CTRLM_MAIN_IARM_BUS_API_REVISION; + //Can't be replaced with safeC version of this, as safeC string functions doesn't allow string size more than 4K + snprintf(data->payload, str_size, "%s", payload_str); + + IARM_Result_t res = IARM_Bus_BroadcastEvent(bus_name, event, data, size); + if(res != IARM_RESULT_SUCCESS) { + XLOGD_ERROR("IARM Bus Error %d", res); + } else { + ret = true; + } + + free(data); + } + + free(payload_str); + } + + if(event_data) { + json_decref(event_data); + } + return(ret); } diff --git a/src/ipc/ctrlm_ipc_iarm.h b/src/ipc/ctrlm_ipc_iarm.h index 78568186..c966c080 100644 --- a/src/ipc/ctrlm_ipc_iarm.h +++ b/src/ipc/ctrlm_ipc_iarm.h @@ -39,28 +39,7 @@ class ctrlm_ipc_iarm_t { static void turn_off(std::atomic_bool &abool) { abool.store(false); } bool register_iarm_call(const char *call, IARM_BusCall_t handler) const; - bool broadcast_iarm_event_legacy(const char *bus_name, int event, void *data, size_t data_size) const; - - template - bool broadcast_iarm_event(const char *bus_name, unsigned char api_revision, int event, const char *str) const { - bool ret = false; - size_t str_size = strlen(str) + 1; - size_t size = sizeof(T) + str_size; - T *data = (T *)calloc(1, size); - data->api_revision = api_revision; - if(!data) { - return(ret); - } else { - snprintf(data->payload, str_size, "%s", str); - if(IARM_Bus_BroadcastEvent(bus_name, event, data, size)) { - ret = true; - } - if(data) { - free(data); - } - } - return(ret); - } + bool broadcast_iarm_event(const char *bus_name, int event, json_t* event_data) const; }; #endif diff --git a/src/ipc/ctrlm_rcp_ipc_event.cpp b/src/ipc/ctrlm_rcp_ipc_event.cpp index 5c24208e..0ce44bae 100644 --- a/src/ipc/ctrlm_rcp_ipc_event.cpp +++ b/src/ipc/ctrlm_rcp_ipc_event.cpp @@ -135,12 +135,9 @@ void ctrlm_rcp_ipc_net_status_t::populate_status(const ctrlm_obj_network_t &netw } } -std::string ctrlm_base_event_json_t::to_string() const +char *ctrlm_rcp_ipc_net_status_t::to_string() const { - char *json_str = json_dumps(to_json(), JSON_ENCODE_ANY); - std::string copy = json_str; - free(json_str); - return copy; + return json_dumps(to_json(), JSON_ENCODE_ANY); } ctrlm_rcp_ipc_upgrade_status_t::~ctrlm_rcp_ipc_upgrade_status_t() @@ -173,6 +170,11 @@ json_t *ctrlm_rcp_ipc_upgrade_status_t::to_json() const return (err) ? NULL : status; } +char *ctrlm_rcp_ipc_upgrade_status_t::to_string() const +{ + return json_dumps(to_json(), JSON_ENCODE_ANY); +} + ctrlm_rcp_ipc_validation_status_t::~ctrlm_rcp_ipc_validation_status_t() { } @@ -214,3 +216,8 @@ json_t *ctrlm_rcp_ipc_validation_status_t::to_json() const return (err) ? NULL : status; } + +char *ctrlm_rcp_ipc_validation_status_t::to_string() const +{ + return json_dumps(to_json(), JSON_ENCODE_ANY); +} diff --git a/src/ipc/ctrlm_rcp_ipc_event.h b/src/ipc/ctrlm_rcp_ipc_event.h index bf31a823..ae257af6 100644 --- a/src/ipc/ctrlm_rcp_ipc_event.h +++ b/src/ipc/ctrlm_rcp_ipc_event.h @@ -63,18 +63,17 @@ namespace rcp_net_status_json_keys constexpr char const* ERROR_STRING = "errorString"; } -class ctrlm_base_event_json_t +class ctrlm_virtual_json_t { public: - virtual ~ctrlm_base_event_json_t() {}; + virtual ~ctrlm_virtual_json_t() {}; virtual json_t *to_json() const = 0; - virtual std::string to_string() const; }; class ctrlm_obj_controller_t; class ctrlm_obj_network_t; -class ctrlm_rcp_ipc_controller_status_t : public ctrlm_base_event_json_t +class ctrlm_rcp_ipc_controller_status_t : public ctrlm_virtual_json_t { public: ctrlm_rcp_ipc_controller_status_t() = default; @@ -104,7 +103,7 @@ class ctrlm_rcp_ipc_controller_status_t : public ctrlm_base_event_json_t std::string upgrade_session_id_ = ""; }; -class ctrlm_rcp_ipc_net_status_t : public ctrlm_base_event_json_t +class ctrlm_rcp_ipc_net_status_t : public ctrlm_virtual_json_t { public: ctrlm_rcp_ipc_net_status_t() = default; @@ -112,6 +111,7 @@ class ctrlm_rcp_ipc_net_status_t : public ctrlm_base_event_json_t virtual json_t *to_json() const; + char *to_string() const; uint8_t get_api_revision() const { return api_revision_; } bool get_result() const { return (result_ == CTRLM_IARM_CALL_RESULT_SUCCESS) ? true : false; } void set_result(ctrlm_iarm_call_result_t result) { result_ = result; } @@ -131,13 +131,14 @@ class ctrlm_rcp_ipc_net_status_t : public ctrlm_base_event_json_t std::vector controller_status_list_; }; -class ctrlm_rcp_ipc_upgrade_status_t : public ctrlm_base_event_json_t +class ctrlm_rcp_ipc_upgrade_status_t : public ctrlm_virtual_json_t { public: ctrlm_rcp_ipc_upgrade_status_t() = default; ~ctrlm_rcp_ipc_upgrade_status_t(); virtual json_t *to_json() const; + char *to_string() const; bool get_result() const { return (result_ == CTRLM_IARM_CALL_RESULT_SUCCESS) ? true : false; } void set_result(ctrlm_iarm_call_result_t result) { result_ = result; } ctrlm_network_id_t get_net_id() const { return net_id_; } @@ -155,13 +156,14 @@ class ctrlm_rcp_ipc_upgrade_status_t : public ctrlm_base_event_json_t ctrlm_iarm_call_result_t result_ = CTRLM_IARM_CALL_RESULT_INVALID; }; -class ctrlm_rcp_ipc_validation_status_t : public ctrlm_base_event_json_t +class ctrlm_rcp_ipc_validation_status_t : public ctrlm_virtual_json_t { public: ctrlm_rcp_ipc_validation_status_t() = default; ~ctrlm_rcp_ipc_validation_status_t(); virtual json_t *to_json() const; + char *to_string() const; uint8_t get_api_revision() const { return api_revision_; } bool get_result() const { return (result_ == CTRLM_IARM_CALL_RESULT_SUCCESS) ? true : false; } void set_result(ctrlm_iarm_call_result_t result) { result_ = result; } diff --git a/src/ipc/ctrlm_rcp_ipc_iarm_thunder.cpp b/src/ipc/ctrlm_rcp_ipc_iarm_thunder.cpp index 82a005bc..02f4128d 100644 --- a/src/ipc/ctrlm_rcp_ipc_iarm_thunder.cpp +++ b/src/ipc/ctrlm_rcp_ipc_iarm_thunder.cpp @@ -114,7 +114,18 @@ bool ctrlm_rcp_ipc_iarm_thunder_t::on_status(const ctrlm_rcp_ipc_net_status_t &n return(false); } - return broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_MAIN_IARM_BUS_API_REVISION, CTRLM_RCU_IARM_EVENT_RCU_STATUS, net_status.to_string().c_str()); + json_t *ret = json_object(); + int err = 0; + + err |= json_object_set_new_nocheck(ret, STATUS, net_status.to_json()); + + if (err) { + XLOGD_ERROR("JSON object set error"); + json_decref(ret); + return(false); + } + + return broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_RCU_IARM_EVENT_RCU_STATUS, ret); } bool ctrlm_rcp_ipc_iarm_thunder_t::on_validation_status(const ctrlm_rcp_ipc_validation_status_t &validation_status) const @@ -129,7 +140,18 @@ bool ctrlm_rcp_ipc_iarm_thunder_t::on_validation_status(const ctrlm_rcp_ipc_vali return(false); } - return broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_MAIN_IARM_BUS_API_REVISION, CTRLM_RCU_IARM_EVENT_VALIDATION_STATUS, validation_status.to_string().c_str()); + json_t *ret = json_object(); + int err = 0; + + err |= json_object_set_new_nocheck(ret, STATUS, validation_status.to_json()); + + if (err) { + XLOGD_ERROR("JSON object set error"); + json_decref(ret); + return(false); + } + + return broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_RCU_IARM_EVENT_VALIDATION_STATUS, ret); } bool ctrlm_rcp_ipc_iarm_thunder_t::on_firmware_update_progress(const ctrlm_rcp_ipc_upgrade_status_t &upgrade_status) const @@ -155,7 +177,7 @@ bool ctrlm_rcp_ipc_iarm_thunder_t::on_firmware_update_progress(const ctrlm_rcp_i return(false); } - return broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_MAIN_IARM_BUS_API_REVISION, CTRLM_RCU_IARM_EVENT_FIRMWARE_UPDATE_PROGRESS, upgrade_status.to_string().c_str()); + return broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_RCU_IARM_EVENT_FIRMWARE_UPDATE_PROGRESS, ret); } bool ctrlm_rcp_ipc_iarm_thunder_t::on_validation(const ctrlm_rcp_ipc_validation_status_t &validation_status) const @@ -176,7 +198,7 @@ bool ctrlm_rcp_ipc_iarm_thunder_t::on_validation(const ctrlm_rcp_ipc_validation_ return(false); } - return broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_MAIN_IARM_BUS_API_REVISION, CTRLM_RCU_IARM_EVENT_VALIDATION_STATUS, validation_status.to_string().c_str()); + return broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_RCU_IARM_EVENT_VALIDATION_STATUS, ret); } IARM_Result_t ctrlm_rcp_ipc_iarm_thunder_t::start_pairing(void *arg) diff --git a/src/voice/ipc/ctrlm_voice_ipc.h b/src/voice/ipc/ctrlm_voice_ipc.h index 969a8380..25197ff8 100644 --- a/src/voice/ipc/ctrlm_voice_ipc.h +++ b/src/voice/ipc/ctrlm_voice_ipc.h @@ -22,7 +22,6 @@ #include "ctrlm.h" #include "ctrlm_voice_types.h" #include "ctrlm_ipc_voice.h" -#include "ctrlm_ipc_iarm.h" // Classes for eventing @@ -172,7 +171,7 @@ class ctrlm_voice_ipc_event_session_statistics_t { }; // End classes for eventing -class ctrlm_voice_ipc_t : public ctrlm_ipc_iarm_t { +class ctrlm_voice_ipc_t { public: ctrlm_voice_ipc_t(ctrlm_voice_t *obj_voice) { this->obj_voice = obj_voice; @@ -180,6 +179,7 @@ class ctrlm_voice_ipc_t : public ctrlm_ipc_iarm_t { virtual ~ctrlm_voice_ipc_t() {}; // Interface + virtual bool register_ipc() const = 0; virtual bool session_begin(const ctrlm_voice_ipc_event_session_begin_t &session_begin) = 0; virtual bool stream_begin(const ctrlm_voice_ipc_event_stream_begin_t &stream_begin) = 0; virtual bool stream_end(const ctrlm_voice_ipc_event_stream_end_t &stream_end) = 0; @@ -187,6 +187,7 @@ class ctrlm_voice_ipc_t : public ctrlm_ipc_iarm_t { virtual bool server_message(const char *message, unsigned long size) = 0; // Pass a pointer to the message to avoid copying possible large chunks of data virtual bool keyword_verification(const ctrlm_voice_ipc_event_keyword_verification_t &keyword_verification) = 0; virtual bool session_statistics(const ctrlm_voice_ipc_event_session_statistics_t &session_stats) = 0; + virtual void deregister_ipc() const = 0; // End Interface protected: diff --git a/src/voice/ipc/ctrlm_voice_ipc_iarm_legacy.cpp b/src/voice/ipc/ctrlm_voice_ipc_iarm_legacy.cpp index 1121e795..c07f22b1 100644 --- a/src/voice/ipc/ctrlm_voice_ipc_iarm_legacy.cpp +++ b/src/voice/ipc/ctrlm_voice_ipc_iarm_legacy.cpp @@ -23,6 +23,7 @@ #include "ctrlm_voice_obj.h" static IARM_Result_t update_settings(void *arg); +static bool broadcast_event(const char *bus_name, int event, void *data, size_t data_size); ctrlm_voice_ipc_iarm_legacy_t::ctrlm_voice_ipc_iarm_legacy_t(ctrlm_voice_t *obj_voice) : ctrlm_voice_ipc_t(obj_voice) { this->state = EVENT_ALL; @@ -67,7 +68,7 @@ bool ctrlm_voice_ipc_iarm_legacy_t::session_begin(const ctrlm_voice_ipc_event_se safec_rc = strcpy_s((char *)event.language, sizeof(event.language), session_begin.language.c_str()); ERR_CHK(safec_rc); event.is_voice_assistant = session_begin.common.voice_assistant ? 1 : 0; - ret = broadcast_iarm_event_legacy(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_SESSION_BEGIN, &event, sizeof(event)); + ret = broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_SESSION_BEGIN, &event, sizeof(event)); } return(ret); } @@ -89,7 +90,7 @@ bool ctrlm_voice_ipc_iarm_legacy_t::stream_end(const ctrlm_voice_ipc_event_strea event.session_id = stream_end.common.session_id_ctrlm; event.reason = (ctrlm_voice_session_end_reason_t)stream_end.reason; event.is_voice_assistant = stream_end.common.voice_assistant ? 1 : 0; - ret = broadcast_iarm_event_legacy(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_SESSION_END, &event, sizeof(event)); + ret = broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_SESSION_END, &event, sizeof(event)); } return(ret); } @@ -132,7 +133,7 @@ bool ctrlm_voice_ipc_iarm_legacy_t::session_end(const ctrlm_voice_ipc_event_sess event.curl_request_dns_time = session_end.server_stats->dns_time; event.curl_request_connect_time = session_end.server_stats->connect_time; } - ret = broadcast_iarm_event_legacy(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_SESSION_RESULT, &event, sizeof(event)); + ret = broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_SESSION_RESULT, &event, sizeof(event)); break; } case SESSION_END_ABORT: { @@ -143,7 +144,7 @@ bool ctrlm_voice_ipc_iarm_legacy_t::session_end(const ctrlm_voice_ipc_event_sess event.controller_id = session_end.common.controller_id; event.session_id = session_end.common.session_id_ctrlm; event.reason = (ctrlm_voice_session_abort_reason_t)session_end.reason; - ret = broadcast_iarm_event_legacy(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_SESSION_ABORT, &event, sizeof(event)); + ret = broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_SESSION_ABORT, &event, sizeof(event)); break; } case SESSION_END_SHORT_UTTERANCE: { @@ -155,7 +156,7 @@ bool ctrlm_voice_ipc_iarm_legacy_t::session_end(const ctrlm_voice_ipc_event_sess event.session_id = session_end.common.session_id_ctrlm; event.reason = (ctrlm_voice_session_end_reason_t)session_end.reason; event.return_code_internal = session_end.return_code_internal; - ret = broadcast_iarm_event_legacy(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_SESSION_SHORT, &event, sizeof(event)); + ret = broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_SESSION_SHORT, &event, sizeof(event)); break; } } @@ -194,7 +195,7 @@ bool ctrlm_voice_ipc_iarm_legacy_t::session_statistics(const ctrlm_voice_ipc_eve event.session_id = session_stats.common.session_id_ctrlm; event.session = session_stats.session; event.reboot = session_stats.reboot; - return(broadcast_iarm_event_legacy(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_SESSION_STATS, &event, sizeof(event))); + return(broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_SESSION_STATS, &event, sizeof(event))); } void ctrlm_voice_ipc_iarm_legacy_t::deregister_ipc() const { @@ -228,4 +229,14 @@ IARM_Result_t update_settings(void *arg) { } return(IARM_RESULT_SUCCESS); -} \ No newline at end of file +} + +bool broadcast_event(const char *bus_name, int event, void *data, size_t data_size) { + bool ret = true; + IARM_Result_t result = IARM_Bus_BroadcastEvent(bus_name, event, data, data_size); + if(IARM_RESULT_SUCCESS != result) { + XLOGD_ERROR("IARM Bus Error!"); + ret = false; + } + return(ret); +} diff --git a/src/voice/ipc/ctrlm_voice_ipc_iarm_thunder.cpp b/src/voice/ipc/ctrlm_voice_ipc_iarm_thunder.cpp index ad9cc5db..1dfa80b8 100644 --- a/src/voice/ipc/ctrlm_voice_ipc_iarm_thunder.cpp +++ b/src/voice/ipc/ctrlm_voice_ipc_iarm_thunder.cpp @@ -83,6 +83,7 @@ #define JSON_SESSION_END_SERVER_STATS_DNS_TIME "dnsTime" #define JSON_SESSION_END_SERVER_STATS_CONNECT_TIME "connectTime" +static bool broadcast_event(const char *bus_name, int event, const char *str); static const char *voice_device_str(ctrlm_voice_device_t device); static const char *voice_device_status_str(uint8_t status); @@ -92,31 +93,63 @@ ctrlm_voice_ipc_iarm_thunder_t::ctrlm_voice_ipc_iarm_thunder_t(ctrlm_voice_t *ob bool ctrlm_voice_ipc_iarm_thunder_t::register_ipc() const { bool ret = true; + IARM_Result_t rc; XLOGD_INFO("Thunder"); // NOTE: The IARM events are registered in ctrlm_main.cpp - if(!register_iarm_call(CTRLM_VOICE_IARM_CALL_STATUS, &ctrlm_voice_ipc_iarm_thunder_t::status)) { + XLOGD_INFO("Registering for %s IARM call", CTRLM_VOICE_IARM_CALL_STATUS); + rc = IARM_Bus_RegisterCall(CTRLM_VOICE_IARM_CALL_STATUS, &ctrlm_voice_ipc_iarm_thunder_t::status); + if(rc != IARM_RESULT_SUCCESS) { + XLOGD_ERROR("Failed to register %d", rc); ret = false; } - if(!register_iarm_call(CTRLM_VOICE_IARM_CALL_CONFIGURE_VOICE, &ctrlm_voice_ipc_iarm_thunder_t::configure_voice)) { + + XLOGD_INFO("Registering for %s IARM call", CTRLM_VOICE_IARM_CALL_CONFIGURE_VOICE); + rc = IARM_Bus_RegisterCall(CTRLM_VOICE_IARM_CALL_CONFIGURE_VOICE, &ctrlm_voice_ipc_iarm_thunder_t::configure_voice); + if(rc != IARM_RESULT_SUCCESS) { + XLOGD_ERROR("Failed to register %d", rc); ret = false; } - if(!register_iarm_call(CTRLM_VOICE_IARM_CALL_SET_VOICE_INIT, &ctrlm_voice_ipc_iarm_thunder_t::set_voice_init)) { + + XLOGD_INFO("Registering for %s IARM call", CTRLM_VOICE_IARM_CALL_SET_VOICE_INIT); + rc = IARM_Bus_RegisterCall(CTRLM_VOICE_IARM_CALL_SET_VOICE_INIT, &ctrlm_voice_ipc_iarm_thunder_t::set_voice_init); + if(rc != IARM_RESULT_SUCCESS) { + XLOGD_ERROR("Failed to register %d", rc); ret = false; } - if(!register_iarm_call(CTRLM_VOICE_IARM_CALL_SEND_VOICE_MESSAGE, &ctrlm_voice_ipc_iarm_thunder_t::send_voice_message)) { + + XLOGD_INFO("Registering for %s IARM call", CTRLM_VOICE_IARM_CALL_SEND_VOICE_MESSAGE); + rc = IARM_Bus_RegisterCall(CTRLM_VOICE_IARM_CALL_SEND_VOICE_MESSAGE, &ctrlm_voice_ipc_iarm_thunder_t::send_voice_message); + if(rc != IARM_RESULT_SUCCESS) { + XLOGD_ERROR("Failed to register %d", rc); ret = false; } - if(!register_iarm_call(CTRLM_VOICE_IARM_CALL_SESSION_TYPES, &ctrlm_voice_ipc_iarm_thunder_t::voice_session_types)) { + + XLOGD_INFO("Registering for %s IARM call", CTRLM_VOICE_IARM_CALL_SESSION_TYPES); + rc = IARM_Bus_RegisterCall(CTRLM_VOICE_IARM_CALL_SESSION_TYPES, &ctrlm_voice_ipc_iarm_thunder_t::voice_session_types); + if(rc != IARM_RESULT_SUCCESS) { + XLOGD_ERROR("Failed to register %d", rc); ret = false; } - if(!register_iarm_call(CTRLM_VOICE_IARM_CALL_SESSION_REQUEST, &ctrlm_voice_ipc_iarm_thunder_t::voice_session_request)) { + + XLOGD_INFO("Registering for %s IARM call", CTRLM_VOICE_IARM_CALL_SESSION_REQUEST); + rc = IARM_Bus_RegisterCall(CTRLM_VOICE_IARM_CALL_SESSION_REQUEST, &ctrlm_voice_ipc_iarm_thunder_t::voice_session_request); + if(rc != IARM_RESULT_SUCCESS) { + XLOGD_ERROR("Failed to register %d", rc); ret = false; } - if(!register_iarm_call(CTRLM_VOICE_IARM_CALL_SESSION_TERMINATE, &ctrlm_voice_ipc_iarm_thunder_t::voice_session_terminate)) { + + XLOGD_INFO("Registering for %s IARM call", CTRLM_VOICE_IARM_CALL_SESSION_TERMINATE); + rc = IARM_Bus_RegisterCall(CTRLM_VOICE_IARM_CALL_SESSION_TERMINATE, &ctrlm_voice_ipc_iarm_thunder_t::voice_session_terminate); + if(rc != IARM_RESULT_SUCCESS) { + XLOGD_ERROR("Failed to register %d", rc); ret = false; } - if(!register_iarm_call(CTRLM_VOICE_IARM_CALL_SESSION_AUDIO_STREAM_START, &ctrlm_voice_ipc_iarm_thunder_t::voice_session_audio_stream_start)) { + + XLOGD_INFO("Registering for %s IARM call", CTRLM_VOICE_IARM_CALL_SESSION_AUDIO_STREAM_START); + rc = IARM_Bus_RegisterCall(CTRLM_VOICE_IARM_CALL_SESSION_AUDIO_STREAM_START, &ctrlm_voice_ipc_iarm_thunder_t::voice_session_audio_stream_start); + if(rc != IARM_RESULT_SUCCESS) { + XLOGD_ERROR("Failed to register %d", rc); ret = false; } @@ -142,7 +175,7 @@ bool ctrlm_voice_ipc_iarm_thunder_t::session_begin(const ctrlm_voice_ipc_event_s if(json_str) { //TODO: surface the event through IARM XLOGD_INFO("%s", json_str); - ret = broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_BUS_API_REVISION, CTRLM_VOICE_IARM_EVENT_JSON_SESSION_BEGIN, json_str); + ret = broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_JSON_SESSION_BEGIN, json_str); free(json_str); } else { XLOGD_ERROR("Failed to encode JSON string"); @@ -171,7 +204,7 @@ bool ctrlm_voice_ipc_iarm_thunder_t::stream_begin(const ctrlm_voice_ipc_event_st if(json_str) { //TODO: surface the event through IARM XLOGD_INFO("%s", json_str); - ret = broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_BUS_API_REVISION, CTRLM_VOICE_IARM_EVENT_JSON_STREAM_BEGIN, json_str); + ret = broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_JSON_STREAM_BEGIN, json_str); free(json_str); } else { XLOGD_ERROR("Failed to encode JSON string"); @@ -201,7 +234,7 @@ bool ctrlm_voice_ipc_iarm_thunder_t::stream_end(const ctrlm_voice_ipc_event_stre if(json_str) { //TODO: surface the event through IARM XLOGD_INFO("%s", json_str); - ret = broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_BUS_API_REVISION, CTRLM_VOICE_IARM_EVENT_JSON_STREAM_END, json_str); + ret = broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_JSON_STREAM_END, json_str); free(json_str); } else { XLOGD_ERROR("Failed to encode JSON string"); @@ -325,7 +358,7 @@ bool ctrlm_voice_ipc_iarm_thunder_t::session_end(const ctrlm_voice_ipc_event_ses if(json_str) { //TODO: surface the event through IARM XLOGD_INFO("<%s>", this->obj_voice->voice_stb_data_pii_mask_get() ? "***" : json_str); - ret = broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_BUS_API_REVISION, CTRLM_VOICE_IARM_EVENT_JSON_SESSION_END, json_str); + ret = broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_JSON_SESSION_END, json_str); free(json_str); } else { XLOGD_ERROR("Failed to encode JSON string"); @@ -341,7 +374,7 @@ bool ctrlm_voice_ipc_iarm_thunder_t::server_message(const char *message, unsigne bool ret = false; if(message) { XLOGD_INFO("%ul : <%s>", size, this->obj_voice->voice_stb_data_pii_mask_get() ? "***" : message); //CID -160950 - Printargs - ret = broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_BUS_API_REVISION, CTRLM_VOICE_IARM_EVENT_JSON_SERVER_MESSAGE, message); + ret = broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_JSON_SERVER_MESSAGE, message); } return(ret); } @@ -364,7 +397,7 @@ bool ctrlm_voice_ipc_iarm_thunder_t::keyword_verification(const ctrlm_voice_ipc_ if(json_str) { //TODO: surface the event through IARM XLOGD_INFO("%s", json_str); - ret = broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_BUS_API_REVISION, CTRLM_VOICE_IARM_EVENT_JSON_KEYWORD_VERIFICATION, json_str); + ret = broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_JSON_KEYWORD_VERIFICATION, json_str); free(json_str); } else { XLOGD_ERROR("Failed to encode JSON string"); @@ -951,6 +984,35 @@ const char *voice_device_status_str(uint8_t status) { return("invalid"); } +bool broadcast_event(const char *bus_name, int event, const char *str) { + bool ret = false; + size_t str_size = strlen(str) + 1; + size_t size = sizeof(ctrlm_voice_iarm_event_json_t) + str_size; + ctrlm_voice_iarm_event_json_t *data = (ctrlm_voice_iarm_event_json_t *)malloc(size); + if(data) { + IARM_Result_t result; + + //Can't be replaced with safeC version of this + memset(data, 0, size); + + data->api_revision = CTRLM_VOICE_IARM_BUS_API_REVISION; + //Can't be replaced with safeC version of this, as safeC string functions doesn't allow string size more than 4K + snprintf(data->payload, str_size, "%s", str); + result = IARM_Bus_BroadcastEvent(bus_name, event, data, size); + if(IARM_RESULT_SUCCESS != result) { + XLOGD_ERROR("IARM Bus Error!"); + } else { + ret = true; + } + if(data) { + free(data); + } + } else { + XLOGD_ERROR("Failed to allocate data for IARM event"); + } + return(ret); +} + bool ctrlm_voice_ipc_request_supported_ptt_transcription(ctrlm_voice_ipc_request_config_t *config) { config->requires_transcription = true; config->requires_audio_file = false; From e65264187e036f9c10fc07d98f54dbec40cee04c Mon Sep 17 00:00:00 2001 From: dwolaver <44593664+dwolaver@users.noreply.github.com> Date: Mon, 17 Nov 2025 15:41:45 -0500 Subject: [PATCH 04/39] RDKEMW-7905 : remove ctrlm build flags - ANSI_CODES_DISABLED (#110) --- CMakeLists.txt | 1 - src/ctrlm_log.h | 4 ---- src/ctrlm_main.cpp | 2 +- src/factory/ctrlmf_version.c | 2 +- 4 files changed, 2 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 61dbb8e0..55367138 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,6 @@ project(ctrlm-main VERSION ${CMAKE_PROJECT_VERSION}) # OPTIONS option(A5000_ENABLE "ES1 A5000 use libse051" OFF) -option(ANSI_CODES_DISABLED "Disable ANSI code logging" OFF) option(ASSERT_ON_WRONG_THREAD "Assert on wrong thread" OFF) option(AUTH_ENABLED "Enable AUTH" OFF) option(BLE_ENABLED "Enable BLE" ON) diff --git a/src/ctrlm_log.h b/src/ctrlm_log.h index d804cd84..5bf0eb60 100644 --- a/src/ctrlm_log.h +++ b/src/ctrlm_log.h @@ -22,11 +22,7 @@ #include -#ifdef ANSI_CODES_DISABLED -#define XLOG_OPTS_DEFAULT (XLOG_OPTS_DATE | XLOG_OPTS_TIME | XLOG_OPTS_LF | XLOG_OPTS_MOD_NAME | XLOG_OPTS_LEVEL) -#else #define XLOG_OPTS_DEFAULT (XLOG_OPTS_DATE | XLOG_OPTS_TIME | XLOG_OPTS_LF | XLOG_OPTS_MOD_NAME | XLOG_OPTS_LEVEL | XLOG_OPTS_COLOR) -#endif #ifndef XLOG_MODULE_ID #define XLOG_MODULE_ID XLOG_MODULE_ID_CTRLM diff --git a/src/ctrlm_main.cpp b/src/ctrlm_main.cpp index e12749c5..72778ea8 100644 --- a/src/ctrlm_main.cpp +++ b/src/ctrlm_main.cpp @@ -518,7 +518,7 @@ int main(int argc, char *argv[]) { XLOGD_INFO("name <%-24s> version <%-9s> branch <%-20s> commit <%s>", entry->name ? entry->name : "NULL", entry->version ? entry->version : "NULL", entry->branch ? entry->branch : "NULL", entry->commit_id ? entry->commit_id : "NULL"); } } - vsdk_init(); + vsdk_init(true); //struct sched_param param; //param.sched_priority = 10; diff --git a/src/factory/ctrlmf_version.c b/src/factory/ctrlmf_version.c index 9fd9b69a..cffa6584 100644 --- a/src/factory/ctrlmf_version.c +++ b/src/factory/ctrlmf_version.c @@ -36,7 +36,7 @@ bool ctrlmf_init(xlog_level_t level, bool requires_audio_playback) { rdk_version_object_free(&info); - int rc = xlog_init(XLOG_MODULE_ID, NULL, 0); + int rc = xlog_init(XLOG_MODULE_ID, NULL, 0, true); xlog_level_set_all(level); if(rc != 0) { From fc5045c6514f90060ee2ede391c62c0c12830d96 Mon Sep 17 00:00:00 2001 From: dwolaver <44593664+dwolaver@users.noreply.github.com> Date: Mon, 17 Nov 2025 15:53:15 -0500 Subject: [PATCH 05/39] RDKEMW-8295 : remove ctrlm build flags - MEMORY_LOCK (#111) --- CMakeLists.txt | 6 ------ src/ctrlm_main.cpp | 38 -------------------------------------- 2 files changed, 44 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 55367138..ea865c0d 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,7 +50,6 @@ option(IP_ENABLED "Enable IP" OFF) option(LOCAL_MIC "Local Microphone" OFF) option(LOCAL_MIC_DISABLE_VIA_PRIVACY "Use Privacy to disable microphone" OFF) option(MEM_DEBUG "Enable memory debugging" OFF) -option(MEMORY_LOCK "Memory Lock" OFF) option(MIC_TAP "Enable MIC_TAP" OFF) option(RF4CE_ENABLED "Enable RF4CE" ON) option(TELEMETRY_SUPPORT "Enable TELEMETRY_SUPPORT" OFF) @@ -244,11 +243,6 @@ if(MEM_DEBUG) add_compile_definitions(MEM_DEBUG) endif() -if(MEMORY_LOCK) - add_compile_definitions(MEMORY_LOCK) - target_link_libraries(controLMgr clnl) -endif() - # RF4CE options if(RF4CE_ENABLED) # All RF4CE platforms have HAL NVM diff --git a/src/ctrlm_main.cpp b/src/ctrlm_main.cpp index 72778ea8..ed0d3fed 100644 --- a/src/ctrlm_main.cpp +++ b/src/ctrlm_main.cpp @@ -86,9 +86,6 @@ #include "xr_fdc.h" #endif #include -#ifdef MEMORY_LOCK -#include "clnl.h" -#endif using namespace std; @@ -402,17 +399,6 @@ static void control_service_values_read_from_db(); #ifdef USE_DEPRECATED_IRMGR static void ctrlm_check_for_key_tag(int key_tag) __attribute__((unused)); //USE_DEPRECATED_IRMGR #endif -#ifdef MEMORY_LOCK -const char *memory_lock_progs[] = { -"/usr/bin/controlMgr", -"/usr/lib/libctrlm_hal_rf4ce.so.0.0.0", -"/usr/lib/libxraudio.so.0.0.0", -"/usr/lib/libxraudio-hal.so.0.0.0", -"/usr/lib/libxr_mq.so.0.0.0", -"/usr/lib/libxr-timer.so.0.0.0", -"/usr/lib/libxr-timestamp.so.0.0.0" -}; -#endif #if CTRLM_HAL_RF4CE_API_VERSION >= 9 static void ctrlm_crash_recovery_check(); @@ -448,21 +434,6 @@ int main(int argc, char *argv[]) { XLOGD_INFO("name <%-24s> version <%-9s> branch <%-20s> commit <%s>", "ctrlm-main", CTRLM_MAIN_VERSION, CTRLM_MAIN_BRANCH, CTRLM_MAIN_COMMIT_ID); -#ifdef MEMORY_LOCK - clnl_init(); - for(unsigned int i = 0; i < (sizeof(memory_lock_progs) / sizeof(memory_lock_progs[0])); i++) { - if(ctrlm_file_exists(memory_lock_progs[i])) { - if(clnl_lock(memory_lock_progs[i], SECTION_TEXT)) { - XLOGD_ERROR("failed to lock instructions to memory <%s>", memory_lock_progs[i]); - } else { - XLOGD_INFO("successfully locked to memory <%s>", memory_lock_progs[i]); - } - } else { - XLOGD_DEBUG("file doesn't exist, cannot lock to memory <%s>", memory_lock_progs[i]); - } - } -#endif - ctrlm_signals_register(); #ifdef BREAKPAD_SUPPORT @@ -875,15 +846,6 @@ int main(int argc, char *argv[]) { sem_destroy(&g_ctrlm.ctrlm_utils_sem); -#ifdef MEMORY_LOCK - for(unsigned int i = 0; i < (sizeof(memory_lock_progs) / sizeof(memory_lock_progs[0])); i++) { - if(ctrlm_file_exists(memory_lock_progs[i])) { - clnl_unlock(memory_lock_progs[i], SECTION_TEXT); - } - } - clnl_destroy(); -#endif - ctrlm_config_t::destroy_instance(); ctrlm_rfc_t::destroy_instance(); #ifdef TELEMETRY_SUPPORT From 284efc8e29cc4347a959bb85a5e455386b942038 Mon Sep 17 00:00:00 2001 From: dwolaver <44593664+dwolaver@users.noreply.github.com> Date: Mon, 17 Nov 2025 15:56:23 -0500 Subject: [PATCH 06/39] RDKEMW-8296 : remove ctrlm build flags - DEEPSLEEP_CLOSE_DB (#112) --- CMakeLists.txt | 5 --- src/database/ctrlm_database.cpp | 77 ++++++++++++++------------------- 2 files changed, 33 insertions(+), 49 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ea865c0d..341b5607 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,7 +41,6 @@ option(BLE_ENABLED "Enable BLE" ON) option(BLE_SERVICES "Enable BLE Services" OFF) option(BREAKPAD "Enable BREAKPAD" OFF) option(BUILD_CTRLM_FACTORY "Build Control Factory Test" OFF) -option(DEEPSLEEP_CLOSE_DB "Deep Sleep Close DB" OFF) option(ENABLE_NETWORKED_STANDBY_MODE "Enable Networked Standby Mode)" OFF) option(FACTORY_AUDIO_PLAYBACK "Factory test audio playback" OFF) option(FACTORY_CUSTOM_AUDIO_ANALYSIS "Factory custom audio analysis" OFF) @@ -205,10 +204,6 @@ if(BREAKPAD) add_compile_definitions(BREAKPAD_SUPPORT) endif() -if(DEEPSLEEP_CLOSE_DB) - add_compile_definitions(DEEPSLEEP_CLOSE_DB) -endif() - if(ENABLE_ASYNC_SRVR_MSG) add_compile_definitions(SUPPORT_ASYNC_SRVR_MSG) endif() diff --git a/src/database/ctrlm_database.cpp b/src/database/ctrlm_database.cpp index c334cc7a..dfe2bb21 100644 --- a/src/database/ctrlm_database.cpp +++ b/src/database/ctrlm_database.cpp @@ -91,9 +91,7 @@ typedef enum { CTRLM_DB_QUEUE_MSG_TYPE_CONTROLLER_DESTROY = 5, CTRLM_DB_QUEUE_MSG_TYPE_CONTROLLER_CREATE = 6, CTRLM_DB_QUEUE_MSG_TYPE_BACKUP = 7, -#ifdef DEEPSLEEP_CLOSE_DB CTRLM_DB_QUEUE_MSG_TYPE_POWER_STATE_CHANGE = 8, -#endif CTRLM_DB_QUEUE_MSG_TYPE_WRITE_ATTR = 9, CTRLM_DB_QUEUE_MSG_TYPE_TICKLE = CTRLM_MAIN_QUEUE_MSG_TYPE_TICKLE } ctrlm_db_queue_msg_type_t; @@ -147,12 +145,10 @@ typedef struct { bool * ret; } ctrlm_db_queue_msg_backup_t; -#ifdef DEEPSLEEP_CLOSE_DB typedef struct { ctrlm_db_queue_msg_header_t header; gboolean waking_up; } ctrlm_db_queue_msg_power_state_change_t; -#endif typedef struct { sqlite3 * handle; @@ -162,10 +158,9 @@ typedef struct { GAsyncQueue * queue; sem_t semaphore; -#ifdef DEEPSLEEP_CLOSE_DB + bool deepsleep_close_db; char path[PATH_MAX]; sem_t ds_signal; -#endif vector rf4ce_network_list; vector ip_network_list; @@ -216,9 +211,7 @@ static void ctrlm_db_write_blob (const char *table, const char *key, const gucha static void ctrlm_db_write_blob_(const char *table, const char *key, const guchar *value, guint32 length); static void ctrlm_db_write_file_(const char *path, const guchar *data, guint32 length); -#ifdef DEEPSLEEP_CLOSE_DB static void ctrlm_db_power_state_change_(gboolean waking_up); -#endif static int ctrlm_db_insert_or_update(const char *table, const char *key, const int *value_int, const sqlite3_int64 *value_int64, const guchar *value_str, guint32 blob_length); #if 0 static int ctrlm_db_insert(const char *table, const char *key, const int *value_int, const char *value_str, guint32 blob_length); @@ -284,11 +277,13 @@ void ctrlm_db_close() { gboolean ctrlm_db_init(const char *db_path) { g_ctrlm_db.created_default_db = false; -#ifdef DEEPSLEEP_CLOSE_DB - errno_t safec_rc = strcpy_s(g_ctrlm_db.path, sizeof(g_ctrlm_db.path), db_path); - ERR_CHK(safec_rc); - sem_init(&g_ctrlm_db.ds_signal, 0, 0); -#endif + g_ctrlm_db.deepsleep_close_db = true; // Default to true. This can be overridden by vendor layer config as required in the future. + + if(g_ctrlm_db.deepsleep_close_db) { + errno_t safec_rc = strcpy_s(g_ctrlm_db.path, sizeof(g_ctrlm_db.path), db_path); + ERR_CHK(safec_rc); + sem_init(&g_ctrlm_db.ds_signal, 0, 0); + } // check for presence of database file and if not present, create it if(false == ctrlm_db_open(db_path)) { @@ -360,9 +355,9 @@ void ctrlm_db_terminate(void) { } } } -#ifdef DEEPSLEEP_CLOSE_DB - sem_destroy(&g_ctrlm_db.ds_signal); -#endif + if(g_ctrlm_db.deepsleep_close_db) { + sem_destroy(&g_ctrlm_db.ds_signal); + } sem_destroy(&g_ctrlm_db.semaphore); ctrlm_db_close(); @@ -399,29 +394,28 @@ bool ctrlm_db_backup() { } void ctrlm_db_power_state_change(gboolean waking_up) { -#ifdef DEEPSLEEP_CLOSE_DB - ctrlm_db_queue_msg_power_state_change_t *msg = (ctrlm_db_queue_msg_power_state_change_t *)g_malloc(sizeof(ctrlm_db_queue_msg_power_state_change_t)); - if(NULL == msg) { - XLOGD_ERROR("Failed to allocate memory"); - g_assert(0); - return; - } + if(g_ctrlm_db.deepsleep_close_db) { + ctrlm_db_queue_msg_power_state_change_t *msg = (ctrlm_db_queue_msg_power_state_change_t *)g_malloc(sizeof(ctrlm_db_queue_msg_power_state_change_t)); + if(NULL == msg) { + XLOGD_ERROR("Failed to allocate memory"); + g_assert(0); + return; + } - msg->header.type = CTRLM_DB_QUEUE_MSG_TYPE_POWER_STATE_CHANGE; - msg->waking_up = waking_up; + msg->header.type = CTRLM_DB_QUEUE_MSG_TYPE_POWER_STATE_CHANGE; + msg->waking_up = waking_up; - if(waking_up) { - ctrlm_db_queue_msg_push_front(msg); - sem_post(&g_ctrlm_db.ds_signal); + if(waking_up) { + ctrlm_db_queue_msg_push_front(msg); + sem_post(&g_ctrlm_db.ds_signal); + } else { + ctrlm_db_queue_msg_push(msg); + } } else { - ctrlm_db_queue_msg_push(msg); + XLOGD_INFO("No action for DB"); } -#else - XLOGD_INFO("No action for DB"); -#endif } -#ifdef DEEPSLEEP_CLOSE_DB void ctrlm_db_power_state_change_(gboolean waking_up) { if(waking_up == true ) { @@ -432,13 +426,10 @@ void ctrlm_db_power_state_change_(gboolean waking_up) { ctrlm_db_close(); } } -#endif gpointer ctrlm_db_thread(gpointer param) { bool running = true; -#ifdef DEEPSLEEP_CLOSE_DB bool ds_sem_wait = false; -#endif XLOGD_INFO("Started"); // Unblock the caller that launched this thread @@ -531,26 +522,24 @@ gpointer ctrlm_db_thread(gpointer param) { sem_post(&g_ctrlm_db.semaphore); break; } -#ifdef DEEPSLEEP_CLOSE_DB case CTRLM_DB_QUEUE_MSG_TYPE_POWER_STATE_CHANGE: { - XLOGD_DEBUG("POWER STATE CHANGE"); - ctrlm_db_queue_msg_power_state_change_t *power_state_change = (ctrlm_db_queue_msg_power_state_change_t *)msg; - ds_sem_wait = power_state_change->waking_up ? false : true; - ctrlm_db_power_state_change_(power_state_change->waking_up); + if(g_ctrlm_db.deepsleep_close_db) { + XLOGD_DEBUG("POWER STATE CHANGE"); + ctrlm_db_queue_msg_power_state_change_t *power_state_change = (ctrlm_db_queue_msg_power_state_change_t *)msg; + ds_sem_wait = power_state_change->waking_up ? false : true; + ctrlm_db_power_state_change_(power_state_change->waking_up); + } break; } -#endif default: { break; } } ctrlm_db_queue_msg_destroy(msg); -#ifdef DEEPSLEEP_CLOSE_DB if(ds_sem_wait == true) { sem_wait(&g_ctrlm_db.ds_signal); } -#endif } while(running); return(NULL); } From d327435ffe2f810930b672ed1c2d7472e2710f60 Mon Sep 17 00:00:00 2001 From: dwolaver <44593664+dwolaver@users.noreply.github.com> Date: Mon, 17 Nov 2025 16:05:35 -0500 Subject: [PATCH 07/39] RDKEMW-8668 : modify ctrlm build flag - BREAKPAD (#119) --- src/ctrlm_main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ctrlm_main.cpp b/src/ctrlm_main.cpp index ed0d3fed..e832501e 100644 --- a/src/ctrlm_main.cpp +++ b/src/ctrlm_main.cpp @@ -437,6 +437,7 @@ int main(int argc, char *argv[]) { ctrlm_signals_register(); #ifdef BREAKPAD_SUPPORT + XLOGD_INFO("breakpad enabled"); std::string minidump_path = "/opt/minidumps"; #ifdef BREAKPAD_MINIDUMP_PATH_OVERRIDE minidump_path = BREAKPAD_MINIDUMP_PATH_OVERRIDE; @@ -452,6 +453,8 @@ int main(int argc, char *argv[]) { google_breakpad::ExceptionHandler eh(descriptor, NULL, ctrlm_minidump_callback, NULL, true, -1); //ctrlm_crash(); +#else + XLOGD_INFO("breakpad disabled"); #endif XLOGD_INFO("glib run-time version... %d.%d.%d", glib_major_version, glib_minor_version, glib_micro_version); From cd566c448b640c39b2a4c32606208cac82c6a1e2 Mon Sep 17 00:00:00 2001 From: dwolaver <44593664+dwolaver@users.noreply.github.com> Date: Mon, 17 Nov 2025 16:09:28 -0500 Subject: [PATCH 08/39] RDKEMW-8297 : remove ctrlm build flags - A5000_ENABLE (#117) --- CMakeLists.txt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 341b5607..66c5d7f5 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,6 @@ set(CMAKE_NO_SYSTEM_FROM_IMPORTED ON) project(ctrlm-main VERSION ${CMAKE_PROJECT_VERSION}) # OPTIONS -option(A5000_ENABLE "ES1 A5000 use libse051" OFF) option(ASSERT_ON_WRONG_THREAD "Assert on wrong thread" OFF) option(AUTH_ENABLED "Enable AUTH" OFF) option(BLE_ENABLED "Enable BLE" ON) @@ -178,11 +177,6 @@ install(TARGETS controlMgr RUNTIME DESTINATION bin) install(FILES ${CMAKE_BINARY_DIR}/ctrlm_config.json.template DESTINATION ${CMAKE_INSTALL_SYSCONFDIR} COMPONENT config ) # DEFINES FROM OPTIONS -if(A5000_ENABLE) - find_library( SE_HAL_PATH SE_HAL ${CMAKE_SYSROOT}/usr/lib/se051) - target_link_libraries(controlMgr ${SE_HAL_PATH}) -endif() - if(ANSI_CODES_DISABLED) add_compile_definitions(ANSI_CODES_DISABLED) endif() From 97ea7393ffc476688f65f20bbe5a9b75683e3e7b Mon Sep 17 00:00:00 2001 From: dwolaver <44593664+dwolaver@users.noreply.github.com> Date: Mon, 17 Nov 2025 16:26:24 -0500 Subject: [PATCH 09/39] RDKEMW-8664 : remove ctrlm build flags - MEM_DEBUG, ASSERT_ON_WRONG_THREAD (#118) --- CMakeLists.txt | 10 ---------- src/ctrlm_main.cpp | 17 ----------------- 2 files changed, 27 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 66c5d7f5..f8696dea 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,6 @@ set(CMAKE_NO_SYSTEM_FROM_IMPORTED ON) project(ctrlm-main VERSION ${CMAKE_PROJECT_VERSION}) # OPTIONS -option(ASSERT_ON_WRONG_THREAD "Assert on wrong thread" OFF) option(AUTH_ENABLED "Enable AUTH" OFF) option(BLE_ENABLED "Enable BLE" ON) option(BLE_SERVICES "Enable BLE Services" OFF) @@ -47,7 +46,6 @@ option(FDC_ENABLED "Enable FDC" OFF) option(IP_ENABLED "Enable IP" OFF) option(LOCAL_MIC "Local Microphone" OFF) option(LOCAL_MIC_DISABLE_VIA_PRIVACY "Use Privacy to disable microphone" OFF) -option(MEM_DEBUG "Enable memory debugging" OFF) option(MIC_TAP "Enable MIC_TAP" OFF) option(RF4CE_ENABLED "Enable RF4CE" ON) option(TELEMETRY_SUPPORT "Enable TELEMETRY_SUPPORT" OFF) @@ -181,10 +179,6 @@ if(ANSI_CODES_DISABLED) add_compile_definitions(ANSI_CODES_DISABLED) endif() -if(ASSERT_ON_WRONG_THREAD) - add_compile_definitions(ASSERT_ON_WRONG_THREAD) -endif() - if(BLE_ENABLED) target_link_libraries(controlMgr BTMgr) if(BLE_SERVICES) @@ -228,10 +222,6 @@ if(LOCAL_MIC) endif() endif() -if(MEM_DEBUG) - add_compile_definitions(MEM_DEBUG) -endif() - # RF4CE options if(RF4CE_ENABLED) # All RF4CE platforms have HAL NVM diff --git a/src/ctrlm_main.cpp b/src/ctrlm_main.cpp index e832501e..768cedb4 100644 --- a/src/ctrlm_main.cpp +++ b/src/ctrlm_main.cpp @@ -409,13 +409,6 @@ static void ctrlm_ir_controller_thread_poll(void *data); static void ctrlm_vsdk_thread_poll(void *data); static void ctrlm_vsdk_thread_response(void *data); -#ifdef MEM_DEBUG -static gboolean ctrlm_memory_profile(gpointer user_data) { - g_mem_profile(); - return(TRUE); -} -#endif - #ifdef BREAKPAD_SUPPORT static bool ctrlm_minidump_callback(const google_breakpad::MinidumpDescriptor& descriptor, void* context, bool succeeded) { XLOGD_FATAL("Minidump location: %s Status: %s", descriptor.path(), succeeded ? "SUCCEEDED" : "FAILED"); @@ -468,11 +461,6 @@ int main(int argc, char *argv[]) { XLOGD_INFO("Glib run-time library is compatible"); } -#ifdef MEM_DEBUG - XLOGD_WARN("Memory debug is ENABLED."); - g_mem_set_vtable(glib_mem_profiler_table); -#endif - sem_init(&g_ctrlm.ctrlm_utils_sem, 0, 1); if(!ctrlm_iarm_init()) { @@ -586,11 +574,6 @@ int main(int argc, char *argv[]) { g_ctrlm.discovery_remote_type[0] = '\0'; -#ifdef MEM_DEBUG - g_mem_profile(); - g_timeout_add_seconds(10, ctrlm_memory_profile, NULL); -#endif - XLOGD_INFO("load version"); if(!ctrlm_load_version()) { XLOGD_FATAL("failed to load version"); From 84e8ce8bff2e59d35268d9380fcfacd0a61c00c6 Mon Sep 17 00:00:00 2001 From: dwolaver <44593664+dwolaver@users.noreply.github.com> Date: Mon, 17 Nov 2025 16:35:47 -0500 Subject: [PATCH 10/39] RDKEMW-8676 : remove ctrlm build flags - MIC_TAP, LOCAL_MIC, LOCAL_MIC_DISABLE_VIA_PRIVACY (#120) --- CMakeLists.txt | 25 -- src/ctrlm.h | 1 + src/ctrlm_main.cpp | 36 +- src/ctrlm_main_iarm.cpp | 5 - src/ctrlm_powermanager.h | 2 - src/ctrlm_powermanager_factory.cpp | 5 +- src/ctrlm_utils.cpp | 3 +- src/ctrlm_utils.h | 4 +- src/ipc/ctrlm_ipc_iarm_powermanager.cpp | 6 +- src/ipc/ctrlm_ipc_iarm_powermanager.h | 2 - src/shared_memory/ctrlm_shared_memory.cpp | 4 - src/shared_memory/ctrlm_shared_memory.h | 2 - .../ctrlm_thunder_plugin_powermanager.cpp | 2 - .../ctrlm_thunder_plugin_powermanager.h | 2 - src/thunder/ctrlm_thunder_powermanager.cpp | 6 +- src/thunder/ctrlm_thunder_powermanager.h | 2 - src/voice/ctrlm_voice_obj.cpp | 342 ++++++++---------- src/voice/ctrlm_voice_obj.h | 44 +-- src/voice/ctrlm_voice_obj_generic.cpp | 26 +- src/voice/ctrlm_voice_types.h | 4 - .../ipc/ctrlm_voice_ipc_iarm_thunder.cpp | 85 ++--- 21 files changed, 235 insertions(+), 373 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f8696dea..655f17d2 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,21 +39,16 @@ option(BLE_ENABLED "Enable BLE" ON) option(BLE_SERVICES "Enable BLE Services" OFF) option(BREAKPAD "Enable BREAKPAD" OFF) option(BUILD_CTRLM_FACTORY "Build Control Factory Test" OFF) -option(ENABLE_NETWORKED_STANDBY_MODE "Enable Networked Standby Mode)" OFF) option(FACTORY_AUDIO_PLAYBACK "Factory test audio playback" OFF) option(FACTORY_CUSTOM_AUDIO_ANALYSIS "Factory custom audio analysis" OFF) option(FDC_ENABLED "Enable FDC" OFF) option(IP_ENABLED "Enable IP" OFF) -option(LOCAL_MIC "Local Microphone" OFF) -option(LOCAL_MIC_DISABLE_VIA_PRIVACY "Use Privacy to disable microphone" OFF) -option(MIC_TAP "Enable MIC_TAP" OFF) option(RF4CE_ENABLED "Enable RF4CE" ON) option(TELEMETRY_SUPPORT "Enable TELEMETRY_SUPPORT" OFF) option(THUNDER "Enable THUNDER" ON) option(THUNDER_SECURITY "Enable THUNDER_SECURITY" OFF) option(USE_SAFEC "Use safec" OFF) option(USE_IARM_POWER_MANAGER "Use IARM Power Manager" OFF) -option(VOICE_KEYWORD_BEEP "Enable VOICE_KEYWORD_BEEP" OFF) option(XRSR_HTTP "Enable XRSR_HTTP" OFF) option(XRSR_SDT "Enable XRSR_SDT" OFF) option(ENABLE_ASYNC_SRVR_MSG "Enable Asynchronous Server Messaging Feature" OFF) @@ -200,10 +195,6 @@ if(ENABLE_AVS_WITH_SDT) add_compile_definitions(SUPPORT_VOICE_DEST_ALSA SUPPORT_ASYNC_SRVR_MSG) endif() -if(ENABLE_NETWORKED_STANDBY_MODE) - add_compile_definitions(NETWORKED_STANDBY_MODE_ENABLED) -endif() - if(FDC_ENABLED) add_compile_definitions(FDC_ENABLED) endif() @@ -212,16 +203,6 @@ if(IP_ENABLED) add_compile_definitions(CTRLM_NETWORK_IP CTRLM_IP_HAL_LOG_ENABLED) endif() -if(LOCAL_MIC) - add_compile_definitions(CTRLM_LOCAL_MIC) - if(MIC_TAP) - add_compile_definitions(CTRLM_LOCAL_MIC_TAP) - endif() - if(LOCAL_MIC_DISABLE_VIA_PRIVACY) - add_compile_definitions(CTRLM_LOCAL_MIC_DISABLE_VIA_PRIVACY) - endif() -endif() - # RF4CE options if(RF4CE_ENABLED) # All RF4CE platforms have HAL NVM @@ -275,12 +256,6 @@ else() add_compile_definitions(SAFEC_DUMMY_API) endif() -if(VOICE_KEYWORD_BEEP) - add_compile_definitions(BEEP_ON_KWD_ENABLED) - add_definitions(-DBEEP_ON_KWD_FILE=\"${CMAKE_DATADIR}/${BEEP_ON_KWD_FILE}\") - install(FILES ${CMAKE_SOURCE_DIR}/../${BEEP_ON_KWD_FILE} DESTINATION share ) -endif() - if(USE_DEPRECATED_HDMI_INPUT_PLUGIN) add_compile_definitions(USE_DEPRECATED_HDMI_INPUT_PLUGIN) endif() diff --git a/src/ctrlm.h b/src/ctrlm.h index 68fa1818..905803d1 100644 --- a/src/ctrlm.h +++ b/src/ctrlm.h @@ -453,6 +453,7 @@ gboolean ctrlm_is_one_touch_autobind_active(void); gboolean ctrlm_is_binding_table_empty(void); gboolean ctrlm_is_binding_table_full(void); bool ctrlm_is_pii_mask_enabled(void); +bool ctrlm_is_networked_standby_supported(void); gboolean ctrlm_main_has_device_id_get(void); gboolean ctrlm_main_has_device_type_get(void); gboolean ctrlm_main_has_service_account_id_get(void); diff --git a/src/ctrlm_main.cpp b/src/ctrlm_main.cpp index 768cedb4..65f3ad19 100644 --- a/src/ctrlm_main.cpp +++ b/src/ctrlm_main.cpp @@ -285,9 +285,8 @@ typedef struct { gboolean local_conf; guint telemetry_report_interval; ctrlm_ir_controller_t *ir_controller; -#ifdef NETWORKED_STANDBY_MODE_ENABLED + bool networked_standby_supported; gboolean wake_with_voice_allowed; -#endif } ctrlm_global_t; static ctrlm_global_t g_ctrlm; @@ -566,9 +565,16 @@ int main(int argc, char *argv[]) { g_ctrlm.last_key_info.last_ir_remote_type = CTRLM_IR_REMOTE_TYPE_UNKNOWN; g_ctrlm.last_key_info.is_screen_bind_mode = false; g_ctrlm.last_key_info.remote_keypad_config = CTRLM_REMOTE_KEYPAD_CONFIG_INVALID; - #ifdef NETWORKED_STANDBY_MODE_ENABLED + + xrsr_config_t xrsr_config; + if(xrsr_config_get(&xrsr_config)) { + g_ctrlm.networked_standby_supported = xrsr_config.networked_standby; + } else { + g_ctrlm.networked_standby_supported = false; + } + XLOGD_INFO("networked standby supported <%s>", g_ctrlm.networked_standby_supported ? "YES" : "NO"); + g_ctrlm.wake_with_voice_allowed = false; - #endif errno_t safec_rc = strcpy_s(g_ctrlm.last_key_info.source_name, sizeof(g_ctrlm.last_key_info.source_name), ctrlm_rcu_ir_remote_types_str(g_ctrlm.last_key_info.last_ir_remote_type)); ERR_CHK(safec_rc); @@ -2632,9 +2638,9 @@ gpointer ctrlm_main_thread(gpointer param) { if( (old_state == CTRLM_POWER_STATE_DEEP_SLEEP) && (dqm->new_state != CTRLM_POWER_STATE_DEEP_SLEEP) ) { XLOGD_INFO("power_state_change: wake DB and networks"); - #ifdef NETWORKED_STANDBY_MODE_ENABLED - g_ctrlm.wake_with_voice_allowed = true; - #endif + if(g_ctrlm.networked_standby_supported) { + g_ctrlm.wake_with_voice_allowed = true; + } ctrlm_db_power_state_change(true); for(auto const &itr : g_ctrlm.networks) { itr.second->power_state_change(true); @@ -2647,9 +2653,8 @@ gpointer ctrlm_main_thread(gpointer param) { } } - #ifdef NETWORKED_STANDBY_MODE_ENABLED //Wake with voice? Handle NSM voice, do not change power state - if(dqm->new_state == CTRLM_POWER_STATE_ON) { + if(g_ctrlm.networked_standby_supported && dqm->new_state == CTRLM_POWER_STATE_ON) { bool wake_with_voice_allowed = g_ctrlm.wake_with_voice_allowed; g_ctrlm.wake_with_voice_allowed = false; @@ -2663,17 +2668,14 @@ gpointer ctrlm_main_thread(gpointer param) { break; } } - #endif //If execution reaches here, then change power state and inform VSDK of on or deep sleep states g_ctrlm.power_state = dqm->new_state; XLOGD_INFO("Enter power state <%s>", ctrlm_power_state_str(g_ctrlm.power_state)); - #ifdef NETWORKED_STANDBY_MODE_ENABLED - if(g_ctrlm.power_state == CTRLM_POWER_STATE_DEEP_SLEEP) { + if(g_ctrlm.networked_standby_supported && (g_ctrlm.power_state == CTRLM_POWER_STATE_DEEP_SLEEP)) { XLOGD_INFO("NSM is <%s>", (ctrlm_main_get_networked_standby_mode())?"ENABLED":"DISABLED"); } - #endif if(dqm->new_state != CTRLM_POWER_STATE_STANDBY) { // Set VSDK power state @@ -3129,6 +3131,10 @@ bool ctrlm_is_pii_mask_enabled(void) { return(g_ctrlm.mask_pii); } +bool ctrlm_is_networked_standby_supported(void) { + return(g_ctrlm.networked_standby_supported); +} + gboolean ctrlm_timeout_recently_booted(gpointer user_data) { XLOGD_INFO("Timeout - Recently booted."); g_ctrlm.recently_booted = FALSE; @@ -5807,11 +5813,9 @@ ctrlm_power_state_t ctrlm_main_get_system_power_state(void) { gboolean ctrlm_main_get_networked_standby_mode(void) { bool networked_standby_mode = false; - #ifdef NETWORKED_STANDBY_MODE_ENABLED - if(g_ctrlm.power_state == CTRLM_POWER_STATE_DEEP_SLEEP) { + if(g_ctrlm.networked_standby_supported && (g_ctrlm.power_state == CTRLM_POWER_STATE_DEEP_SLEEP)) { networked_standby_mode = g_ctrlm.power_manager->get_networked_standby_mode(); } - #endif return networked_standby_mode ? true : false; } diff --git a/src/ctrlm_main_iarm.cpp b/src/ctrlm_main_iarm.cpp index 92ceb987..8012b334 100644 --- a/src/ctrlm_main_iarm.cpp +++ b/src/ctrlm_main_iarm.cpp @@ -26,9 +26,6 @@ #include "irMgr.h" #endif #include "sysMgr.h" -#ifdef NETWORKED_STANDBY_MODE_ENABLED -#include "deepSleepMgr.h" -#endif #include "comcastIrKeyCodes.h" #include "ctrlm.h" #include "ctrlm_log.h" @@ -62,11 +59,9 @@ static IARM_Result_t ctrlm_main_iarm_call_start_pair_with_code(void *arg); static IARM_Result_t ctrlm_main_iarm_call_chip_status_get(void *arg); static IARM_Result_t ctrlm_main_iarm_call_audio_capture_start(void *arg); static IARM_Result_t ctrlm_main_iarm_call_audio_capture_stop(void *arg); -#ifdef NETWORKED_STANDBY_MODE_ENABLED #if CTRLM_HAL_RF4CE_API_VERSION >= 10 && !defined(CTRLM_DPI_CONTROL_NOT_SUPPORTED) extern IARM_Result_t ctrlm_iarm_powermanager_event_handler_power_pre_change(void* pArgs); #endif -#endif typedef struct { const char * name; diff --git a/src/ctrlm_powermanager.h b/src/ctrlm_powermanager.h index 89705b32..c55223ce 100755 --- a/src/ctrlm_powermanager.h +++ b/src/ctrlm_powermanager.h @@ -28,10 +28,8 @@ class ctrlm_powermanager_t { static ctrlm_powermanager_t *get_instance(); static void destroy_instance(); virtual ctrlm_power_state_t get_power_state() = 0; - #ifdef NETWORKED_STANDBY_MODE_ENABLED virtual bool get_networked_standby_mode() = 0; virtual bool get_wakeup_reason_voice() = 0; - #endif }; #endif diff --git a/src/ctrlm_powermanager_factory.cpp b/src/ctrlm_powermanager_factory.cpp index 93d9dcea..7048c028 100755 --- a/src/ctrlm_powermanager_factory.cpp +++ b/src/ctrlm_powermanager_factory.cpp @@ -16,10 +16,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include #include "ctrlm_powermanager.h" +#ifdef USE_IARM_POWER_MANAGER #include "ctrlm_ipc_iarm_powermanager.h" +#else #include "ctrlm_thunder_powermanager.h" - +#endif static ctrlm_powermanager_t *instance = NULL; diff --git a/src/ctrlm_utils.cpp b/src/ctrlm_utils.cpp index 7166aba5..b77595ac 100644 --- a/src/ctrlm_utils.cpp +++ b/src/ctrlm_utils.cpp @@ -1373,7 +1373,7 @@ const char *ctrlm_linux_key_code_str(uint16_t code, bool mask) { } } -#ifdef NETWORKED_STANDBY_MODE_ENABLED +#ifdef USE_IARM_POWER_MANAGER const char *ctrlm_wakeup_reason_str(DeepSleep_WakeupReason_t wakeup_reason) { switch(wakeup_reason) { case DEEPSLEEP_WAKEUPREASON_IR: return("IR"); @@ -1400,7 +1400,6 @@ const char *ctrlm_wakeup_reason_str(DeepSleep_WakeupReason_t wakeup_reason) { } #endif - bool ctrlm_file_copy(const char* src, const char* dst, bool overwrite, bool follow_dst_symbolic_link) { bool ret = FALSE; GFile *g_src = g_file_new_for_path(src); diff --git a/src/ctrlm_utils.h b/src/ctrlm_utils.h index 5e984a1e..baed40e7 100644 --- a/src/ctrlm_utils.h +++ b/src/ctrlm_utils.h @@ -36,7 +36,7 @@ #include "libIBus.h" #include "libIBusDaemon.h" #include -#ifdef NETWORKED_STANDBY_MODE_ENABLED +#ifdef USE_IARM_POWER_MANAGER #include "deepSleepMgr.h" #endif #ifdef TELEMETRY_SUPPORT @@ -205,7 +205,7 @@ const char *ctrlm_ir_state_str(ctrlm_ir_state_t state); const char *ctrlm_power_state_str(ctrlm_power_state_t state); const char *ctrlm_device_type_str(ctrlm_device_type_t device_type); -#ifdef NETWORKED_STANDBY_MODE_ENABLED +#ifdef USE_IARM_POWER_MANAGER const char *ctrlm_wakeup_reason_str(DeepSleep_WakeupReason_t wakeup_reason); #endif const char *ctrlm_rcu_wakeup_config_str(ctrlm_rcu_wakeup_config_t config); diff --git a/src/ipc/ctrlm_ipc_iarm_powermanager.cpp b/src/ipc/ctrlm_ipc_iarm_powermanager.cpp index 0fb5cd5e..0bef46ce 100755 --- a/src/ipc/ctrlm_ipc_iarm_powermanager.cpp +++ b/src/ipc/ctrlm_ipc_iarm_powermanager.cpp @@ -41,19 +41,16 @@ ctrlm_power_state_t ctrlm_ipc_iarm_powermanager_t::get_power_state() { XLOGD_WARN("IARM bus failed to read power state, defaulting to <%s>", ctrlm_power_state_str(power_state)); } else { power_state = ctrlm_iarm_power_state_map(param.curState); - #ifdef NETWORKED_STANDBY_MODE_ENABLED //If ctrlm restarts with system STANDBY state, set to ON, will receive a DEEP_SLEEP or ON message shortly - if(power_state == CTRLM_POWER_STATE_STANDBY) { + if(ctrlm_is_networked_standby_supported() && (power_state == CTRLM_POWER_STATE_STANDBY)) { power_state = CTRLM_POWER_STATE_ON; } - #endif XLOGD_DEBUG("power state <%s>", ctrlm_power_state_str(power_state)); } return power_state; } -#ifdef NETWORKED_STANDBY_MODE_ENABLED bool ctrlm_ipc_iarm_powermanager_t::get_networked_standby_mode() { IARM_Bus_PWRMgr_NetworkStandbyMode_Param_t param = {0}; IARM_Result_t res = IARM_Bus_Call(IARM_BUS_PWRMGR_NAME, IARM_BUS_PWRMGR_API_GetNetworkStandbyMode, (void *)¶m, sizeof(param)); @@ -89,7 +86,6 @@ bool ctrlm_ipc_iarm_powermanager_t::get_wakeup_reason_voice() { return wakeup_reason_voice; } -#endif #if CTRLM_HAL_RF4CE_API_VERSION >= 10 && !defined(CTRLM_DPI_CONTROL_NOT_SUPPORTED) IARM_Result_t ctrlm_iarm_powermanager_event_handler_power_pre_change(void* pArgs) diff --git a/src/ipc/ctrlm_ipc_iarm_powermanager.h b/src/ipc/ctrlm_ipc_iarm_powermanager.h index 20613c20..4944340a 100755 --- a/src/ipc/ctrlm_ipc_iarm_powermanager.h +++ b/src/ipc/ctrlm_ipc_iarm_powermanager.h @@ -26,10 +26,8 @@ class ctrlm_ipc_iarm_powermanager_t : public ctrlm_powermanager_t { ~ctrlm_ipc_iarm_powermanager_t(); ctrlm_power_state_t get_power_state(); - #ifdef NETWORKED_STANDBY_MODE_ENABLED bool get_networked_standby_mode(); bool get_wakeup_reason_voice(); - #endif private: diff --git a/src/shared_memory/ctrlm_shared_memory.cpp b/src/shared_memory/ctrlm_shared_memory.cpp index 03249419..b53b6db0 100644 --- a/src/shared_memory/ctrlm_shared_memory.cpp +++ b/src/shared_memory/ctrlm_shared_memory.cpp @@ -54,10 +54,8 @@ typedef struct { char url_ptt[CTRLM_VOICE_SERVER_URL_MAX_LENGTH]; bool url_ff_valid; char url_ff[CTRLM_VOICE_SERVER_URL_MAX_LENGTH]; - #ifdef CTRLM_LOCAL_MIC_TAP bool url_mic_tap_valid; char url_mic_tap[CTRLM_VOICE_SERVER_URL_MAX_LENGTH]; - #endif uint32_t query_string_ptt_count; query_string_pair_t query_string_ptt_pairs[CTRLM_VOICE_QUERY_STRING_MAX_PAIRS]; @@ -313,7 +311,6 @@ void ctrlm_sm_voice_url_ff_write(std::string url) { g_ctrlm_sm.mmap->url_ff_valid = true; } -#ifdef CTRLM_LOCAL_MIC_TAP void ctrlm_sm_voice_url_mic_tap_read(std::string &url) { if(g_ctrlm_sm.mmap == NULL) { XLOGD_ERROR("mmap is invalid"); @@ -334,7 +331,6 @@ void ctrlm_sm_voice_url_mic_tap_write(std::string url) { g_ctrlm_sm.mmap->url_mic_tap[sizeof(g_ctrlm_sm.mmap->url_mic_tap) - 1] = '\0'; g_ctrlm_sm.mmap->url_mic_tap_valid = true; } -#endif void ctrlm_sm_voice_query_string_ptt_count_read(uint8_t &count) { if(g_ctrlm_sm.mmap == NULL) { diff --git a/src/shared_memory/ctrlm_shared_memory.h b/src/shared_memory/ctrlm_shared_memory.h index 9c4e05e9..25479c66 100644 --- a/src/shared_memory/ctrlm_shared_memory.h +++ b/src/shared_memory/ctrlm_shared_memory.h @@ -53,10 +53,8 @@ void ctrlm_sm_voice_url_ptt_write(std::string url); void ctrlm_sm_voice_url_ff_read(std::string &url); void ctrlm_sm_voice_url_ff_write(std::string url); -#ifdef CTRLM_LOCAL_MIC_TAP void ctrlm_sm_voice_url_mic_tap_read(std::string &url); void ctrlm_sm_voice_url_mic_tap_write(std::string url); -#endif void ctrlm_sm_voice_query_string_ptt_count_read(uint8_t &count); void ctrlm_sm_voice_query_string_ptt_count_write(uint8_t count); diff --git a/src/thunder/ctrlm_thunder_plugin_powermanager.cpp b/src/thunder/ctrlm_thunder_plugin_powermanager.cpp index 70c9c1d5..6e0c83b0 100755 --- a/src/thunder/ctrlm_thunder_plugin_powermanager.cpp +++ b/src/thunder/ctrlm_thunder_plugin_powermanager.cpp @@ -86,7 +86,6 @@ ctrlm_power_state_t ctrlm_thunder_plugin_powermanager_t::get_power_state() { } -#ifdef NETWORKED_STANDBY_MODE_ENABLED /* root@pioneer-uhd:~# curl --request POST --url http://127.0.0.1:9998/jsonrpc --header 'Content-Type: application/json' --data '{ "jsonrpc": "2.0", "id": 1234567890, "method": "org.rdk.PowerManager.1.getNetworkStandbyMode", "params": {} }' {"jsonrpc":"2.0","id":1234567890,"result":true} */ bool ctrlm_thunder_plugin_powermanager_t::get_networked_standby_mode() { @@ -124,7 +123,6 @@ bool ctrlm_thunder_plugin_powermanager_t::get_wakeup_reason_voice() { return wakeup_reason_voice; } -#endif void ctrlm_thunder_plugin_powermanager_t::on_power_state_changed(const ctrlm_power_state_t ¤t_state, const ctrlm_power_state_t &new_state) { ctrlm_main_queue_power_state_change_t *msg = (ctrlm_main_queue_power_state_change_t *)g_malloc(sizeof(ctrlm_main_queue_power_state_change_t)); diff --git a/src/thunder/ctrlm_thunder_plugin_powermanager.h b/src/thunder/ctrlm_thunder_plugin_powermanager.h index ab6ae554..9d2c51a2 100755 --- a/src/thunder/ctrlm_thunder_plugin_powermanager.h +++ b/src/thunder/ctrlm_thunder_plugin_powermanager.h @@ -54,7 +54,6 @@ class ctrlm_thunder_plugin_powermanager_t : public Thunder::Plugin::ctrlm_thunde */ ctrlm_power_state_t get_power_state(); - #ifdef NETWORKED_STANDBY_MODE_ENABLED /** * This function is used to get the networked standby mode from PowerManager plugin. * @@ -67,7 +66,6 @@ class ctrlm_thunder_plugin_powermanager_t : public Thunder::Plugin::ctrlm_thunde * */ bool get_wakeup_reason_voice(); - #endif void on_power_state_changed(const ctrlm_power_state_t ¤t_state, const ctrlm_power_state_t &new_state); diff --git a/src/thunder/ctrlm_thunder_powermanager.cpp b/src/thunder/ctrlm_thunder_powermanager.cpp index ddc95499..8b80a4aa 100755 --- a/src/thunder/ctrlm_thunder_powermanager.cpp +++ b/src/thunder/ctrlm_thunder_powermanager.cpp @@ -36,14 +36,13 @@ ctrlm_power_state_t ctrlm_thunder_powermanager_t::get_power_state() { } } -#ifdef NETWORKED_STANDBY_MODE_ENABLED bool ctrlm_thunder_powermanager_t::get_networked_standby_mode() { if(this->plugin == NULL) { XLOGD_ERROR("plugin not yet available"); return false; } else { - return this->plugin->get_networked_standby_mode(networked_standby_mode); + return this->plugin->get_networked_standby_mode(); } } @@ -53,7 +52,6 @@ bool ctrlm_thunder_powermanager_t::get_wakeup_reason_voice() { XLOGD_WARN("plugin not yet available"); return false; } else { - return this->plugin->get_wakeup_reason_voice(wakeup_reason_voice); + return this->plugin->get_wakeup_reason_voice(); } } -#endif diff --git a/src/thunder/ctrlm_thunder_powermanager.h b/src/thunder/ctrlm_thunder_powermanager.h index 25dc45e9..b87ef19e 100755 --- a/src/thunder/ctrlm_thunder_powermanager.h +++ b/src/thunder/ctrlm_thunder_powermanager.h @@ -11,10 +11,8 @@ class ctrlm_thunder_powermanager_t : public ctrlm_powermanager_t { bool is_ready(); ctrlm_power_state_t get_power_state(); - #ifdef NETWORKED_STANDBY_MODE bool get_networked_standby_mode(); bool get_wakeup_reason_voice(); - #endif private: Thunder::PowerManager::ctrlm_thunder_plugin_powermanager_t *plugin; diff --git a/src/voice/ctrlm_voice_obj.cpp b/src/voice/ctrlm_voice_obj.cpp index 2491ae9a..93c12ac2 100644 --- a/src/voice/ctrlm_voice_obj.cpp +++ b/src/voice/ctrlm_voice_obj.cpp @@ -56,14 +56,18 @@ #define ADPCM_COMMAND_ID_MIN (0x20) ///< Minimum bound of command id as defined by XVP Spec. #define ADPCM_COMMAND_ID_MAX (0x3F) ///< Maximum bound of command id as defined by XVP Spec. +#define BEEP_ON_KWD_FILE_VD "/vendor/usr/share/keyword_beep.wav" +#define BEEP_ON_KWD_FILE_MW "/usr/share/keyword_beep.wav" + +#define BEEP_ON_KWD_SAP_VD "file://" BEEP_ON_KWD_FILE_VD +#define BEEP_ON_KWD_SAP_MW "file://" BEEP_ON_KWD_FILE_MW + static void ctrlm_voice_session_response_confirm(bool result, signed long long rsp_time, unsigned int rsp_window, const std::string &err_str, ctrlm_timestamp_t *timestamp, void *user_data); static void ctrlm_voice_data_post_processing_cb(int bytes_sent, void *user_data); static ctrlm_voice_session_group_t voice_device_to_session_group(ctrlm_voice_device_t device_type); -#ifdef BEEP_ON_KWD_ENABLED static void ctrlm_voice_system_audio_player_event_handler(system_audio_player_event_t event, void *user_data); -#endif static xrsr_power_mode_t voice_xrsr_power_map(ctrlm_power_state_t ctrlm_power_state); @@ -138,15 +142,38 @@ ctrlm_voice_t::ctrlm_voice_t() { this->session_id = 0; this->software_version = "N/A"; this->mask_pii = ctrlm_is_production_build() ? JSON_ARRAY_VAL_BOOL_CTRLM_GLOBAL_MASK_PII_0 : JSON_ARRAY_VAL_BOOL_CTRLM_GLOBAL_MASK_PII_1; + + xrsr_config_t xrsr_config; + if(xrsr_config_get(&xrsr_config)) { + this->local_mic = xrsr_config.local_mic; + this->local_mic_tap = xrsr_config.local_mic_tap; + this->local_mic_disable_via_privacy = this->local_mic; // set if local mic is present for now + } else { + XLOGD_ERROR("xrsr_config_get failed"); + this->local_mic = false; + this->local_mic_tap = false; + this->local_mic_disable_via_privacy = false; + + } + + if(ctrlm_file_exists(BEEP_ON_KWD_FILE_VD)) { + this->beep_on_kwd_file = BEEP_ON_KWD_SAP_VD; + this->beep_on_kwd_supported = true; + } else if(ctrlm_file_exists(BEEP_ON_KWD_FILE_MW)) { + this->beep_on_kwd_file = BEEP_ON_KWD_SAP_MW; + this->beep_on_kwd_supported = true; + } else { + this->beep_on_kwd_file = NULL; + this->beep_on_kwd_supported = false; + } + this->ocsp_verify_stapling = false; this->ocsp_verify_ca = false; this->capture_active = false; this->device_cert.type = CTRLM_VOICE_CERT_TYPE_NONE; this->prefs.server_url_src_ptt = JSON_STR_VALUE_VOICE_URL_SRC_PTT; this->prefs.server_url_src_ff = JSON_STR_VALUE_VOICE_URL_SRC_FF; - #ifdef CTRLM_LOCAL_MIC_TAP this->prefs.server_url_src_mic_tap = JSON_STR_VALUE_VOICE_URL_SRC_MIC_TAP; - #endif #ifdef JSON_ARRAY_VAL_STR_VOICE_SERVER_HOSTS_0 this->url_hostname_pattern_add(JSON_ARRAY_VAL_STR_VOICE_SERVER_HOSTS_0); #endif @@ -203,14 +230,12 @@ ctrlm_voice_t::ctrlm_voice_t() { } #endif - #ifdef NETWORKED_STANDBY_MODE_ENABLED this->prefs.dst_params_standby.connect_check_interval = JSON_INT_VALUE_VOICE_DST_PARAMS_STANDBY_CONNECT_CHECK_INTERVAL; this->prefs.dst_params_standby.timeout_connect = JSON_INT_VALUE_VOICE_DST_PARAMS_STANDBY_TIMEOUT_CONNECT; this->prefs.dst_params_standby.timeout_inactivity = JSON_INT_VALUE_VOICE_DST_PARAMS_STANDBY_TIMEOUT_INACTIVITY; this->prefs.dst_params_standby.timeout_session = JSON_INT_VALUE_VOICE_DST_PARAMS_STANDBY_TIMEOUT_SESSION; this->prefs.dst_params_standby.ipv4_fallback = JSON_BOOL_VALUE_VOICE_DST_PARAMS_STANDBY_IPV4_FALLBACK; this->prefs.dst_params_standby.backoff_delay = JSON_INT_VALUE_VOICE_DST_PARAMS_STANDBY_BACKOFF_DELAY; - #endif this->prefs.dst_params_low_latency.connect_check_interval = JSON_INT_VALUE_VOICE_DST_PARAMS_LOW_LATENCY_CONNECT_CHECK_INTERVAL; this->prefs.dst_params_low_latency.timeout_connect = JSON_INT_VALUE_VOICE_DST_PARAMS_LOW_LATENCY_TIMEOUT_CONNECT; @@ -225,14 +250,10 @@ ctrlm_voice_t::ctrlm_voice_t() { this->device_requires_stb_data[CTRLM_VOICE_DEVICE_PTT] = true; this->device_status[CTRLM_VOICE_DEVICE_FF] = CTRLM_VOICE_DEVICE_STATUS_NONE; this->device_requires_stb_data[CTRLM_VOICE_DEVICE_FF] = true; -#ifdef CTRLM_LOCAL_MIC this->device_status[CTRLM_VOICE_DEVICE_MICROPHONE] = CTRLM_VOICE_DEVICE_STATUS_NONE; this->device_requires_stb_data[CTRLM_VOICE_DEVICE_MICROPHONE] = true; -#endif -#ifdef CTRLM_LOCAL_MIC_TAP this->device_status[CTRLM_VOICE_DEVICE_MICROPHONE_TAP] = CTRLM_VOICE_DEVICE_STATUS_NONE; this->device_requires_stb_data[CTRLM_VOICE_DEVICE_MICROPHONE_TAP] = true; -#endif this->device_status[CTRLM_VOICE_DEVICE_INVALID] = CTRLM_VOICE_DEVICE_STATUS_NOT_SUPPORTED; this->device_requires_stb_data[CTRLM_VOICE_DEVICE_INVALID] = true; @@ -247,14 +268,14 @@ ctrlm_voice_t::ctrlm_voice_t() { // These semaphores are used to make sure we have all the data before calling the session begin callback sem_init(&this->vsr_semaphore, 0, 0); - #ifdef BEEP_ON_KWD_ENABLED - this->obj_sap = Thunder::SystemAudioPlayer::ctrlm_thunder_plugin_system_audio_player_t::getInstance(); - this->obj_sap->add_event_handler(ctrlm_voice_system_audio_player_event_handler, this); - this->sap_opened = this->obj_sap->open(SYSTEM_AUDIO_PLAYER_AUDIO_TYPE_WAV, SYSTEM_AUDIO_PLAYER_SOURCE_TYPE_FILE, SYSTEM_AUDIO_PLAYER_PLAY_MODE_SYSTEM); - if(!this->sap_opened) { - XLOGD_WARN("unable to open system audio player"); + if(this->beep_on_kwd_supported) { + this->obj_sap = Thunder::SystemAudioPlayer::ctrlm_thunder_plugin_system_audio_player_t::getInstance(); + this->obj_sap->add_event_handler(ctrlm_voice_system_audio_player_event_handler, this); + this->sap_opened = this->obj_sap->open(SYSTEM_AUDIO_PLAYER_AUDIO_TYPE_WAV, SYSTEM_AUDIO_PLAYER_SOURCE_TYPE_FILE, SYSTEM_AUDIO_PLAYER_PLAY_MODE_SYSTEM); + if(!this->sap_opened) { + XLOGD_WARN("unable to open system audio player"); + } } - #endif // Set audio mode to default ctrlm_voice_audio_settings_t settings = CTRLM_VOICE_AUDIO_SETTINGS_INITIALIZER; @@ -293,14 +314,12 @@ ctrlm_voice_t::~ctrlm_voice_t() { } } - #ifdef BEEP_ON_KWD_ENABLED - if(this->sap_opened) { + if(this->beep_on_kwd_supported && this->sap_opened) { if(!this->obj_sap->close()) { XLOGD_WARN("unable to close system audio player"); } this->sap_opened = false; } - #endif /* Close Voice SDK */ @@ -422,9 +441,7 @@ bool ctrlm_voice_t::voice_configure_config_file_json(json_t *obj_voice, json_t * conf.config_value_get(JSON_BOOL_NAME_VOICE_ENABLE, enabled); conf.config_value_get(JSON_STR_NAME_VOICE_URL_SRC_PTT, this->prefs.server_url_src_ptt); conf.config_value_get(JSON_STR_NAME_VOICE_URL_SRC_FF, this->prefs.server_url_src_ff); - #ifdef CTRLM_LOCAL_MIC_TAP conf.config_value_get(JSON_STR_NAME_VOICE_URL_SRC_MIC_TAP, this->prefs.server_url_src_mic_tap); - #endif conf.config_value_get(JSON_STR_NAME_VOICE_LANGUAGE, this->prefs.guide_language); conf.config_value_get(JSON_INT_NAME_VOICE_MINIMUM_DURATION, this->prefs.utterance_duration_min); if(conf.config_value_get(JSON_BOOL_NAME_VOICE_ENABLE_SAT, this->sat_token_required)) { @@ -483,14 +500,12 @@ bool ctrlm_voice_t::voice_configure_config_file_json(json_t *obj_voice, json_t * conf.config_value_get(JSON_FLOAT_NAME_VOICE_AUDIO_DUCKING_LEVEL, audio_settings.ducking_level, 0.0, 1.0); conf.config_value_get(JSON_BOOL_NAME_VOICE_AUDIO_DUCKING_BEEP, audio_settings.ducking_beep); - #ifdef NETWORKED_STANDBY_MODE_ENABLED conf.config_value_get(JSON_INT_NAME_VOICE_DST_PARAMS_STANDBY_CONNECT_CHECK_INTERVAL, this->prefs.dst_params_standby.connect_check_interval); conf.config_value_get(JSON_INT_NAME_VOICE_DST_PARAMS_STANDBY_TIMEOUT_CONNECT, this->prefs.dst_params_standby.timeout_connect); conf.config_value_get(JSON_INT_NAME_VOICE_DST_PARAMS_STANDBY_TIMEOUT_INACTIVITY, this->prefs.dst_params_standby.timeout_inactivity); conf.config_value_get(JSON_INT_NAME_VOICE_DST_PARAMS_STANDBY_TIMEOUT_SESSION, this->prefs.dst_params_standby.timeout_session); conf.config_value_get(JSON_BOOL_NAME_VOICE_DST_PARAMS_STANDBY_IPV4_FALLBACK, this->prefs.dst_params_standby.ipv4_fallback); conf.config_value_get(JSON_INT_NAME_VOICE_DST_PARAMS_STANDBY_BACKOFF_DELAY, this->prefs.dst_params_standby.backoff_delay); - #endif conf.config_value_get(JSON_INT_NAME_VOICE_DST_PARAMS_LOW_LATENCY_CONNECT_CHECK_INTERVAL, this->prefs.dst_params_low_latency.connect_check_interval); conf.config_value_get(JSON_INT_NAME_VOICE_DST_PARAMS_LOW_LATENCY_TIMEOUT_CONNECT, this->prefs.dst_params_low_latency.timeout_connect); @@ -517,11 +532,9 @@ bool ctrlm_voice_t::voice_configure_config_file_json(json_t *obj_voice, json_t * for(int i = CTRLM_VOICE_DEVICE_PTT; i < CTRLM_VOICE_DEVICE_INVALID; i++) { uint8_t voice_device_status = CTRLM_VOICE_DEVICE_STATUS_NONE; ctrlm_db_voice_read_device_status(i, (int *)&voice_device_status); - #ifdef CTRLM_LOCAL_MIC if((i == CTRLM_VOICE_DEVICE_MICROPHONE) && (voice_device_status & CTRLM_VOICE_DEVICE_STATUS_PRIVACY)) { this->voice_privacy_enable(false); } - #endif if((voice_device_status & CTRLM_VOICE_DEVICE_STATUS_LEGACY) && (voice_device_status != CTRLM_VOICE_DEVICE_STATUS_DISABLED)) { // Convert from legacy to current (some value other than DISABLED set) XLOGD_INFO("Converting legacy device status value 0x%02X", voice_device_status); voice_device_status = CTRLM_VOICE_DEVICE_STATUS_NONE; @@ -533,9 +546,7 @@ bool ctrlm_voice_t::voice_configure_config_file_json(json_t *obj_voice, json_t * } ctrlm_sm_voice_url_ptt_read(this->prefs.server_url_src_ptt); ctrlm_sm_voice_url_ff_read(this->prefs.server_url_src_ff); - #ifdef CTRLM_LOCAL_MIC_TAP ctrlm_sm_voice_url_mic_tap_read(this->prefs.server_url_src_mic_tap); - #endif ctrlm_sm_voice_sat_enable_read(this->sat_token_required); ctrlm_sm_voice_mtls_enable_read(this->mtls_required); ctrlm_sm_voice_secure_url_required_read(this->secure_url_required); @@ -584,28 +595,28 @@ bool ctrlm_voice_t::voice_configure_config_file_json(json_t *obj_voice, json_t * // Update routes this->voice_sdk_update_routes(); - #ifdef CTRLM_LOCAL_MIC - // Read privacy mode state from the DB in case power cycle lost HW GPIO state - if(this->device_status[CTRLM_VOICE_DEVICE_MICROPHONE] & CTRLM_VOICE_DEVICE_STATUS_DISABLED) { - XLOGD_INFO("voice is disabled, skip privacy"); - } else { - bool privacy_enabled = this->voice_is_privacy_enabled(); - if(privacy_enabled != this->vsdk_is_privacy_enabled()) { - privacy_enabled ? this->voice_privacy_enable(false) : this->voice_privacy_disable(false); - } - // Check keyword detector sensitivity value against limits; apply default if out of range. - double sensitivity_set = this->vsdk_keyword_sensitivity_limit_check(this->prefs.keyword_sensitivity); - if(sensitivity_set != this->prefs.keyword_sensitivity) { - xrsr_keyword_config_t kw_config; - kw_config.sensitivity = (float)sensitivity_set; - if(!xrsr_keyword_config_set(&kw_config)) { - XLOGD_ERROR("error updating keyword config"); - } else { - this->prefs.keyword_sensitivity = sensitivity_set; + if(this->local_mic) { + // Read privacy mode state from the DB in case power cycle lost HW GPIO state + if(this->device_status[CTRLM_VOICE_DEVICE_MICROPHONE] & CTRLM_VOICE_DEVICE_STATUS_DISABLED) { + XLOGD_INFO("voice is disabled, skip privacy"); + } else { + bool privacy_enabled = this->voice_is_privacy_enabled(); + if(privacy_enabled != this->vsdk_is_privacy_enabled()) { + privacy_enabled ? this->voice_privacy_enable(false) : this->voice_privacy_disable(false); + } + // Check keyword detector sensitivity value against limits; apply default if out of range. + double sensitivity_set = this->vsdk_keyword_sensitivity_limit_check(this->prefs.keyword_sensitivity); + if(sensitivity_set != this->prefs.keyword_sensitivity) { + xrsr_keyword_config_t kw_config; + kw_config.sensitivity = (float)sensitivity_set; + if(!xrsr_keyword_config_set(&kw_config)) { + XLOGD_ERROR("error updating keyword config"); + } else { + this->prefs.keyword_sensitivity = sensitivity_set; + } } } } - #endif // Set init message if read from DB if(!init.empty()) { @@ -726,7 +737,6 @@ bool ctrlm_voice_t::voice_configure(ctrlm_voice_iarm_call_settings_t *settings, ctrlm_sm_voice_url_ff_write(this->prefs.server_url_src_ff); } } - #ifdef CTRLM_LOCAL_MIC_TAP if(settings->available & CTRLM_VOICE_SETTINGS_MIC_TAP_SERVER_URL) { settings->server_url_src_mic_tap[CTRLM_VOICE_SERVER_URL_MAX_LENGTH - 1] = '\0'; XLOGD_INFO("Mic tap URL <%s>", this->mask_pii ? "***" : settings->server_url_src_mic_tap); @@ -736,7 +746,6 @@ bool ctrlm_voice_t::voice_configure(ctrlm_voice_iarm_call_settings_t *settings, ctrlm_sm_voice_url_mic_tap_write(this->prefs.server_url_src_mic_tap); } } - #endif if(update_routes && this->xrsr_opened) { this->voice_sdk_update_routes(); @@ -781,9 +790,7 @@ bool ctrlm_voice_t::voice_configure(json_t *settings, bool db_write) { } } if(conf.config_value_get("urlAll", url)) { - #ifdef CTRLM_LOCAL_MIC_TAP this->prefs.server_url_src_mic_tap = url; - #endif this->prefs.server_url_src_ptt = url; this->prefs.server_url_src_ff = std::move(url); update_routes = true; @@ -796,12 +803,10 @@ bool ctrlm_voice_t::voice_configure(json_t *settings, bool db_write) { this->prefs.server_url_src_ff = std::move(url); update_routes = true; } - #ifdef CTRLM_LOCAL_MIC_TAP if(conf.config_value_get("urlMicTap", url)) { this->prefs.server_url_src_mic_tap = std::move(url); update_routes = true; } - #endif if(conf.config_value_get("prv", prv_enabled)) { this->prefs.par_voice_enabled = prv_enabled; XLOGD_INFO("Press and Release Voice is <%s>", this->prefs.par_voice_enabled ? "ENABLED" : "DISABLED"); @@ -829,45 +834,43 @@ bool ctrlm_voice_t::voice_configure(json_t *settings, bool db_write) { } } } - #ifdef CTRLM_LOCAL_MIC - if(conf.config_object_get("mic", device_config)) { - if(device_config.config_value_get("enable", enable)) { - XLOGD_TELEMETRY("Voice Control MIC is <%s>", enable ? "ENABLED" : "DISABLED"); - #ifdef CTRLM_LOCAL_MIC_DISABLE_VIA_PRIVACY - bool privacy_enabled = this->voice_is_privacy_enabled(); - if(enable) { - if(privacy_enabled) { - this->voice_privacy_disable(true); + if(this->local_mic) { + if(conf.config_object_get("mic", device_config)) { + if(device_config.config_value_get("enable", enable)) { + XLOGD_TELEMETRY("Voice Control MIC is <%s>", enable ? "ENABLED" : "DISABLED"); + if(this->local_mic_disable_via_privacy) { + bool privacy_enabled = this->voice_is_privacy_enabled(); + if(enable) { + if(privacy_enabled) { + this->voice_privacy_disable(true); + } + } else if(!privacy_enabled) { + this->voice_privacy_enable(true); + } + } else { + if(enable) { + this->voice_device_enable(CTRLM_VOICE_DEVICE_MICROPHONE, db_write, &update_routes); + } else { + this->voice_device_disable(CTRLM_VOICE_DEVICE_MICROPHONE, db_write, &update_routes); + } } - } else if(!privacy_enabled) { - this->voice_privacy_enable(true); - } - #else - if(enable) { - this->voice_device_enable(CTRLM_VOICE_DEVICE_MICROPHONE, db_write, &update_routes); - } else { - this->voice_device_disable(CTRLM_VOICE_DEVICE_MICROPHONE, db_write, &update_routes); } - #endif } - } - #endif - if(conf.config_value_get("wwFeedback", enable)) { // This option will enable / disable the Wake Word feedback (typically an audible beep). - XLOGD_INFO("Voice Control kwd feedback is <%s>", enable ? "ENABLED" : "DISABLED"); - this->audio_ducking_beep_enabled = enable; + if(conf.config_value_get("wwFeedback", enable)) { // This option will enable / disable the Wake Word feedback (typically an audible beep). + XLOGD_INFO("Voice Control kwd feedback is <%s>", enable ? "ENABLED" : "DISABLED"); + this->audio_ducking_beep_enabled = enable; - if(db_write) { - ctrlm_db_voice_write_audio_ducking_beep_enable(enable); - } + if(db_write) { + ctrlm_db_voice_write_audio_ducking_beep_enable(enable); + } + } } if(update_routes && this->xrsr_opened) { this->voice_sdk_update_routes(); if(db_write) { ctrlm_sm_voice_url_ptt_write(this->prefs.server_url_src_ptt); ctrlm_sm_voice_url_ff_write(this->prefs.server_url_src_ff); - #ifdef CTRLM_LOCAL_MIC_TAP ctrlm_sm_voice_url_mic_tap_write(this->prefs.server_url_src_mic_tap); - #endif } } } @@ -914,11 +917,7 @@ bool ctrlm_voice_t::voice_status(ctrlm_voice_status_t *status) { */ ctrlm_voice_status_capabilities_t capabilities = { .prv = true, - #ifdef BEEP_ON_KWD_ENABLED - .wwFeedback = true, - #else - .wwFeedback = false, - #endif + .wwFeedback = this->beep_on_kwd_supported, }; if(!this->xrsr_opened) { @@ -928,9 +927,7 @@ bool ctrlm_voice_t::voice_status(ctrlm_voice_status_t *status) { } else { status->urlPtt = this->prefs.server_url_src_ptt; status->urlHf = this->prefs.server_url_src_ff; - #ifdef CTRLM_LOCAL_MIC_TAP status->urlMicTap = this->prefs.server_url_src_mic_tap; - #endif sem_wait(&this->device_status_semaphore); for(int i = CTRLM_VOICE_DEVICE_PTT; i < CTRLM_VOICE_DEVICE_INVALID; i++) { status->status[i] = this->device_status[i]; @@ -2358,6 +2355,14 @@ bool ctrlm_voice_t::voice_stb_data_pii_mask_get() const { return(this->mask_pii); } +bool ctrlm_voice_t::voice_stb_data_local_mic_get() const { + return(this->local_mic); +} + +bool ctrlm_voice_t::voice_stb_data_local_mic_tap_get() const { + return(this->local_mic_tap); +} + bool ctrlm_voice_t::voice_stb_data_device_certificate_set(ctrlm_voice_cert_t &device_cert, bool &ocsp_verify_stapling, bool &ocsp_verify_ca) { this->ocsp_verify_stapling = ocsp_verify_stapling; this->ocsp_verify_ca = ocsp_verify_ca; @@ -2659,29 +2664,20 @@ void ctrlm_voice_t::voice_session_end_callback(ctrlm_voice_session_end_cb_t *ses this->voice_status_set(session); break; } - #ifdef CTRLM_LOCAL_MIC case CTRLM_VOICE_DEVICE_MICROPHONE: { command_status = (session_end->success ? VOICE_COMMAND_STATUS_SUCCESS : VOICE_COMMAND_STATUS_FAILURE); // No need to set, as it's not a controller break; } - #endif default: { break; } } } - #ifdef CTRLM_LOCAL_MIC - #ifdef CTRLM_LOCAL_MIC_TAP if(session->voice_device == CTRLM_VOICE_DEVICE_MICROPHONE || session->voice_device == CTRLM_VOICE_DEVICE_MICROPHONE_TAP) { - #else - if(session->voice_device == CTRLM_VOICE_DEVICE_MICROPHONE) { - #endif XLOGD_INFO("src <%s> reason <%s> voice command status <%s>", ctrlm_voice_device_str(session->voice_device), xrsr_session_end_reason_str(stats->reason), ctrlm_voice_command_status_str(command_status)); - } else - #endif - { + } else { XLOGD_INFO("src <%s> audio sent bytes <%u> samples <%u> reason <%s> voice command status <%s>", ctrlm_voice_device_str(session->voice_device), session->audio_sent_bytes, session->audio_sent_samples, xrsr_session_end_reason_str(stats->reason), ctrlm_voice_command_status_str(command_status)); } @@ -3079,8 +3075,7 @@ void ctrlm_voice_t::voice_action_keyword_verification_callback(const uuid_t uuid } void ctrlm_voice_t::voice_keyword_verified_action(void) { - #ifdef BEEP_ON_KWD_ENABLED - if(this->audio_ducking_beep_enabled) { // play beep audio before ducking audio + if(this->beep_on_kwd_supported && (this->beep_on_kwd_file != NULL) && this->audio_ducking_beep_enabled) { // play beep audio before ducking audio if(this->audio_ducking_beep_in_progress) { XLOGD_WARN("audio ducking beep already in progress!"); this->obj_sap->close(); @@ -3102,8 +3097,8 @@ void ctrlm_voice_t::voice_keyword_verified_action(void) { } } - if(!this->obj_sap->play("file://" BEEP_ON_KWD_FILE)) { - XLOGD_WARN("unable to play beep file <%s>", BEEP_ON_KWD_FILE); + if(!this->obj_sap->play(this->beep_on_kwd_file)) { + XLOGD_WARN("unable to play beep file <%s>", this->beep_on_kwd_file); if(!this->obj_sap->close()) { XLOGD_WARN("unable to close system audio player"); } @@ -3120,11 +3115,9 @@ void ctrlm_voice_t::voice_keyword_verified_action(void) { return; } while(retry >= 0); } - #endif this->audio_state_set(true); } -#ifdef BEEP_ON_KWD_ENABLED void ctrlm_voice_t::voice_keyword_beep_completed_normal(void *data, int size) { this->voice_keyword_beep_completed_callback(false, false); } @@ -3159,7 +3152,6 @@ void ctrlm_voice_t::voice_keyword_beep_completed_callback(bool timeout, bool pla this->audio_state_set(true); } } -#endif void ctrlm_voice_t::voice_session_transcription_callback(const uuid_t uuid, const char *transcription) { // Get session based on uuid @@ -3241,12 +3233,8 @@ const char *ctrlm_voice_device_str(ctrlm_voice_device_t device) { switch(device) { case CTRLM_VOICE_DEVICE_PTT: return("PTT"); case CTRLM_VOICE_DEVICE_FF: return("FF"); - #ifdef CTRLM_LOCAL_MIC case CTRLM_VOICE_DEVICE_MICROPHONE: return("MICROPHONE"); - #endif - #ifdef CTRLM_LOCAL_MIC_TAP case CTRLM_VOICE_DEVICE_MICROPHONE_TAP: return("MICROPHONE_TAP"); - #endif case CTRLM_VOICE_DEVICE_INVALID: return("INVALID"); } return("UNKNOWN"); @@ -3307,18 +3295,14 @@ ctrlm_voice_device_t xrsr_to_voice_device(xrsr_src_t device) { ret = CTRLM_VOICE_DEVICE_FF; break; } - #ifdef CTRLM_LOCAL_MIC case XRSR_SRC_MICROPHONE: { ret = CTRLM_VOICE_DEVICE_MICROPHONE; break; } - #endif - #ifdef CTRLM_LOCAL_MIC_TAP case XRSR_SRC_MICROPHONE_TAP: { ret = CTRLM_VOICE_DEVICE_MICROPHONE_TAP; break; } - #endif default: { XLOGD_ERROR("unrecognized device type %d", device); break; @@ -3338,18 +3322,14 @@ xrsr_src_t voice_device_to_xrsr(ctrlm_voice_device_t device) { ret = XRSR_SRC_RCU_FF; break; } - #ifdef CTRLM_LOCAL_MIC case CTRLM_VOICE_DEVICE_MICROPHONE: { ret = XRSR_SRC_MICROPHONE; break; } - #endif - #ifdef CTRLM_LOCAL_MIC_TAP case CTRLM_VOICE_DEVICE_MICROPHONE_TAP: { ret = XRSR_SRC_MICROPHONE_TAP; break; } - #endif default: { XLOGD_ERROR("unrecognized device type %d", device); break; @@ -3359,11 +3339,9 @@ xrsr_src_t voice_device_to_xrsr(ctrlm_voice_device_t device) { } ctrlm_voice_session_group_t voice_device_to_session_group(ctrlm_voice_device_t device_type) { - #ifdef CTRLM_LOCAL_MIC_TAP if(device_type == CTRLM_VOICE_DEVICE_MICROPHONE_TAP) { return(VOICE_SESSION_GROUP_MIC_TAP); } - #endif return(VOICE_SESSION_GROUP_DEFAULT); } @@ -3463,16 +3441,12 @@ ctrlm_voice_format_t xrsr_to_voice_format(xrsr_audio_format_t format) { bool ctrlm_voice_t::is_voice_assistant(ctrlm_voice_device_t device) { bool voice_assistant = false; switch(device) { - #ifdef CTRLM_LOCAL_MIC case CTRLM_VOICE_DEVICE_MICROPHONE: - #endif case CTRLM_VOICE_DEVICE_FF: { voice_assistant = true; break; } - #ifdef CTRLM_LOCAL_MIC_TAP case CTRLM_VOICE_DEVICE_MICROPHONE_TAP: - #endif case CTRLM_VOICE_DEVICE_PTT: case CTRLM_VOICE_DEVICE_INVALID: default: { @@ -3590,12 +3564,10 @@ int ctrlm_voice_t::ctrlm_voice_controller_command_status_read_timeout(void *data return(false); } -#ifdef BEEP_ON_KWD_ENABLED int ctrlm_voice_t::ctrlm_voice_keyword_beep_end_timeout(void *data) { ctrlm_get_voice_obj()->voice_keyword_beep_completed_callback(true, false); return(false); } -#endif // Timeouts end @@ -3642,9 +3614,7 @@ const char *ctrlm_voice_session_response_status_str(ctrlm_voice_session_response const char *ctrlm_voice_session_group_str(ctrlm_voice_session_group_t group) { switch(group) { case VOICE_SESSION_GROUP_DEFAULT: return("DEFAULT"); - #ifdef CTRLM_LOCAL_MIC_TAP case VOICE_SESSION_GROUP_MIC_TAP: return("MIC_TAP"); - #endif case VOICE_SESSION_GROUP_QTY: break; // fall thru to return an invalid group } return(ctrlm_invalid_return(group)); @@ -3810,14 +3780,14 @@ void ctrlm_voice_t::voice_power_state_change(ctrlm_power_state_t power_state) { xrsr_power_mode_t xrsr_power_mode = voice_xrsr_power_map(power_state); - #ifdef CTRLM_LOCAL_MIC - if(power_state == CTRLM_POWER_STATE_ON) { - bool privacy_enabled = this->vsdk_is_privacy_enabled(); - if(privacy_enabled != this->voice_is_privacy_enabled()) { - privacy_enabled ? this->voice_privacy_enable(false) : this->voice_privacy_disable(false); + if(this->local_mic) { + if(power_state == CTRLM_POWER_STATE_ON) { + bool privacy_enabled = this->vsdk_is_privacy_enabled(); + if(privacy_enabled != this->voice_is_privacy_enabled()) { + privacy_enabled ? this->voice_privacy_enable(false) : this->voice_privacy_disable(false); + } } } - #endif if(!xrsr_power_mode_set(xrsr_power_mode)) { XLOGD_ERROR("failed to set xrsr to power state %s", ctrlm_power_state_str(power_state)); @@ -3851,57 +3821,56 @@ void ctrlm_voice_t::voice_session_set_inactive(ctrlm_voice_device_t device) { } bool ctrlm_voice_t::voice_is_privacy_enabled(void) { - #ifdef CTRLM_LOCAL_MIC - sem_wait(&this->device_status_semaphore); - bool value = (this->device_status[CTRLM_VOICE_DEVICE_MICROPHONE] & CTRLM_VOICE_DEVICE_STATUS_PRIVACY) ? true : false; - sem_post(&this->device_status_semaphore); - return(value); - #else + if(this->local_mic) { + sem_wait(&this->device_status_semaphore); + bool value = (this->device_status[CTRLM_VOICE_DEVICE_MICROPHONE] & CTRLM_VOICE_DEVICE_STATUS_PRIVACY) ? true : false; + sem_post(&this->device_status_semaphore); + return(value); + } return(false); - #endif } void ctrlm_voice_t::voice_privacy_enable(bool update_vsdk) { - #ifdef CTRLM_LOCAL_MIC - sem_wait(&this->device_status_semaphore); - if(this->device_status[CTRLM_VOICE_DEVICE_MICROPHONE] & CTRLM_VOICE_DEVICE_STATUS_PRIVACY) { - sem_post(&this->device_status_semaphore); - XLOGD_WARN("already enabled"); - return; - } + if(this->local_mic) { + sem_wait(&this->device_status_semaphore); + if(this->device_status[CTRLM_VOICE_DEVICE_MICROPHONE] & CTRLM_VOICE_DEVICE_STATUS_PRIVACY) { + sem_post(&this->device_status_semaphore); + XLOGD_WARN("already enabled"); + return; + } - this->device_status[CTRLM_VOICE_DEVICE_MICROPHONE] |= CTRLM_VOICE_DEVICE_STATUS_PRIVACY; - ctrlm_db_voice_write_device_status(CTRLM_VOICE_DEVICE_MICROPHONE, (this->device_status[CTRLM_VOICE_DEVICE_MICROPHONE] & CTRLM_VOICE_DEVICE_STATUS_MASK_DB)); + this->device_status[CTRLM_VOICE_DEVICE_MICROPHONE] |= CTRLM_VOICE_DEVICE_STATUS_PRIVACY; + ctrlm_db_voice_write_device_status(CTRLM_VOICE_DEVICE_MICROPHONE, (this->device_status[CTRLM_VOICE_DEVICE_MICROPHONE] & CTRLM_VOICE_DEVICE_STATUS_MASK_DB)); - #ifdef CTRLM_LOCAL_MIC_DISABLE_VIA_PRIVACY - if(update_vsdk && this->xrsr_opened && !xrsr_privacy_mode_set(true)) { - XLOGD_ERROR("xrsr_privacy_mode_set failed"); - } - #endif + if(this->local_mic_disable_via_privacy) { + if(update_vsdk && this->xrsr_opened && !xrsr_privacy_mode_set(true)) { + XLOGD_ERROR("xrsr_privacy_mode_set failed"); + } + } - sem_post(&this->device_status_semaphore); - #endif + sem_post(&this->device_status_semaphore); + } } void ctrlm_voice_t::voice_privacy_disable(bool update_vsdk) { - #ifdef CTRLM_LOCAL_MIC - sem_wait(&this->device_status_semaphore); - if(!(this->device_status[CTRLM_VOICE_DEVICE_MICROPHONE] & CTRLM_VOICE_DEVICE_STATUS_PRIVACY)) { - sem_post(&this->device_status_semaphore); - XLOGD_WARN("already disabled"); - return; - } + if(this->local_mic) { + sem_wait(&this->device_status_semaphore); + if(!(this->device_status[CTRLM_VOICE_DEVICE_MICROPHONE] & CTRLM_VOICE_DEVICE_STATUS_PRIVACY)) { + sem_post(&this->device_status_semaphore); + XLOGD_WARN("already disabled"); + return; + } - this->device_status[CTRLM_VOICE_DEVICE_MICROPHONE] &= ~CTRLM_VOICE_DEVICE_STATUS_PRIVACY; - ctrlm_db_voice_write_device_status(CTRLM_VOICE_DEVICE_MICROPHONE, (this->device_status[CTRLM_VOICE_DEVICE_MICROPHONE] & CTRLM_VOICE_DEVICE_STATUS_MASK_DB)); + this->device_status[CTRLM_VOICE_DEVICE_MICROPHONE] &= ~CTRLM_VOICE_DEVICE_STATUS_PRIVACY; + ctrlm_db_voice_write_device_status(CTRLM_VOICE_DEVICE_MICROPHONE, (this->device_status[CTRLM_VOICE_DEVICE_MICROPHONE] & CTRLM_VOICE_DEVICE_STATUS_MASK_DB)); - #ifdef CTRLM_LOCAL_MIC_DISABLE_VIA_PRIVACY - if(update_vsdk && this->xrsr_opened && !xrsr_privacy_mode_set(false)) { - XLOGD_ERROR("xrsr_privacy_mode_set failed"); - } - #endif - sem_post(&this->device_status_semaphore); - #endif + if(this->local_mic_disable_via_privacy) { + if(update_vsdk && this->xrsr_opened && !xrsr_privacy_mode_set(false)) { + XLOGD_ERROR("xrsr_privacy_mode_set failed"); + } + } + sem_post(&this->device_status_semaphore); + } } void ctrlm_voice_t::voice_device_enable(ctrlm_voice_device_t device, bool db_write, bool *update_routes) { @@ -3940,7 +3909,6 @@ void ctrlm_voice_t::voice_device_disable(ctrlm_voice_device_t device, bool db_wr sem_post(&this->device_status_semaphore); } -#ifdef BEEP_ON_KWD_ENABLED void ctrlm_voice_system_audio_player_event_handler(system_audio_player_event_t event, void *user_data) { if(user_data == NULL) { return; @@ -3980,27 +3948,24 @@ void ctrlm_voice_system_audio_player_event_handler(system_audio_player_event_t e } } } -#endif -#ifdef NETWORKED_STANDBY_MODE_ENABLED void ctrlm_voice_t::voice_nsm_session_request(void) { ctrlm_network_id_t network_id = CTRLM_MAIN_NETWORK_ID_DSP; ctrlm_controller_id_t controller_id = CTRLM_MAIN_CONTROLLER_ID_DSP; ctrlm_voice_device_t device = CTRLM_VOICE_DEVICE_MICROPHONE; ctrlm_voice_format_t format = { .type = CTRLM_VOICE_FORMAT_PCM_32_BIT }; - #ifdef CTRLM_LOCAL_MIC_DISABLE_VIA_PRIVACY - //If the user un-muted the microphones in standby, we must un-mute our components - if(this->voice_is_privacy_enabled()) { - this->voice_privacy_disable(true); + if(this->local_mic_disable_via_privacy) { + //If the user un-muted the microphones in standby, we must un-mute our components + if(this->voice_is_privacy_enabled()) { + this->voice_privacy_disable(true); + } } - #endif this->nsm_voice_session = true; voice_session_req(network_id, controller_id, device, format, NULL, "NSM", "0.0.0.0", "0.0.0.0", 0.0); } -#endif int ctrlm_voice_t::packet_loss_threshold_get() const { return(this->packet_loss_threshold); @@ -4025,11 +3990,11 @@ xrsr_power_mode_t voice_xrsr_power_map(ctrlm_power_state_t ctrlm_power_state) { switch(ctrlm_power_state) { case CTRLM_POWER_STATE_DEEP_SLEEP: - #ifdef NETWORKED_STANDBY_MODE_ENABLED - xrsr_power_mode = ctrlm_main_get_networked_standby_mode() ? XRSR_POWER_MODE_LOW : XRSR_POWER_MODE_SLEEP; - #else - xrsr_power_mode = XRSR_POWER_MODE_SLEEP; - #endif + if(ctrlm_is_networked_standby_supported()) { + xrsr_power_mode = ctrlm_main_get_networked_standby_mode() ? XRSR_POWER_MODE_LOW : XRSR_POWER_MODE_SLEEP; + } else { + xrsr_power_mode = XRSR_POWER_MODE_SLEEP; + } break; case CTRLM_POWER_STATE_ON: case CTRLM_POWER_STATE_STANDBY: @@ -4149,14 +4114,13 @@ void ctrlm_voice_t::voice_rfc_retrieved_handler(const ctrlm_rfc_attr_t& attr) { // All attributes that need a re-route to apply if(attr.get_rfc_value(JSON_INT_NAME_VOICE_MINIMUM_DURATION, this->prefs.utterance_duration_min) | - #ifdef NETWORKED_STANDBY_MODE_ENABLED attr.get_rfc_value(JSON_INT_NAME_VOICE_DST_PARAMS_STANDBY_CONNECT_CHECK_INTERVAL, this->prefs.dst_params_standby.connect_check_interval) | attr.get_rfc_value(JSON_INT_NAME_VOICE_DST_PARAMS_STANDBY_TIMEOUT_CONNECT, this->prefs.dst_params_standby.timeout_connect) | attr.get_rfc_value(JSON_INT_NAME_VOICE_DST_PARAMS_STANDBY_TIMEOUT_INACTIVITY, this->prefs.dst_params_standby.timeout_inactivity) | attr.get_rfc_value(JSON_INT_NAME_VOICE_DST_PARAMS_STANDBY_TIMEOUT_SESSION, this->prefs.dst_params_standby.timeout_session) | attr.get_rfc_value(JSON_BOOL_NAME_VOICE_DST_PARAMS_STANDBY_IPV4_FALLBACK, this->prefs.dst_params_standby.ipv4_fallback) | attr.get_rfc_value(JSON_INT_NAME_VOICE_DST_PARAMS_STANDBY_BACKOFF_DELAY, this->prefs.dst_params_standby.backoff_delay) | - #endif + attr.get_rfc_value(JSON_INT_NAME_VOICE_DST_PARAMS_LOW_LATENCY_CONNECT_CHECK_INTERVAL, this->prefs.dst_params_low_latency.connect_check_interval) | attr.get_rfc_value(JSON_INT_NAME_VOICE_DST_PARAMS_LOW_LATENCY_TIMEOUT_CONNECT, this->prefs.dst_params_low_latency.timeout_connect) | attr.get_rfc_value(JSON_INT_NAME_VOICE_DST_PARAMS_LOW_LATENCY_TIMEOUT_INACTIVITY, this->prefs.dst_params_low_latency.timeout_inactivity) | @@ -4176,9 +4140,7 @@ void ctrlm_voice_t::voice_rfc_retrieved_handler(const ctrlm_rfc_attr_t& attr) { attr.get_rfc_value(JSON_BOOL_NAME_VOICE_ENABLE, enabled); attr.get_rfc_value(JSON_STR_NAME_VOICE_URL_SRC_PTT, this->prefs.server_url_src_ptt); attr.get_rfc_value(JSON_STR_NAME_VOICE_URL_SRC_FF, this->prefs.server_url_src_ff); - #ifdef CTRLM_LOCAL_MIC_TAP attr.get_rfc_value(JSON_STR_NAME_VOICE_URL_SRC_MIC_TAP, this->prefs.server_url_src_mic_tap); - #endif // Check if enabled if(!enabled) { for(int i = CTRLM_VOICE_DEVICE_PTT; i < CTRLM_VOICE_DEVICE_INVALID; i++) { diff --git a/src/voice/ctrlm_voice_obj.h b/src/voice/ctrlm_voice_obj.h index 70ddb4c7..bd8de16c 100644 --- a/src/voice/ctrlm_voice_obj.h +++ b/src/voice/ctrlm_voice_obj.h @@ -37,21 +37,14 @@ #include "ctrlm_rfc.h" #include "xrsr.h" #include "ctrlm_voice_telemetry_events.h" - -#ifdef BEEP_ON_KWD_ENABLED #include "ctrlm_thunder_plugin_system_audio_player.h" -#endif #define VOICE_SESSION_REQ_DATA_LEN_MAX (33) typedef enum { VOICE_SESSION_GROUP_DEFAULT = 0, // Session index for regular voice sessions (PTT, FFV) - #ifdef CTRLM_LOCAL_MIC_TAP VOICE_SESSION_GROUP_MIC_TAP = 1, // Session index for microphone tap voice sessions VOICE_SESSION_GROUP_QTY = 2 - #else - VOICE_SESSION_GROUP_QTY = 1 - #endif } ctrlm_voice_session_group_t; #ifdef VOICE_BUFFER_STATS @@ -282,9 +275,7 @@ typedef struct { typedef struct { std::string server_url_src_ptt; std::string server_url_src_ff; - #ifdef CTRLM_LOCAL_MIC_TAP std::string server_url_src_mic_tap; - #endif std::vector server_hosts; std::string aspect_ratio; std::string guide_language; @@ -313,9 +304,7 @@ typedef struct { uint8_t opus_encoder_params[CTRLM_RCU_RIB_ATTR_LEN_OPUS_ENCODING_PARAMS]; bool force_toggle_fallback; bool telemetry_session_stats; - #ifdef NETWORKED_STANDBY_MODE_ENABLED xrsr_dst_params_t dst_params_standby; - #endif xrsr_dst_params_t dst_params_low_latency; bool par_voice_enabled; uint8_t par_voice_eos_method; @@ -391,9 +380,7 @@ typedef struct { typedef struct { std::string urlPtt; std::string urlHf; - #ifdef CTRLM_LOCAL_MIC_TAP std::string urlMicTap; - #endif uint8_t status[CTRLM_VOICE_DEVICE_INVALID]; bool prv_enabled; bool wwFeedback; @@ -529,6 +516,8 @@ class ctrlm_voice_t { bool voice_stb_data_bypass_wuw_verify_failure_get() const; virtual void voice_stb_data_pii_mask_set(bool mask_pii); bool voice_stb_data_pii_mask_get() const; + bool voice_stb_data_local_mic_get() const; + bool voice_stb_data_local_mic_tap_get() const; virtual bool voice_stb_data_device_certificate_set(ctrlm_voice_cert_t &device_cert, bool &ocsp_verify_stapling, bool &ocsp_verify_ca); virtual bool voice_stb_data_device_certificate_set(const char *p12_cert, const char *p12_pass); virtual bool voice_stb_data_device_certificate_set(const char *pem_cert, const char *pem_pkey, const char *pem_chain, const char *pem_passphrase); @@ -586,9 +575,7 @@ class ctrlm_voice_t { static int ctrlm_voice_packet_timeout(void *data); static int ctrlm_voice_controller_session_stats_rxd_timeout(void *data); static int ctrlm_voice_controller_command_status_read_timeout(void *data); - #ifdef BEEP_ON_KWD_ENABLED static int ctrlm_voice_keyword_beep_end_timeout(void *data); - #endif // End Static Callbacks // Event Interface @@ -609,15 +596,11 @@ class ctrlm_voice_t { virtual void voice_server_return_code_callback(const uuid_t uuid, const char *reason, long ret_code); virtual void voice_session_transcription_callback(const uuid_t uuid, const char *transcription); virtual void voice_power_state_change(ctrlm_power_state_t power_state); - #ifdef NETWORKED_STANDBY_MODE_ENABLED virtual void voice_nsm_session_request(void); - #endif virtual void voice_keyword_verified_action(void); - #ifdef BEEP_ON_KWD_ENABLED virtual void voice_keyword_beep_completed_normal(void *data, int size); virtual void voice_keyword_beep_completed_error(void *data, int size); virtual void voice_keyword_beep_completed_callback(bool timeout, bool playback_error); - #endif // End Event Interface protected: @@ -663,6 +646,11 @@ class ctrlm_voice_t { bool mtls_required; bool secure_url_required; bool mask_pii; + bool local_mic; + bool local_mic_tap; + bool local_mic_disable_via_privacy; + const char * beep_on_kwd_file; + bool beep_on_kwd_supported; bool ocsp_verify_stapling; bool ocsp_verify_ca; bool capture_active; @@ -685,11 +673,9 @@ class ctrlm_voice_t { bool xrsr_opened; ctrlm_voice_ipc_t *voice_ipc; - #ifdef BEEP_ON_KWD_ENABLED Thunder::SystemAudioPlayer::ctrlm_thunder_plugin_system_audio_player_t *obj_sap; bool sap_opened; ctrlm_timestamp_t sap_play_timestamp; - #endif // Current Session Data unsigned long opus_samples_per_packet; @@ -759,27 +745,11 @@ xrsr_src_t voice_device_to_xrsr(ctrlm_voice_device_t device); __inline bool ctrlm_voice_device_is_mic(ctrlm_voice_device_t device) { - #ifdef CTRLM_LOCAL_MIC - #ifdef CTRLM_LOCAL_MIC_TAP return(device == CTRLM_VOICE_DEVICE_MICROPHONE || device == CTRLM_VOICE_DEVICE_MICROPHONE_TAP); - #else - return(device == CTRLM_VOICE_DEVICE_MICROPHONE); - #endif - #else - return(false); - #endif } __inline bool ctrlm_voice_xrsr_src_is_mic(xrsr_src_t src) { - #ifdef CTRLM_LOCAL_MIC - #ifdef CTRLM_LOCAL_MIC_TAP return(src == XRSR_SRC_MICROPHONE || src == XRSR_SRC_MICROPHONE_TAP); - #else - return(src == XRSR_SRC_MICROPHONE); - #endif - #else - return(false); - #endif } #endif diff --git a/src/voice/ctrlm_voice_obj_generic.cpp b/src/voice/ctrlm_voice_obj_generic.cpp index 340b295d..4cb35f99 100644 --- a/src/voice/ctrlm_voice_obj_generic.cpp +++ b/src/voice/ctrlm_voice_obj_generic.cpp @@ -165,6 +165,8 @@ void ctrlm_voice_generic_t::voice_sdk_update_routes() { errno_t safec_rc = memset_s(&routes, sizeof(routes), 0, sizeof(routes)); ERR_CHK(safec_rc); + bool networked_standby_supported = ctrlm_is_networked_standby_supported(); + // iterate over source to url mapping for(int j = 0; j < XRSR_SRC_INVALID; j++) { xrsr_src_t src = (xrsr_src_t)j; @@ -178,19 +180,15 @@ void ctrlm_voice_generic_t::voice_sdk_update_routes() { url = &this->prefs.server_url_src_ptt; break; } - #ifdef CTRLM_LOCAL_MIC case CTRLM_VOICE_DEVICE_MICROPHONE: - #endif case CTRLM_VOICE_DEVICE_FF: { url = &this->prefs.server_url_src_ff; break; } - #ifdef CTRLM_LOCAL_MIC_TAP case CTRLM_VOICE_DEVICE_MICROPHONE_TAP: { url = &this->prefs.server_url_src_mic_tap; break; } - #endif default: { break; } @@ -243,11 +241,9 @@ void ctrlm_voice_generic_t::voice_sdk_update_routes() { routes[i].dsts[0].stream_from = stream_from; routes[i].dsts[0].stream_offset = stream_offset; routes[i].dsts[0].stream_until = stream_until; - #ifdef NETWORKED_STANDBY_MODE_ENABLED - if(src == XRSR_SRC_MICROPHONE) { + if(networked_standby_supported && (src == XRSR_SRC_MICROPHONE)) { routes[i].dsts[0].params[XRSR_POWER_MODE_LOW] = &this->prefs.dst_params_standby; } - #endif i++; XLOGD_INFO("url translation from %s to %s", url->c_str(), urls_translated[translated_index].c_str()); } @@ -277,11 +273,9 @@ void ctrlm_voice_generic_t::voice_sdk_update_routes() { routes[i].dsts[0].stream_from = XRSR_STREAM_FROM_LIVE; routes[i].dsts[0].stream_offset = 0; routes[i].dsts[0].stream_until = XRSR_STREAM_UNTIL_END_OF_STREAM; - #ifdef NETWORKED_STANDBY_MODE_ENABLED - if(src == XRSR_SRC_MICROPHONE) { + if(networked_standby_supported && (src == XRSR_SRC_MICROPHONE)) { routes[i].dsts[0].params[XRSR_POWER_MODE_LOW] = &this->prefs.dst_params_standby; } - #endif // Set low latency websocket parameters routes[i].dsts[0].params[XRSR_POWER_MODE_FULL] = &this->prefs.dst_params_low_latency; @@ -324,11 +318,9 @@ void ctrlm_voice_generic_t::voice_sdk_update_routes() { routes[i].dsts[0].stream_from = stream_from; routes[i].dsts[0].stream_offset = stream_offset; routes[i].dsts[0].stream_until = stream_until; - #ifdef NETWORKED_STANDBY_MODE_ENABLED - if(src == XRSR_SRC_MICROPHONE) { + if(networked_standby_supported && (src == XRSR_SRC_MICROPHONE)) { routes[i].dsts[0].params[XRSR_POWER_MODE_LOW] = &this->prefs.dst_params_standby; } - #endif i++; } } @@ -351,11 +343,9 @@ void ctrlm_voice_generic_t::voice_sdk_update_routes() { routes[i].dsts[0].stream_from = stream_from; routes[i].dsts[0].stream_offset = stream_offset; routes[i].dsts[0].stream_until = stream_until; - #ifdef NETWORKED_STANDBY_MODE_ENABLED - if(src == XRSR_SRC_MICROPHONE) { + if(networked_standby_supported && (src == XRSR_SRC_MICROPHONE)) { routes[i].dsts[0].params[XRSR_POWER_MODE_LOW] = &this->prefs.dst_params_standby; } - #endif i++; } } else if(url->rfind("avs", 0) == 0) { @@ -376,11 +366,9 @@ void ctrlm_voice_generic_t::voice_sdk_update_routes() { routes[i].dsts[0].stream_from = stream_from; routes[i].dsts[0].stream_offset = stream_offset; routes[i].dsts[0].stream_until = stream_until; - #ifdef NETWORKED_STANDBY_MODE_ENABLED - if(src == XRSR_SRC_MICROPHONE) { + if(networked_standby_supported && (src == XRSR_SRC_MICROPHONE)) { routes[i].dsts[0].params[XRSR_POWER_MODE_LOW] = &this->prefs.dst_params_standby; } - #endif i++; } } diff --git a/src/voice/ctrlm_voice_types.h b/src/voice/ctrlm_voice_types.h index e8f86fe6..e65a49ba 100644 --- a/src/voice/ctrlm_voice_types.h +++ b/src/voice/ctrlm_voice_types.h @@ -31,12 +31,8 @@ typedef enum { CTRLM_VOICE_DEVICE_PTT, CTRLM_VOICE_DEVICE_FF, - #ifdef CTRLM_LOCAL_MIC CTRLM_VOICE_DEVICE_MICROPHONE, - #ifdef CTRLM_LOCAL_MIC_TAP CTRLM_VOICE_DEVICE_MICROPHONE_TAP, - #endif - #endif CTRLM_VOICE_DEVICE_INVALID, } ctrlm_voice_device_t; diff --git a/src/voice/ipc/ctrlm_voice_ipc_iarm_thunder.cpp b/src/voice/ipc/ctrlm_voice_ipc_iarm_thunder.cpp index 1dfa80b8..022b71f4 100644 --- a/src/voice/ipc/ctrlm_voice_ipc_iarm_thunder.cpp +++ b/src/voice/ipc/ctrlm_voice_ipc_iarm_thunder.cpp @@ -444,9 +444,7 @@ IARM_Result_t ctrlm_voice_ipc_iarm_thunder_t::status(void *data) { rc |= json_object_set_new_nocheck(obj, JSON_URL_PTT, json_string(status.urlPtt.c_str())); rc |= json_object_set_new_nocheck(obj, JSON_URL_HF, json_string(status.urlHf.c_str())); - #ifdef CTRLM_LOCAL_MIC_TAP rc |= json_object_set_new_nocheck(obj, JSON_URL_MIC_TAP, json_string(status.urlMicTap.c_str())); - #endif rc |= json_object_set_new_nocheck(obj, JSON_WW_FEEDBACK, status.wwFeedback ? json_true() : json_false()); rc |= json_object_set_new_nocheck(obj, JSON_PRV, status.prv_enabled ? json_true() : json_false()); rc |= json_object_set_new_nocheck(obj, JSON_THUNDER_RESULT, json_true()); @@ -586,14 +584,16 @@ IARM_Result_t ctrlm_voice_ipc_iarm_thunder_t::voice_session_types(void *data) { int rc = json_array_append_new(obj_types, json_string("ptt_transcription")); rc |= json_array_append_new(obj_types, json_string("ptt_audio_file")); - #ifdef CTRLM_LOCAL_MIC - rc |= json_array_append_new(obj_types, json_string("mic_audio_file")); - rc |= json_array_append_new(obj_types, json_string("mic_stream_single")); - rc |= json_array_append_new(obj_types, json_string("mic_stream_multi")); - rc |= json_array_append_new(obj_types, json_string("mic_tap_stream_single")); - rc |= json_array_append_new(obj_types, json_string("mic_tap_stream_multi")); - rc |= json_array_append_new(obj_types, json_string("mic_factory_test")); - #endif + if(voice_obj->voice_stb_data_local_mic_get()) { + rc |= json_array_append_new(obj_types, json_string("mic_audio_file")); + rc |= json_array_append_new(obj_types, json_string("mic_stream_single")); + rc |= json_array_append_new(obj_types, json_string("mic_stream_multi")); + if(voice_obj->voice_stb_data_local_mic_tap_get()) { + rc |= json_array_append_new(obj_types, json_string("mic_tap_stream_single")); + rc |= json_array_append_new(obj_types, json_string("mic_tap_stream_multi")); + } + rc |= json_array_append_new(obj_types, json_string("mic_factory_test")); + } rc |= json_object_set_new_nocheck(obj_result, JSON_TYPES, obj_types); rc |= json_object_set_new_nocheck(obj_result, JSON_THUNDER_RESULT, json_true()); @@ -964,12 +964,8 @@ const char *voice_device_str(ctrlm_voice_device_t device) { switch(device) { case CTRLM_VOICE_DEVICE_PTT: return("ptt"); case CTRLM_VOICE_DEVICE_FF: return("ff"); - #ifdef CTRLM_LOCAL_MIC case CTRLM_VOICE_DEVICE_MICROPHONE: return("mic"); - #ifdef CTRLM_LOCAL_MIC_TAP case CTRLM_VOICE_DEVICE_MICROPHONE_TAP: return("mic_tap"); - #endif - #endif default: break; } return("invalid"); @@ -1051,9 +1047,9 @@ bool ctrlm_voice_ipc_request_supported_mic_transcription(ctrlm_voice_ipc_request } bool ctrlm_voice_ipc_request_supported_mic_audio_file(ctrlm_voice_ipc_request_config_t *config) { - #ifndef CTRLM_LOCAL_MIC - return(false); - #else + if(!ctrlm_get_voice_obj()->voice_stb_data_local_mic_get()) { + return(false); + } config->requires_transcription = false; config->requires_audio_file = true; config->supports_named_pipe = false; @@ -1062,7 +1058,6 @@ bool ctrlm_voice_ipc_request_supported_mic_audio_file(ctrlm_voice_ipc_request_co config->low_latency = false; config->low_cpu_util = false; return(true); - #endif } bool ctrlm_voice_ipc_request_supported_mic_stream_default(ctrlm_voice_ipc_request_config_t *config) { @@ -1081,9 +1076,9 @@ bool ctrlm_voice_ipc_request_supported_mic_stream_default(ctrlm_voice_ipc_reques } bool ctrlm_voice_ipc_request_supported_mic_stream_single(ctrlm_voice_ipc_request_config_t *config) { - #ifndef CTRLM_LOCAL_MIC - return(false); - #else + if(!ctrlm_get_voice_obj()->voice_stb_data_local_mic_get()) { + return(false); + } config->requires_transcription = false; config->requires_audio_file = false; config->supports_named_pipe = false; @@ -1092,13 +1087,12 @@ bool ctrlm_voice_ipc_request_supported_mic_stream_single(ctrlm_voice_ipc_request config->low_latency = true; config->low_cpu_util = false; return(true); - #endif } bool ctrlm_voice_ipc_request_supported_mic_stream_multi(ctrlm_voice_ipc_request_config_t *config) { - #ifndef CTRLM_LOCAL_MIC - return(false); - #else + if(!ctrlm_get_voice_obj()->voice_stb_data_local_mic_get()) { + return(false); + } config->requires_transcription = false; config->requires_audio_file = false; config->supports_named_pipe = false; @@ -1107,13 +1101,12 @@ bool ctrlm_voice_ipc_request_supported_mic_stream_multi(ctrlm_voice_ipc_request_ config->low_latency = true; config->low_cpu_util = false; return(true); - #endif } bool ctrlm_voice_ipc_request_supported_mic_tap_stream_single(ctrlm_voice_ipc_request_config_t *config) { - #ifndef CTRLM_LOCAL_MIC_TAP - return(false); - #else + if(!ctrlm_get_voice_obj()->voice_stb_data_local_mic_tap_get()) { + return(false); + } config->requires_transcription = false; config->requires_audio_file = false; config->supports_named_pipe = false; @@ -1122,13 +1115,12 @@ bool ctrlm_voice_ipc_request_supported_mic_tap_stream_single(ctrlm_voice_ipc_req config->low_latency = true; config->low_cpu_util = true; return(true); - #endif } bool ctrlm_voice_ipc_request_supported_mic_tap_stream_multi(ctrlm_voice_ipc_request_config_t *config) { - #ifndef CTRLM_LOCAL_MIC_TAP - return(false); - #else + if(!ctrlm_get_voice_obj()->voice_stb_data_local_mic_tap_get()) { + return(false); + } config->requires_transcription = false; config->requires_audio_file = false; config->supports_named_pipe = false; @@ -1137,20 +1129,22 @@ bool ctrlm_voice_ipc_request_supported_mic_tap_stream_multi(ctrlm_voice_ipc_requ config->low_latency = true; config->low_cpu_util = true; return(true); - #endif } bool ctrlm_voice_ipc_request_supported_mic_factory_test(ctrlm_voice_ipc_request_config_t *config) { - #ifdef CTRLM_LOCAL_MIC_TAP - config->requires_transcription = false; - config->requires_audio_file = false; - config->supports_named_pipe = false; - config->device = CTRLM_VOICE_DEVICE_MICROPHONE_TAP; - config->format = { .type = CTRLM_VOICE_FORMAT_PCM_RAW }; - config->low_latency = true; - config->low_cpu_util = true; - return(true); - #elif defined(CTRLM_LOCAL_MIC) + if(ctrlm_get_voice_obj()->voice_stb_data_local_mic_tap_get()) { + config->requires_transcription = false; + config->requires_audio_file = false; + config->supports_named_pipe = false; + config->device = CTRLM_VOICE_DEVICE_MICROPHONE_TAP; + config->format = { .type = CTRLM_VOICE_FORMAT_PCM_RAW }; + config->low_latency = true; + config->low_cpu_util = true; + return(true); + } + if(!ctrlm_get_voice_obj()->voice_stb_data_local_mic_get()) { + return(false); + } config->requires_transcription = false; config->requires_audio_file = false; config->supports_named_pipe = false; @@ -1159,7 +1153,4 @@ bool ctrlm_voice_ipc_request_supported_mic_factory_test(ctrlm_voice_ipc_request_ config->low_latency = true; config->low_cpu_util = false; return(true); - #else - return(false); - #endif } From bcc3be830dd5b956b82c3c05c80d25179cf66dd4 Mon Sep 17 00:00:00 2001 From: dwolaver <44593664+dwolaver@users.noreply.github.com> Date: Tue, 18 Nov 2025 19:56:45 -0500 Subject: [PATCH 11/39] RDKEMW-9124 : remove xr-voice-sdk build flags - XRAUDIO_CURTAIL XLOG_CURTAIL (#132) --- src/ctrlm_main.cpp | 5 ++++- src/factory/ctrlmf_version.c | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ctrlm_main.cpp b/src/ctrlm_main.cpp index 65f3ad19..272d254e 100644 --- a/src/ctrlm_main.cpp +++ b/src/ctrlm_main.cpp @@ -479,7 +479,10 @@ int main(int argc, char *argv[]) { XLOGD_INFO("name <%-24s> version <%-9s> branch <%-20s> commit <%s>", entry->name ? entry->name : "NULL", entry->version ? entry->version : "NULL", entry->branch ? entry->branch : "NULL", entry->commit_id ? entry->commit_id : "NULL"); } } - vsdk_init(true); + + const char *filename = NULL; + uint32_t file_size_max = 0; + vsdk_init(true, filename, file_size_max); //struct sched_param param; //param.sched_priority = 10; diff --git a/src/factory/ctrlmf_version.c b/src/factory/ctrlmf_version.c index cffa6584..459f0fd7 100644 --- a/src/factory/ctrlmf_version.c +++ b/src/factory/ctrlmf_version.c @@ -36,7 +36,7 @@ bool ctrlmf_init(xlog_level_t level, bool requires_audio_playback) { rdk_version_object_free(&info); - int rc = xlog_init(XLOG_MODULE_ID, NULL, 0, true); + int rc = xlog_init(XLOG_MODULE_ID, NULL, 0, true, false); xlog_level_set_all(level); if(rc != 0) { From a5109c82635bae5cf6a97f86bf1e43be051c5d5f Mon Sep 17 00:00:00 2001 From: dwolaver <44593664+dwolaver@users.noreply.github.com> Date: Wed, 19 Nov 2025 07:28:04 -0500 Subject: [PATCH 12/39] RDKEMW-10480 : ctrlm release v1.1.6, xr-voice-sdk v1.0.7 (#149) --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef1e336b..ea63c55d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,22 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [1.1.6](https://github.com/rdkcentral/control/compare/1.1.5...1.1.6) + +> 19 November 2025 + +- RDKEMW-9124 : remove xr-voice-sdk build flags - XRAUDIO_CURTAIL XLOG_CURTAIL [`#132`](https://github.com/rdkcentral/control/pull/132) +- RDKEMW-8676 : remove ctrlm build flags - MIC_TAP, LOCAL_MIC, LOCAL_MIC_DISABLE_VIA_PRIVACY [`#120`](https://github.com/rdkcentral/control/pull/120) +- RDKEMW-8664 : remove ctrlm build flags - MEM_DEBUG, ASSERT_ON_WRONG_THREAD [`#118`](https://github.com/rdkcentral/control/pull/118) +- RDKEMW-8297 : remove ctrlm build flags - A5000_ENABLE [`#117`](https://github.com/rdkcentral/control/pull/117) +- RDKEMW-8668 : modify ctrlm build flag - BREAKPAD [`#119`](https://github.com/rdkcentral/control/pull/119) +- RDKEMW-8296 : remove ctrlm build flags - DEEPSLEEP_CLOSE_DB [`#112`](https://github.com/rdkcentral/control/pull/112) +- RDKEMW-8295 : remove ctrlm build flags - MEMORY_LOCK [`#111`](https://github.com/rdkcentral/control/pull/111) +- RDKEMW-7905 : remove ctrlm build flags - ANSI_CODES_DISABLED [`#110`](https://github.com/rdkcentral/control/pull/110) +- Revert "RDKEMW-8929 (#129)" [`#145`](https://github.com/rdkcentral/control/pull/145) +- RDKEMW-10311 : RF4CE update key mapping [`#140`](https://github.com/rdkcentral/control/pull/140) +- RDKEMW-10164: update CHANGELOG for release v1.1.5 [`#139`](https://github.com/rdkcentral/control/pull/139) + #### [1.1.5](https://github.com/rdkcentral/control/compare/1.1.4...1.1.5) > 5 November 2025 From e1fadf0ac1c8191f15e94f2a8e7658dd506c3842 Mon Sep 17 00:00:00 2001 From: Kelvin Lu <119349872+klu339@users.noreply.github.com> Date: Wed, 19 Nov 2025 10:29:46 -0500 Subject: [PATCH 13/39] RDKEMW-9600: FIRST_PACKET_TIMEOUTs (#135) --- src/ble/ctrlm_ble_network.cpp | 79 ++++-- src/ble/ctrlm_ble_network.h | 2 + src/ctrlm_network.cpp | 5 + src/ctrlm_network.h | 2 + src/rf4ce/ctrlm_rf4ce_network.cpp | 226 ++++++++++-------- src/rf4ce/ctrlm_rf4ce_network.h | 2 + src/voice/ctrlm_voice_obj.cpp | 15 +- src/voice/ctrlm_voice_obj.h | 29 ++- .../ipc/ctrlm_voice_ipc_iarm_thunder.cpp | 3 +- 9 files changed, 246 insertions(+), 117 deletions(-) diff --git a/src/ble/ctrlm_ble_network.cpp b/src/ble/ctrlm_ble_network.cpp index dca4c78f..1e141823 100644 --- a/src/ble/ctrlm_ble_network.cpp +++ b/src/ble/ctrlm_ble_network.cpp @@ -525,7 +525,6 @@ void ctrlm_obj_network_ble_t::req_process_voice_session_begin(void *data, int si // only support ADPCM from ble-rcu component ctrlm_hal_ble_VoiceEncoding_t encoding = CTRLM_HAL_BLE_ENCODING_ADPCM; - ctrlm_hal_ble_VoiceStreamEnd_t streamEnd = CTRLM_HAL_BLE_VOICE_STREAM_END_ON_KEY_UP; ctrlm_voice_format_t voice_format = { .type = CTRLM_VOICE_FORMAT_INVALID }; @@ -543,18 +542,21 @@ void ctrlm_obj_network_ble_t::req_process_voice_session_begin(void *data, int si audio_format.getHeaderInfoAdpcm(adpcm_frame->offset_step_size_index, adpcm_frame->offset_predicted_sample_lsb, adpcm_frame->offset_predicted_sample_msb, adpcm_frame->offset_sequence_value, adpcm_frame->shift_sequence_value, adpcm_frame->sequence_value_min, adpcm_frame->sequence_value_max); pressAndHoldSupport = audio_format.getPressAndHoldSupport(); - if(!pressAndHoldSupport) { - streamEnd = CTRLM_HAL_BLE_VOICE_STREAM_END_ON_AUDIO_DURATION; - } controllers_[controller_id]->setPressAndHoldSupport(pressAndHoldSupport); } } + ctrlm_voice_start_audio_params_t audio_start_params; + audio_start_params.m_controller_id = controller_id; + audio_start_params.m_fd = -1; + audio_start_params.m_started = false; + auto audio_start_cb = std::bind(&ctrlm_obj_network_ble_t::start_controller_audio_streaming, this, std::placeholders::_1); + voice_status = ctrlm_get_voice_obj()->voice_session_req(network_id_get(), controller_id, device, voice_format, NULL, controllers_[controller_id]->get_model().c_str(), controllers_[controller_id]->get_sw_revision().to_string().c_str(), controllers_[controller_id]->get_hw_revision().to_string().c_str(), 0.0, - false, NULL, NULL, NULL, true, pressAndHoldSupport); + false, NULL, NULL, NULL, true, pressAndHoldSupport, audio_start_cb, &audio_start_params); if (!controllers_[controller_id]->get_capabilities().has_capability(ctrlm_controller_capabilities_t::capability::PAR) && (VOICE_SESSION_RESPONSE_AVAILABLE_PAR_VOICE == voice_status)) { XLOGD_WARN("PAR voice is enabled but not supported by BLE controller treating as normal voice session"); voice_status = VOICE_SESSION_RESPONSE_AVAILABLE; @@ -562,24 +564,21 @@ void ctrlm_obj_network_ble_t::req_process_voice_session_begin(void *data, int si if (VOICE_SESSION_RESPONSE_AVAILABLE != voice_status) { XLOGD_TELEMETRY("Failed opening voice session in ctrlm_voice_t, error = <%d>", voice_status); } else { + int fd = -1; bool success = false; - if (ble_rcu_interface_) { - int fd = -1; - - if (!ble_rcu_interface_->startAudioStreaming(ieee_address, encoding, streamEnd, fd)) { - XLOGD_ERROR("failed to start audio streaming on remote"); - } else { + if (!audio_start_params.m_started) { // voice session req did not need to start audio + start_controller_audio_streaming(&audio_start_params); + } + fd = audio_start_params.m_fd; - if (fd < 0) { - XLOGD_ERROR("Voice streaming pipe invalid (fd = <%d>), aborting voice session", fd); - success = false; - } else { - XLOGD_INFO("Acquired voice streaming pipe fd = <%d>, sending to voice engine", fd); - //Send the fd acquired from bluez to the voice engine - success = ctrlm_get_voice_obj()->voice_session_data(network_id_get(), controller_id, fd); - } - } + if (fd < 0) { + XLOGD_ERROR("Voice streaming pipe invalid (fd = <%d>), aborting voice session", fd); + success = false; + } else { + XLOGD_INFO("Acquired voice streaming pipe fd = <%d>, sending to voice engine", fd); + //Send the fd acquired from bluez to the voice engine + success = ctrlm_get_voice_obj()->voice_session_data(network_id_get(), controller_id, fd); } if (false == success) { @@ -2616,3 +2615,43 @@ ctrlm_controller_id_t ctrlm_obj_network_ble_t::find_controller_from_upgrade_sess } return id; } + +void ctrlm_obj_network_ble_t::start_controller_audio_streaming(ctrlm_voice_start_audio_params_t *params) { + THREAD_ID_VALIDATE(); + int fd = -1; + ctrlm_controller_id_t id = params->m_controller_id; + params->m_fd = fd; + params->m_started = false; + + if (!ready_) { + XLOGD_FATAL("Network is not ready!"); + return; + } + + if(!controller_exists(id)) { + XLOGD_WARN("Controller %u doesn't exist.", id); + return; + } + + if (!ble_rcu_interface_) { + XLOGD_WARN("ble rcu interface not ready"); + return; + } + + ctrlm_hal_ble_VoiceEncoding_t encoding = CTRLM_HAL_BLE_ENCODING_ADPCM; + ctrlm_hal_ble_VoiceStreamEnd_t streamEnd = CTRLM_HAL_BLE_VOICE_STREAM_END_ON_KEY_UP; + auto rcu = controllers_.at(id); + + if (rcu->getPressAndHoldSupport()) { + streamEnd = CTRLM_HAL_BLE_VOICE_STREAM_END_ON_AUDIO_DURATION; + } + + uint64_t ieee_address = rcu->ieee_address_get().get_value(); + if (!ble_rcu_interface_->startAudioStreaming(ieee_address, encoding, streamEnd, fd)) { + XLOGD_ERROR("failed to start audio streaming on remote"); + return; + } + + params->m_fd = fd; + params->m_started = true; +} diff --git a/src/ble/ctrlm_ble_network.h b/src/ble/ctrlm_ble_network.h index 92868ca1..787bb8b8 100644 --- a/src/ble/ctrlm_ble_network.h +++ b/src/ble/ctrlm_ble_network.h @@ -192,6 +192,8 @@ class ctrlm_obj_network_ble_t : public ctrlm_obj_network_t { std::shared_ptr getConfigSettings(); + virtual void start_controller_audio_streaming(ctrlm_voice_start_audio_params_t *params); + private: ctrlm_obj_network_ble_t(); diff --git a/src/ctrlm_network.cpp b/src/ctrlm_network.cpp index 74ff4129..69fa462b 100644 --- a/src/ctrlm_network.cpp +++ b/src/ctrlm_network.cpp @@ -1074,3 +1074,8 @@ void ctrlm_obj_network_t::iarm_event_rcu_firmware_status(const ctrlm_obj_control } #endif } + +void ctrlm_obj_network_t::start_controller_audio_streaming(ctrlm_voice_start_audio_params_t *params) { + XLOGD_WARN("not implemented for %s network", name_get()); + return; +} diff --git a/src/ctrlm_network.h b/src/ctrlm_network.h index ab22b51b..c39f3285 100644 --- a/src/ctrlm_network.h +++ b/src/ctrlm_network.h @@ -289,6 +289,8 @@ class ctrlm_obj_network_t virtual void iarm_event_rcu_validation_status(void); virtual void iarm_event_rcu_firmware_status(const ctrlm_obj_controller_t &rcu); + virtual void start_controller_audio_streaming(ctrlm_voice_start_audio_params_t *params); + // Internal methods std::string version_; diff --git a/src/rf4ce/ctrlm_rf4ce_network.cpp b/src/rf4ce/ctrlm_rf4ce_network.cpp index de5a22ff..5fea2cd3 100644 --- a/src/rf4ce/ctrlm_rf4ce_network.cpp +++ b/src/rf4ce/ctrlm_rf4ce_network.cpp @@ -3751,94 +3751,35 @@ void ctrlm_obj_network_rf4ce_t::ind_process_voice_session_request(void *data, in XLOGD_INFO("processing session request - type <%s> voice format <%s>", ctrlm_voice_device_str(device_type), ctrlm_voice_format_str(voice_format)); } - std::string controller_name = controllers_[dqm->controller_id]->product_name_get(); - ctrlm_hal_rf4ce_cfm_data_t cb_confirm_rf4ce = NULL; - void * cb_confirm_param = NULL; + std::string controller_name = controllers_[dqm->controller_id]->product_name_get(); + void * cb_confirm_param = NULL; ctrlm_voice_session_rsp_confirm_t cb_confirm_voice_obj = NULL; + ctrlm_voice_start_audio_params_t start_audio_params; + start_audio_params.m_controller_id = dqm->controller_id; + start_audio_params.m_use_stream_params = use_stream_params; + start_audio_params.m_offset = offset; + start_audio_params.m_started = false; + start_audio_params.m_timestamp = dqm->timestamp; + start_audio_params.m_device_type = device_type; + auto audio_start_cb = std::bind(&ctrlm_obj_network_rf4ce_t::start_controller_audio_streaming, this, std::placeholders::_1); + session = ctrlm_get_voice_obj()->voice_session_req(network_id_get(), dqm->controller_id, device_type, voice_format, use_stream_params ? &stream_params : NULL, controller_name.c_str(), sw_version.to_string().c_str(), hw_version.to_string().c_str(), (((double)battery_status.get_voltage_loaded()) * 4.0 / 255), command_status, - &dqm->timestamp, &cb_confirm_voice_obj, &cb_confirm_param); - if(session == VOICE_SESSION_RESPONSE_AVAILABLE_PAR_VOICE) { - if(controllers_[dqm->controller_id]->get_capabilities().has_capability(ctrlm_controller_capabilities_t::capability::PAR)) { - session = VOICE_SESSION_RESPONSE_AVAILABLE_SKIP_CHAN_CHECK_PAR_VOICE; - } else { - session = VOICE_SESSION_RESPONSE_AVAILABLE; - } - } - if(session == VOICE_SESSION_RESPONSE_AVAILABLE) { - session = VOICE_SESSION_RESPONSE_AVAILABLE_SKIP_CHAN_CHECK; - } - - XLOGD_INFO("Voice Session Response Status <%#x>", session); - - // Send the response back to the HAL device - guchar response[5]; - guchar response_len = 2; - - response[0] = MSO_VOICE_CMD_ID_VOICE_SESSION_RESPONSE; - response[1] = session; - if(use_stream_params && session == VOICE_SESSION_RESPONSE_AVAILABLE_SKIP_CHAN_CHECK) { // Add stream params in the response - response[1] |= 0x80; - response[2] = (guchar) stream_begin_; - response[3] = (offset & 0xFF); - response[4] = (offset >> 8); - response_len = 5; - } - - if(session == VOICE_SESSION_RESPONSE_AVAILABLE_SKIP_CHAN_CHECK_PAR_VOICE) { - voice_params_par_t params; - ctrlm_get_voice_obj()->voice_params_par_get(¶ms); + &dqm->timestamp, &cb_confirm_voice_obj, &cb_confirm_param, + false, false, audio_start_cb, &start_audio_params); - XLOGD_INFO("PAR Voice EOS data bytes timeout <%d> method <%d>", params.par_voice_eos_timeout, params.par_voice_eos_method); - response[2] = params.par_voice_eos_method; - response[3] = (params.par_voice_eos_timeout & 0xFF); - response[4] = (params.par_voice_eos_timeout >> 8); - response_len = 5; + if(!start_audio_params.m_started) { + start_audio_params.m_cb_confirm_voice_obj = cb_confirm_voice_obj; + start_audio_params.m_cb_confirm_param = cb_confirm_param; + start_audio_params.m_status = session; + start_controller_audio_streaming(&start_audio_params); } - ctrlm_timestamp_t hal_timestamp = dqm->timestamp; - - // Determine when to send the response (50 ms after receipt) - if(controller_type_get(dqm->controller_id) == RF4CE_CONTROLLER_TYPE_XR19) { - ctrlm_timestamp_add_ms(&dqm->timestamp, response_idle_time_ff_); - } else { - ctrlm_timestamp_add_ms(&dqm->timestamp, CTRLM_RF4CE_CONST_RESPONSE_IDLE_TIME); - } - - - if(cb_confirm_voice_obj != NULL && (session == VOICE_SESSION_RESPONSE_AVAILABLE_SKIP_CHAN_CHECK || - session == VOICE_SESSION_RESPONSE_AVAILABLE_SKIP_CHAN_CHECK_PAR_VOICE)) { // Only confirm response for accepted session so there is only ever one response stored - voice_session_rsp_confirm_ = cb_confirm_voice_obj; - voice_session_rsp_confirm_param_ = cb_confirm_param; - - timestamp_voice_session_request_ = hal_timestamp; - timestamp_voice_first_packet_ = hal_timestamp; - - cb_confirm_rf4ce = ctrlm_network_rf4ce_cfm_voice_session_rsp; - cb_confirm_param = voice_session_rsp_params_.network_id; - - // Store controller id, packet and timestamp for retransmission in case of send error - voice_session_rsp_params_.controller_id = dqm->controller_id; - voice_session_rsp_params_.response_len = response_len; - voice_session_rsp_params_.timestamp_hal = hal_timestamp; - voice_session_rsp_params_.timestamp_begin = dqm->timestamp; - voice_session_rsp_params_.timestamp_end = dqm->timestamp; - voice_session_rsp_params_.retries = 0; - ctrlm_timestamp_add_ms(&voice_session_rsp_params_.timestamp_end, CTRLM_RF4CE_CONST_RESPONSE_WAIT_TIME); - errno_t safec_rc = memcpy_s(&voice_session_rsp_params_.response, sizeof(voice_session_rsp_params_.response),response, response_len); - ERR_CHK(safec_rc); - ctrlm_timestamp_get(&voice_session_rsp_params_.timestamp_rsp_req); - } - - req_data(CTRLM_RF4CE_PROFILE_ID_VOICE, dqm->controller_id, dqm->timestamp, response_len, response, NULL, NULL, false, single_channel_rsp_, cb_confirm_rf4ce, cb_confirm_param); - - XLOGD_INFO("session response delivered"); - if(session != VOICE_SESSION_RESPONSE_AVAILABLE_SKIP_CHAN_CHECK && session != VOICE_SESSION_RESPONSE_AVAILABLE && session != VOICE_SESSION_RESPONSE_AVAILABLE_SKIP_CHAN_CHECK_PAR_VOICE && session != VOICE_SESSION_RESPONSE_AVAILABLE_PAR_VOICE) { voice_session_active_count_--; @@ -3847,26 +3788,10 @@ void ctrlm_obj_network_rf4ce_t::ind_process_voice_session_request(void *data, in property.state = CTRLM_HAL_FREQUENCY_AGILITY_ENABLE; ctrlm_network_property_set(network_id_get(), CTRLM_HAL_NETWORK_PROPERTY_FREQUENCY_AGILITY, (void *)&property, sizeof(property)); } - - if(device_type == CTRLM_VOICE_DEVICE_PTT) { - // Send voice key up event since the session was not accepted - process_event_key(dqm->controller_id, CTRLM_KEY_STATUS_UP, CTRLM_KEY_CODE_PUSH_TO_TALK); - } } if(dqm->status != VOICE_SESSION_RESPONSE_AVAILABLE && dqm->status != VOICE_SESSION_RESPONSE_AVAILABLE_SKIP_CHAN_CHECK) { // Session was aborted XLOGD_INFO("voice session abort"); - - // // Broadcast the event over the iarm bus - // ctrlm_voice_iarm_event_session_abort_t event; - // event.api_revision = CTRLM_VOICE_IARM_BUS_API_REVISION; - // event.network_id = dqm->header.network_id; - // event.network_type = ctrlm_network_type_get(dqm->header.network_id); - // event.controller_id = dqm->controller_id; - // event.session_id = ctrlm_voice_session_id_get_next(); - // event.reason = dqm->reason; - - // ctrlm_voice_iarm_event_session_abort(&event); } } @@ -3901,7 +3826,6 @@ void ctrlm_obj_network_rf4ce_t::cfm_voice_session_rsp(void *data, int size) { } ctrlm_timestamp_t now; ctrlm_timestamp_get(&now); - double loadavg[3] = { -1, -1, -1 }; getloadavg(loadavg, 3); struct sysinfo s_info; @@ -5093,3 +5017,117 @@ void ctrlm_obj_network_rf4ce_t::controller_init_uinput(ctrlm_controller_id_t con return; } } + +void ctrlm_obj_network_rf4ce_t::start_controller_audio_streaming(ctrlm_voice_start_audio_params_t *params) { + THREAD_ID_VALIDATE(); + params->m_started = false; + ctrlm_controller_id_t controller_id = params->m_controller_id; + ctrlm_voice_device_t device_type = params->m_device_type; + + if(!ready_) { + XLOGD_FATAL("Network is not ready!"); + return; + } + + if(!controller_exists(controller_id)) { + XLOGD_WARN("Controller %u doesn't exist.", controller_id); + return; + } + + ctrlm_voice_session_response_status_t session = params->m_status; + + if(session == VOICE_SESSION_RESPONSE_AVAILABLE_PAR_VOICE) { + if(controllers_[controller_id]->get_capabilities().has_capability(ctrlm_controller_capabilities_t::capability::PAR)) { + session = VOICE_SESSION_RESPONSE_AVAILABLE_SKIP_CHAN_CHECK_PAR_VOICE; + } else { + session = VOICE_SESSION_RESPONSE_AVAILABLE; + } + } + if(session == VOICE_SESSION_RESPONSE_AVAILABLE) { + session = VOICE_SESSION_RESPONSE_AVAILABLE_SKIP_CHAN_CHECK; + } + + XLOGD_INFO("Voice Session Response Status <%#x>", session); + + // Send the response back to the HAL device + guchar response[5]; + guchar response_len = 2; + gint16 offset = params->m_offset; + + response[0] = MSO_VOICE_CMD_ID_VOICE_SESSION_RESPONSE; + response[1] = session; + if(params->m_use_stream_params && session == VOICE_SESSION_RESPONSE_AVAILABLE_SKIP_CHAN_CHECK) { // Add stream params in the response + response[1] |= 0x80; + response[2] = (guchar) stream_begin_; + response[3] = (offset & 0xFF); + response[4] = (offset >> 8); + response_len = 5; + } + + if(session == VOICE_SESSION_RESPONSE_AVAILABLE_SKIP_CHAN_CHECK_PAR_VOICE) { + voice_params_par_t voice_params; + ctrlm_get_voice_obj()->voice_params_par_get(&voice_params); + + XLOGD_INFO("PAR Voice EOS data bytes timeout <%d> method <%d>", voice_params.par_voice_eos_timeout, voice_params.par_voice_eos_method); + response[2] = voice_params.par_voice_eos_method; + response[3] = (voice_params.par_voice_eos_timeout & 0xFF); + response[4] = (voice_params.par_voice_eos_timeout >> 8); + response_len = 5; + } + + ctrlm_timestamp_t hal_timestamp = params->m_timestamp; + + // Determine when to send the response (50 ms after receipt) + if(controller_type_get(controller_id) == RF4CE_CONTROLLER_TYPE_XR19) { + ctrlm_timestamp_add_ms(¶ms->m_timestamp, response_idle_time_ff_); + } else { + ctrlm_timestamp_add_ms(¶ms->m_timestamp, CTRLM_RF4CE_CONST_RESPONSE_IDLE_TIME); + } + + ctrlm_hal_rf4ce_cfm_data_t cb_confirm_rf4ce = NULL; + + if(params->m_cb_confirm_voice_obj != NULL && (session == VOICE_SESSION_RESPONSE_AVAILABLE_SKIP_CHAN_CHECK || + session == VOICE_SESSION_RESPONSE_AVAILABLE_SKIP_CHAN_CHECK_PAR_VOICE)) { // Only confirm response for accepted session so there is only ever one response stored + voice_session_rsp_confirm_ = params->m_cb_confirm_voice_obj; + voice_session_rsp_confirm_param_ = params->m_cb_confirm_param; + + timestamp_voice_session_request_ = hal_timestamp; + timestamp_voice_first_packet_ = hal_timestamp; + + cb_confirm_rf4ce = ctrlm_network_rf4ce_cfm_voice_session_rsp; + params->m_cb_confirm_param = voice_session_rsp_params_.network_id; + + // Store controller id, packet and timestamp for retransmission in case of send error + voice_session_rsp_params_.controller_id = controller_id; + voice_session_rsp_params_.response_len = response_len; + voice_session_rsp_params_.timestamp_hal = hal_timestamp; + voice_session_rsp_params_.timestamp_begin = params->m_timestamp; + voice_session_rsp_params_.timestamp_end = params->m_timestamp; + voice_session_rsp_params_.retries = 0; + ctrlm_timestamp_add_ms(&voice_session_rsp_params_.timestamp_end, CTRLM_RF4CE_CONST_RESPONSE_WAIT_TIME); + errno_t safec_rc = memcpy_s(&voice_session_rsp_params_.response, sizeof(voice_session_rsp_params_.response),response, response_len); + ERR_CHK(safec_rc); + ctrlm_timestamp_get(&voice_session_rsp_params_.timestamp_rsp_req); + } + + req_data(CTRLM_RF4CE_PROFILE_ID_VOICE, controller_id, params->m_timestamp, response_len, response, NULL, NULL, false, single_channel_rsp_, cb_confirm_rf4ce, params->m_cb_confirm_param); + + XLOGD_INFO("session response delivered"); + + if(session != VOICE_SESSION_RESPONSE_AVAILABLE_SKIP_CHAN_CHECK && session != VOICE_SESSION_RESPONSE_AVAILABLE && + session != VOICE_SESSION_RESPONSE_AVAILABLE_SKIP_CHAN_CHECK_PAR_VOICE && session != VOICE_SESSION_RESPONSE_AVAILABLE_PAR_VOICE) { + voice_session_active_count_--; + if(voice_session_active_count_ == 0) { // Re-enable frequency agility if the no other active RF4CE voice sessions + ctrlm_hal_network_property_frequency_agility_t property; + property.state = CTRLM_HAL_FREQUENCY_AGILITY_ENABLE; + ctrlm_network_property_set(network_id_get(), CTRLM_HAL_NETWORK_PROPERTY_FREQUENCY_AGILITY, (void *)&property, sizeof(property)); + } + + if(device_type == CTRLM_VOICE_DEVICE_PTT) { + // Send voice key up event since the session was not accepted + process_event_key(controller_id, CTRLM_KEY_STATUS_UP, CTRLM_KEY_CODE_PUSH_TO_TALK); + } + } + + params->m_started = true; +} diff --git a/src/rf4ce/ctrlm_rf4ce_network.h b/src/rf4ce/ctrlm_rf4ce_network.h index 1e4ce251..07298971 100644 --- a/src/rf4ce/ctrlm_rf4ce_network.h +++ b/src/rf4ce/ctrlm_rf4ce_network.h @@ -462,6 +462,8 @@ class ctrlm_obj_network_rf4ce_t : public ctrlm_obj_network_t virtual std::vector get_controller_obj_list() const; void rcu_timeout_key_release(void *data, int data_size); + virtual void start_controller_audio_streaming(ctrlm_voice_start_audio_params_t *params); + protected: virtual gboolean key_event_hook(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_key_status_t key_status, ctrlm_key_code_t key_code); diff --git a/src/voice/ctrlm_voice_obj.cpp b/src/voice/ctrlm_voice_obj.cpp index 93c12ac2..4a26f316 100644 --- a/src/voice/ctrlm_voice_obj.cpp +++ b/src/voice/ctrlm_voice_obj.cpp @@ -1344,7 +1344,7 @@ ctrlm_voice_session_response_status_t ctrlm_voice_t::voice_session_req(ctrlm_net ctrlm_voice_device_t device_type, ctrlm_voice_format_t format, voice_session_req_stream_params *stream_params, const char *controller_name, const char *sw_version, const char *hw_version, double voltage, bool command_status, - ctrlm_timestamp_t *timestamp, ctrlm_voice_session_rsp_confirm_t *cb_confirm, void **cb_confirm_param, bool use_external_data_pipe, bool press_and_hold, const char *l_transcription_in, const char *audio_file_in, const uuid_t *uuid, bool low_latency, bool low_cpu_util, int audio_fd) { + ctrlm_timestamp_t *timestamp, ctrlm_voice_session_rsp_confirm_t *cb_confirm, void **cb_confirm_param, bool use_external_data_pipe, bool press_and_hold, std::function cb_start_audio, ctrlm_voice_start_audio_params_t *cb_audio_start_params, const char *l_transcription_in, const char *audio_file_in, const uuid_t *uuid, bool low_latency, bool low_cpu_util, int audio_fd) { ctrlm_voice_session_t *session = &this->voice_session[voice_device_to_session_group(device_type)]; @@ -1376,6 +1376,7 @@ ctrlm_voice_session_response_status_t ctrlm_voice_t::voice_session_req(ctrlm_net // Cancel current speech router session XLOGD_INFO("Waiting on the results from previous session, aborting this and continuing.."); + pre_session_terminate(cb_start_audio, cb_audio_start_params, cb_confirm, cb_confirm_param); xrsr_session_terminate(voice_device_to_xrsr(session->voice_device)); // Synchronous - this will take a bit of time. Might need to revisit this down the road. } bool request_new_session = true; @@ -1387,6 +1388,7 @@ ctrlm_voice_session_response_status_t ctrlm_voice_t::voice_session_req(ctrlm_net request_new_session = false; } else { // Cancel current speech router session XLOGD_WARN("Session in progress with same controller - src <%s> dst <%s>, aborting this and continuing..", ctrlm_voice_state_src_str(session->state_src), ctrlm_voice_state_dst_str(session->state_dst)); + pre_session_terminate(cb_start_audio, cb_audio_start_params, cb_confirm, cb_confirm_param); xrsr_session_terminate(voice_device_to_xrsr(session->voice_device)); // Synchronous - this will take a bit of time. Might need to revisit this down the road. } } else { // session in progress with different controller @@ -4244,3 +4246,14 @@ void ctrlm_voice_t::url_hostname_patterns(const std::vector &obj_se this->url_hostname_pattern_add(itr.c_str()); } } + +void ctrlm_voice_t::pre_session_terminate(std::function cb_start_audio, ctrlm_voice_start_audio_params_t *cb_audio_start_params, ctrlm_voice_session_rsp_confirm_t *cb_confirm, void **cb_confirm_param) { + if (cb_start_audio != nullptr && cb_audio_start_params != nullptr) { + if(cb_confirm != NULL && cb_confirm_param != NULL) { + cb_audio_start_params->m_cb_confirm_voice_obj = ctrlm_voice_session_response_confirm; + cb_audio_start_params->m_cb_confirm_param = NULL; + cb_audio_start_params->m_status = (this->prefs.par_voice_enabled) ? VOICE_SESSION_RESPONSE_AVAILABLE_PAR_VOICE : VOICE_SESSION_RESPONSE_AVAILABLE; + } + cb_start_audio(cb_audio_start_params); + } +} diff --git a/src/voice/ctrlm_voice_obj.h b/src/voice/ctrlm_voice_obj.h index bd8de16c..3976a62c 100644 --- a/src/voice/ctrlm_voice_obj.h +++ b/src/voice/ctrlm_voice_obj.h @@ -389,6 +389,29 @@ typedef struct { typedef void (*ctrlm_voice_session_rsp_confirm_t)(bool result, signed long long rsp_time, unsigned int rsp_window, const std::string &err_str, ctrlm_timestamp_t *timestamp, void *user_data); +class ctrlm_voice_start_audio_params_t +{ +public: + // Generic + ctrlm_voice_start_audio_params_t() = default; + virtual ~ctrlm_voice_start_audio_params_t() = default; + + ctrlm_controller_id_t m_controller_id = -1; + bool m_started = false; + + // BLE + int m_fd = -1; + + // RF4CE + bool m_use_stream_params = false; + int16_t m_offset = 0; + ctrlm_timestamp_t m_timestamp; + ctrlm_voice_session_rsp_confirm_t m_cb_confirm_voice_obj; + void * m_cb_confirm_param; + ctrlm_voice_session_response_status_t m_status; + ctrlm_voice_device_t m_device_type; +}; + typedef struct { ctrlm_network_id_t network_id; ctrlm_network_type_t network_type; @@ -471,7 +494,7 @@ class ctrlm_voice_t { ctrlm_voice_t(); virtual ~ctrlm_voice_t(); - ctrlm_voice_session_response_status_t voice_session_req(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_voice_device_t device_type, ctrlm_voice_format_t format, voice_session_req_stream_params *stream_params, const char *controller_name, const char *sw_version, const char *hw_version, double voltage, bool command_status=false, ctrlm_timestamp_t *timestamp=NULL, ctrlm_voice_session_rsp_confirm_t *cb_confirm=NULL, void **cb_confirm_param=NULL, bool use_external_data_pipe=false, bool press_and_hold=true, const char *transcription_in=NULL, const char *audio_file_in=NULL, const uuid_t *uuid = NULL, bool low_latency=false, bool low_cpu_util=false, int audio_fd = -1); + ctrlm_voice_session_response_status_t voice_session_req(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_voice_device_t device_type, ctrlm_voice_format_t format, voice_session_req_stream_params *stream_params, const char *controller_name, const char *sw_version, const char *hw_version, double voltage, bool command_status=false, ctrlm_timestamp_t *timestamp=NULL, ctrlm_voice_session_rsp_confirm_t *cb_confirm=NULL, void **cb_confirm_param=NULL, bool use_external_data_pipe=false, bool press_and_hold=true, std::function cb_start_audio=NULL, ctrlm_voice_start_audio_params_t *cb_audio_start_params=NULL, const char *transcription_in=NULL, const char *audio_file_in=NULL, const uuid_t *uuid = NULL, bool low_latency=false, bool low_cpu_util=false, int audio_fd = -1); void voice_session_rsp_confirm(bool result, signed long long rsp_time, unsigned int rsp_window, const std::string &err_str, ctrlm_timestamp_t *timestamp); bool voice_session_data(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, const char *buffer, long unsigned int length, ctrlm_timestamp_t *timestamp=NULL, uint8_t *lqi=NULL); bool voice_session_data(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, int fd, const uuid_t *uuid=NULL); @@ -723,6 +746,10 @@ class ctrlm_voice_t { void audio_state_set(bool session); bool vsdk_is_privacy_enabled(void); double vsdk_keyword_sensitivity_limit_check(double sensitivity); + void pre_session_terminate(std::function cb_start_audio, + ctrlm_voice_start_audio_params_t *cb_audio_start_params, + ctrlm_voice_session_rsp_confirm_t *cb_confirm, + void **cb_confirm_param); }; // Helper Functions diff --git a/src/voice/ipc/ctrlm_voice_ipc_iarm_thunder.cpp b/src/voice/ipc/ctrlm_voice_ipc_iarm_thunder.cpp index 022b71f4..f88d6fb9 100644 --- a/src/voice/ipc/ctrlm_voice_ipc_iarm_thunder.cpp +++ b/src/voice/ipc/ctrlm_voice_ipc_iarm_thunder.cpp @@ -793,7 +793,8 @@ IARM_Result_t ctrlm_voice_ipc_iarm_thunder_t::voice_session_request(void *data) ctrlm_voice_session_response_status_t voice_status = voice_obj->voice_session_req( CTRLM_MAIN_NETWORK_ID_INVALID, CTRLM_MAIN_CONTROLLER_ID_INVALID, request_config.device, request_config.format, NULL, str_name_of_source.c_str(), "0.0.0.0", "0.0.0.0", 0.0, - false, NULL, NULL, NULL, (fd >= 0) ? true : false, true, str_transcription.empty() ? NULL : str_transcription.c_str(), str_audio_file.empty() ? NULL : str_audio_file.c_str(), &request_uuid, request_config.low_latency, request_config.low_cpu_util, fd); + false, NULL, NULL, NULL, (fd >= 0) ? true : false, true, NULL, NULL, + str_transcription.empty() ? NULL : str_transcription.c_str(), str_audio_file.empty() ? NULL : str_audio_file.c_str(), &request_uuid, request_config.low_latency, request_config.low_cpu_util, fd); if (voice_status != VOICE_SESSION_RESPONSE_AVAILABLE && voice_status != VOICE_SESSION_RESPONSE_AVAILABLE_PAR_VOICE) { XLOGD_ERROR("Failed opening voice session <%s>", ctrlm_voice_session_response_status_str(voice_status)); From baebbf2e09e5f01bebb36a974618fc208a3a7540 Mon Sep 17 00:00:00 2001 From: Kelvin Lu <119349872+klu339@users.noreply.github.com> Date: Tue, 2 Dec 2025 12:09:49 -0500 Subject: [PATCH 14/39] RDKEMW-10425: Automation Logging (#144) --- src/ble/ctrlm_ble_controller.cpp | 6 ++--- src/ble/ctrlm_ble_network.cpp | 22 +++++++++---------- .../hal/blercu/blercupairingstatemachine.cpp | 12 +++++----- src/ble/hal/blercu/bluez/blercuadapter.cpp | 4 ++-- src/ble/hal/blercu/bluez/blercudevice.cpp | 2 +- src/ctrlm_controller.cpp | 10 ++++----- src/ctrlm_ir_controller.cpp | 2 +- src/ctrlm_main.cpp | 8 +++---- src/ctrlm_main_iarm.cpp | 2 +- src/ipc/ctrlm_ipc_iarm_powermanager.cpp | 2 +- src/voice/ctrlm_voice_obj.cpp | 14 ++++++------ .../endpoints/ctrlm_voice_endpoint_http.cpp | 2 +- .../endpoints/ctrlm_voice_endpoint_sdt.cpp | 2 +- .../ctrlm_voice_endpoint_ws_nextgen.cpp | 4 ++-- .../endpoints/ctrlm_voice_endpoint_ws_nsp.cpp | 2 +- .../ipc/ctrlm_voice_ipc_iarm_thunder.cpp | 4 ++-- 16 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/ble/ctrlm_ble_controller.cpp b/src/ble/ctrlm_ble_controller.cpp index d8886150..d86650db 100644 --- a/src/ble/ctrlm_ble_controller.cpp +++ b/src/ble/ctrlm_ble_controller.cpp @@ -615,13 +615,13 @@ void ctrlm_obj_controller_ble_t::print_status() { XLOGD_INFO("Model : %s", model_->to_string().c_str()); XLOGD_INFO("MAC Address : %s", ieee_address_->to_string().c_str()); XLOGD_INFO("Device Minor ID : %d", device_minor_id_); - XLOGD_INFO("Battery Level : %u%%", get_battery_percent()); + XLOGD_AUTOMATION_INFO("Battery Level : %u%%", get_battery_percent()); XLOGD_INFO("HW Revision : %s", hw_revision_->to_string().c_str()); XLOGD_INFO("FW Revision : %s", fw_revision_->to_string().c_str()); - XLOGD_INFO("SW Revision : %s", sw_revision_->to_string().c_str()); + XLOGD_AUTOMATION_INFO("SW Revision : %s", sw_revision_->to_string().c_str()); XLOGD_INFO("Serial Number : %s", serial_number_->to_string().c_str()); XLOGD_INFO(""); - XLOGD_INFO("Connected : %s", (connected_==true) ? "true" : "false"); + XLOGD_AUTOMATION_INFO("Connected : %s", (connected_==true) ? "true" : "false"); XLOGD_INFO("Last Activity Time : %s", ctrlm_utils_time_as_string(this->last_activity_time_get()).c_str()); XLOGD_INFO("Bound Time : %s", ctrlm_utils_time_as_string(this->time_binding_get()).c_str()); XLOGD_INFO(""); diff --git a/src/ble/ctrlm_ble_network.cpp b/src/ble/ctrlm_ble_network.cpp index 1e141823..8965b71a 100644 --- a/src/ble/ctrlm_ble_network.cpp +++ b/src/ble/ctrlm_ble_network.cpp @@ -576,7 +576,7 @@ void ctrlm_obj_network_ble_t::req_process_voice_session_begin(void *data, int si XLOGD_ERROR("Voice streaming pipe invalid (fd = <%d>), aborting voice session", fd); success = false; } else { - XLOGD_INFO("Acquired voice streaming pipe fd = <%d>, sending to voice engine", fd); + XLOGD_AUTOMATION_INFO("Acquired voice streaming pipe fd = <%d>, sending to voice engine", fd); //Send the fd acquired from bluez to the voice engine success = ctrlm_get_voice_obj()->voice_session_data(network_id_get(), controller_id, fd); } @@ -1825,7 +1825,7 @@ void ctrlm_obj_network_ble_t::ind_process_rcu_status(void *data, int size) { print_status = false; break; case CTRLM_HAL_BLE_PROPERTY_IS_UPGRADING: - XLOGD_INFO("Controller <%s> firmware upgrading = %s", controller->ieee_address_get().to_string().c_str(), dqm->rcu_data.is_upgrading ? "TRUE" : "FALSE"); + XLOGD_AUTOMATION_INFO("Controller <%s> firmware upgrading = %s", controller->ieee_address_get().to_string().c_str(), dqm->rcu_data.is_upgrading ? "TRUE" : "FALSE"); upgrade_in_progress_ = dqm->rcu_data.is_upgrading; if (!dqm->rcu_data.is_upgrading) { // If we get FALSE here, make sure the controller upgrade progress flag is cleared. But we don't want to set the controller progress @@ -1836,7 +1836,7 @@ void ctrlm_obj_network_ble_t::ind_process_rcu_status(void *data, int size) { print_status = false; break; case CTRLM_HAL_BLE_PROPERTY_UPGRADE_PROGRESS: - XLOGD_INFO("Controller <%s> firmware upgrade %d%% complete...", controller->ieee_address_get().to_string().c_str(), dqm->rcu_data.upgrade_progress); + XLOGD_AUTOMATION_INFO("Controller <%s> firmware upgrade %d%% complete...", controller->ieee_address_get().to_string().c_str(), dqm->rcu_data.upgrade_progress); // From a controller perspective, we cannot use the CTRLM_HAL_BLE_PROPERTY_IS_UPGRADING flag above to determine if its actively upgrading. // Instead, its more accurate to use the progress percentage to determine if the remote is actively receiving firmware packets. controller->setUpgradeInProgress(dqm->rcu_data.upgrade_progress > 0 && dqm->rcu_data.upgrade_progress < 100); @@ -1849,7 +1849,7 @@ void ctrlm_obj_network_ble_t::ind_process_rcu_status(void *data, int size) { print_status = false; break; case CTRLM_HAL_BLE_PROPERTY_UPGRADE_ERROR: - XLOGD_ERROR("Controller <%s> firmware upgrade FAILED with error <%s>.", controller->ieee_address_get().to_string().c_str(), dqm->rcu_data.upgrade_error); + XLOGD_AUTOMATION_ERROR("Controller <%s> firmware upgrade FAILED with error <%s>.", controller->ieee_address_get().to_string().c_str(), dqm->rcu_data.upgrade_error); report_status = false; print_status = false; controller->set_upgrade_error(dqm->rcu_data.upgrade_error); @@ -1882,7 +1882,7 @@ void ctrlm_obj_network_ble_t::ind_process_rcu_status(void *data, int size) { controller->ota_failure_cnt_incr(); break; case CTRLM_HAL_BLE_PROPERTY_UNPAIR_REASON: - XLOGD_INFO("Controller <%s> notified reason for unpairing = <%s>", controller->ieee_address_get().to_string().c_str(), ctrlm_ble_unpair_reason_str(dqm->rcu_data.unpair_reason)); + XLOGD_AUTOMATION_INFO("Controller <%s> notified reason for unpairing = <%s>", controller->ieee_address_get().to_string().c_str(), ctrlm_ble_unpair_reason_str(dqm->rcu_data.unpair_reason)); last_rcu_unpair_metrics_.write_rcu_unpair_event(controller->ieee_address_get().get_value(), string(ctrlm_ble_unpair_reason_str(dqm->rcu_data.unpair_reason))); report_status = false; print_status = false; @@ -1897,7 +1897,7 @@ void ctrlm_obj_network_ble_t::ind_process_rcu_status(void *data, int size) { } break; case CTRLM_HAL_BLE_PROPERTY_REBOOT_REASON: - XLOGD_TELEMETRY("Controller <%s> notified reason for rebooting = <%s%s%s%s>", + XLOGD_AUTOMATION_TELEMETRY("Controller <%s> notified reason for rebooting = <%s%s%s%s>", controller->ieee_address_get().to_string().c_str(), ctrlm_ble_reboot_reason_str(dqm->rcu_data.reboot_reason), dqm->rcu_data.reboot_reason == CTRLM_BLE_RCU_REBOOT_REASON_ASSERT ? " - \"" : "", @@ -2205,7 +2205,7 @@ void ctrlm_obj_network_ble_t::ind_process_keypress(void *data, int size) { controller->setVoiceStartTime(keyDownTime); XLOGD_INFO("------------------------------------------------------------------------"); - XLOGD_INFO("CODE_VOICE_KEY button PRESSED event for device: %s", controller->ieee_address_get().to_string().c_str()); + XLOGD_AUTOMATION_INFO("CODE_VOICE_KEY button PRESSED event for device: %s", controller->ieee_address_get().to_string().c_str()); XLOGD_INFO("------------------------------------------------------------------------"); ctrlm_voice_iarm_call_voice_session_t v_params; @@ -2255,7 +2255,7 @@ void ctrlm_obj_network_ble_t::ind_process_keypress(void *data, int size) { if (controller->isVoiceKey(dqm->event.code)) { if(!controller->getPressAndHoldSupport()) { // if the voice session is "Press and Release" then don't end session on voice key up event XLOGD_INFO("------------------------------------------------------------------------"); - XLOGD_INFO("CODE_VOICE_KEY button RELEASED event for device: %s (ignored for PAR session)", controller->ieee_address_get().to_string().c_str()); + XLOGD_AUTOMATION_INFO("CODE_VOICE_KEY button RELEASED event for device: %s (ignored for PAR session)", controller->ieee_address_get().to_string().c_str()); XLOGD_INFO("------------------------------------------------------------------------"); } else { rdkx_timestamp_t keyUpTime, keyUpTimeLocal, voiceStartTimeLocal, firstAudioDataTime; @@ -2290,11 +2290,11 @@ void ctrlm_obj_network_ble_t::ind_process_keypress(void *data, int size) { } XLOGD_INFO("------------------------------------------------------------------------"); - XLOGD_INFO("CODE_VOICE_KEY button RELEASED event for device: %s duration <%lld ms> start lag <%lld ms>", controller->ieee_address_get().to_string().c_str(), audioDurationKeys, startAudioLag); + XLOGD_AUTOMATION_INFO("CODE_VOICE_KEY button RELEASED event for device: %s duration <%lld ms> start lag <%lld ms>", controller->ieee_address_get().to_string().c_str(), audioDurationKeys, startAudioLag); XLOGD_INFO("------------------------------------------------------------------------"); } else { XLOGD_INFO("------------------------------------------------------------------------"); - XLOGD_INFO("CODE_VOICE_KEY button RELEASED event for device: %s duration <%lld ms>", controller->ieee_address_get().to_string().c_str(), audioDurationKeys); + XLOGD_AUTOMATION_INFO("CODE_VOICE_KEY button RELEASED event for device: %s duration <%lld ms>", controller->ieee_address_get().to_string().c_str(), audioDurationKeys); XLOGD_INFO("------------------------------------------------------------------------"); } @@ -2497,7 +2497,7 @@ void ctrlm_obj_network_ble_t::printStatus() { it->second->print_status(); } XLOGD_INFO("BLE Network Status: <%s>", ctrlm_rf_pair_state_str(state_)); - XLOGD_TELEMETRY("IR Programming Status: <%s>", ctrlm_ir_state_str(ir_state_)); + XLOGD_AUTOMATION_TELEMETRY("IR Programming Status: <%s>", ctrlm_ir_state_str(ir_state_)); XLOGD_WARN("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); } diff --git a/src/ble/hal/blercu/blercupairingstatemachine.cpp b/src/ble/hal/blercu/blercupairingstatemachine.cpp index 0a5572c5..b55613ed 100644 --- a/src/ble/hal/blercu/blercupairingstatemachine.cpp +++ b/src/ble/hal/blercu/blercupairingstatemachine.cpp @@ -517,19 +517,19 @@ void BleRcuPairingStateMachine::onStateTransition(int oldState, int newState) { if (newState == FinishedState) { if (oldState == UnpairingState) { - XLOGD_WARN("timed-out in un-pairing phase (failed rcu may be left paired)"); + XLOGD_AUTOMATION_WARN("timed-out in un-pairing phase (failed rcu may be left paired)"); } else if (oldState == StartingDiscoveryState) { - XLOGD_ERROR("timed-out waiting for discovery started signal"); + XLOGD_AUTOMATION_ERROR("timed-out waiting for discovery started signal"); } else if (oldState == DiscoveringState) { - XLOGD_ERROR("timed-out in discovery phase (didn't find target rcu device to pair to)"); + XLOGD_AUTOMATION_ERROR("timed-out in discovery phase (didn't find target rcu device to pair to)"); } else if (oldState == StoppingDiscoveryState) { - XLOGD_ERROR("timed-out waiting for discovery to stop (suggesting something has gone wrong inside bluez)"); + XLOGD_AUTOMATION_ERROR("timed-out waiting for discovery to stop (suggesting something has gone wrong inside bluez)"); } } else if (newState == UnpairingState) { if (oldState == EnablePairableState || oldState == PairingState) { - XLOGD_WARN("timed-out in pairing phase (rcu device didn't pair within %dms)", m_pairingTimeout); + XLOGD_AUTOMATION_WARN("timed-out in pairing phase (rcu device didn't pair within %dms)", m_pairingTimeout); } else if (oldState == SetupState) { - XLOGD_WARN("timed-out in setup phase (rcu didn't response to all requests within %dms)", m_setupTimeout); + XLOGD_AUTOMATION_WARN("timed-out in setup phase (rcu didn't response to all requests within %dms)", m_setupTimeout); } } } diff --git a/src/ble/hal/blercu/bluez/blercuadapter.cpp b/src/ble/hal/blercu/bluez/blercuadapter.cpp index f8e0bcbd..c7d5834e 100644 --- a/src/ble/hal/blercu/bluez/blercuadapter.cpp +++ b/src/ble/hal/blercu/bluez/blercuadapter.cpp @@ -1721,7 +1721,7 @@ void BleRcuAdapterBluez::onDevicePairedChanged(const BleAddress &address, void BleRcuAdapterBluez::onDeviceReadyChanged(const BleAddress &address, bool ready) { - XLOGD_INFO("device with address %s is %sREADY", address.toString().c_str(), ready ? "" : "NOT "); + XLOGD_AUTOMATION_INFO("device with address %s is %sREADY", address.toString().c_str(), ready ? "" : "NOT "); map>::const_iterator it = m_devices.find(address); @@ -1768,7 +1768,7 @@ bool BleRcuAdapterBluez::setConnectionParams(BleAddress address, double minInter if (address == deviceInfo.address) { - XLOGD_INFO("HCI connection handle: %u, device: %s requesting an update of connection parameters to " + XLOGD_AUTOMATION_INFO("HCI connection handle: %u, device: %s requesting an update of connection parameters to " "minInterval=%f, maxInterval=%f, latency=%d, supervisionTimeout=%d", deviceInfo.handle, deviceInfo.address.toString().c_str(), minInterval, maxInterval, latency, supervisionTimeout); diff --git a/src/ble/hal/blercu/bluez/blercudevice.cpp b/src/ble/hal/blercu/bluez/blercudevice.cpp index 8212a3a1..08aa0287 100644 --- a/src/ble/hal/blercu/bluez/blercudevice.cpp +++ b/src/ble/hal/blercu/bluez/blercudevice.cpp @@ -668,7 +668,7 @@ void BleRcuDeviceBluez::onEnteredRecoveryDisconnectingState() m_recoveryAttempts++; // log the attempt - XLOGD_ERROR("entered recovery state after device %s failed to resolve services (attempt #%d)", + XLOGD_AUTOMATION_ERROR("entered recovery state after device %s failed to resolve services (attempt #%d)", m_address.toString().c_str(), m_recoveryAttempts); diff --git a/src/ctrlm_controller.cpp b/src/ctrlm_controller.cpp index 0088b414..aaae3b40 100644 --- a/src/ctrlm_controller.cpp +++ b/src/ctrlm_controller.cpp @@ -172,11 +172,11 @@ void ctrlm_obj_controller_t::process_event_key(ctrlm_key_status_t key_status, ui last_key_code_->set_value((uint64_t)key_code); last_key_time_update(); - XLOGD_TELEMETRY("ind_process_keypress: %s - MAC Address <%s>, code = <%d> (%s key), status = <%s>", controller_type_str_get().c_str(), - ieee_address_get().to_string().c_str(), - mask ? -1 : key_code, - ctrlm_linux_key_code_str(key_code, mask), - ctrlm_key_status_str(key_status)); + XLOGD_AUTOMATION_TELEMETRY("ind_process_keypress: %s - MAC Address <%s>, code = <%d> (%s key), status = <%s>", controller_type_str_get().c_str(), + ieee_address_get().to_string().c_str(), + mask ? -1 : key_code, + ctrlm_linux_key_code_str(key_code, mask), + ctrlm_key_status_str(key_status)); } ctrlm_controller_capabilities_t ctrlm_obj_controller_t::get_capabilities() const { diff --git a/src/ctrlm_ir_controller.cpp b/src/ctrlm_ir_controller.cpp index db978c7c..17db165b 100644 --- a/src/ctrlm_ir_controller.cpp +++ b/src/ctrlm_ir_controller.cpp @@ -489,7 +489,7 @@ void* ctrlm_ir_key_monitor_thread(void *data) { case 2: { key_status = CTRLM_KEY_STATUS_REPEAT; break; } default: break; } - XLOGD_TELEMETRY("%s - code = <%d> (%s key), status = <%s>", ir_controller->name_get().c_str(), + XLOGD_AUTOMATION_TELEMETRY("%s - code = <%d> (%s key), status = <%s>", ir_controller->name_get().c_str(), ir_controller->mask_key_codes_get() ? -1 : event.code, ctrlm_linux_key_code_str(event.code, ir_controller->mask_key_codes_get()), ctrlm_key_status_str(key_status)); diff --git a/src/ctrlm_main.cpp b/src/ctrlm_main.cpp index 272d254e..1bffc6df 100644 --- a/src/ctrlm_main.cpp +++ b/src/ctrlm_main.cpp @@ -806,7 +806,7 @@ int main(int argc, char *argv[]) { ctrlm_trigger_startup_actions(); - XLOGD_INFO("Enter main loop"); + XLOGD_AUTOMATION_INFO("Enter main loop"); g_main_loop_run(g_ctrlm.main_loop); //Save the shutdown time if it is valid @@ -988,7 +988,7 @@ gboolean ctrlm_thread_monitor(gpointer user_data) { XLOGD_DEBUG("Checking %s", it->name); if(it->response != CTRLM_THREAD_MONITOR_RESPONSE_ALIVE) { - XLOGD_TELEMETRY("Thread %s is unresponsive", it->name); + XLOGD_AUTOMATION_TELEMETRY("Thread %s is unresponsive", it->name); #ifdef BREAKPAD_SUPPORT if(g_ctrlm.thread_monitor_minidump) { XLOGD_FATAL("Thread Monitor Minidump is enabled"); @@ -2329,7 +2329,7 @@ gpointer ctrlm_main_thread(gpointer param) { // Unblock the caller that launched this thread sem_post(&g_ctrlm.semaphore); - XLOGD_INFO("Enter main loop"); + XLOGD_AUTOMATION_INFO("Enter main loop"); do { gpointer msg = g_async_queue_pop(g_ctrlm.queue); @@ -2675,7 +2675,7 @@ gpointer ctrlm_main_thread(gpointer param) { //If execution reaches here, then change power state and inform VSDK of on or deep sleep states g_ctrlm.power_state = dqm->new_state; - XLOGD_INFO("Enter power state <%s>", ctrlm_power_state_str(g_ctrlm.power_state)); + XLOGD_AUTOMATION_INFO("Enter power state <%s>", ctrlm_power_state_str(g_ctrlm.power_state)); if(g_ctrlm.networked_standby_supported && (g_ctrlm.power_state == CTRLM_POWER_STATE_DEEP_SLEEP)) { XLOGD_INFO("NSM is <%s>", (ctrlm_main_get_networked_standby_mode())?"ENABLED":"DISABLED"); } diff --git a/src/ctrlm_main_iarm.cpp b/src/ctrlm_main_iarm.cpp index 8012b334..db124af4 100644 --- a/src/ctrlm_main_iarm.cpp +++ b/src/ctrlm_main_iarm.cpp @@ -753,7 +753,7 @@ IARM_Result_t ctrlm_main_iarm_call_start_pair_with_code(void *arg) { return(IARM_RESULT_INVALID_PARAM); } - XLOGD_INFO("params->network_id = <%d>, params->pair_code = 0x%X", params->network_id, params->pair_code); + XLOGD_AUTOMATION_INFO("params->network_id = <%d>, params->pair_code = 0x%X", params->network_id, params->pair_code); // Signal completion of the operation sem_t semaphore; diff --git a/src/ipc/ctrlm_ipc_iarm_powermanager.cpp b/src/ipc/ctrlm_ipc_iarm_powermanager.cpp index 0bef46ce..24897391 100755 --- a/src/ipc/ctrlm_ipc_iarm_powermanager.cpp +++ b/src/ipc/ctrlm_ipc_iarm_powermanager.cpp @@ -80,7 +80,7 @@ bool ctrlm_ipc_iarm_powermanager_t::get_wakeup_reason_voice() { return false; } - XLOGD_INFO("wakeup_reason <%s>", ctrlm_wakeup_reason_str(wakeup_reason)); + XLOGD_AUTOMATION_INFO("wakeup_reason <%s>", ctrlm_wakeup_reason_str(wakeup_reason)); wakeup_reason_voice = (wakeup_reason == DEEPSLEEP_WAKEUPREASON_VOICE) ? true: false; diff --git a/src/voice/ctrlm_voice_obj.cpp b/src/voice/ctrlm_voice_obj.cpp index 4a26f316..d114aeea 100644 --- a/src/voice/ctrlm_voice_obj.cpp +++ b/src/voice/ctrlm_voice_obj.cpp @@ -1772,16 +1772,16 @@ void ctrlm_voice_t::voice_session_data_post_processing(int bytes_sent, const cha float rx_rate = (elapsed == 0) ? 0 : (session->audio_sent_samples * 2 * 8) / elapsed; session->timeout_packet_tag = g_timeout_add(timeout, ctrlm_voice_packet_timeout, NULL); - XLOGD_DEBUG("Audio %s bytes <%lu> samples <%lu> rate <%6.2f kbps> timeout <%lu ms>", action, session->audio_sent_bytes, session->audio_sent_samples, rx_rate, timeout); + XLOGD_AUTOMATION_DEBUG("Audio %s bytes <%lu> samples <%lu> rate <%6.2f kbps> timeout <%lu ms>", action, session->audio_sent_bytes, session->audio_sent_samples, rx_rate, timeout); } else { #ifdef VOICE_BUFFER_STATS if(voice_buffer_warning_triggered) { - XLOGD_DEBUG("Audio %s bytes <%lu> samples <%lu> pkt cnt <%3u> elapsed <%8llu ms> lag <%8lld ms> (%4.2f packets)", action, session->audio_sent_bytes, session->audio_sent_samples, packets_total, session_time / 1000, session_delta / 1000, (((float)session_delta) / this->voice_packet_interval)); + XLOGD_AUTOMATION_DEBUG("Audio %s bytes <%lu> samples <%lu> pkt cnt <%3u> elapsed <%8llu ms> lag <%8lld ms> (%4.2f packets)", action, session->audio_sent_bytes, session->audio_sent_samples, packets_total, session_time / 1000, session_delta / 1000, (((float)session_delta) / this->voice_packet_interval)); } else { - XLOGD_DEBUG("Audio %s bytes <%lu> samples <%lu>", action, session->audio_sent_bytes, session->audio_sent_samples); + XLOGD_AUTOMATION_DEBUG("Audio %s bytes <%lu> samples <%lu>", action, session->audio_sent_bytes, session->audio_sent_samples); } #else - XLOGD_DEBUG("Audio %s bytes <%lu> samples <%lu>", action, session->audio_sent_bytes, session->audio_sent_samples); + XLOGD_AUTOMATION_DEBUG("Audio %s bytes <%lu> samples <%lu>", action, session->audio_sent_bytes, session->audio_sent_samples); #endif } } @@ -2061,10 +2061,10 @@ void ctrlm_voice_t::voice_session_timeout() { signed long long elapsed = rdkx_timestamp_subtract_ms(session->session_timing.ctrl_audio_rxd_first, timestamp); float rx_rate = (elapsed == 0) ? 0 : (session->audio_sent_samples * 2 * 8) / elapsed; - XLOGD_INFO("elapsed time <%llu> ms rx samples <%u> rate <%6.1f> kbps", elapsed, session->audio_sent_samples, rx_rate); + XLOGD_AUTOMATION_INFO("elapsed time <%llu> ms rx samples <%u> rate <%6.1f> kbps", elapsed, session->audio_sent_samples, rx_rate); reason = CTRLM_VOICE_SESSION_END_REASON_MINIMUM_QOS; } - XLOGD_INFO("%s", ctrlm_voice_session_end_reason_str(reason)); + XLOGD_AUTOMATION_INFO("%s", ctrlm_voice_session_end_reason_str(reason)); this->voice_session_end(session, reason); } @@ -2981,7 +2981,7 @@ void ctrlm_voice_t::voice_stream_end_callback(ctrlm_voice_stream_end_cb_t *strea stream_duration = (session->packets_processed * frame_duration_us) / 1000; samples_per_packet = (session->format.value.adpcm_frame.size_packet - session->format.value.adpcm_frame.size_header) * 2; // 2 samples per byte for ADPCM } - XLOGD_TELEMETRY("src <%s> Packets Lost/Total <%u/%u> %.02f%% duration <%u> ms", ctrlm_voice_device_str(session->voice_device), session->packets_lost, session->packets_lost + session->packets_processed, 100.0 * ((double)session->packets_lost / (double)(session->packets_lost + session->packets_processed)), stream_duration); + XLOGD_AUTOMATION_TELEMETRY("src <%s> Packets Lost/Total <%u/%u> %.02f%% duration <%u> ms", ctrlm_voice_device_str(session->voice_device), session->packets_lost, session->packets_lost + session->packets_processed, 100.0 * ((double)session->packets_lost / (double)(session->packets_lost + session->packets_processed)), stream_duration); #ifdef TELEMETRY_SUPPORT if(this->prefs.telemetry_session_stats) { uint32_t packets_total = session->packets_lost + session->packets_processed; diff --git a/src/voice/endpoints/ctrlm_voice_endpoint_http.cpp b/src/voice/endpoints/ctrlm_voice_endpoint_http.cpp index 653e2260..93396a4b 100644 --- a/src/voice/endpoints/ctrlm_voice_endpoint_http.cpp +++ b/src/voice/endpoints/ctrlm_voice_endpoint_http.cpp @@ -194,7 +194,7 @@ void ctrlm_voice_endpoint_http_t::voice_session_begin_callback_http(void *data, has_sat = true; } - XLOGD_TELEMETRY("session begin - src <%s> h_SAT <%s> h_MTLS <%s> h_OCSPst <%s> h_OCSPca <%s>", ctrlm_voice_device_str(source), has_sat ? "YES" : "NO", use_mtls ? "YES" : "NO", ocsp_verify_stapling ? "YES" : "NO", ocsp_verify_ca ? "YES" : "NO"); + XLOGD_AUTOMATION_TELEMETRY("session begin - src <%s> h_SAT <%s> h_MTLS <%s> h_OCSPst <%s> h_OCSPca <%s>", ctrlm_voice_device_str(source), has_sat ? "YES" : "NO", use_mtls ? "YES" : "NO", ocsp_verify_stapling ? "YES" : "NO", ocsp_verify_ca ? "YES" : "NO"); errno_t safec_rc = strcpy_s(this->user_agent, sizeof(this->user_agent), user_agent.str().c_str()); ERR_CHK(safec_rc); diff --git a/src/voice/endpoints/ctrlm_voice_endpoint_sdt.cpp b/src/voice/endpoints/ctrlm_voice_endpoint_sdt.cpp index ca4fe980..2324878c 100644 --- a/src/voice/endpoints/ctrlm_voice_endpoint_sdt.cpp +++ b/src/voice/endpoints/ctrlm_voice_endpoint_sdt.cpp @@ -250,7 +250,7 @@ void ctrlm_voice_endpoint_sdt_t::voice_session_begin_callback_sdt(void *data, in keyword_verification = true; } } - XLOGD_INFO("session begin - ptt <%s> keyword begin <%u> end <%u> doa <%u> gain <%4.1f> db", (stream_params->push_to_talk ? "TRUE" : "FALSE"), stream_params->keyword_sample_begin, stream_params->keyword_sample_end, stream_params->keyword_doa, stream_params->dynamic_gain); + XLOGD_AUTOMATION_INFO("session begin - ptt <%s> keyword begin <%u> end <%u> doa <%u> gain <%4.1f> db", (stream_params->push_to_talk ? "TRUE" : "FALSE"), stream_params->keyword_sample_begin, stream_params->keyword_sample_end, stream_params->keyword_doa, stream_params->dynamic_gain); } // End handle stream parameters diff --git a/src/voice/endpoints/ctrlm_voice_endpoint_ws_nextgen.cpp b/src/voice/endpoints/ctrlm_voice_endpoint_ws_nextgen.cpp index 248832cc..fcf9b12a 100644 --- a/src/voice/endpoints/ctrlm_voice_endpoint_ws_nextgen.cpp +++ b/src/voice/endpoints/ctrlm_voice_endpoint_ws_nextgen.cpp @@ -365,7 +365,7 @@ void ctrlm_voice_endpoint_ws_nextgen_t::voice_session_begin_callback_ws_nextgen( } config_in.ws.app_config = stream_params_out; - XLOGD_TELEMETRY("session begin - src <%s> ptt <%s> w_SAT <%s> w_MTLS <%s> w_OCSPst <%s> w_OCSPca <%s> keyword begin <%u> end <%u> doa <%u> gain <%4.1f> db", ctrlm_voice_device_str(source), (stream_params->push_to_talk ? "TRUE" : "FALSE"), has_sat ? "YES" : "NO", use_mtls ? "YES" : "NO", ocsp_verify_stapling ? "YES" : "NO", ocsp_verify_ca ? "YES" : "NO", stream_params->keyword_sample_begin, stream_params->keyword_sample_end, stream_params->keyword_doa, stream_params->dynamic_gain); + XLOGD_AUTOMATION_TELEMETRY("session begin - src <%s> ptt <%s> w_SAT <%s> w_MTLS <%s> w_OCSPst <%s> w_OCSPca <%s> keyword begin <%u> end <%u> doa <%u> gain <%4.1f> db", ctrlm_voice_device_str(source), (stream_params->push_to_talk ? "TRUE" : "FALSE"), has_sat ? "YES" : "NO", use_mtls ? "YES" : "NO", ocsp_verify_stapling ? "YES" : "NO", ocsp_verify_ca ? "YES" : "NO", stream_params->keyword_sample_begin, stream_params->keyword_sample_end, stream_params->keyword_doa, stream_params->dynamic_gain); } else if(!is_mic || dqm->configuration.user_initiated) { xrsv_ws_nextgen_stream_params_t *stream_params = (xrsv_ws_nextgen_stream_params_t *)malloc(sizeof(xrsv_ws_nextgen_stream_params_t)); @@ -378,7 +378,7 @@ void ctrlm_voice_endpoint_ws_nextgen_t::voice_session_begin_callback_ws_nextgen( } config_in.ws.app_config = stream_params; - XLOGD_TELEMETRY("session begin - src <%s> ptt w_SAT <%s> w_MTLS <%s> w_OCSPst <%s> w_OCSPca <%s>", ctrlm_voice_device_str(source), has_sat ? "YES" : "NO", use_mtls ? "YES" : "NO", ocsp_verify_stapling ? "YES" : "NO", ocsp_verify_ca ? "YES" : "NO"); + XLOGD_AUTOMATION_TELEMETRY("session begin - src <%s> ptt w_SAT <%s> w_MTLS <%s> w_OCSPst <%s> w_OCSPca <%s>", ctrlm_voice_device_str(source), has_sat ? "YES" : "NO", use_mtls ? "YES" : "NO", ocsp_verify_stapling ? "YES" : "NO", ocsp_verify_ca ? "YES" : "NO"); } else { XLOGD_ERROR("session begin - invalid params - src <%s>", ctrlm_voice_device_str(source)); } diff --git a/src/voice/endpoints/ctrlm_voice_endpoint_ws_nsp.cpp b/src/voice/endpoints/ctrlm_voice_endpoint_ws_nsp.cpp index 45ad9714..da4d4035 100644 --- a/src/voice/endpoints/ctrlm_voice_endpoint_ws_nsp.cpp +++ b/src/voice/endpoints/ctrlm_voice_endpoint_ws_nsp.cpp @@ -133,7 +133,7 @@ void ctrlm_voice_endpoint_ws_nsp_t::voice_session_begin_callback_ws_nsp(void *da config_in.ws.cert_revoked_allow = false; config_in.ws.ocsp_expired_allow = false; - XLOGD_TELEMETRY("session begin - src <%s> x_MTLS <%s> x_OCSPst <%s> x_OCSPca <%s>", ctrlm_voice_device_str(source), use_mtls ? "YES" : "NO", ocsp_verify_stapling ? "YES" : "NO", ocsp_verify_ca ? "YES" : "NO"); + XLOGD_AUTOMATION_TELEMETRY("session begin - src <%s> x_MTLS <%s> x_OCSPst <%s> x_OCSPca <%s>", ctrlm_voice_device_str(source), use_mtls ? "YES" : "NO", ocsp_verify_stapling ? "YES" : "NO", ocsp_verify_ca ? "YES" : "NO"); ctrlm_voice_session_begin_cb_t session_begin; uuid_copy(session_begin.header.uuid, dqm->uuid); diff --git a/src/voice/ipc/ctrlm_voice_ipc_iarm_thunder.cpp b/src/voice/ipc/ctrlm_voice_ipc_iarm_thunder.cpp index f88d6fb9..02b4408e 100644 --- a/src/voice/ipc/ctrlm_voice_ipc_iarm_thunder.cpp +++ b/src/voice/ipc/ctrlm_voice_ipc_iarm_thunder.cpp @@ -357,7 +357,7 @@ bool ctrlm_voice_ipc_iarm_thunder_t::session_end(const ctrlm_voice_ipc_event_ses char *json_str = json_dumps(event_data, JSON_ENCODE_FLAGS); if(json_str) { //TODO: surface the event through IARM - XLOGD_INFO("<%s>", this->obj_voice->voice_stb_data_pii_mask_get() ? "***" : json_str); + XLOGD_AUTOMATION_INFO("<%s>", this->obj_voice->voice_stb_data_pii_mask_get() ? "***" : json_str); ret = broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_JSON_SESSION_END, json_str); free(json_str); } else { @@ -373,7 +373,7 @@ bool ctrlm_voice_ipc_iarm_thunder_t::session_end(const ctrlm_voice_ipc_event_ses bool ctrlm_voice_ipc_iarm_thunder_t::server_message(const char *message, unsigned long size) { bool ret = false; if(message) { - XLOGD_INFO("%ul : <%s>", size, this->obj_voice->voice_stb_data_pii_mask_get() ? "***" : message); //CID -160950 - Printargs + XLOGD_AUTOMATION_INFO("%ul : <%s>", size, this->obj_voice->voice_stb_data_pii_mask_get() ? "***" : message); //CID -160950 - Printargs ret = broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_JSON_SERVER_MESSAGE, message); } return(ret); From d72398a041fef8118a40204ac80c9743cd91e356 Mon Sep 17 00:00:00 2001 From: Gene Gallagher <129112619+egalla204@users.noreply.github.com> Date: Thu, 4 Dec 2025 11:44:32 -0500 Subject: [PATCH 15/39] RDKEMW-11159: new_certselector_type (#157) --- src/auth/ctrlm_auth_certificate.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/auth/ctrlm_auth_certificate.cpp b/src/auth/ctrlm_auth_certificate.cpp index 63ff900c..63ae514e 100644 --- a/src/auth/ctrlm_auth_certificate.cpp +++ b/src/auth/ctrlm_auth_certificate.cpp @@ -42,7 +42,7 @@ ctrlm_auth_certificate_t::ctrlm_auth_certificate_t() { char *cert_path = NULL; char *cert_password = NULL; - rdkcertselector_h cert_selector = rdkcertselector_new( NULL, NULL, "MTLS" ); + rdkcertselector_h cert_selector = rdkcertselector_new( NULL, NULL, "FBK_MTLS" ); if(cert_selector == NULL){ XLOGD_TELEMETRY("cert selector init failed"); From 4f688c6aca99e5c5d8674d4b3edc60fe97eb0633 Mon Sep 17 00:00:00 2001 From: Gene Gallagher <129112619+egalla204@users.noreply.github.com> Date: Thu, 4 Dec 2025 14:07:59 -0500 Subject: [PATCH 16/39] RDKEMW-11249: update CHANGELOG for ctrlm release v1.1.7 (#158) --- CHANGELOG.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea63c55d..cd51fc43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,16 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - +#### [1.1.7](https://github.com/rdkcentral/control/compare/1.1.6...1.1.7) + +> 4 December 2025 + +- RDKEMW-11159: new_certselector_type [`#157`](https://github.com/rdkcentral/control/pull/157) +- RDKEMW-10425: Automation Logging [`#144`](https://github.com/rdkcentral/control/pull/144) +- RDKEMW-9600: FIRST_PACKET_TIMEOUTs [`#135`](https://github.com/rdkcentral/control/pull/135) + #### [1.1.6](https://github.com/rdkcentral/control/compare/1.1.5...1.1.6) > 19 November 2025 From 2f1050b142d14a66bf31c7279c3900c6b876bda9 Mon Sep 17 00:00:00 2001 From: dwolaver <44593664+dwolaver@users.noreply.github.com> Date: Mon, 8 Dec 2025 16:50:44 -0500 Subject: [PATCH 17/39] RDKEMW-8930 : remove ctrlm build flags - FACTORY_AUDIO_PLAYBACK (#143) --- CMakeLists.txt | 2 - src/factory/CMakeLists.txt | 73 +++--------- src/factory/ctrlm_fta_caa.h | 2 + src/factory/ctrlm_fta_lib.h | 4 +- src/factory/ctrlmf_audio_capture.cpp | 74 +++++++----- src/factory/ctrlmf_audio_capture.h | 2 +- src/factory/ctrlmf_main.c | 29 +---- src/factory/ctrlmf_mic_test.cpp | 98 ++++++++-------- src/factory/ctrlmf_version.c | 101 ++++++++++++---- src/factory/ctrlmf_ws.c | 167 ++++++++++++++++----------- src/factory/ctrlmf_ws.h | 2 +- 11 files changed, 291 insertions(+), 263 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 655f17d2..c38b5657 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,8 +39,6 @@ option(BLE_ENABLED "Enable BLE" ON) option(BLE_SERVICES "Enable BLE Services" OFF) option(BREAKPAD "Enable BREAKPAD" OFF) option(BUILD_CTRLM_FACTORY "Build Control Factory Test" OFF) -option(FACTORY_AUDIO_PLAYBACK "Factory test audio playback" OFF) -option(FACTORY_CUSTOM_AUDIO_ANALYSIS "Factory custom audio analysis" OFF) option(FDC_ENABLED "Enable FDC" OFF) option(IP_ENABLED "Enable IP" OFF) option(RF4CE_ENABLED "Enable RF4CE" ON) diff --git a/src/factory/CMakeLists.txt b/src/factory/CMakeLists.txt index a16ae0eb..530cbf5b 100644 --- a/src/factory/CMakeLists.txt +++ b/src/factory/CMakeLists.txt @@ -17,8 +17,6 @@ # limitations under the License. ########################################################################## -option(FACTORY_AUDIO_PLAYBACK "AUDIO PLAYBACK" OFF) - add_executable(controlFactory ctrlmf_main.c) add_library(ctrlm-fta SHARED) set_target_properties( ctrlm-fta PROPERTIES @@ -30,6 +28,9 @@ include_directories( . iarm thunder + ${CMAKE_SYSROOT}/usr/include/rdk/ds + ${CMAKE_SYSROOT}/usr/include/rdk/ds-rpc + ${CMAKE_SYSROOT}/usr/include/rdk/ds-hal ) target_sources(ctrlm-fta PRIVATE @@ -37,37 +38,21 @@ target_sources(ctrlm-fta PRIVATE ctrlmf_reset.cpp ctrlmf_systemd.c ctrlmf_utils.c + ctrlmf_audio_capture.cpp + ctrlmf_audio_control.cpp + ctrlmf_audio_playback.cpp + ctrlmf_mic_test.cpp + ctrlmf_ws.c iarm/ctrlmf_iarm_client.cpp iarm/ctrlmf_iarm_control_manager.cpp ) -target_link_libraries(ctrlm-fta c rdkversion dbus-1 glib-2.0 IARMBus xr-voice-sdk pthread nopoll secure_wrapper) +target_link_libraries(ctrlm-fta c rdkversion dbus-1 glib-2.0 IARMBus xr-voice-sdk pthread nopoll secure_wrapper ds) target_link_libraries(controlFactory c ctrlm-fta secure_wrapper) -if(CUSTOM_AUDIO_ANALYSIS_LIB) - add_compile_definitions(PRIVATE CTRLMF_CUSTOM_AUDIO_ANALYSIS) - target_link_libraries(controlFactory ${CUSTOM_AUDIO_ANALYSIS_LIB}) -endif() - -if(CUSTOM_AUTH_LIB) +if(AUTH_ENABLED) add_compile_definitions(PRIVATE CTRLMF_WSS_ENABLED) - target_link_libraries(controlFactory ${CUSTOM_AUTH_LIB}) -endif() - -if(EXISTS ${CMAKE_SYSROOT}/usr/lib/libctrlm-hal-certificate.so) - target_link_libraries(controlFactory ctrlm-hal-certificate) -else() - if(AUTH_ENABLED) - message(WARNING "ctrlm-hal-certificate library is not provided, disabling authentication") - unset(AUTH_ENABLED) - endif() -endif() - -if(LOCAL_MIC) - add_compile_definitions(PRIVATE CTRLMF_LOCAL_MIC) - if(MIC_TAP) - add_compile_definitions(PRIVATE CTRLMF_LOCAL_MIC_TAP) - endif() + target_link_libraries(ctrlm-fta RdkCertSelector rdkconfig) endif() if(THUNDER) @@ -75,6 +60,7 @@ if(THUNDER) target_sources(ctrlm-fta PRIVATE thunder/ctrlmf_thunder_controller.cpp thunder/ctrlmf_thunder_plugin.cpp + thunder/ctrlmf_thunder_plugin_system_audio_player.cpp ) target_link_libraries(controlFactory WPEFrameworkCore WPEFrameworkPlugins) @@ -84,40 +70,11 @@ if(THUNDER) if(WPE_FRAMEWORK_PROTO_TRACING) target_link_libraries(controlFactory WPEFrameworkProtocols WPEFrameworkTracing) endif() -endif() -if(THUNDER_SECURITY) - add_compile_definitions(PRIVATE THUNDER_SECURITY) - target_link_libraries(controlFactory WPEFrameworkSecurityUtil secure_wrapper) -endif() - -if(FACTORY_AUDIO_PLAYBACK) - add_compile_definitions(PRIVATE CTRLMF_AUDIO_PLAYBACK) - include_directories( ${CMAKE_SYSROOT}/usr/include/rdk/ds - ${CMAKE_SYSROOT}/usr/include/rdk/ds-rpc - ${CMAKE_SYSROOT}/usr/include/rdk/ds-hal - ) - target_sources(ctrlm-fta PRIVATE ctrlmf_audio_playback.cpp) - if(THUNDER) - target_sources(ctrlm-fta PRIVATE thunder/ctrlmf_thunder_plugin_system_audio_player.cpp) + if(THUNDER_SECURITY) + add_compile_definitions(PRIVATE THUNDER_SECURITY) + target_link_libraries(controlFactory WPEFrameworkSecurityUtil secure_wrapper) endif() - - install(FILES ${CMAKE_SOURCE_DIR}/../tone_1khz.wav DESTINATION share ) -endif() - -if(FACTORY_AUDIO_CONTROL) - add_compile_definitions(PRIVATE CTRLMF_AUDIO_CONTROL) - target_sources(ctrlm-fta PRIVATE - ctrlmf_audio_control.cpp - ) -endif() - -if(LOCAL_MIC) - target_sources(ctrlm-fta PRIVATE - ctrlmf_audio_capture.cpp - ctrlmf_mic_test.cpp - ctrlmf_ws.c - ) endif() install(TARGETS controlFactory DESTINATION bin) diff --git a/src/factory/ctrlm_fta_caa.h b/src/factory/ctrlm_fta_caa.h index ee0b6a97..39373a55 100644 --- a/src/factory/ctrlm_fta_caa.h +++ b/src/factory/ctrlm_fta_caa.h @@ -48,6 +48,8 @@ extern "C" { bool ctrlmf_mic_test_audio_analyze(ctrlmf_test_type_t test_type, const char *output_filename, uint32_t level, ctrlmf_audio_frame_t audio_frames_noise, ctrlmf_audio_frame_t audio_frames_signal, uint32_t frame_qty, uint32_t mic_qty, ctrlmf_test_result_t *test_result); +typedef bool (*ctrlmf_mic_test_audio_analyze_t)(ctrlmf_test_type_t test_type, const char *output_filename, uint32_t level, ctrlmf_audio_frame_t audio_frames_noise, ctrlmf_audio_frame_t audio_frames_signal, uint32_t frame_qty, uint32_t mic_qty, ctrlmf_test_result_t *test_result); + #ifdef __cplusplus } #endif diff --git a/src/factory/ctrlm_fta_lib.h b/src/factory/ctrlm_fta_lib.h index f45f26eb..b4700a7f 100644 --- a/src/factory/ctrlm_fta_lib.h +++ b/src/factory/ctrlm_fta_lib.h @@ -38,7 +38,7 @@ extern "C" { #endif -bool ctrlmf_init(xlog_level_t level, bool requires_audio_playback); +bool ctrlmf_init(xlog_level_t level, bool requires_audio_playback, bool requires_audio_control, ctrlmf_mic_test_audio_analyze_t *audio_analyze_func); void ctrlmf_term(void); bool ctrlmf_factory_reset(void); @@ -51,7 +51,7 @@ bool ctrlmf_audio_control_attenuate(bool enable, bool relative, double vol); bool ctrlmf_audio_playback_start(const char *filename); -bool ctrlmf_mic_test_factory(uint32_t duration, const char *output_filename, uint32_t level, const char *audio_filename, double *snr_min, double *snr_max, double *snr_var, ctrlmf_test_result_t *test_result); +bool ctrlmf_mic_test_factory(uint32_t duration, const char *output_filename, uint32_t level, const char *audio_filename, double *snr_min, double *snr_max, double *snr_var, ctrlmf_test_result_t *test_result, ctrlmf_mic_test_audio_analyze_t audio_analyze_func); #ifdef __cplusplus } diff --git a/src/factory/ctrlmf_audio_capture.cpp b/src/factory/ctrlmf_audio_capture.cpp index d9ed82f5..0d76772a 100644 --- a/src/factory/ctrlmf_audio_capture.cpp +++ b/src/factory/ctrlmf_audio_capture.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -16,13 +17,8 @@ #define CTRLMF_WS_PORT_STR "9880" #define CTRLMF_WS_PORT_INT (9880) -#ifdef CTRLMF_WSS_ENABLED -#define CTRLMF_WS_URL_BASE "aowss://" -#else -#define CTRLMF_WS_URL_BASE "aows://" -#endif - -#define CTRLMF_WS_URL CTRLMF_WS_URL_BASE CTRLMF_WS_HOST ":" CTRLMF_WS_PORT_STR "/mic_test" +#define CTRLMF_WS_URL "aows://" CTRLMF_WS_HOST ":" CTRLMF_WS_PORT_STR "/mic_test" +#define CTRLMF_WSS_URL "aowss://" CTRLMF_WS_HOST ":" CTRLMF_WS_PORT_STR "/mic_test" typedef struct { sem_t semaphore_connected; @@ -50,7 +46,7 @@ static ctrlmf_audio_cap_global_t g_audio_cap; // Capture an audio clip using websocket -bool ctrlmf_audio_capture_init(uint32_t audio_frame_size, bool use_mic_tap) { +bool ctrlmf_audio_capture_init(uint32_t audio_frame_size, bool *has_local_mic_tap) { g_audio_cap.obj_ctrlm = new Iarm::ControlManager::ctrlm_iarm_client_control_manager_t; @@ -60,20 +56,8 @@ bool ctrlmf_audio_capture_init(uint32_t audio_frame_size, bool use_mic_tap) { } g_audio_cap.obj_ctrlm->add_event_handler(ctrlmf_audio_capture_event_handler, NULL); - g_audio_cap.use_mic_tap = use_mic_tap; + g_audio_cap.use_mic_tap = false; - // Get the current url - if(g_audio_cap.use_mic_tap) { - if(!g_audio_cap.obj_ctrlm->status_voice_mic_tap(g_audio_cap.url, &g_audio_cap.url_enabled)) { - XLOGD_ERROR("unable to get mic tap status"); - return(false); - } - } else { - if(!g_audio_cap.obj_ctrlm->status_voice_hf(g_audio_cap.url, &g_audio_cap.url_enabled)) { - XLOGD_ERROR("unable to get hf status"); - return(false); - } - } if(!g_audio_cap.obj_ctrlm->voice_session_types(g_audio_cap.request_types)) { XLOGD_ERROR("unable to get voice session request types"); return(false); @@ -90,23 +74,34 @@ bool ctrlmf_audio_capture_init(uint32_t audio_frame_size, bool use_mic_tap) { first = false; } - XLOGD_INFO("get url <%s> enabled <%s> request types <%s>", g_audio_cap.url.c_str(), g_audio_cap.url_enabled ? "YES" : "NO", request_types.str().c_str()); + bool has_local_mic = false; + if(std::find(g_audio_cap.request_types.begin(), g_audio_cap.request_types.end(), "mic_stream_single") != g_audio_cap.request_types.end()) { + has_local_mic = true; + } + if(std::find(g_audio_cap.request_types.begin(), g_audio_cap.request_types.end(), "mic_tap_stream_single") != g_audio_cap.request_types.end()) { + g_audio_cap.use_mic_tap = true; + } - // Set the FFV url to our websocket - std::string url_new = CTRLMF_WS_URL; + if(!has_local_mic) { + XLOGD_ERROR("platform does not support local mic stream"); + return(false); + } + // Get the current url if(g_audio_cap.use_mic_tap) { - if(!g_audio_cap.obj_ctrlm->configure_voice_mic_tap(url_new, true)) { - XLOGD_ERROR("unable to set mic tap url"); + if(!g_audio_cap.obj_ctrlm->status_voice_mic_tap(g_audio_cap.url, &g_audio_cap.url_enabled)) { + XLOGD_ERROR("unable to get mic tap status"); return(false); } } else { - if(!g_audio_cap.obj_ctrlm->configure_voice_hf(url_new, true)) { - XLOGD_ERROR("unable to set hf url"); + if(!g_audio_cap.obj_ctrlm->status_voice_hf(g_audio_cap.url, &g_audio_cap.url_enabled)) { + XLOGD_ERROR("unable to get hf status"); return(false); } } + XLOGD_INFO("get url <%s> enabled <%s> request types <%s>", g_audio_cap.url.c_str(), g_audio_cap.url_enabled ? "YES" : "NO", request_types.str().c_str()); + // Start websocket server sem_init(&g_audio_cap.callback_data.semaphore_connected, 0, 0); sem_init(&g_audio_cap.callback_data.semaphore_disconnected, 0, 0); @@ -115,7 +110,28 @@ bool ctrlmf_audio_capture_init(uint32_t audio_frame_size, bool use_mic_tap) { g_audio_cap.callbacks.disconnected = ctrlmf_ws_disconnected; g_audio_cap.callbacks.data = &g_audio_cap.callback_data; g_audio_cap.session_id = ""; - ctrlmf_ws_init(audio_frame_size, CTRLMF_WS_PORT_INT, true, &g_audio_cap.callbacks); + + bool has_valid_cert = false; + ctrlmf_ws_init(audio_frame_size, CTRLMF_WS_PORT_INT, true, &g_audio_cap.callbacks, &has_valid_cert); + + // Set the FFV url to our websocket + std::string url_new = has_valid_cert ? CTRLMF_WSS_URL : CTRLMF_WS_URL; + + if(g_audio_cap.use_mic_tap) { + if(!g_audio_cap.obj_ctrlm->configure_voice_mic_tap(url_new, true)) { + XLOGD_ERROR("unable to set mic tap url"); + return(false); + } + } else { + if(!g_audio_cap.obj_ctrlm->configure_voice_hf(url_new, true)) { + XLOGD_ERROR("unable to set hf url"); + return(false); + } + } + + if(has_local_mic_tap != NULL) { + *has_local_mic_tap = g_audio_cap.use_mic_tap; + } return(true); } diff --git a/src/factory/ctrlmf_audio_capture.h b/src/factory/ctrlmf_audio_capture.h index dfcf343e..79e14e1f 100644 --- a/src/factory/ctrlmf_audio_capture.h +++ b/src/factory/ctrlmf_audio_capture.h @@ -26,7 +26,7 @@ extern "C" { #endif -bool ctrlmf_audio_capture_init(uint32_t audio_frame_size, bool use_mic_tap); +bool ctrlmf_audio_capture_init(uint32_t audio_frame_size, bool *has_local_mic_tap); bool ctrlmf_audio_capture_term(void); bool ctrlmf_audio_capture_start(const char *request_type, ctrlmf_audio_frame_t audio_frames, uint32_t audio_frame_qty, uint32_t duration); diff --git a/src/factory/ctrlmf_main.c b/src/factory/ctrlmf_main.c index b923c9db..e70337d9 100644 --- a/src/factory/ctrlmf_main.c +++ b/src/factory/ctrlmf_main.c @@ -44,10 +44,7 @@ static struct argp_option options[] = { {"factory-reset", 'F', 0, 0, "Perform control manager factory reset and restart the application." }, {"soft-factory-reset",'f', 0, 0, "Perform control manager factory reset" }, {"ctrlm-restart", 'r', 0, 0, "Restart the control manager application" }, - #ifdef CTRLMF_LOCAL_MIC - #ifdef CTRLMF_AUDIO_PLAYBACK {"mic-test-audio", 'a', "", 0, "Microphone test audio file" }, - #endif {"mic-test-factory", 'd', 0, 0, "Factory microphone test" }, {"mic-test-duration", 'u', "", 0, "Microphone test duration in milliseconds" }, {"mic-test-snr-min", 'x', "", 0, "Microphone test SNR minimum value" }, @@ -55,10 +52,7 @@ static struct argp_option options[] = { {"mic-test-snr-var", 'z', "", 0, "Microphone test SNR maximum variance" }, {"mic-test-output", 'g', "", 0, "Microphone test output filename" }, {"mic-test-level", 'l', "", 0, "Microphone test level" }, - #endif - #ifdef CTRLMF_AUDIO_CONTROL {"mute-main-audio", 'm', 0, 0, "Mute the main audio output" }, - #endif { 0 } }; @@ -99,8 +93,9 @@ int main(int argc, char* argv[]) { } bool requires_audio_playback = (g_ctrlmf_opts.audio_file_path != NULL) ? true : false; + ctrlmf_mic_test_audio_analyze_t audio_analyze_func = NULL; - if(!ctrlmf_init(level, requires_audio_playback)) { + if(!ctrlmf_init(level, requires_audio_playback, g_ctrlmf_opts.mute_main_audio, &audio_analyze_func)) { XLOGD_ERROR("ctrlmf_main: init failed"); } else { XLOGD_INFO("ctrlmf_main: Run main loop"); @@ -110,30 +105,22 @@ int main(int argc, char* argv[]) { if(g_ctrlmf_opts.ctrlm_restart) { ctrlmf_systemd_service_exec("ctrlm-main.service", CTRLMF_SYSTEMD_METHOD_RESTART); } - #ifdef CTRLMF_AUDIO_CONTROL if(g_ctrlmf_opts.mute_main_audio) { ctrlmf_audio_control_mute(true); } - #endif if(g_ctrlmf_opts.mic_test_factory) { - #ifdef CTRLMF_LOCAL_MIC ctrlmf_test_result_t test_result; - if(!ctrlmf_mic_test_factory(g_ctrlmf_opts.mic_test_duration, g_ctrlmf_opts.output_file_path, g_ctrlmf_opts.mic_test_level, g_ctrlmf_opts.audio_file_path, g_ctrlmf_opts.mic_test_snr_min, g_ctrlmf_opts.mic_test_snr_max, g_ctrlmf_opts.mic_test_snr_var, &test_result)) { + if(!ctrlmf_mic_test_factory(g_ctrlmf_opts.mic_test_duration, g_ctrlmf_opts.output_file_path, g_ctrlmf_opts.mic_test_level, g_ctrlmf_opts.audio_file_path, g_ctrlmf_opts.mic_test_snr_min, g_ctrlmf_opts.mic_test_snr_max, g_ctrlmf_opts.mic_test_snr_var, &test_result, audio_analyze_func)) { XLOGD_ERROR("ctrlmf_main: mic test failed"); } else { XLOGD_INFO("ctrlmf_main: test result <%s>", test_result.pass ? "PASS" : "FAIL"); } - #endif } else if(g_ctrlmf_opts.audio_file_path != NULL) { - #ifdef CTRLMF_AUDIO_PLAYBACK ctrlmf_audio_playback_start(g_ctrlmf_opts.audio_file_path); - #endif } - #ifdef CTRLMF_AUDIO_CONTROL if(g_ctrlmf_opts.mute_main_audio) { ctrlmf_audio_control_mute(false); } - #endif XLOGD_INFO("ctrlmf_main: main loop ended"); } @@ -169,14 +156,11 @@ error_t ctrlmf_parse_opt(int key, char *arg, struct argp_state *state) { arguments->ctrlm_restart = true; break; } - #ifdef CTRLMF_LOCAL_MIC - #ifdef CTRLMF_AUDIO_PLAYBACK case 'a': { XLOGD_INFO("mic test audio file <%s>", arg); arguments->audio_file_path = arg; break; } - #endif case 'g': { XLOGD_INFO("output file path <%s>", arg); arguments->output_file_path = arg; @@ -221,13 +205,10 @@ error_t ctrlmf_parse_opt(int key, char *arg, struct argp_state *state) { arguments->mic_test_snr_var = &arguments->snr_var; break; } - #endif - #ifdef CTRLMF_AUDIO_CONTROL case 'm': { arguments->mute_main_audio = true; break; } - #endif case ARGP_KEY_ARG: { argp_usage(state); return(ARGP_ERR_UNKNOWN); @@ -257,14 +238,10 @@ bool ctrlmf_cmdline_args(int argc, char *argv[]) { XLOGD_INFO("ctrlm restart <%s>", g_ctrlmf_opts.ctrlm_restart ? "YES" : "NO"); XLOGD_INFO("audio file <%s>", g_ctrlmf_opts.audio_file_path ? g_ctrlmf_opts.audio_file_path : "NULL"); XLOGD_INFO("output file path <%s>", g_ctrlmf_opts.output_file_path ? g_ctrlmf_opts.output_file_path : "NULL"); - #ifdef CTRLMF_LOCAL_MIC if(g_ctrlmf_opts.mic_test_factory) { XLOGD_INFO("mic test duration <%d ms> snr min <%f> max <%f> var <%f>", g_ctrlmf_opts.mic_test_duration, *g_ctrlmf_opts.mic_test_snr_min, *g_ctrlmf_opts.mic_test_snr_max, *g_ctrlmf_opts.mic_test_snr_var); } - #endif - #ifdef CTRLMF_AUDIO_CONTROL XLOGD_INFO("mute main audio <%s>", g_ctrlmf_opts.mute_main_audio ? "YES" : "NO"); - #endif return(true); } diff --git a/src/factory/ctrlmf_mic_test.cpp b/src/factory/ctrlmf_mic_test.cpp index b3eab24c..1db94630 100644 --- a/src/factory/ctrlmf_mic_test.cpp +++ b/src/factory/ctrlmf_mic_test.cpp @@ -22,19 +22,17 @@ #define FILENAME_WAV_NOISE "/opt/logs/mic_test_noise.wav" #define FILENAME_WAV_SIGNAL "/opt/logs/mic_test_signal.wav" -#ifndef CTRLMF_CUSTOM_AUDIO_ANALYSIS -static bool ctrlmf_mic_test_audio_analyze(const char *output_filename, uint32_t level, ctrlmf_audio_frame_t audio_frames_noise, ctrlmf_audio_frame_t audio_frames_signal, uint32_t frame_qty, uint32_t mic_qty, double snr_min, double snr_max, double snr_var, ctrlmf_test_result_t *test_result); -#endif +static bool ctrlmf_mic_test_audio_analyze_default(const char *output_filename, uint32_t level, ctrlmf_audio_frame_t audio_frames_noise, ctrlmf_audio_frame_t audio_frames_signal, uint32_t frame_qty, uint32_t mic_qty, double snr_min, double snr_max, double snr_var, ctrlmf_test_result_t *test_result); -#if defined(CTRLMF_THUNDER) && defined(CTRLMF_AUDIO_PLAYBACK) -static bool ctrlmf_mic_test_via_audio_file(uint32_t duration, const char *output_filename, uint32_t level, const char *audio_filename, double snr_min, double snr_max, double snr_var, ctrlmf_test_result_t *test_result); +#ifdef CTRLMF_THUNDER +static bool ctrlmf_mic_test_via_audio_file(uint32_t duration, const char *output_filename, uint32_t level, const char *audio_filename, double snr_min, double snr_max, double snr_var, ctrlmf_test_result_t *test_result, ctrlmf_mic_test_audio_analyze_t audio_analyze_func); #endif -static bool ctrlmf_mic_test_via_ambient(uint32_t duration, const char *output_filename, uint32_t level, double snr_min, double snr_max, double snr_var, ctrlmf_test_result_t *test_result); +static bool ctrlmf_mic_test_via_ambient(uint32_t duration, const char *output_filename, uint32_t level, double snr_min, double snr_max, double snr_var, ctrlmf_test_result_t *test_result, ctrlmf_mic_test_audio_analyze_t audio_analyze_func); static void ctrlmf_mic_test_audio_export(const char *filename, ctrlmf_audio_frame_t audio_frames, uint32_t frame_qty, uint32_t channel_qty); static void ctrlmf_wave_header_gen(uint8_t *header, uint16_t audio_format, uint16_t num_channels, uint32_t sample_rate, uint16_t bits_per_sample, uint32_t pcm_data_size); -bool ctrlmf_mic_test_factory(uint32_t duration, const char *output_filename, uint32_t level, const char *audio_filename, double *snr_min, double *snr_max, double *snr_var, ctrlmf_test_result_t *test_result) { +bool ctrlmf_mic_test_factory(uint32_t duration, const char *output_filename, uint32_t level, const char *audio_filename, double *snr_min, double *snr_max, double *snr_var, ctrlmf_test_result_t *test_result, ctrlmf_mic_test_audio_analyze_t audio_analyze_func) { if(!ctrlmf_is_initialized()) { XLOGD_ERROR("not initialized"); return(false); @@ -44,18 +42,18 @@ bool ctrlmf_mic_test_factory(uint32_t duration, const char *output_filename, uin double snr_var_val = (snr_var != NULL) ? *snr_var : SNR_VAR; if(audio_filename != NULL) { - #if defined(CTRLMF_THUNDER) && defined(CTRLMF_AUDIO_PLAYBACK) - return(ctrlmf_mic_test_via_audio_file(duration, output_filename, level, audio_filename, snr_min_val, snr_max_val, snr_var_val, test_result)); + #ifdef CTRLMF_THUNDER + return(ctrlmf_mic_test_via_audio_file(duration, output_filename, level, audio_filename, snr_min_val, snr_max_val, snr_var_val, test_result, audio_analyze_func)); #else XLOGD_ERROR("audio playback is disabled"); return(false); #endif } - return(ctrlmf_mic_test_via_ambient(duration, output_filename, level, snr_min_val, snr_max_val, snr_var_val, test_result)); + return(ctrlmf_mic_test_via_ambient(duration, output_filename, level, snr_min_val, snr_max_val, snr_var_val, test_result, audio_analyze_func)); } -#if defined(CTRLMF_THUNDER) && defined(CTRLMF_AUDIO_PLAYBACK) -bool ctrlmf_mic_test_via_audio_file(uint32_t duration, const char *output_filename, uint32_t level, const char *audio_filename, double snr_min, double snr_max, double snr_var, ctrlmf_test_result_t *test_result) { +#ifdef CTRLMF_THUNDER +bool ctrlmf_mic_test_via_audio_file(uint32_t duration, const char *output_filename, uint32_t level, const char *audio_filename, double snr_min, double snr_max, double snr_var, ctrlmf_test_result_t *test_result, ctrlmf_mic_test_audio_analyze_t audio_analyze_func) { ctrlmf_audio_frame_t audio_frames_noise = NULL; ctrlmf_audio_frame_t audio_frames_signal = NULL; bool result = false; @@ -84,21 +82,19 @@ bool ctrlmf_mic_test_via_audio_file(uint32_t duration, const char *output_filena memset(audio_frames_noise, 0, audio_buffer_size); memset(audio_frames_signal, 0, audio_buffer_size); - #ifdef CTRLMF_LOCAL_MIC_TAP - if(!ctrlmf_audio_capture_init(audio_frame_size, true)) { - #else - if(!ctrlmf_audio_capture_init(audio_frame_size, false)) { - #endif + bool use_local_mic_tap = false; + if(!ctrlmf_audio_capture_init(audio_frame_size, &use_local_mic_tap)) { XLOGD_ERROR("unable to init audio capture"); break; } audio_capture_initialized = true; - #ifdef CTRLMF_LOCAL_MIC_TAP - const char *request_type = (MIC_RAW_AUDIO) ? "mic_factory_test" : (MIC_CHANNEL_QTY == 1) ? "mic_tap_stream_single" : "mic_tap_stream_multi"; - #else - const char *request_type = (MIC_RAW_AUDIO) ? "mic_factory_test" : (MIC_CHANNEL_QTY == 1) ? "mic_stream_single" : "mic_stream_multi"; - #endif + const char *request_type = NULL; + if(use_local_mic_tap) { + request_type = (MIC_RAW_AUDIO) ? "mic_factory_test" : (MIC_CHANNEL_QTY == 1) ? "mic_tap_stream_single" : "mic_tap_stream_multi"; + } else { + request_type = (MIC_RAW_AUDIO) ? "mic_factory_test" : (MIC_CHANNEL_QTY == 1) ? "mic_stream_single" : "mic_stream_multi"; + } // Capture noise if(!ctrlmf_audio_capture_start(request_type, audio_frames_noise, audio_frame_qty, duration)) { @@ -120,13 +116,16 @@ bool ctrlmf_mic_test_via_audio_file(uint32_t duration, const char *output_filena } XLOGD_INFO("analyze audio capture"); - #ifndef CTRLMF_CUSTOM_AUDIO_ANALYSIS - if(!ctrlmf_mic_test_audio_analyze(output_filename, level, audio_frames_noise, audio_frames_signal, audio_frame_qty, MIC_CHANNEL_QTY, snr_min, snr_max, snr_var, test_result)) { - #else - if(!ctrlmf_mic_test_audio_analyze(CTRLMF_TEST_FACTORY, output_filename, level, audio_frames_noise, audio_frames_signal, audio_frame_qty, MIC_CHANNEL_QTY, test_result)) { - #endif - XLOGD_ERROR("unable to analyze audio"); - break; + if(audio_analyze_func != NULL) { + if(!(*audio_analyze_func)(CTRLMF_TEST_FACTORY, output_filename, level, audio_frames_noise, audio_frames_signal, audio_frame_qty, MIC_CHANNEL_QTY, test_result)) { + XLOGD_ERROR("unable to analyze audio"); + break; + } + } else { + if(!ctrlmf_mic_test_audio_analyze_default(output_filename, level, audio_frames_noise, audio_frames_signal, audio_frame_qty, MIC_CHANNEL_QTY, snr_min, snr_max, snr_var, test_result)) { + XLOGD_ERROR("unable to analyze audio"); + break; + } } if(!ctrlmf_is_production()) { ctrlmf_mic_test_audio_export(FILENAME_WAV_NOISE, audio_frames_noise, audio_frame_qty, MIC_CHANNEL_QTY); @@ -149,7 +148,7 @@ bool ctrlmf_mic_test_via_audio_file(uint32_t duration, const char *output_filena } #endif -bool ctrlmf_mic_test_via_ambient(uint32_t duration, const char *output_filename, uint32_t level, double snr_min, double snr_max, double snr_var, ctrlmf_test_result_t *test_result) { +bool ctrlmf_mic_test_via_ambient(uint32_t duration, const char *output_filename, uint32_t level, double snr_min, double snr_max, double snr_var, ctrlmf_test_result_t *test_result, ctrlmf_mic_test_audio_analyze_t audio_analyze_func) { ctrlmf_audio_frame_t audio_frames_signal = NULL; bool result = false; bool audio_capture_initialized = false; @@ -170,21 +169,19 @@ bool ctrlmf_mic_test_via_ambient(uint32_t duration, const char *output_filename, memset(audio_frames_signal, 0, audio_buffer_size); - #ifdef CTRLMF_LOCAL_MIC_TAP - if(!ctrlmf_audio_capture_init(audio_frame_size, true)) { - #else - if(!ctrlmf_audio_capture_init(audio_frame_size, false)) { - #endif + bool use_local_mic_tap = false; + if(!ctrlmf_audio_capture_init(audio_frame_size, &use_local_mic_tap)) { XLOGD_ERROR("unable to init audio capture"); break; } audio_capture_initialized = true; - #ifdef CTRLMF_LOCAL_MIC_TAP - const char *request_type = (MIC_RAW_AUDIO) ? "mic_factory_test" : (MIC_CHANNEL_QTY == 1) ? "mic_tap_stream_single" : "mic_tap_stream_multi"; - #else - const char *request_type = (MIC_RAW_AUDIO) ? "mic_factory_test" : (MIC_CHANNEL_QTY == 1) ? "mic_stream_single" : "mic_stream_multi"; - #endif + const char *request_type = NULL; + if(use_local_mic_tap) { + request_type = (MIC_RAW_AUDIO) ? "mic_factory_test" : (MIC_CHANNEL_QTY == 1) ? "mic_tap_stream_single" : "mic_tap_stream_multi"; + } else { + request_type = (MIC_RAW_AUDIO) ? "mic_factory_test" : (MIC_CHANNEL_QTY == 1) ? "mic_stream_single" : "mic_stream_multi"; + } // Capture signal if(!ctrlmf_audio_capture_start(request_type, audio_frames_signal, audio_frame_qty, duration)) { @@ -193,13 +190,16 @@ bool ctrlmf_mic_test_via_ambient(uint32_t duration, const char *output_filename, } XLOGD_INFO("analyze audio capture"); - #ifndef CTRLMF_CUSTOM_AUDIO_ANALYSIS - if(!ctrlmf_mic_test_audio_analyze(output_filename, level, NULL, audio_frames_signal, audio_frame_qty, MIC_CHANNEL_QTY, snr_min, snr_max, snr_var, test_result)) { - #else - if(!ctrlmf_mic_test_audio_analyze(CTRLMF_TEST_FACTORY, output_filename, level, NULL, audio_frames_signal, audio_frame_qty, MIC_CHANNEL_QTY, test_result)) { - #endif - XLOGD_ERROR("unable to analyze audio"); - break; + if(audio_analyze_func != NULL) { + if(!(*audio_analyze_func)(CTRLMF_TEST_FACTORY, output_filename, level, NULL, audio_frames_signal, audio_frame_qty, MIC_CHANNEL_QTY, test_result)) { + XLOGD_ERROR("unable to analyze audio"); + break; + } + } else { + if(!ctrlmf_mic_test_audio_analyze_default(output_filename, level, NULL, audio_frames_signal, audio_frame_qty, MIC_CHANNEL_QTY, snr_min, snr_max, snr_var, test_result)) { + XLOGD_ERROR("unable to analyze audio"); + break; + } } if(!ctrlmf_is_production()) { ctrlmf_mic_test_audio_export(FILENAME_WAV_SIGNAL, audio_frames_signal, audio_frame_qty, MIC_CHANNEL_QTY); @@ -217,8 +217,7 @@ bool ctrlmf_mic_test_via_ambient(uint32_t duration, const char *output_filename, return(result); } -#ifndef CTRLMF_CUSTOM_AUDIO_ANALYSIS -bool ctrlmf_mic_test_audio_analyze(const char *output_filename, uint32_t level, ctrlmf_audio_frame_t audio_frames_noise, ctrlmf_audio_frame_t audio_frames_signal, uint32_t frame_qty, uint32_t mic_qty, double snr_min, double snr_max, double snr_var, ctrlmf_test_result_t *test_result) { +bool ctrlmf_mic_test_audio_analyze_default(const char *output_filename, uint32_t level, ctrlmf_audio_frame_t audio_frames_noise, ctrlmf_audio_frame_t audio_frames_signal, uint32_t frame_qty, uint32_t mic_qty, double snr_min, double snr_max, double snr_var, ctrlmf_test_result_t *test_result) { double pcm_sq_sum_noise[mic_qty]; double pcm_sq_sum_signal[mic_qty]; @@ -295,7 +294,6 @@ bool ctrlmf_mic_test_audio_analyze(const char *output_filename, uint32_t level, } return(true); } -#endif void ctrlmf_mic_test_audio_export(const char *filename, ctrlmf_audio_frame_t audio_frames, uint32_t frame_qty, uint32_t channel_qty) { uint8_t header[WAVE_HEADER_SIZE_MIN]; diff --git a/src/factory/ctrlmf_version.c b/src/factory/ctrlmf_version.c index 459f0fd7..7d52efc0 100644 --- a/src/factory/ctrlmf_version.c +++ b/src/factory/ctrlmf_version.c @@ -1,7 +1,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -10,20 +12,25 @@ #include typedef struct { - bool initialized; - bool audio_control_init; - bool audio_playback_init; - bool is_production; + bool initialized; + void *handle_audio_analysis; + bool audio_control_init; + bool audio_playback_init; + bool is_production; } ctrlmf_global_t; ctrlmf_global_t g_ctrlmf = { - .initialized = false, - .audio_control_init = false, - .audio_playback_init = false, - .is_production = true + .initialized = false, + .handle_audio_analysis = NULL, + .audio_control_init = false, + .audio_playback_init = false, + .is_production = true }; -bool ctrlmf_init(xlog_level_t level, bool requires_audio_playback) { +static bool ctrlmf_file_exists(const char *filename); +static void *ctrlmf_load_plugin_audio_analysis(ctrlmf_mic_test_audio_analyze_t *audio_analyze_func); + +bool ctrlmf_init(xlog_level_t level, bool requires_audio_playback, bool requires_audio_control, ctrlmf_mic_test_audio_analyze_t *audio_analyze_func) { rdk_version_info_t info; int ret_val = rdk_version_parse_version(&info); @@ -44,42 +51,40 @@ bool ctrlmf_init(xlog_level_t level, bool requires_audio_playback) { return(false); } - #ifdef CTRLMF_AUDIO_CONTROL - if(!ctrlmf_audio_control_init()) { + if(requires_audio_control && !ctrlmf_audio_control_init()) { XLOGD_ERROR("failed to init audio control"); return(false); } - #endif - #ifdef CTRLMF_AUDIO_PLAYBACK if(requires_audio_playback && !ctrlmf_audio_playback_init()) { XLOGD_ERROR("failed to init audio playback"); - #ifdef CTRLMF_AUDIO_CONTROL - ctrlmf_audio_control_term(); - #endif + if(requires_audio_control) { + ctrlmf_audio_control_term(); + } return(false); } - #endif - g_ctrlmf.audio_control_init = true; - g_ctrlmf.audio_playback_init = requires_audio_playback; - g_ctrlmf.initialized = true; + g_ctrlmf.handle_audio_analysis = ctrlmf_load_plugin_audio_analysis(audio_analyze_func); + g_ctrlmf.audio_control_init = requires_audio_control; + g_ctrlmf.audio_playback_init = requires_audio_playback; + g_ctrlmf.initialized = true; return(true); } void ctrlmf_term(void) { - #ifdef CTRLMF_AUDIO_PLAYBACK if(g_ctrlmf.audio_playback_init) { ctrlmf_audio_playback_term(); } - #endif - #ifdef CTRLMF_AUDIO_CONTROL if(g_ctrlmf.audio_control_init) { ctrlmf_audio_control_term(); } - #endif + + if(g_ctrlmf.handle_audio_analysis != NULL) { + dlclose(g_ctrlmf.handle_audio_analysis); + g_ctrlmf.handle_audio_analysis = NULL; + } g_ctrlmf.audio_playback_init = false; g_ctrlmf.audio_control_init = false; @@ -95,3 +100,51 @@ bool ctrlmf_is_production(void) { return(g_ctrlmf.is_production); } +bool ctrlmf_file_exists(const char *filename) { + if(filename == NULL) { + return false; + } + struct stat buffer; + if(stat(filename, &buffer) == 0) { + return true; + } + return false; +} + +void *ctrlmf_load_plugin_audio_analysis(ctrlmf_mic_test_audio_analyze_t *audio_analyze_func) { + if(audio_analyze_func == NULL) { + XLOGD_INFO("Audio Analysis plugin not requested."); + return(NULL); + } + void *handle = NULL; + + const char *so_path_vd = "/vendor/lib/libctrlmf_audio_analysis.so"; + const char *so_path_mw = "/usr/lib/libctrlmf_audio_analysis.so"; + if(ctrlmf_file_exists(so_path_vd)) { + handle = dlopen(so_path_vd, RTLD_NOW); + } else if(ctrlmf_file_exists(so_path_mw)) { + handle = dlopen(so_path_mw, RTLD_NOW); + } else { + XLOGD_INFO("Audio Analysis plugin is not present."); + return(NULL); + } + + if(NULL == handle) { + XLOGD_ERROR("Failed to load Audio Analysis plugin <%s>", dlerror()); + return(NULL); + } + + dlerror(); // Clear any existing error + + *audio_analyze_func = (ctrlmf_mic_test_audio_analyze_t)dlsym(handle, "ctrlmf_mic_test_audio_analyze"); + char *error = dlerror(); + + if(error != NULL) { + XLOGD_ERROR("Failed to find plugin method (ctrlmf_mic_test_audio_analyze), error <%s>", error); + dlclose(handle); + return(NULL); + } + + XLOGD_INFO("Audio Analysis plugin is loaded."); + return(handle); +} diff --git a/src/factory/ctrlmf_ws.c b/src/factory/ctrlmf_ws.c index ea175c06..4befff0a 100644 --- a/src/factory/ctrlmf_ws.c +++ b/src/factory/ctrlmf_ws.c @@ -16,11 +16,13 @@ #include #ifdef CTRLMF_WSS_ENABLED +#include "rdkcertselector.h" #include #define CTRLMF_WS_CIPHER_LIST "AES256-SHA256:AES128-GCM-SHA256:AES128-SHA256" #define CTRLMF_WS_TLS_CERT_KEY_FILE "/tmp/serverXXXXXX" #define CTRLMF_WS_CERT_NAME_LEN (1024) #define CTRLMF_WS_CERT_PW_LEN (128) +#define CTRLMF_CERT_FILENAME_PREFIX "file://" #endif typedef enum { @@ -37,6 +39,7 @@ typedef struct { uint32_t * audio_frame_qty; uint32_t audio_frame_size; ctrlmf_ws_callbacks_t *callbacks; + bool *has_valid_cert; } ctrlmf_ws_thread_params_t; typedef struct { @@ -72,7 +75,7 @@ static bool ctrlmf_ws_add_chain(FILE *cert_key_fp, STACK_OF(X509) *additi ctrlmf_ws_global_t g_ctrlmf_ws; -bool ctrlmf_ws_init(uint32_t audio_frame_size, uint16_t port, bool log_enable, ctrlmf_ws_callbacks_t *callbacks) { +bool ctrlmf_ws_init(uint32_t audio_frame_size, uint16_t port, bool log_enable, ctrlmf_ws_callbacks_t *callbacks, bool *has_valid_cert) { ctrlmf_ws_thread_params_t params; sem_t semaphore; @@ -87,6 +90,7 @@ bool ctrlmf_ws_init(uint32_t audio_frame_size, uint16_t port, bool log_enable, c params.audio_frame_qty = &g_ctrlmf_ws.audio_frame_qty; params.audio_frame_size = audio_frame_size; params.callbacks = callbacks; + params.has_valid_cert = has_valid_cert; g_ctrlmf_ws.nopoll_ctx = NULL; g_ctrlmf_ws.audio_frames = NULL; @@ -146,52 +150,56 @@ void *ctrlmf_ws_main(void *param) { return(NULL); } - #ifdef CTRLMF_WSS_ENABLED - int cert_key_fd = -1; - FILE *cert_key_fp = NULL; char tmp_cert[32] = {0}; - int err_store; - - safec_rc = sprintf_s(tmp_cert, sizeof(tmp_cert), "%s", CTRLMF_WS_TLS_CERT_KEY_FILE); - if(safec_rc < EOK) { - ERR_CHK(safec_rc); - } + bool cert_valid = false; + #ifdef CTRLMF_WSS_ENABLED + do { + int cert_key_fd = -1; + FILE *cert_key_fp = NULL; + int err_store; - umask(0600); - cert_key_fd = mkstemp(tmp_cert); - if (cert_key_fd == -1) - { - err_store = errno; - XLOGD_ERROR("mkstemp failed: <%s>", strerror(err_store)); - return(NULL); - } + safec_rc = sprintf_s(tmp_cert, sizeof(tmp_cert), "%s", CTRLMF_WS_TLS_CERT_KEY_FILE); + if(safec_rc < EOK) { + ERR_CHK(safec_rc); + } - cert_key_fp = fdopen(cert_key_fd, "w"); - if(cert_key_fp == NULL) { - err_store = errno; - XLOGD_ERROR("fdopen failed: <%s>", strerror(err_store)); - if(0 != unlink(&tmp_cert[0])) { + umask(0600); + cert_key_fd = mkstemp(tmp_cert); + if (cert_key_fd == -1) + { err_store = errno; - XLOGD_ERROR("failed to remove temp cert <%s>", strerror(err_store)); + XLOGD_ERROR("mkstemp failed: <%s>", strerror(err_store)); + break; } - return(NULL); - } - if(!ctrlmf_ws_cert_config(cert_key_fp)) { - XLOGD_ERROR("failed to set cert or key, exit"); - fclose(cert_key_fp); - if(0 != unlink(&tmp_cert[0])) { + cert_key_fp = fdopen(cert_key_fd, "w"); + if(cert_key_fp == NULL) { err_store = errno; - XLOGD_ERROR("failed to remove temp cert <%s>", strerror(err_store)); + XLOGD_ERROR("fdopen failed: <%s>", strerror(err_store)); + if(0 != unlink(&tmp_cert[0])) { + err_store = errno; + XLOGD_ERROR("failed to remove temp cert <%s>", strerror(err_store)); + } + break; } - return(NULL); - } - fclose(cert_key_fp); - // Init OpenSSL - SSL_library_init(); - SSL_load_error_strings(); - OpenSSL_add_all_algorithms(); + if(!ctrlmf_ws_cert_config(cert_key_fp)) { + XLOGD_ERROR("failed to set cert or key"); + fclose(cert_key_fp); + if(0 != unlink(&tmp_cert[0])) { + err_store = errno; + XLOGD_ERROR("failed to remove temp cert <%s>", strerror(err_store)); + } + break; + } + fclose(cert_key_fp); + + // Init OpenSSL + SSL_library_init(); + SSL_load_error_strings(); + OpenSSL_add_all_algorithms(); + cert_valid = true; + } while(0); #endif if(params.log_enable) { @@ -203,17 +211,17 @@ void *ctrlmf_ws_main(void *param) { nopoll_ctx_set_on_ready(g_ctrlmf_ws.nopoll_ctx, ctrlmf_ws_on_ready, &state); nopoll_ctx_set_on_msg(g_ctrlmf_ws.nopoll_ctx, ctrlmf_ws_on_message, &state); - #ifdef CTRLMF_WSS_ENABLED - nopoll_conn_opts_set_ssl_protocol(opts, NOPOLL_METHOD_TLSV1_2); - nopoll_conn_opts_ssl_host_verify(opts, nopoll_false); //localhost will not match host specified in certificate - - if(!nopoll_conn_opts_set_ssl_certs(opts, &tmp_cert[0], &tmp_cert[0], NULL, NULL)) { - XLOGD_ERROR("Failed to add cert/key files to nopoll_conn"); - nopoll_ctx_unref(g_ctrlmf_ws.nopoll_ctx); - nopoll_conn_opts_free(opts); - return(NULL); + if(cert_valid) { + nopoll_conn_opts_set_ssl_protocol(opts, NOPOLL_METHOD_TLSV1_2); + nopoll_conn_opts_ssl_host_verify(opts, nopoll_false); //localhost will not match host specified in certificate + + if(!nopoll_conn_opts_set_ssl_certs(opts, &tmp_cert[0], &tmp_cert[0], NULL, NULL)) { + XLOGD_ERROR("Failed to add cert/key files to nopoll_conn"); + nopoll_ctx_unref(g_ctrlmf_ws.nopoll_ctx); + nopoll_conn_opts_free(opts); + return(NULL); + } } - #endif char port[6]; safec_rc = sprintf_s(port, sizeof(port), "%u", params.port); @@ -222,11 +230,11 @@ void *ctrlmf_ws_main(void *param) { } // Start IPv4/6 listener - #ifdef CTRLMF_WSS_ENABLED - state.nopoll_conn = nopoll_listener_tls_new_opts6(g_ctrlmf_ws.nopoll_ctx, opts, "::", port); - #else - state.nopoll_conn = nopoll_listener_new_opts6(g_ctrlmf_ws.nopoll_ctx, opts, "::", port); - #endif + if(cert_valid) { + state.nopoll_conn = nopoll_listener_tls_new_opts6(g_ctrlmf_ws.nopoll_ctx, opts, "::", port); + } else { + state.nopoll_conn = nopoll_listener_new_opts6(g_ctrlmf_ws.nopoll_ctx, opts, "::", port); + } if(!nopoll_conn_is_ok(state.nopoll_conn)) { XLOGD_ERROR("Listener connection IPv6 NOT ok"); nopoll_ctx_unref(g_ctrlmf_ws.nopoll_ctx); @@ -234,6 +242,10 @@ void *ctrlmf_ws_main(void *param) { return(NULL); } + if(params.has_valid_cert != NULL) { + *(params.has_valid_cert) = cert_valid; + } + // Unblock the caller that launched this thread sem_post(params.semaphore); params.semaphore = NULL; @@ -247,12 +259,12 @@ void *ctrlmf_ws_main(void *param) { nopoll_ctx_unref(g_ctrlmf_ws.nopoll_ctx); g_ctrlmf_ws.nopoll_ctx = NULL; - #ifdef CTRLMF_WSS_ENABLED - if(0 != unlink(tmp_cert)) { - int err_store = errno; - XLOGD_ERROR("failed to remove temp cert <%s>", strerror(err_store)); + if(cert_valid) { + if(0 != unlink(tmp_cert)) { + int err_store = errno; + XLOGD_ERROR("failed to remove temp cert <%s>", strerror(err_store)); + } } - #endif return(NULL); } @@ -372,9 +384,9 @@ void ctrlmf_ws_on_close(noPollCtx *ctx, noPollConn *conn, noPollPtr user_data) { #ifdef CTRLMF_WSS_ENABLED bool ctrlmf_ws_cert_config(FILE* cert_key_fp) { - bool ret = false; - ctrlm_fta_platform_cert_info_t *cert_info = NULL; + + rdkcertselector_h cert_selector = NULL; do { FILE *device_cert_fp = NULL; PKCS12 *p12_cert = NULL; @@ -382,18 +394,33 @@ bool ctrlmf_ws_cert_config(FILE* cert_key_fp) { X509 *x509_cert = NULL; STACK_OF(X509) *additional_certs = NULL; - cert_info = ctrlm_fta_platform_cert_info_get(false); - if(cert_info == NULL) { - XLOGD_ERROR("unable to get certificate info"); + char *cert_path = NULL; + char *cert_password = NULL; + cert_selector = rdkcertselector_new(NULL, NULL, "FBK_MTLS"); + + if(cert_selector == NULL){ + XLOGD_TELEMETRY("cert selector init failed"); break; } - if(cert_info->type != CTRLM_FTA_PLATFORM_VOICE_CERT_TYPE_P12) { - XLOGD_ERROR("unable to parse certificates that are not of PKCS12 type"); + rdkcertselectorStatus_t cert_status = rdkcertselector_getCert(cert_selector, &cert_path, &cert_password); + + if(cert_status != certselectorOk) { + XLOGD_TELEMETRY("cert selector retrieval failed"); + break; + } + + if(cert_path == NULL || cert_password == NULL) { + XLOGD_TELEMETRY("cert selector get failed"); break; } - device_cert_fp = fopen(cert_info->filename, "rb"); + char *local_path = cert_path; + if(strncmp(local_path, CTRLMF_CERT_FILENAME_PREFIX, strlen(CTRLMF_CERT_FILENAME_PREFIX)) == 0) { + local_path += strlen(CTRLMF_CERT_FILENAME_PREFIX); + } + + device_cert_fp = fopen(local_path, "rb"); if(device_cert_fp == NULL) { XLOGD_ERROR("unable to open P12 certificate"); break; @@ -408,7 +435,7 @@ bool ctrlmf_ws_cert_config(FILE* cert_key_fp) { break; } - if(1 != PKCS12_parse(p12_cert, cert_info->password, &pkey, &x509_cert, &additional_certs)) { + if(1 != PKCS12_parse(p12_cert, cert_password, &pkey, &x509_cert, &additional_certs)) { XLOGD_ERROR("unable to parse P12 certificate"); break; } @@ -423,7 +450,7 @@ bool ctrlmf_ws_cert_config(FILE* cert_key_fp) { break; } - if(1 != PEM_write_PrivateKey(cert_key_fp, pkey, NULL, (unsigned char*)cert_info->password, strlen(cert_info->password), NULL, NULL)) { + if(1 != PEM_write_PrivateKey(cert_key_fp, pkey, NULL, (unsigned char*)cert_password, strlen(cert_password), NULL, NULL)) { XLOGD_ERROR("failed to write temp key"); break; } @@ -431,8 +458,8 @@ bool ctrlmf_ws_cert_config(FILE* cert_key_fp) { ret = true; }while(0); - if(cert_info != NULL) { - ctrlm_fta_platform_cert_info_free(cert_info); + if(cert_selector != NULL) { + rdkcertselector_free(&cert_selector); } return ret; diff --git a/src/factory/ctrlmf_ws.h b/src/factory/ctrlmf_ws.h index f68490e3..203a2ac2 100644 --- a/src/factory/ctrlmf_ws.h +++ b/src/factory/ctrlmf_ws.h @@ -35,7 +35,7 @@ typedef struct { extern "C" { #endif -bool ctrlmf_ws_init(uint32_t audio_frame_size, uint16_t port, bool log_enable, ctrlmf_ws_callbacks_t *callbacks); +bool ctrlmf_ws_init(uint32_t audio_frame_size, uint16_t port, bool log_enable, ctrlmf_ws_callbacks_t *callbacks, bool *has_valid_cert); bool ctrlmf_ws_capture_set(ctrlmf_audio_frame_t audio_frames, uint32_t audio_frame_qty); void ctrlmf_ws_term(void); From f7ef989dd14c2690d7ef32ca22be6956dfe13074 Mon Sep 17 00:00:00 2001 From: Gene Gallagher <129112619+egalla204@users.noreply.github.com> Date: Tue, 9 Dec 2025 09:01:05 -0500 Subject: [PATCH 18/39] RDKEMW-11283: add product description docs (#159) --- PRODUCT.md | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 PRODUCT.md diff --git a/PRODUCT.md b/PRODUCT.md new file mode 100644 index 00000000..0279a77b --- /dev/null +++ b/PRODUCT.md @@ -0,0 +1,64 @@ +# rdkcentral/control Product Functionality + +This document summarizes the core product features, capabilities, and user-facing functionality provided by the `rdkcentral/control` project. + +## 1. Product Overview + +`rdkcentral/control` provides the central control and management solution for RDK-based devices, focusing on remote control integration, device state management, configuration handling, and hardware abstraction. It enables flexible, reliable control of device functions, typically in set-top boxes and smart TV platforms. + +## 2. Key Functional Areas + +### 2.1 Remote Control Manager + +- **Multi-protocol Support:** Integrates with RF4CE and BLE-based remote controls, supporting automatic pairing and discovery of devices. +- **Key Mapping & Input:** Manages IR, RF, and BLE key events, including vendor-specific key mappings (e.g., for AMC App). +- **Telemetry & Logging:** Captures and processes telemetry data from voice streams, key events, and audio sessions for diagnostics and monitoring. +- **OTA & Firmware Management:** Handles remote control firmware updates and network discovery, with stability features when interrupted (e.g., OTA interrupted by reset). + +### 2.2 Device State & Power Management + +- **Deep Sleep & Wake Handling:** Responds to device state changes, ensuring proper initialization/timer handling during deep sleep or wake events. +- **Power Plugin Integration:** Uses RDK's Power Manager Thunder plugin for system power state management and interaction. + +### 2.3 Configuration Management + +- **Dynamic Configuration:** Reads, updates, and applies runtime configuration changes from files, including support for vendor override files. +- **Device Discovery:** Provides mechanisms to discover IR input devices, support for multiple device types and fallback/stub implementations if hardware is absent. +- **HAL Abstraction:** Exposes interfaces to control hardware-specific features via C++ classes (see `ctrlm_hal.h`, `ctrlm_hal_rf4ce.h`, `ctrlm_hal_ble.h`). + +### 2.4 Audio & Voice Control + +- **Voice Session Management:** Supports BLE/RF voice streaming; logs sessions; manages session state, end times, and error reporting. +- **Audio Stream Management:** Reports and optimizes audio pipe size; ensures reliable audio sample reporting for voice sessions. + +### 2.5 API & Service Integration + +- **Thunder & HDMI Plugins:** Integrates with plugin frameworks to extend support for HDMI input, AV input, MAC address fetch, and advanced service bridging. +- **ASB Detection:** Offers runtime detection for Advanced Service Bridge capabilities. + +## 3. Product Extensibility + +- **Vendor Layer Integration:** Provides hooks for vendor-specific features, such as configuration overrides and device database stubs. +- **Flexible Build & Runtime Flags:** Build flags allow enabling/disabling features (e.g., BLE audio, packet analysis, deepsleep, memory lock). +- **Plugin & Target Customization:** Can build custom targets (e.g., just the control config file). + +## 4. Typical Use Cases + +- **User Experience:** Enables seamless remote pairing and input handling, responsive device wake/sleep, and dynamic feature provisioning. +- **Monitoring/Diagnostics:** Logs device events and telemetry, aiding both advanced diagnostics and data-driven product improvement. +- **Integration Point:** Forms the backbone for device control in RDK deployments where remote management and hardware abstraction are required. + +## 5. Recent Product Updates (Selected Highlights) + +- Multi-protocol remote integration (BLE and RF4CE support). +- Overhaul of key mapping and vendor integration logic. +- Telemetry improvements for voice stream analytics. +- Refactoring to enhance HAL interface extensibility. +- Crash and stability fixes for deep sleep, rapid input, and device discovery. +- Improved runtime configuration and plugin extensibility. + +_For full release notes, please see the [CHANGELOG](https://github.com/rdkcentral/control/blob/develop/CHANGELOG.md)._ + +## 6. Summary + +`rdkcentral/control` delivers a comprehensive control and management solution for RDK devices, emphasizing extensibility, reliability, and integration with modern remote protocols and power management frameworks. It remains the canonical product for remote control, device state, and configuration management within the RDK platform. From 3ab9e9275912dd8e609a3bb6a2867176f8c37319 Mon Sep 17 00:00:00 2001 From: Kelvin Lu <119349872+klu339@users.noreply.github.com> Date: Tue, 16 Dec 2025 12:00:56 -0500 Subject: [PATCH 19/39] RDKEMW-8929: Refactor base ipc class (#162) * RDKEMW-8929: Refactor base ipc class Reason for change: Test Procedure: Risks: Signed-off-by: Kelvin Lu * Updating based on Copilot review comments --------- Signed-off-by: Kelvin Lu --- include/ctrlm_ipc_voice.h | 8 +- src/ipc/ctrlm_ipc_iarm.cpp | 53 ++++-------- src/ipc/ctrlm_ipc_iarm.h | 52 +++++++++++- src/ipc/ctrlm_rcp_ipc_iarm_thunder.cpp | 9 +- src/voice/ipc/ctrlm_voice_ipc.h | 5 +- src/voice/ipc/ctrlm_voice_ipc_iarm_legacy.cpp | 23 ++--- .../ipc/ctrlm_voice_ipc_iarm_thunder.cpp | 85 ++++--------------- 7 files changed, 98 insertions(+), 137 deletions(-) diff --git a/include/ctrlm_ipc_voice.h b/include/ctrlm_ipc_voice.h index d5a58bc0..270b92d9 100644 --- a/include/ctrlm_ipc_voice.h +++ b/include/ctrlm_ipc_voice.h @@ -304,11 +304,11 @@ typedef struct { // IARM Event JSON // This structure is used for the following calls: -// CTRLM_VOICE_IARM_EVENT_SESSION_BEGIN_JSON -// CTRLM_VOICE_IARM_EVENT_STREAM_BEGIN_JSON +// CTRLM_VOICE_IARM_EVENT_SESSION_BEGIN_JSON +// CTRLM_VOICE_IARM_EVENT_STREAM_BEGIN_JSON // CTRLM_VOICE_IARM_EVENT_SERVER_MESSAGE_JSON -// CTRLM_VOICE_IARM_EVENT_STREAM_END_JSON -// CTRLM_VOICE_IARM_EVENT_SESSION_END_JSON +// CTRLM_VOICE_IARM_EVENT_STREAM_END_JSON +// CTRLM_VOICE_IARM_EVENT_SESSION_END_JSON // // The payload MUST be a NULL terminated JSON String. typedef struct { diff --git a/src/ipc/ctrlm_ipc_iarm.cpp b/src/ipc/ctrlm_ipc_iarm.cpp index b8d16842..420b44ce 100644 --- a/src/ipc/ctrlm_ipc_iarm.cpp +++ b/src/ipc/ctrlm_ipc_iarm.cpp @@ -20,6 +20,15 @@ #include "ctrlm_ipc_iarm.h" #include "ctrlm.h" #include "ctrlm_log.h" +#include "ctrlm_ipc_voice.h" + +void ctrlm_ipc_iarm_t::set_api_revision(unsigned char api_revision) { + api_revision_ = api_revision; +} + +unsigned char ctrlm_ipc_iarm_t::get_api_revision(void) const { + return api_revision_; +} bool ctrlm_ipc_iarm_t::register_iarm_call(const char *call, IARM_BusCall_t handler) const { @@ -35,44 +44,12 @@ bool ctrlm_ipc_iarm_t::register_iarm_call(const char *call, IARM_BusCall_t handl return(ret); } -bool ctrlm_ipc_iarm_t::broadcast_iarm_event(const char *bus_name, int event, json_t* event_data) const -{ - bool ret = false; - if(!event_data) { - return(ret); - } - - char *payload_str = json_dumps(event_data, JSON_COMPACT); - - if(payload_str != NULL) { - size_t str_size = strlen(payload_str) + 1; - size_t size = sizeof(ctrlm_main_iarm_event_json_t) + str_size; - - ctrlm_main_iarm_event_json_t *data = (ctrlm_main_iarm_event_json_t *)calloc(1, size); - if (data == NULL) { - XLOGD_ERROR("failed to allocate memory for the IARM event, so cannot broadcast...."); - } else { - - data->api_revision = CTRLM_MAIN_IARM_BUS_API_REVISION; - //Can't be replaced with safeC version of this, as safeC string functions doesn't allow string size more than 4K - snprintf(data->payload, str_size, "%s", payload_str); - - IARM_Result_t res = IARM_Bus_BroadcastEvent(bus_name, event, data, size); - if(res != IARM_RESULT_SUCCESS) { - XLOGD_ERROR("IARM Bus Error %d", res); - } else { - ret = true; - } - - free(data); - } - - free(payload_str); - } - - if(event_data) { - json_decref(event_data); +bool ctrlm_ipc_iarm_t::broadcast_iarm_event_legacy(const char *bus_name, int event, void *data, size_t data_size) const { + bool ret = true; + IARM_Result_t result = IARM_Bus_BroadcastEvent(bus_name, event, data, data_size); + if(IARM_RESULT_SUCCESS != result) { + XLOGD_ERROR("IARM Bus Error!"); + ret = false; } - return(ret); } diff --git a/src/ipc/ctrlm_ipc_iarm.h b/src/ipc/ctrlm_ipc_iarm.h index c966c080..51e487b5 100644 --- a/src/ipc/ctrlm_ipc_iarm.h +++ b/src/ipc/ctrlm_ipc_iarm.h @@ -26,6 +26,9 @@ #include class ctrlm_ipc_iarm_t { +private: + unsigned char api_revision_ = 0; + public: ctrlm_ipc_iarm_t() {}; virtual ~ctrlm_ipc_iarm_t() {}; @@ -38,8 +41,55 @@ class ctrlm_ipc_iarm_t { static void turn_on(std::atomic_bool &abool) { abool.store(true); } static void turn_off(std::atomic_bool &abool) { abool.store(false); } + void set_api_revision(unsigned char api_revision); + unsigned char get_api_revision(void) const; + bool register_iarm_call(const char *call, IARM_BusCall_t handler) const; - bool broadcast_iarm_event(const char *bus_name, int event, json_t* event_data) const; + bool broadcast_iarm_event_legacy(const char *bus_name, int event, void *data, size_t data_size) const; + + template + bool broadcast_iarm_event(const char *bus_name, int event, json_t* event_data) const + { + bool ret = false; + if(!event_data) { + return(ret); + } + + char *payload_str = json_dumps(event_data, JSON_COMPACT); + + if(payload_str != NULL) { + ret = broadcast_iarm_event(bus_name, event, payload_str); + free(payload_str); + } + + if(event_data) { + json_decref(event_data); + } + + return(ret); + } + + template + bool broadcast_iarm_event(const char *bus_name, int event, const char *str) const + { + bool ret = false; + size_t str_size = strlen(str) + 1; + size_t size = sizeof(T) + str_size; + + T *data = (T *)calloc(1, size); + if (data != nullptr) { + data->api_revision = api_revision_; + //Can't be replaced with safeC version of this, as safeC string functions doesn't allow string size more than 4K + snprintf(data->payload, str_size, "%s", str); + + IARM_Result_t res = IARM_Bus_BroadcastEvent(bus_name, event, data, size); + if(res == IARM_RESULT_SUCCESS) { + ret = true; + } + free(data); + } + return(ret); + } }; #endif diff --git a/src/ipc/ctrlm_rcp_ipc_iarm_thunder.cpp b/src/ipc/ctrlm_rcp_ipc_iarm_thunder.cpp index 02f4128d..88d2a38f 100644 --- a/src/ipc/ctrlm_rcp_ipc_iarm_thunder.cpp +++ b/src/ipc/ctrlm_rcp_ipc_iarm_thunder.cpp @@ -36,6 +36,7 @@ ctrlm_rcp_ipc_iarm_thunder_t::ctrlm_rcp_ipc_iarm_thunder_t() : ctrlm_ipc_iarm_t( { XLOGD_INFO(""); configure(); + set_api_revision(CTRLM_MAIN_IARM_BUS_API_REVISION); } ctrlm_rcp_ipc_iarm_thunder_t::~ctrlm_rcp_ipc_iarm_thunder_t() @@ -125,7 +126,7 @@ bool ctrlm_rcp_ipc_iarm_thunder_t::on_status(const ctrlm_rcp_ipc_net_status_t &n return(false); } - return broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_RCU_IARM_EVENT_RCU_STATUS, ret); + return broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_RCU_IARM_EVENT_RCU_STATUS, ret); } bool ctrlm_rcp_ipc_iarm_thunder_t::on_validation_status(const ctrlm_rcp_ipc_validation_status_t &validation_status) const @@ -151,7 +152,7 @@ bool ctrlm_rcp_ipc_iarm_thunder_t::on_validation_status(const ctrlm_rcp_ipc_vali return(false); } - return broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_RCU_IARM_EVENT_VALIDATION_STATUS, ret); + return broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_RCU_IARM_EVENT_VALIDATION_STATUS, ret); } bool ctrlm_rcp_ipc_iarm_thunder_t::on_firmware_update_progress(const ctrlm_rcp_ipc_upgrade_status_t &upgrade_status) const @@ -177,7 +178,7 @@ bool ctrlm_rcp_ipc_iarm_thunder_t::on_firmware_update_progress(const ctrlm_rcp_i return(false); } - return broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_RCU_IARM_EVENT_FIRMWARE_UPDATE_PROGRESS, ret); + return broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_RCU_IARM_EVENT_FIRMWARE_UPDATE_PROGRESS, ret); } bool ctrlm_rcp_ipc_iarm_thunder_t::on_validation(const ctrlm_rcp_ipc_validation_status_t &validation_status) const @@ -198,7 +199,7 @@ bool ctrlm_rcp_ipc_iarm_thunder_t::on_validation(const ctrlm_rcp_ipc_validation_ return(false); } - return broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_RCU_IARM_EVENT_VALIDATION_STATUS, ret); + return broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_RCU_IARM_EVENT_VALIDATION_STATUS, ret); } IARM_Result_t ctrlm_rcp_ipc_iarm_thunder_t::start_pairing(void *arg) diff --git a/src/voice/ipc/ctrlm_voice_ipc.h b/src/voice/ipc/ctrlm_voice_ipc.h index 25197ff8..969a8380 100644 --- a/src/voice/ipc/ctrlm_voice_ipc.h +++ b/src/voice/ipc/ctrlm_voice_ipc.h @@ -22,6 +22,7 @@ #include "ctrlm.h" #include "ctrlm_voice_types.h" #include "ctrlm_ipc_voice.h" +#include "ctrlm_ipc_iarm.h" // Classes for eventing @@ -171,7 +172,7 @@ class ctrlm_voice_ipc_event_session_statistics_t { }; // End classes for eventing -class ctrlm_voice_ipc_t { +class ctrlm_voice_ipc_t : public ctrlm_ipc_iarm_t { public: ctrlm_voice_ipc_t(ctrlm_voice_t *obj_voice) { this->obj_voice = obj_voice; @@ -179,7 +180,6 @@ class ctrlm_voice_ipc_t { virtual ~ctrlm_voice_ipc_t() {}; // Interface - virtual bool register_ipc() const = 0; virtual bool session_begin(const ctrlm_voice_ipc_event_session_begin_t &session_begin) = 0; virtual bool stream_begin(const ctrlm_voice_ipc_event_stream_begin_t &stream_begin) = 0; virtual bool stream_end(const ctrlm_voice_ipc_event_stream_end_t &stream_end) = 0; @@ -187,7 +187,6 @@ class ctrlm_voice_ipc_t { virtual bool server_message(const char *message, unsigned long size) = 0; // Pass a pointer to the message to avoid copying possible large chunks of data virtual bool keyword_verification(const ctrlm_voice_ipc_event_keyword_verification_t &keyword_verification) = 0; virtual bool session_statistics(const ctrlm_voice_ipc_event_session_statistics_t &session_stats) = 0; - virtual void deregister_ipc() const = 0; // End Interface protected: diff --git a/src/voice/ipc/ctrlm_voice_ipc_iarm_legacy.cpp b/src/voice/ipc/ctrlm_voice_ipc_iarm_legacy.cpp index c07f22b1..6564ef4c 100644 --- a/src/voice/ipc/ctrlm_voice_ipc_iarm_legacy.cpp +++ b/src/voice/ipc/ctrlm_voice_ipc_iarm_legacy.cpp @@ -23,7 +23,6 @@ #include "ctrlm_voice_obj.h" static IARM_Result_t update_settings(void *arg); -static bool broadcast_event(const char *bus_name, int event, void *data, size_t data_size); ctrlm_voice_ipc_iarm_legacy_t::ctrlm_voice_ipc_iarm_legacy_t(ctrlm_voice_t *obj_voice) : ctrlm_voice_ipc_t(obj_voice) { this->state = EVENT_ALL; @@ -68,7 +67,7 @@ bool ctrlm_voice_ipc_iarm_legacy_t::session_begin(const ctrlm_voice_ipc_event_se safec_rc = strcpy_s((char *)event.language, sizeof(event.language), session_begin.language.c_str()); ERR_CHK(safec_rc); event.is_voice_assistant = session_begin.common.voice_assistant ? 1 : 0; - ret = broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_SESSION_BEGIN, &event, sizeof(event)); + ret = broadcast_iarm_event_legacy(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_SESSION_BEGIN, &event, sizeof(event)); } return(ret); } @@ -90,7 +89,7 @@ bool ctrlm_voice_ipc_iarm_legacy_t::stream_end(const ctrlm_voice_ipc_event_strea event.session_id = stream_end.common.session_id_ctrlm; event.reason = (ctrlm_voice_session_end_reason_t)stream_end.reason; event.is_voice_assistant = stream_end.common.voice_assistant ? 1 : 0; - ret = broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_SESSION_END, &event, sizeof(event)); + ret = broadcast_iarm_event_legacy(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_SESSION_END, &event, sizeof(event)); } return(ret); } @@ -133,7 +132,7 @@ bool ctrlm_voice_ipc_iarm_legacy_t::session_end(const ctrlm_voice_ipc_event_sess event.curl_request_dns_time = session_end.server_stats->dns_time; event.curl_request_connect_time = session_end.server_stats->connect_time; } - ret = broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_SESSION_RESULT, &event, sizeof(event)); + ret = broadcast_iarm_event_legacy(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_SESSION_RESULT, &event, sizeof(event)); break; } case SESSION_END_ABORT: { @@ -144,7 +143,7 @@ bool ctrlm_voice_ipc_iarm_legacy_t::session_end(const ctrlm_voice_ipc_event_sess event.controller_id = session_end.common.controller_id; event.session_id = session_end.common.session_id_ctrlm; event.reason = (ctrlm_voice_session_abort_reason_t)session_end.reason; - ret = broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_SESSION_ABORT, &event, sizeof(event)); + ret = broadcast_iarm_event_legacy(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_SESSION_ABORT, &event, sizeof(event)); break; } case SESSION_END_SHORT_UTTERANCE: { @@ -156,7 +155,7 @@ bool ctrlm_voice_ipc_iarm_legacy_t::session_end(const ctrlm_voice_ipc_event_sess event.session_id = session_end.common.session_id_ctrlm; event.reason = (ctrlm_voice_session_end_reason_t)session_end.reason; event.return_code_internal = session_end.return_code_internal; - ret = broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_SESSION_SHORT, &event, sizeof(event)); + ret = broadcast_iarm_event_legacy(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_SESSION_SHORT, &event, sizeof(event)); break; } } @@ -195,7 +194,7 @@ bool ctrlm_voice_ipc_iarm_legacy_t::session_statistics(const ctrlm_voice_ipc_eve event.session_id = session_stats.common.session_id_ctrlm; event.session = session_stats.session; event.reboot = session_stats.reboot; - return(broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_SESSION_STATS, &event, sizeof(event))); + return(broadcast_iarm_event_legacy(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_SESSION_STATS, &event, sizeof(event))); } void ctrlm_voice_ipc_iarm_legacy_t::deregister_ipc() const { @@ -230,13 +229,3 @@ IARM_Result_t update_settings(void *arg) { return(IARM_RESULT_SUCCESS); } - -bool broadcast_event(const char *bus_name, int event, void *data, size_t data_size) { - bool ret = true; - IARM_Result_t result = IARM_Bus_BroadcastEvent(bus_name, event, data, data_size); - if(IARM_RESULT_SUCCESS != result) { - XLOGD_ERROR("IARM Bus Error!"); - ret = false; - } - return(ret); -} diff --git a/src/voice/ipc/ctrlm_voice_ipc_iarm_thunder.cpp b/src/voice/ipc/ctrlm_voice_ipc_iarm_thunder.cpp index 02b4408e..6b407173 100644 --- a/src/voice/ipc/ctrlm_voice_ipc_iarm_thunder.cpp +++ b/src/voice/ipc/ctrlm_voice_ipc_iarm_thunder.cpp @@ -83,73 +83,47 @@ #define JSON_SESSION_END_SERVER_STATS_DNS_TIME "dnsTime" #define JSON_SESSION_END_SERVER_STATS_CONNECT_TIME "connectTime" -static bool broadcast_event(const char *bus_name, int event, const char *str); static const char *voice_device_str(ctrlm_voice_device_t device); static const char *voice_device_status_str(uint8_t status); ctrlm_voice_ipc_iarm_thunder_t::ctrlm_voice_ipc_iarm_thunder_t(ctrlm_voice_t *obj_voice): ctrlm_voice_ipc_t(obj_voice) { - + set_api_revision(CTRLM_VOICE_IARM_BUS_API_REVISION); } bool ctrlm_voice_ipc_iarm_thunder_t::register_ipc() const { bool ret = true; - IARM_Result_t rc; XLOGD_INFO("Thunder"); // NOTE: The IARM events are registered in ctrlm_main.cpp - XLOGD_INFO("Registering for %s IARM call", CTRLM_VOICE_IARM_CALL_STATUS); - rc = IARM_Bus_RegisterCall(CTRLM_VOICE_IARM_CALL_STATUS, &ctrlm_voice_ipc_iarm_thunder_t::status); - if(rc != IARM_RESULT_SUCCESS) { - XLOGD_ERROR("Failed to register %d", rc); + if(!register_iarm_call(CTRLM_VOICE_IARM_CALL_STATUS, &ctrlm_voice_ipc_iarm_thunder_t::status)) { ret = false; } - XLOGD_INFO("Registering for %s IARM call", CTRLM_VOICE_IARM_CALL_CONFIGURE_VOICE); - rc = IARM_Bus_RegisterCall(CTRLM_VOICE_IARM_CALL_CONFIGURE_VOICE, &ctrlm_voice_ipc_iarm_thunder_t::configure_voice); - if(rc != IARM_RESULT_SUCCESS) { - XLOGD_ERROR("Failed to register %d", rc); + if(!register_iarm_call(CTRLM_VOICE_IARM_CALL_CONFIGURE_VOICE, &ctrlm_voice_ipc_iarm_thunder_t::configure_voice)) { ret = false; } - XLOGD_INFO("Registering for %s IARM call", CTRLM_VOICE_IARM_CALL_SET_VOICE_INIT); - rc = IARM_Bus_RegisterCall(CTRLM_VOICE_IARM_CALL_SET_VOICE_INIT, &ctrlm_voice_ipc_iarm_thunder_t::set_voice_init); - if(rc != IARM_RESULT_SUCCESS) { - XLOGD_ERROR("Failed to register %d", rc); + if(!register_iarm_call(CTRLM_VOICE_IARM_CALL_SET_VOICE_INIT, &ctrlm_voice_ipc_iarm_thunder_t::set_voice_init)) { ret = false; } - XLOGD_INFO("Registering for %s IARM call", CTRLM_VOICE_IARM_CALL_SEND_VOICE_MESSAGE); - rc = IARM_Bus_RegisterCall(CTRLM_VOICE_IARM_CALL_SEND_VOICE_MESSAGE, &ctrlm_voice_ipc_iarm_thunder_t::send_voice_message); - if(rc != IARM_RESULT_SUCCESS) { - XLOGD_ERROR("Failed to register %d", rc); + if(!register_iarm_call(CTRLM_VOICE_IARM_CALL_SEND_VOICE_MESSAGE, &ctrlm_voice_ipc_iarm_thunder_t::send_voice_message)) { ret = false; } - XLOGD_INFO("Registering for %s IARM call", CTRLM_VOICE_IARM_CALL_SESSION_TYPES); - rc = IARM_Bus_RegisterCall(CTRLM_VOICE_IARM_CALL_SESSION_TYPES, &ctrlm_voice_ipc_iarm_thunder_t::voice_session_types); - if(rc != IARM_RESULT_SUCCESS) { - XLOGD_ERROR("Failed to register %d", rc); + if(!register_iarm_call(CTRLM_VOICE_IARM_CALL_SESSION_TYPES, &ctrlm_voice_ipc_iarm_thunder_t::voice_session_types)) { ret = false; } - XLOGD_INFO("Registering for %s IARM call", CTRLM_VOICE_IARM_CALL_SESSION_REQUEST); - rc = IARM_Bus_RegisterCall(CTRLM_VOICE_IARM_CALL_SESSION_REQUEST, &ctrlm_voice_ipc_iarm_thunder_t::voice_session_request); - if(rc != IARM_RESULT_SUCCESS) { - XLOGD_ERROR("Failed to register %d", rc); + if(!register_iarm_call(CTRLM_VOICE_IARM_CALL_SESSION_REQUEST, &ctrlm_voice_ipc_iarm_thunder_t::voice_session_request)) { ret = false; } - XLOGD_INFO("Registering for %s IARM call", CTRLM_VOICE_IARM_CALL_SESSION_TERMINATE); - rc = IARM_Bus_RegisterCall(CTRLM_VOICE_IARM_CALL_SESSION_TERMINATE, &ctrlm_voice_ipc_iarm_thunder_t::voice_session_terminate); - if(rc != IARM_RESULT_SUCCESS) { - XLOGD_ERROR("Failed to register %d", rc); + if(!register_iarm_call(CTRLM_VOICE_IARM_CALL_SESSION_TERMINATE, &ctrlm_voice_ipc_iarm_thunder_t::voice_session_terminate)) { ret = false; } - XLOGD_INFO("Registering for %s IARM call", CTRLM_VOICE_IARM_CALL_SESSION_AUDIO_STREAM_START); - rc = IARM_Bus_RegisterCall(CTRLM_VOICE_IARM_CALL_SESSION_AUDIO_STREAM_START, &ctrlm_voice_ipc_iarm_thunder_t::voice_session_audio_stream_start); - if(rc != IARM_RESULT_SUCCESS) { - XLOGD_ERROR("Failed to register %d", rc); + if(!register_iarm_call(CTRLM_VOICE_IARM_CALL_SESSION_AUDIO_STREAM_START, &ctrlm_voice_ipc_iarm_thunder_t::voice_session_audio_stream_start)) { ret = false; } @@ -175,7 +149,7 @@ bool ctrlm_voice_ipc_iarm_thunder_t::session_begin(const ctrlm_voice_ipc_event_s if(json_str) { //TODO: surface the event through IARM XLOGD_INFO("%s", json_str); - ret = broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_JSON_SESSION_BEGIN, json_str); + ret = broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_JSON_SESSION_BEGIN, json_str); free(json_str); } else { XLOGD_ERROR("Failed to encode JSON string"); @@ -204,7 +178,7 @@ bool ctrlm_voice_ipc_iarm_thunder_t::stream_begin(const ctrlm_voice_ipc_event_st if(json_str) { //TODO: surface the event through IARM XLOGD_INFO("%s", json_str); - ret = broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_JSON_STREAM_BEGIN, json_str); + ret = broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_JSON_STREAM_BEGIN, json_str); free(json_str); } else { XLOGD_ERROR("Failed to encode JSON string"); @@ -234,7 +208,7 @@ bool ctrlm_voice_ipc_iarm_thunder_t::stream_end(const ctrlm_voice_ipc_event_stre if(json_str) { //TODO: surface the event through IARM XLOGD_INFO("%s", json_str); - ret = broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_JSON_STREAM_END, json_str); + ret = broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_JSON_STREAM_END, json_str); free(json_str); } else { XLOGD_ERROR("Failed to encode JSON string"); @@ -358,7 +332,7 @@ bool ctrlm_voice_ipc_iarm_thunder_t::session_end(const ctrlm_voice_ipc_event_ses if(json_str) { //TODO: surface the event through IARM XLOGD_AUTOMATION_INFO("<%s>", this->obj_voice->voice_stb_data_pii_mask_get() ? "***" : json_str); - ret = broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_JSON_SESSION_END, json_str); + ret = broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_JSON_SESSION_END, json_str); free(json_str); } else { XLOGD_ERROR("Failed to encode JSON string"); @@ -374,7 +348,7 @@ bool ctrlm_voice_ipc_iarm_thunder_t::server_message(const char *message, unsigne bool ret = false; if(message) { XLOGD_AUTOMATION_INFO("%ul : <%s>", size, this->obj_voice->voice_stb_data_pii_mask_get() ? "***" : message); //CID -160950 - Printargs - ret = broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_JSON_SERVER_MESSAGE, message); + ret = broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_JSON_SERVER_MESSAGE, message); } return(ret); } @@ -397,7 +371,7 @@ bool ctrlm_voice_ipc_iarm_thunder_t::keyword_verification(const ctrlm_voice_ipc_ if(json_str) { //TODO: surface the event through IARM XLOGD_INFO("%s", json_str); - ret = broadcast_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_JSON_KEYWORD_VERIFICATION, json_str); + ret = broadcast_iarm_event(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_VOICE_IARM_EVENT_JSON_KEYWORD_VERIFICATION, json_str); free(json_str); } else { XLOGD_ERROR("Failed to encode JSON string"); @@ -981,35 +955,6 @@ const char *voice_device_status_str(uint8_t status) { return("invalid"); } -bool broadcast_event(const char *bus_name, int event, const char *str) { - bool ret = false; - size_t str_size = strlen(str) + 1; - size_t size = sizeof(ctrlm_voice_iarm_event_json_t) + str_size; - ctrlm_voice_iarm_event_json_t *data = (ctrlm_voice_iarm_event_json_t *)malloc(size); - if(data) { - IARM_Result_t result; - - //Can't be replaced with safeC version of this - memset(data, 0, size); - - data->api_revision = CTRLM_VOICE_IARM_BUS_API_REVISION; - //Can't be replaced with safeC version of this, as safeC string functions doesn't allow string size more than 4K - snprintf(data->payload, str_size, "%s", str); - result = IARM_Bus_BroadcastEvent(bus_name, event, data, size); - if(IARM_RESULT_SUCCESS != result) { - XLOGD_ERROR("IARM Bus Error!"); - } else { - ret = true; - } - if(data) { - free(data); - } - } else { - XLOGD_ERROR("Failed to allocate data for IARM event"); - } - return(ret); -} - bool ctrlm_voice_ipc_request_supported_ptt_transcription(ctrlm_voice_ipc_request_config_t *config) { config->requires_transcription = true; config->requires_audio_file = false; From d66eb1d6ea15455c26069bd834d2fa23edd89bdb Mon Sep 17 00:00:00 2001 From: dwolaver <44593664+dwolaver@users.noreply.github.com> Date: Mon, 5 Jan 2026 15:23:30 -0500 Subject: [PATCH 20/39] RDKEMW-12151 : ctrlm release v1.1.8, xr-voice-sdk v1.0.9 (#166) --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd51fc43..18d43be6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [1.1.8](https://github.com/rdkcentral/control/compare/1.1.7...1.1.8) + +> 5 January 2026 + +- RDKEMW-8929: Refactor base ipc class [`#162`](https://github.com/rdkcentral/control/pull/162) +- RDKEMW-11283: add product description docs [`#159`](https://github.com/rdkcentral/control/pull/159) +- RDKEMW-8930 : remove ctrlm build flags - FACTORY_AUDIO_PLAYBACK [`#143`](https://github.com/rdkcentral/control/pull/143) + #### [1.1.7](https://github.com/rdkcentral/control/compare/1.1.6...1.1.7) > 4 December 2025 From e502de17994b8f1e9b7303171626d39e622665ec Mon Sep 17 00:00:00 2001 From: Kelvin Lu <119349872+klu339@users.noreply.github.com> Date: Mon, 12 Jan 2026 13:51:10 -0500 Subject: [PATCH 21/39] RDKEMW-11471: Remove netType param (#164) --- src/ble/ctrlm_ble_controller.cpp | 17 ++++ src/ble/ctrlm_ble_controller.h | 2 + src/ble/ctrlm_ble_network.cpp | 58 +++++++++----- src/ble/ctrlm_ble_network.h | 5 ++ src/ble/hal/blercu/blercucontroller.cpp | 2 +- src/ble/hal/blercu/blercucontroller_p.h | 4 +- src/ctrlm_controller.cpp | 17 ++++ src/ctrlm_controller.h | 1 + src/ctrlm_main.cpp | 5 -- src/ctrlm_network.cpp | 5 ++ src/ctrlm_network.h | 6 ++ src/ipc/ctrlm_rcp_ipc_event.cpp | 17 ++++ src/ipc/ctrlm_rcp_ipc_event.h | 25 +++--- src/ipc/ctrlm_rcp_ipc_iarm_thunder.cpp | 84 ++++++++++---------- src/irdb/ctrlm_irdb_interface.cpp | 68 ++++++++++++---- src/irdb/ctrlm_irdb_interface.h | 5 +- src/irdb/ipc/ctrlm_irdb_ipc_iarm_thunder.cpp | 18 +---- src/rf4ce/ctrlm_rf4ce_network.cpp | 27 +++++-- src/rf4ce/ctrlm_rf4ce_network.h | 4 + 19 files changed, 250 insertions(+), 120 deletions(-) diff --git a/src/ble/ctrlm_ble_controller.cpp b/src/ble/ctrlm_ble_controller.cpp index d86650db..fdbd155f 100644 --- a/src/ble/ctrlm_ble_controller.cpp +++ b/src/ble/ctrlm_ble_controller.cpp @@ -654,4 +654,21 @@ void ctrlm_obj_controller_ble_t::print_status() { XLOGD_WARN("------------------------------------------------------------"); } +void ctrlm_obj_controller_ble_t::update_controller_id_and_db_entry(std::string db_name, ctrlm_network_id_t network_id, ctrlm_controller_id_t new_id) { + ctrlm_obj_controller_t::update_controller_id_and_db_entry(db_name, network_id, new_id); + + std::stringstream new_controller_db_table; + new_controller_db_table << db_name << "_" << COUT_HEX_MODIFIER << (int)network_id << "_controller_" << COUT_HEX_MODIFIER << (int)new_id; + std::string new_table = new_controller_db_table.str(); + + product_name_->set_table(new_table); + serial_number_->set_table(new_table); + manufacturer_->set_table(new_table); + model_->set_table(new_table); + fw_revision_->set_table(new_table); + sw_revision_->set_table(new_table); + hw_revision_->set_table(new_table); + battery_percent_->set_table(new_table); +} + // End Function Implementations diff --git a/src/ble/ctrlm_ble_controller.h b/src/ble/ctrlm_ble_controller.h index 5179578c..432f5c76 100644 --- a/src/ble/ctrlm_ble_controller.h +++ b/src/ble/ctrlm_ble_controller.h @@ -147,6 +147,8 @@ class ctrlm_obj_controller_ble_t : public ctrlm_obj_controller_t { ctrlm_timestamp_t getVoiceStartTimeKey() const; ctrlm_timestamp_t getVoiceStartTimeLocal() const; + void update_controller_id_and_db_entry(std::string name, ctrlm_network_id_t network_id, ctrlm_controller_id_t new_id); + private: ctrlm_obj_network_ble_t *obj_network_ble_ = NULL; diff --git a/src/ble/ctrlm_ble_network.cpp b/src/ble/ctrlm_ble_network.cpp index 8965b71a..aff81aeb 100644 --- a/src/ble/ctrlm_ble_network.cpp +++ b/src/ble/ctrlm_ble_network.cpp @@ -779,13 +779,15 @@ void ctrlm_obj_network_ble_t::req_process_program_ir_codes(void *data, int size) g_assert(dqm); g_assert(size == sizeof(ctrlm_main_queue_msg_program_ir_codes_t)); - if(dqm->success) {*(dqm->success) = false;} + bool success = false; if (!ready_) { XLOGD_FATAL("Network is not ready!"); } else { ctrlm_controller_id_t controller_id = dqm->controller_id; - if (!controller_exists(controller_id)) { + if (!is_managed_by_network(controller_id)) { + XLOGD_ERROR("Controller %d is not managed by the %s network", controller_id, name_get()); + } else if (!controller_exists(controller_id)) { XLOGD_ERROR("Controller doesn't exist!"); } else if (!controllers_[controller_id]->isSupportedIrdb(dqm->vendor_info)) { XLOGD_ERROR("Unsupported IRDB - not continuing with ir code download!"); @@ -815,12 +817,10 @@ void ctrlm_obj_network_ble_t::req_process_program_ir_codes(void *data, int size) XLOGD_ERROR("failed to program IR signal waveforms on remote"); } else { - - if (dqm->success) { *(dqm->success) = true; } - - controllers_[controller_id]->irdb_entry_id_name_set(CTRLM_IRDB_DEV_TYPE_TV, ir_rf_database_.get_tv_ir_code_id()); - controllers_[controller_id]->irdb_entry_id_name_set(CTRLM_IRDB_DEV_TYPE_AVR, ir_rf_database_.get_avr_ir_code_id()); - XLOGD_INFO("irdb_entry_id_name = <%s>", dqm->ir_codes->id.c_str()); + success = true; + controllers_[controller_id]->irdb_entry_id_name_set(CTRLM_IRDB_DEV_TYPE_TV, ir_rf_database_.get_tv_ir_code_id()); + controllers_[controller_id]->irdb_entry_id_name_set(CTRLM_IRDB_DEV_TYPE_AVR, ir_rf_database_.get_avr_ir_code_id()); + XLOGD_INFO("irdb_entry_id_name = <%s>", dqm->ir_codes->id.c_str()); } } // Store the IR codes in the database @@ -828,6 +828,7 @@ void ctrlm_obj_network_ble_t::req_process_program_ir_codes(void *data, int size) } } } + if(dqm->success) {dqm->success->push_back(success);} if(dqm->semaphore) { sem_post(dqm->semaphore); } @@ -842,13 +843,15 @@ void ctrlm_obj_network_ble_t::req_process_ir_clear_codes(void *data, int size) { g_assert(dqm); g_assert(size == sizeof(ctrlm_main_queue_msg_ir_clear_t)); - if(dqm->success) {*(dqm->success) = false;} + bool success = false; if (!ready_) { XLOGD_FATAL("Network is not ready!"); } else { ctrlm_controller_id_t controller_id = dqm->controller_id; - if (!controller_exists(controller_id)) { + if (!is_managed_by_network(controller_id)) { + XLOGD_ERROR("Controller %d is not managed by the %s network", controller_id, name_get()); + } else if (!controller_exists(controller_id)) { XLOGD_ERROR("Controller doesn't exist!"); } else { @@ -856,9 +859,7 @@ void ctrlm_obj_network_ble_t::req_process_ir_clear_codes(void *data, int size) { if (!ble_rcu_interface_->eraseIrSignals(controllers_[controller_id]->ieee_address_get().get_value())) { XLOGD_ERROR("failed to erase IR signal waveforms on remote"); } else { - - if (dqm->success) { *(dqm->success) = true; } - + success = true; ir_rf_database_.clear_ir_codes(); XLOGD_INFO("\n%s", ir_rf_database_.to_string(true).c_str()); controllers_[controller_id]->irdb_entry_id_name_set(CTRLM_IRDB_DEV_TYPE_TV, "0"); @@ -868,6 +869,7 @@ void ctrlm_obj_network_ble_t::req_process_ir_clear_codes(void *data, int size) { ir_rf_database_.store_db(); } } + if(dqm->success) {dqm->success->push_back(success);} if(dqm->semaphore) { sem_post(dqm->semaphore); } @@ -973,7 +975,7 @@ void ctrlm_obj_network_ble_t::req_process_find_my_remote(void *data, int size) { ctrlm_controller_id_t controller_id = get_last_used_controller(); if (CTRLM_HAL_CONTROLLER_ID_INVALID == controller_id) { - XLOGD_ERROR("no connected controllers to find!!"); + XLOGD_ERROR("no connected %s controllers to find!!", name_get()); dqm->params->set_result(CTRLM_IARM_CALL_RESULT_ERROR, network_id_get()); } else { if (ble_rcu_interface_) { @@ -2440,7 +2442,7 @@ void ctrlm_obj_network_ble_t::controller_remove(ctrlm_controller_id_t controller ctrlm_controller_id_t ctrlm_obj_network_ble_t::controller_id_assign() { // Get the next available controller id - for(ctrlm_controller_id_t index = 1; index < CTRLM_MAIN_CONTROLLER_ID_ALL; index++) { + for(ctrlm_controller_id_t index = BLE_RCU_ID_RANGE_MIN; index < BLE_RCU_ID_RANGE_MAX; index++) { if(!controller_exists(index)) { XLOGD_INFO("controller id %u", index); return(index); @@ -2463,10 +2465,26 @@ void ctrlm_obj_network_ble_t::controllers_load() { XLOGD_WARN("deleting legacy IR controller object"); add_controller->db_destroy(); delete add_controller; - } else { - XLOGD_INFO("adding BLE controller with ID = 0x%X", id); - controllers_[id] = add_controller; + continue; } + if (!is_managed_by_network(id)) { + ctrlm_controller_id_t new_id = controller_id_assign(); + + add_controller->db_destroy(); // safely can destroy the old entry since it was loaded earlier + + if (new_id == 0) { + XLOGD_ERROR("Unable to assign a new ID - deleting controller <%d>", id); + delete add_controller; + continue; + } + + add_controller->update_controller_id_and_db_entry(db_name_get(), network_id_get(), new_id); + add_controller->db_create(); // create the new entry with its new ID + XLOGD_WARN("Legacy BLE RCU controller id <%d> found - updating controller id to <%d>", id, new_id); + id = new_id; + } + XLOGD_INFO("adding BLE controller with ID = 0x%X", id); + controllers_[id] = add_controller; } } @@ -2655,3 +2673,7 @@ void ctrlm_obj_network_ble_t::start_controller_audio_streaming(ctrlm_voice_start params->m_fd = fd; params->m_started = true; } + +bool ctrlm_obj_network_ble_t::is_managed_by_network(ctrlm_controller_id_t id) { + return (id >= BLE_RCU_ID_RANGE_MIN && id < BLE_RCU_ID_RANGE_MAX); +} diff --git a/src/ble/ctrlm_ble_network.h b/src/ble/ctrlm_ble_network.h index 787bb8b8..1182889a 100644 --- a/src/ble/ctrlm_ble_network.h +++ b/src/ble/ctrlm_ble_network.h @@ -41,6 +41,8 @@ // End Includes +#define BLE_RCU_ID_RANGE_MIN (NETWORK_ID_BASE_BLE) +#define BLE_RCU_ID_RANGE_MAX ((BLE_RCU_ID_RANGE_MIN)+BLE_MAX_MANAGED_RCUS+1) // +1 as a buffer for pairing typedef struct { ctrlm_main_queue_msg_header_t header; @@ -194,6 +196,9 @@ class ctrlm_obj_network_ble_t : public ctrlm_obj_network_t { virtual void start_controller_audio_streaming(ctrlm_voice_start_audio_params_t *params); +protected: + virtual bool is_managed_by_network(ctrlm_controller_id_t id); + private: ctrlm_obj_network_ble_t(); diff --git a/src/ble/hal/blercu/blercucontroller.cpp b/src/ble/hal/blercu/blercucontroller.cpp index 6ebfc14f..eb1b39ac 100644 --- a/src/ble/hal/blercu/blercucontroller.cpp +++ b/src/ble/hal/blercu/blercucontroller.cpp @@ -65,7 +65,7 @@ BleRcuControllerImpl::BleRcuControllerImpl(const shared_ptr +#define BLE_MAX_MANAGED_RCUS (1) + class ConfigSettings; class BleRcuAdapter; class BleRcuDevice; - - class BleRcuControllerImpl final : public BleRcuController { public: diff --git a/src/ctrlm_controller.cpp b/src/ctrlm_controller.cpp index aaae3b40..0d8b2154 100644 --- a/src/ctrlm_controller.cpp +++ b/src/ctrlm_controller.cpp @@ -410,3 +410,20 @@ uint8_t ctrlm_obj_controller_t::get_upgrade_increment() const { bool ctrlm_obj_controller_t::is_upgrade_progress_at_increment() const { return ((upgrade_progress_ % upgrade_increment_ == 0) || (upgrade_progress_ == 100)); } + +void ctrlm_obj_controller_t::update_controller_id_and_db_entry(std::string db_name, ctrlm_network_id_t network_id, ctrlm_controller_id_t new_id) { + controller_id_ = new_id; + std::stringstream new_controller_db_table; + new_controller_db_table << db_name << "_" << COUT_HEX_MODIFIER << (int)network_id << "_controller_" << COUT_HEX_MODIFIER << (int)new_id; + std::string new_table = new_controller_db_table.str(); + + ieee_address_->set_table(new_table); + time_binding_->set_table(new_table); + last_activity_time_->set_table(new_table); + last_key_time_->set_table(new_table); + last_key_code_->set_table(new_table); + irdb_entry_id_name_tv_->set_table(new_table); + irdb_entry_id_name_avr_->set_table(new_table); + voice_metrics_->set_table(new_table); + ota_failure_cnt_from_last_success_->set_table(new_table); +} diff --git a/src/ctrlm_controller.h b/src/ctrlm_controller.h index d31159fc..66749062 100644 --- a/src/ctrlm_controller.h +++ b/src/ctrlm_controller.h @@ -67,6 +67,7 @@ class ctrlm_obj_controller_t std::string stb_name_get() const; void set_device_minor_id(int device_minor_id); int get_device_minor_id() const; + void update_controller_id_and_db_entry(std::string db_name, ctrlm_network_id_t network_id, ctrlm_controller_id_t id); virtual ctrlm_controller_capabilities_t get_capabilities() const; diff --git a/src/ctrlm_main.cpp b/src/ctrlm_main.cpp index 1bffc6df..0794c861 100644 --- a/src/ctrlm_main.cpp +++ b/src/ctrlm_main.cpp @@ -113,11 +113,6 @@ using namespace std; #define CTRLM_MAIN_QUEUE_REPEAT_DELAY (5000) -#define NETWORK_ID_BASE_RF4CE 1 -#define NETWORK_ID_BASE_IP 11 -#define NETWORK_ID_BASE_BLE 21 -#define NETWORK_ID_BASE_CUSTOM 41 - #define CTRLM_MAIN_FIRST_BOOT_TIME_MAX (180) // maximum amount of uptime allowed (in seconds) for declaring "first boot" typedef void (*ctrlm_queue_push_t)(gpointer); diff --git a/src/ctrlm_network.cpp b/src/ctrlm_network.cpp index 69fa462b..e8f591c3 100644 --- a/src/ctrlm_network.cpp +++ b/src/ctrlm_network.cpp @@ -1079,3 +1079,8 @@ void ctrlm_obj_network_t::start_controller_audio_streaming(ctrlm_voice_start_aud XLOGD_WARN("not implemented for %s network", name_get()); return; } + +bool ctrlm_obj_network_t::is_managed_by_network(ctrlm_controller_id_t) { + XLOGD_WARN("not implemented for %s network", name_get()); + return false; +} diff --git a/src/ctrlm_network.h b/src/ctrlm_network.h index c39f3285..90ea909f 100644 --- a/src/ctrlm_network.h +++ b/src/ctrlm_network.h @@ -36,6 +36,11 @@ #define THREAD_ID_VALIDATE() thread_id_validate(__FUNCTION__) +#define NETWORK_ID_BASE_RF4CE 1 +#define NETWORK_ID_BASE_IP 11 +#define NETWORK_ID_BASE_BLE 21 +#define NETWORK_ID_BASE_CUSTOM 41 + typedef struct : public ctrlm_network_all_ipc_result_wrapper_t { unsigned char api_revision; unsigned int timeout; @@ -313,6 +318,7 @@ class ctrlm_obj_network_t const char * get_thread_name(const GThread *thread_id) const; void thread_id_validate(const char *pCallingFunction) const; virtual gboolean key_event_hook(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_key_status_t key_status, ctrlm_key_code_t key_code); + virtual bool is_managed_by_network(ctrlm_controller_id_t id); private: gboolean mask_key_codes_ = true; diff --git a/src/ipc/ctrlm_rcp_ipc_event.cpp b/src/ipc/ctrlm_rcp_ipc_event.cpp index 0ce44bae..510be650 100644 --- a/src/ipc/ctrlm_rcp_ipc_event.cpp +++ b/src/ipc/ctrlm_rcp_ipc_event.cpp @@ -135,6 +135,23 @@ void ctrlm_rcp_ipc_net_status_t::populate_status(const ctrlm_obj_network_t &netw } } +ctrlm_ir_state_t ctrlm_rcp_ipc_net_status_t::get_ir_prog_state(void) +{ + return irdb_state_; +} + +ctrlm_rf_pair_state_t ctrlm_rcp_ipc_net_status_t::get_rf_pair_state(void) +{ + return pair_state_; +} + +void ctrlm_rcp_ipc_net_status_t::get_controller_status_list(std::vector &list) +{ + for (const auto &status : controller_status_list_) { + list.push_back(status); + } +} + char *ctrlm_rcp_ipc_net_status_t::to_string() const { return json_dumps(to_json(), JSON_ENCODE_ANY); diff --git a/src/ipc/ctrlm_rcp_ipc_event.h b/src/ipc/ctrlm_rcp_ipc_event.h index ae257af6..e2c36e7c 100644 --- a/src/ipc/ctrlm_rcp_ipc_event.h +++ b/src/ipc/ctrlm_rcp_ipc_event.h @@ -111,13 +111,18 @@ class ctrlm_rcp_ipc_net_status_t : public ctrlm_virtual_json_t virtual json_t *to_json() const; - char *to_string() const; - uint8_t get_api_revision() const { return api_revision_; } - bool get_result() const { return (result_ == CTRLM_IARM_CALL_RESULT_SUCCESS) ? true : false; } - void set_result(ctrlm_iarm_call_result_t result) { result_ = result; } - ctrlm_network_id_t get_net_id() const { return net_id_; } - void set_net_id(ctrlm_network_id_t net_id) { net_id_ = net_id; } - void populate_status(const ctrlm_obj_network_t &network); + char *to_string() const; + uint8_t get_api_revision() const { return api_revision_; } + bool get_result() const { return (result_ == CTRLM_IARM_CALL_RESULT_SUCCESS) ? true : false; } + void set_result(ctrlm_iarm_call_result_t result) { result_ = result; } + ctrlm_network_id_t get_net_id() const { return net_id_; } + void set_net_id(ctrlm_network_id_t net_id) { net_id_ = net_id; } + ctrlm_network_type_t get_type() const { return net_type_; } + + void populate_status(const ctrlm_obj_network_t &network); + ctrlm_ir_state_t get_ir_prog_state(void); + ctrlm_rf_pair_state_t get_rf_pair_state(void); + void get_controller_status_list(std::vector &list); private: uint8_t api_revision_ = 0; @@ -197,11 +202,11 @@ class ctrlm_network_all_ipc_result_wrapper_t { return (result_map_[network_id_] == CTRLM_IARM_CALL_RESULT_SUCCESS); } else { for (const auto &it : result_map_) { - if (it.second != CTRLM_IARM_CALL_RESULT_SUCCESS) { - return false; + if (it.second == CTRLM_IARM_CALL_RESULT_SUCCESS) { + return true; } } - return true; + return false; } } }; diff --git a/src/ipc/ctrlm_rcp_ipc_iarm_thunder.cpp b/src/ipc/ctrlm_rcp_ipc_iarm_thunder.cpp index 88d2a38f..5ed63e70 100644 --- a/src/ipc/ctrlm_rcp_ipc_iarm_thunder.cpp +++ b/src/ipc/ctrlm_rcp_ipc_iarm_thunder.cpp @@ -397,32 +397,55 @@ IARM_Result_t ctrlm_rcp_ipc_iarm_thunder_t::get_net_status(void *arg) return(IARM_RESULT_INVALID_PARAM); } - int net_type = CTRLM_NETWORK_TYPE_INVALID; - if (!config.config_value_get(NET_TYPE, net_type)) { - XLOGD_INFO("Missing %s parameter - defaulting to all networks", NET_TYPE); - } std::shared_ptr> params = std::make_shared>(); - params->set_net_id((net_type == CTRLM_NETWORK_TYPE_INVALID) ? CTRLM_MAIN_NETWORK_ID_ALL : ctrlm_network_id_get(static_cast(net_type))); + params->set_net_id(CTRLM_MAIN_NETWORK_ID_ALL); sync_send_netw_handler_to_main_queue_new, ctrlm_main_queue_msg_get_rcu_status_t> (params, (ctrlm_msg_handler_network_t)&ctrlm_obj_network_t::req_process_get_rcu_status); - json_t *ret = json_object(); - json_t *status_array = json_array(); + json_t *ret = json_object(); + json_t *status = json_object(); + json_t *net_type_supported = json_array(); + json_t *remote_array = json_array(); + std::map status_map = params->get_reply(); + std::vector remotes; + + ctrlm_network_type_t type = CTRLM_NETWORK_TYPE_INVALID; + ctrlm_ir_state_t ir_prog_state = CTRLM_IR_STATE_UNKNOWN; + ctrlm_rf_pair_state_t rf_pair_state = CTRLM_RF_PAIR_STATE_UNKNOWN; int err = 0; - if (params->get_net_id() != CTRLM_MAIN_NETWORK_ID_ALL) { - err |= json_object_set_new_nocheck(ret, STATUS, status_map[params->get_net_id()].to_json()); - } else { - for (const auto &it : status_map) { - err |= json_array_append_new(status_array, it.second.to_json()); + for (auto const &it : ctrlm_network_types_get()) { + err |= json_array_append_new(net_type_supported, json_integer(it)); + } + for (auto &it : status_map) { + it.second.get_controller_status_list(remotes); + } + for (const auto &remote : remotes) { + err |= json_array_append_new(remote_array, remote.to_json()); + } + // For now default to RF4CE network reporting if available + for (auto &it : status_map) { + ir_prog_state = it.second.get_ir_prog_state(); + rf_pair_state = it.second.get_rf_pair_state(); + type = it.second.get_type(); + + if (type == CTRLM_NETWORK_TYPE_RF4CE) { + break; } - err |= json_object_set_new_nocheck(ret, STATUS, status_array); } + + err |= json_object_set_new_nocheck(status, REMOTE_DATA, remote_array); + err |= json_object_set_new_nocheck(status, NET_TYPES_SUPPORTED, net_type_supported); + err |= json_object_set_new_nocheck(status, NET_TYPE, json_integer(type)); + err |= json_object_set_new_nocheck(status, IR_PROG_STATE, json_string(ctrlm_ir_state_str(ir_prog_state))); + err |= json_object_set_new_nocheck(status, PAIRING_STATE, json_string(ctrlm_rf_pair_state_str(rf_pair_state))); + + err |= json_object_set_new_nocheck(ret, STATUS, status); err |= json_object_set_new_nocheck(ret, SUCCESS, json_boolean(params->get_result())); if (err) { @@ -463,13 +486,8 @@ IARM_Result_t ctrlm_rcp_ipc_iarm_thunder_t::get_last_keypress(void *arg) return(IARM_RESULT_INVALID_PARAM); } - int net_type = CTRLM_NETWORK_TYPE_INVALID; - if (!config.config_value_get(NET_TYPE, net_type)) { - XLOGD_INFO("Missing %s parameter - defaulting to all networks", NET_TYPE); - } - std::shared_ptr> params = std::make_shared>(); - params->set_net_id((net_type == CTRLM_NETWORK_TYPE_INVALID) ? CTRLM_MAIN_NETWORK_ID_ALL : ctrlm_network_id_get(static_cast(net_type))); + params->set_net_id(CTRLM_MAIN_NETWORK_ID_ALL); sync_send_netw_handler_to_main_queue_new, ctrlm_main_queue_msg_get_last_keypress_t> @@ -484,18 +502,13 @@ IARM_Result_t ctrlm_rcp_ipc_iarm_thunder_t::get_last_keypress(void *arg) ctrlm_network_id_t net_id_index = 0; int err = 0; - if (params->get_net_id() != CTRLM_MAIN_NETWORK_ID_ALL) { - itr = key_info_map.find(params->get_net_id()); - key_info = itr->second; - } else { - for (itr = key_info_map.begin(); itr != key_info_map.end(); itr++) { - if (itr->second.timestamp > time_last_key) { - time_last_key = itr->second.timestamp; - net_id_index = itr->first; - } + for (itr = key_info_map.begin(); itr != key_info_map.end(); itr++) { + if (itr->second.timestamp > time_last_key) { + time_last_key = itr->second.timestamp; + net_id_index = itr->first; } - key_info = key_info_map[net_id_index]; } + key_info = key_info_map[net_id_index]; err |= json_object_set_new_nocheck(ret, CONTROLLER_ID, json_integer(key_info.controller_id)); err |= json_object_set_new_nocheck(ret, TIMESTAMP, json_integer(key_info.timestamp)); @@ -544,11 +557,6 @@ IARM_Result_t ctrlm_rcp_ipc_iarm_thunder_t::find_my_remote(void *arg) return(IARM_RESULT_INVALID_PARAM); } - int net_type = CTRLM_NETWORK_TYPE_INVALID; - if(!config.config_value_get(NET_TYPE, net_type)) { - XLOGD_INFO("Missing %s parameter - defaulting to all networks", NET_TYPE); - } - std::string level; if(!config.config_value_get(LEVEL, level)) { XLOGD_ERROR("Missing %s parameter", LEVEL); @@ -556,7 +564,7 @@ IARM_Result_t ctrlm_rcp_ipc_iarm_thunder_t::find_my_remote(void *arg) } std::shared_ptr params = std::make_shared(); - params->set_net_id((net_type == CTRLM_NETWORK_TYPE_INVALID) ? CTRLM_MAIN_NETWORK_ID_ALL : ctrlm_network_id_get(static_cast(net_type))); + params->set_net_id(CTRLM_MAIN_NETWORK_ID_ALL); params->level = ctrlm_utils_str_to_fmr_level(level); params->duration = 0; @@ -645,10 +653,6 @@ IARM_Result_t ctrlm_rcp_ipc_iarm_thunder_t::write_rcu_wakeup_config(void *arg) return(IARM_RESULT_INVALID_PARAM); } - int net_type = CTRLM_NETWORK_TYPE_INVALID; - if(!config.config_value_get(NET_TYPE, net_type)) { - XLOGD_INFO("Missing %s parameter - defaulting to all networks", NET_TYPE); - } std::string wakeup_config; if(!config.config_value_get(WAKEUP_CONFIG, wakeup_config)) { @@ -665,7 +669,7 @@ IARM_Result_t ctrlm_rcp_ipc_iarm_thunder_t::write_rcu_wakeup_config(void *arg) } ctrlm_iarm_call_WriteRcuWakeupConfig_params_t params = {}; - params.network_id = (net_type == CTRLM_NETWORK_TYPE_INVALID) ? CTRLM_MAIN_NETWORK_ID_ALL : ctrlm_network_id_get(static_cast(net_type)); + params.network_id = CTRLM_MAIN_NETWORK_ID_ALL; params.config = ctrlm_utils_str_to_wakeup_config(wakeup_config); params.customListSize = ctrlm_utils_custom_key_str_to_array(custom_keys, params.customList); diff --git a/src/irdb/ctrlm_irdb_interface.cpp b/src/irdb/ctrlm_irdb_interface.cpp index 1bc55ffd..18a02e57 100644 --- a/src/irdb/ctrlm_irdb_interface.cpp +++ b/src/irdb/ctrlm_irdb_interface.cpp @@ -41,6 +41,7 @@ #include #include +#include using namespace std; @@ -543,17 +544,34 @@ bool ctrlm_irdb_interface_t::program_ir_codes(ctrlm_network_id_t network_id, ctr bool ctrlm_irdb_interface_t::_program_ir_codes(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_irdb_ir_code_set_t *ir_codes) { bool ret = false; + vector success_vec; - ctrlm_main_queue_msg_program_ir_codes_t msg = {0}; - msg.network_id = network_id; - msg.controller_id = controller_id; - msg.ir_codes = ir_codes; - msg.success = &ret; + std::shared_ptr msg = std::make_shared(); + msg->network_id = network_id; + msg->controller_id = controller_id; + msg->ir_codes = ir_codes; + msg->success = &success_vec; - if (false == get_vendor_info(msg.vendor_info)) { - msg.vendor_info.rcu_support_bitmask = 0; + if (false == get_vendor_info(msg->vendor_info)) { + msg->vendor_info.rcu_support_bitmask = 0; + } + ctrlm_main_queue_handler_push_new + (CTRLM_HANDLER_NETWORK, + (ctrlm_msg_handler_network_t)&ctrlm_obj_network_t::req_process_program_ir_codes, + std::move(msg), + NULL, + network_id, + true); + + for (char success : success_vec) { + if (success) { + ret = true; + break; + } else { + ret = false; + } } - ctrlm_main_queue_handler_push(CTRLM_HANDLER_NETWORK, (ctrlm_msg_handler_network_t)&ctrlm_obj_network_t::req_process_program_ir_codes, &msg, sizeof(msg), NULL, network_id, true); return(ret); } @@ -566,14 +584,30 @@ bool ctrlm_irdb_interface_t::clear_ir_codes(ctrlm_network_id_t network_id, ctrlm bool ctrlm_irdb_interface_t::_clear_ir_codes(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id) { bool ret = false; - - ctrlm_main_queue_msg_ir_clear_t msg = {0}; - - msg.network_id = network_id; - msg.controller_id = controller_id; - msg.success = &ret; - - ctrlm_main_queue_handler_push(CTRLM_HANDLER_NETWORK, (ctrlm_msg_handler_network_t)&ctrlm_obj_network_t::req_process_ir_clear_codes, &msg, sizeof(msg), NULL, network_id, true); - + vector success_vec; + + std::shared_ptr msg = std::make_shared(); + + msg->network_id = network_id; + msg->controller_id = controller_id; + msg->success = &success_vec; + + ctrlm_main_queue_handler_push_new + (CTRLM_HANDLER_NETWORK, + (ctrlm_msg_handler_network_t)&ctrlm_obj_network_t::req_process_ir_clear_codes, + std::move(msg), + NULL, + network_id, + true); + + for (char success : success_vec) { + if (success) { + ret = true; + break; + } else { + ret = false; + } + } return(ret); } diff --git a/src/irdb/ctrlm_irdb_interface.h b/src/irdb/ctrlm_irdb_interface.h index 9e7da14e..76669356 100644 --- a/src/irdb/ctrlm_irdb_interface.h +++ b/src/irdb/ctrlm_irdb_interface.h @@ -31,7 +31,6 @@ #include "ctrlm_hal.h" #include "ctrlm_irdb_plugin.h" - inline bool operator==(const ctrlm_irdb_autolookup_entry_ranked_t& lhs, const ctrlm_irdb_autolookup_entry_ranked_t& rhs) { return (lhs.id.compare(rhs.id) == 0); } @@ -42,7 +41,7 @@ typedef struct { ctrlm_network_id_t network_id; ctrlm_controller_id_t controller_id; ctrlm_irdb_ir_code_set_t * ir_codes; - bool * success; + std::vector * success; sem_t * semaphore; ctrlm_irdb_vendor_info_t vendor_info; } ctrlm_main_queue_msg_program_ir_codes_t; @@ -50,7 +49,7 @@ typedef struct { typedef struct { ctrlm_network_id_t network_id; ctrlm_controller_id_t controller_id; - bool * success; + std::vector * success; sem_t * semaphore; } ctrlm_main_queue_msg_ir_clear_t; diff --git a/src/irdb/ipc/ctrlm_irdb_ipc_iarm_thunder.cpp b/src/irdb/ipc/ctrlm_irdb_ipc_iarm_thunder.cpp index 84351718..48b7c29a 100644 --- a/src/irdb/ipc/ctrlm_irdb_ipc_iarm_thunder.cpp +++ b/src/irdb/ipc/ctrlm_irdb_ipc_iarm_thunder.cpp @@ -390,7 +390,6 @@ IARM_Result_t ctrlm_irdb_ipc_iarm_thunder_t::program_ir_codes(void *arg) { bool success = false; ctrlm_irdb_dev_type_t dev_type = CTRLM_IRDB_DEV_TYPE_INVALID; ctrlm_ir_device_type_t ir_dev_type = CTRLM_IR_DEVICE_UNKNOWN; - int network_type_val = CTRLM_NETWORK_TYPE_INVALID; int remote_id = 0; std::string av_dev_str, code; json_config conf; @@ -406,10 +405,6 @@ IARM_Result_t ctrlm_irdb_ipc_iarm_thunder_t::program_ir_codes(void *arg) { return(IARM_RESULT_INVALID_PARAM); } - if(!conf.config_value_get(NET_TYPE, network_type_val)) { - XLOGD_INFO("Missing %s parameter - defaulting to all networks", NET_TYPE); - } - if(!conf.config_value_get(AV_DEV_TYPE, av_dev_str)) { XLOGD_ERROR("Missing %s parameter", AV_DEV_TYPE); return(IARM_RESULT_INVALID_PARAM); @@ -425,9 +420,7 @@ IARM_Result_t ctrlm_irdb_ipc_iarm_thunder_t::program_ir_codes(void *arg) { return(IARM_RESULT_INVALID_PARAM); } - ctrlm_network_id_t network_id = (network_type_val == CTRLM_NETWORK_TYPE_INVALID) ? - CTRLM_MAIN_NETWORK_ID_ALL : - ctrlm_network_id_get(static_cast(network_type_val)); + ctrlm_network_id_t network_id = CTRLM_MAIN_NETWORK_ID_ALL; ctrlm_controller_id_t controller_id = static_cast(remote_id); if(!ctrlm_irdb_dev_type_is_valid(av_dev_str, ir_dev_type)) { @@ -460,7 +453,6 @@ IARM_Result_t ctrlm_irdb_ipc_iarm_thunder_t::clear_ir_codes(void *arg) { json_t *payload = NULL; ctrlm_irdb_interface_t *irdb = ctrlm_main_irdb_get(); bool success = false; - int network_type_val = CTRLM_NETWORK_TYPE_INVALID; int remote_id = 0; json_config conf; @@ -475,18 +467,12 @@ IARM_Result_t ctrlm_irdb_ipc_iarm_thunder_t::clear_ir_codes(void *arg) { return(IARM_RESULT_INVALID_PARAM); } - if(!conf.config_value_get(NET_TYPE, network_type_val)) { - XLOGD_INFO("Missing %s parameter - defaulting to all networks", NET_TYPE); - } - if(!conf.config_value_get(REMOTE_ID, remote_id)){ XLOGD_ERROR("Missing %s parameter", REMOTE_ID); return(IARM_RESULT_INVALID_PARAM); } - ctrlm_network_id_t network_id = (network_type_val == CTRLM_NETWORK_TYPE_INVALID) ? - CTRLM_MAIN_NETWORK_ID_ALL : - ctrlm_network_id_get(static_cast(network_type_val)); + ctrlm_network_id_t network_id = CTRLM_MAIN_NETWORK_ID_ALL; ctrlm_controller_id_t controller_id = static_cast(remote_id); if(irdb) { diff --git a/src/rf4ce/ctrlm_rf4ce_network.cpp b/src/rf4ce/ctrlm_rf4ce_network.cpp index 5fea2cd3..de3adb73 100644 --- a/src/rf4ce/ctrlm_rf4ce_network.cpp +++ b/src/rf4ce/ctrlm_rf4ce_network.cpp @@ -1179,7 +1179,7 @@ void ctrlm_obj_network_rf4ce_t::controllers_load() { ctrlm_controller_id_t ctrlm_obj_network_rf4ce_t::controller_id_assign(void) { // Get the next available controller id - for(ctrlm_controller_id_t index = 1; index < 255; index++) { + for(ctrlm_controller_id_t index = RF4CE_RCU_ID_RANGE_MIN; index < RF4CE_RCU_ID_RANGE_MAX; index++) { if(!controller_exists(index)) { XLOGD_INFO("controller id %u", index); return(index); @@ -4393,7 +4393,11 @@ void ctrlm_obj_network_rf4ce_t::req_process_program_ir_codes(void *data, int siz g_assert(dqm); g_assert(size == sizeof(ctrlm_main_queue_msg_program_ir_codes_t)); - if(controller_exists(dqm->controller_id)) { + bool success = false; + + if(!is_managed_by_network(dqm->controller_id)) { + XLOGD_ERROR("controller %d is not managed by the %s network", dqm->controller_id, name_get()); + } else if(controller_exists(dqm->controller_id)) { if(dqm->ir_codes) { XLOGD_INFO("Setting IR Codes on Controller %u", dqm->controller_id); unsigned char status[1] = {IR_RF_DATABASE_STATUS_DB_DOWNLOAD_YES | IR_RF_DATABASE_STATUS_FORCE_DOWNLOAD}; @@ -4403,16 +4407,15 @@ void ctrlm_obj_network_rf4ce_t::req_process_program_ir_codes(void *data, int siz controllers_[dqm->controller_id]->irdb_entry_id_name_set(CTRLM_IRDB_DEV_TYPE_TV, ir_rf_database_.get_tv_ir_code_id()); controllers_[dqm->controller_id]->irdb_entry_id_name_set(CTRLM_IRDB_DEV_TYPE_AVR, ir_rf_database_.get_avr_ir_code_id()); this->ir_rf_database_.store_db(); - if(dqm->success) *dqm->success = true; + success = true; } else { XLOGD_ERROR("Invalid IR Codes"); - if(dqm->success) *dqm->success = false; } } else { XLOGD_ERROR("Controller %u doesn't exist", dqm->controller_id); - if(dqm->success) *dqm->success = false; } + if(dqm->success) dqm->success->push_back(success); // post the semaphore if(dqm->semaphore) { sem_post(dqm->semaphore); @@ -4424,7 +4427,11 @@ void ctrlm_obj_network_rf4ce_t::req_process_ir_clear_codes(void *data, int size) g_assert(dqm); g_assert(size == sizeof(ctrlm_main_queue_msg_ir_clear_t)); - if(controller_exists(dqm->controller_id)) { + bool success = false; + + if(!is_managed_by_network(dqm->controller_id)) { + XLOGD_ERROR("controller %d is not managed by the %s network", dqm->controller_id, name_get()); + } else if(controller_exists(dqm->controller_id)) { XLOGD_INFO("Clearing IR Codes on Controller %u", dqm->controller_id); unsigned char status[1] = {IR_RF_DATABASE_STATUS_DB_DOWNLOAD_YES | IR_RF_DATABASE_STATUS_FORCE_DOWNLOAD}; this->ir_rf_database_.clear_ir_codes(); @@ -4433,12 +4440,12 @@ void ctrlm_obj_network_rf4ce_t::req_process_ir_clear_codes(void *data, int size) controllers_[dqm->controller_id]->irdb_entry_id_name_set(CTRLM_IRDB_DEV_TYPE_TV, "0"); controllers_[dqm->controller_id]->irdb_entry_id_name_set(CTRLM_IRDB_DEV_TYPE_AVR, "0"); controllers_[dqm->controller_id]->rf4ce_rib_set_target(CTRLM_RF4CE_RIB_ATTR_ID_IR_RF_DATABASE_STATUS, CTRLM_RF4CE_RIB_ATTR_INDEX_GENERAL, CTRLM_RF4CE_RIB_ATTR_LEN_IR_RF_DATABASE_STATUS, status); - if(dqm->success) *dqm->success = true; + success = true; } else { XLOGD_ERROR("Controller %u doesn't exist", dqm->controller_id); - if(dqm->success) *dqm->success = false; } + if(dqm->success) dqm->success->push_back(success); // post the semaphore if(dqm->semaphore) { sem_post(dqm->semaphore); @@ -5131,3 +5138,7 @@ void ctrlm_obj_network_rf4ce_t::start_controller_audio_streaming(ctrlm_voice_sta params->m_started = true; } + +bool ctrlm_obj_network_rf4ce_t::is_managed_by_network(ctrlm_controller_id_t id) { + return (id >= RF4CE_RCU_ID_RANGE_MIN && id < RF4CE_RCU_ID_RANGE_MAX); +} diff --git a/src/rf4ce/ctrlm_rf4ce_network.h b/src/rf4ce/ctrlm_rf4ce_network.h index 07298971..10cc771a 100644 --- a/src/rf4ce/ctrlm_rf4ce_network.h +++ b/src/rf4ce/ctrlm_rf4ce_network.h @@ -67,6 +67,9 @@ #define IR_RF_DATABASE_STATUS_DB_DOWNLOAD_YES (0x80) #define IR_RF_DATABASE_STATUS_RESERVED (0x20) +#define RF4CE_RCU_ID_RANGE_MIN (NETWORK_ID_BASE_RF4CE) +#define RF4CE_RCU_ID_RANGE_MAX (RF4CE_RCU_ID_RANGE_MIN + CTRLM_MAIN_MAX_BOUND_CONTROLLERS) + typedef enum { CTRLM_RF4CE_DEVICE_TYPE_STB = 0x09, CTRLM_RF4CE_DEVICE_TYPE_AUTOBIND = 0xD0, @@ -466,6 +469,7 @@ class ctrlm_obj_network_rf4ce_t : public ctrlm_obj_network_t protected: virtual gboolean key_event_hook(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_key_status_t key_status, ctrlm_key_code_t key_code); + virtual bool is_managed_by_network(ctrlm_controller_id_t id); private: ctrlm_hal_rf4ce_network_main_t hal_api_main_; From fc1c94a8e2de9b196a5f274316eaee5c07c2fbf5 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Tue, 13 Jan 2026 11:01:35 -0500 Subject: [PATCH 22/39] RDKEMW-10631: Filter out unpaired devices when reconnecting all devices --- src/ble/hal/blercu/bluez/blercuadapter.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/ble/hal/blercu/bluez/blercuadapter.cpp b/src/ble/hal/blercu/bluez/blercuadapter.cpp index c7d5834e..56949f40 100644 --- a/src/ble/hal/blercu/bluez/blercuadapter.cpp +++ b/src/ble/hal/blercu/bluez/blercuadapter.cpp @@ -1257,14 +1257,22 @@ bool BleRcuAdapterBluez::addDevice(const BleAddress &address) /*! \internal - Sends a request to bluez to reconnect all devices stored in our internal map + Sends a request to bluez to reconnect all devices stored in our internal map if paired */ void BleRcuAdapterBluez::reconnectAllDevices() { for (auto const &device : m_devices) { - XLOGD_INFO("reconnecting to %s", device.first.toString().c_str()); - device.second->connect(); + bool isPaired = false; + if (device.second->m_deviceProxy) { + device.second->m_deviceProxy->paired(isPaired); + } + if (isPaired) { + XLOGD_INFO("reconnecting to %s", device.first.toString().c_str()); + device.second->connect(); + } else { + XLOGD_INFO("not paired, skipping reconnecting to %s", device.first.toString().c_str()); + } } } From 084f51900da55542dde54d670738ed8f52263ff3 Mon Sep 17 00:00:00 2001 From: Kelvin Lu <119349872+klu339@users.noreply.github.com> Date: Tue, 13 Jan 2026 14:43:53 -0500 Subject: [PATCH 23/39] RDKEMW-12512: ctrlm release v1.1.9 (#169) --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18d43be6..2548677a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +> 13 January 2026 + +#### [1.1.9](https://github.com/rdkcentral/control/compare/1.1.8...1.1.9) + +- RDKEMW-11471: Remove netType param [`#164`](https://github.com/rdkcentral/control/pull/164) +- RDKEMW-10631: Filter out unpaired devices when reconnecting all devices [`fc1c94a`](https://github.com/rdkcentral/control/commit/fc1c94a8e2de9b196a5f274316eaee5c07c2fbf5) + #### [1.1.8](https://github.com/rdkcentral/control/compare/1.1.7...1.1.8) > 5 January 2026 From 932b09e4933a8ceb9d2d22edde48aa43aa51143d Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Wed, 21 Jan 2026 09:51:18 -0500 Subject: [PATCH 24/39] RDKEMW-9843: report loaded and unloaded voltage from RCU (#163) --- .../bleservices/blercuremotecontrolservice.h | 5 + .../gatt/gatt_remotecontrolservice.cpp | 109 ++++++++++++++++++ .../gatt/gatt_remotecontrolservice.h | 8 ++ src/ble/hal/utils/bleuuid.cpp | 1 + src/ble/hal/utils/bleuuid.h | 1 + 5 files changed, 124 insertions(+) diff --git a/src/ble/hal/blercu/bleservices/blercuremotecontrolservice.h b/src/ble/hal/blercu/bleservices/blercuremotecontrolservice.h index 63752f73..653fd872 100644 --- a/src/ble/hal/blercu/bleservices/blercuremotecontrolservice.h +++ b/src/ble/hal/blercu/bleservices/blercuremotecontrolservice.h @@ -64,6 +64,10 @@ class BleRcuRemoteControlService { m_lastKeypressChangedSlots.addSlot(func); } + inline void addRawBatteryVoltageChangedSlot(const Slot &> &func) + { + m_rawBatteryVoltageChangedSlots.addSlot(func); + } inline void addAdvConfigChangedSlot(const Slot &func) { m_advConfigChangedSlots.addSlot(func); @@ -77,6 +81,7 @@ class BleRcuRemoteControlService Slots m_unpairReasonChangedSlots; Slots m_rebootReasonChangedSlots; Slots m_lastKeypressChangedSlots; + Slots &> m_rawBatteryVoltageChangedSlots; Slots m_advConfigChangedSlots; Slots &> m_advConfigCustomListChangedSlots; }; diff --git a/src/ble/hal/blercu/bleservices/gatt/gatt_remotecontrolservice.cpp b/src/ble/hal/blercu/bleservices/gatt/gatt_remotecontrolservice.cpp index 74d36e3e..a6c89198 100644 --- a/src/ble/hal/blercu/bleservices/gatt/gatt_remotecontrolservice.cpp +++ b/src/ble/hal/blercu/bleservices/gatt/gatt_remotecontrolservice.cpp @@ -47,6 +47,7 @@ const BleUuid GattRemoteControlService::m_lastKeypressCharUuid(BleUuid::LastKeyp const BleUuid GattRemoteControlService::m_advConfigCharUuid(BleUuid::AdvertisingConfig); const BleUuid GattRemoteControlService::m_advConfigCustomListCharUuid(BleUuid::AdvertisingConfigCustomList); const BleUuid GattRemoteControlService::m_assertReportCharUuid(BleUuid::AssertReport); +const BleUuid GattRemoteControlService::m_rawBatteryVoltageCharUuid(BleUuid::RawBatteryVoltage); using namespace std; @@ -182,6 +183,12 @@ bool GattRemoteControlService::start(const shared_ptr &gat XLOGD_WARN("failed to get optional Assert Reporting characteristic, continuing anyway..."); } } + if (!m_rawBatteryVoltageCharacteristic || !m_rawBatteryVoltageCharacteristic->isValid()) { + m_rawBatteryVoltageCharacteristic = gattService->characteristic(m_rawBatteryVoltageCharUuid); + if (!m_rawBatteryVoltageCharacteristic || !m_rawBatteryVoltageCharacteristic->isValid()) { + XLOGD_WARN("failed to get Raw Battery Voltage characteristic, continuing anyway..."); + } + } // check we're not already started if (m_stateMachine.state() != IdleState) { @@ -228,6 +235,7 @@ void GattRemoteControlService::onEnteredState(int state) m_rebootReasonCharacteristic.reset(); m_rcuActionCharacteristic.reset(); m_assertReportCharacteristic.reset(); + m_rawBatteryVoltageCharacteristic.reset(); } else if (state == RetrieveInitialValuesState) { @@ -237,12 +245,14 @@ void GattRemoteControlService::onEnteredState(int state) requestAdvConfigCustomList(); requestUnpairReason(); requestRebootReason(); + requestRawBatteryVoltage(); m_readySlots.invoke(); } else if (state == EnableNotificationsState) { requestStartUnpairNotify(); requestStartRebootNotify(); + requestRawBatteryVoltageChangedNotify(); } } @@ -303,6 +313,35 @@ void GattRemoteControlService::requestStartRebootNotify() PendingReply<>(m_isAlive, replyHandler)); } +void GattRemoteControlService::requestRawBatteryVoltageChangedNotify() +{ + if (!m_rawBatteryVoltageCharacteristic || !m_rawBatteryVoltageCharacteristic->isValid()) { + XLOGD_WARN("Invalid raw battery voltage characteristic, skipping notification setup"); + return; + } + + auto replyHandler = [this](PendingReply<> *reply) + { + // check for errors + if (reply->isError()) { + // this is bad if this happens as we won't get updates, so we install a timer to + // retry enabling notifications in a couple of seconds time + XLOGD_ERROR("failed to enable raw battery voltage characteristic notifications due to <%s>", + reply->errorMessage().c_str()); + + m_stateMachine.cancelDelayedEvents(RetryStartNotifyEvent); + m_stateMachine.postDelayedEvent(RetryStartNotifyEvent, 2000); + } else { + XLOGD_INFO("request to start notifications on Raw Battery Voltage characteristic succeeded"); + } + }; + + m_rawBatteryVoltageCharacteristic->enableNotifications( + Slot &>(m_isAlive, + std::bind(&GattRemoteControlService::onRawBatteryVoltageChanged, this, std::placeholders::_1)), + PendingReply<>(m_isAlive, replyHandler)); +} + // ----------------------------------------------------------------------------- /*! Write RCU Action characteristic. @@ -525,6 +564,45 @@ void GattRemoteControlService::requestLastKeypress() } } +// ----------------------------------------------------------------------------- +/*! + \internal + + Sends a request to org.bluez.GattCharacteristic1.Value() to get the value + property of the characteristic which contains the raw battery voltage. + + */ +void GattRemoteControlService::requestRawBatteryVoltage() +{ + // lambda invoked when the request returns + auto replyHandler = [this](PendingReply> *reply) + { + // check for errors + if (reply->isError()) { + XLOGD_ERROR("Failed to read raw battery voltage due to <%s>", reply->errorMessage().c_str()); + } else { + std::vector value; + value = reply->result(); + + if (value.size() == 3) { + onRawBatteryVoltageChanged(value); + } else { + XLOGD_ERROR("Raw battery voltage received has invalid length (%d bytes)", value.size()); + } + } + }; + + + if (m_rawBatteryVoltageCharacteristic && m_rawBatteryVoltageCharacteristic->isValid()) { + + // send a request to the bluez daemon to read the characteristic + m_rawBatteryVoltageCharacteristic->readValue(PendingReply>(m_isAlive, replyHandler)); + + } else { + XLOGD_WARN("Raw battery voltage characteristic is not valid, check that the remote firmware version supports this feature."); + } +} + // ----------------------------------------------------------------------------- /*! \internal @@ -601,7 +679,38 @@ void GattRemoteControlService::requestAdvConfigCustomList() } } +// ----------------------------------------------------------------------------- +/*! + \internal + Internal slot called when a notification from the remote device is sent + due to raw battery voltage changing. + */ +void GattRemoteControlService::onRawBatteryVoltageChanged(const std::vector &newValue) { + m_unloadedVoltage = newValue[0]; + m_loadedVoltage = newValue[1]; + m_voltagePercentage = std::clamp(newValue[2], uint8_t(0), uint8_t(100)); // Clamp percentage between 0 - 100 + + // Formats an 8-bit unsigned integer as a voltage string. + // Upper 2 bits = whole voltage (0-3v), lower 6 bits = 1/64v increments. + // Example: 137 (0x89 = 0b10001001) + // - Upper 2 bits: 0b10 = 2v + // - Lower 6 bits: 0b001001 = 9 = 9/64 = 0.14v + // - Result: "2.14v" + auto formatVoltage = [](uint8_t value) -> std::string { + const uint8_t wholeVolts = (value >> 6) & 0x03; // Upper 2 bits + const uint8_t fractionalBits = value & 0x3F; // Lower 6 bits + const float totalVolts = wholeVolts + (fractionalBits / 64.0f); + + char buffer[16]; + snprintf(buffer, sizeof(buffer), "%.2fv", totalVolts); + return buffer; + }; + + XLOGD_TELEMETRY("Successfully read raw battery voltage characteristic, unloaded = %s, loaded = %s, loaded percentage = %u%%", + formatVoltage(m_unloadedVoltage).c_str(), formatVoltage(m_loadedVoltage).c_str(), (unsigned int)m_voltagePercentage); + m_rawBatteryVoltageChangedSlots.invoke(newValue); +} // ----------------------------------------------------------------------------- /*! diff --git a/src/ble/hal/blercu/bleservices/gatt/gatt_remotecontrolservice.h b/src/ble/hal/blercu/bleservices/gatt/gatt_remotecontrolservice.h index 07f3a511..02534640 100644 --- a/src/ble/hal/blercu/bleservices/gatt/gatt_remotecontrolservice.h +++ b/src/ble/hal/blercu/bleservices/gatt/gatt_remotecontrolservice.h @@ -92,13 +92,16 @@ class GattRemoteControlService : public BleRcuRemoteControlService private: void requestStartUnpairNotify(); void requestStartRebootNotify(); + void requestRawBatteryVoltageChangedNotify(); void requestUnpairReason(); void requestRebootReason(); void requestAssertReport(); void requestLastKeypress(); + void requestRawBatteryVoltage(); void requestAdvConfig(); void requestAdvConfigCustomList(); + void onRawBatteryVoltageChanged(const std::vector &newValue); void onWriteAdvConfigReply(PendingReply<> *reply); void onWriteAdvConfigCustomListReply(PendingReply<> *reply); @@ -112,6 +115,7 @@ class GattRemoteControlService : public BleRcuRemoteControlService std::shared_ptr m_advConfigCharacteristic; std::shared_ptr m_advConfigCustomListCharacteristic; std::shared_ptr m_assertReportCharacteristic; + std::shared_ptr m_rawBatteryVoltageCharacteristic; StateMachine m_stateMachine; @@ -119,6 +123,9 @@ class GattRemoteControlService : public BleRcuRemoteControlService uint8_t m_rebootReason; uint8_t m_rcuAction; uint8_t m_lastKeypress; + uint8_t m_unloadedVoltage; + uint8_t m_loadedVoltage; + uint8_t m_voltagePercentage; uint8_t m_advConfig; std::vector m_advConfigCustomList; @@ -135,6 +142,7 @@ class GattRemoteControlService : public BleRcuRemoteControlService static const BleUuid m_advConfigCharUuid; static const BleUuid m_advConfigCustomListCharUuid; static const BleUuid m_assertReportCharUuid; + static const BleUuid m_rawBatteryVoltageCharUuid; private: static const Event::Type StartServiceRequestEvent = Event::Type(Event::User + 1); diff --git a/src/ble/hal/utils/bleuuid.cpp b/src/ble/hal/utils/bleuuid.cpp index fd7b0636..62d4294c 100644 --- a/src/ble/hal/utils/bleuuid.cpp +++ b/src/ble/hal/utils/bleuuid.cpp @@ -74,6 +74,7 @@ bool ble_uuid_names_init(void) BleUuid(BleUuid::AdvertisingConfig, std::string("Advertising Config")); BleUuid(BleUuid::AdvertisingConfigCustomList, std::string("Advertising Config Custom List")); BleUuid(BleUuid::AssertReport, std::string("Assert Report")); + BleUuid(BleUuid::RawBatteryVoltage, std::string("Raw Battery Voltage")); BleUuid(BleUuid::InfraredSignalReference, std::string("Infrared Signal Reference")); BleUuid(BleUuid::InfraredSignalConfiguration, std::string("Infrared Signal Configuration")); BleUuid(BleUuid::FirmwarePacketWindowSize, std::string("Firmware Packet Window Size")); diff --git a/src/ble/hal/utils/bleuuid.h b/src/ble/hal/utils/bleuuid.h index 3552b8e8..7b9df4f2 100644 --- a/src/ble/hal/utils/bleuuid.h +++ b/src/ble/hal/utils/bleuuid.h @@ -104,6 +104,7 @@ class BleUuid AdvertisingConfig = 0xed05, AdvertisingConfigCustomList = 0xed06, AssertReport = 0xed07, + RawBatteryVoltage = 0xed08, }; enum DescriptorType { From 7517d91517dde97e6e73d75eefba49c17110a0fd Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Fri, 23 Jan 2026 11:10:40 -0500 Subject: [PATCH 25/39] RDKEMW-12457: No longer ignoring device re-pair if it's already paired and connected. (#171) --- src/ble/hal/blercu/blercupairingstatemachine.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/ble/hal/blercu/blercupairingstatemachine.cpp b/src/ble/hal/blercu/blercupairingstatemachine.cpp index b55613ed..bb769b41 100644 --- a/src/ble/hal/blercu/blercupairingstatemachine.cpp +++ b/src/ble/hal/blercu/blercupairingstatemachine.cpp @@ -917,12 +917,6 @@ void BleRcuPairingStateMachine::processDevice(const BleAddress &address, // is the device currently paired? if so we have to remove (unpair) // it and then remain in the current state if (m_adapter->isDevicePaired(address)) { - if (m_adapter->isDeviceConnected(address)) { - XLOGD_INFO("Ignoring device (%s, %s)... it is currently paired and connected, no need to re-pair.", - name.c_str(), address.toString().c_str()); - return; - } - XLOGD_INFO("Found target device (%s, %s) but it's currently paired. Will unpair and wait till it shows up in a scan again.", name.c_str(), address.toString().c_str()); From e6a6bd6e13e15885fd0bb76945d980b958b54fa1 Mon Sep 17 00:00:00 2001 From: dwolaver <44593664+dwolaver@users.noreply.github.com> Date: Mon, 9 Feb 2026 12:46:19 -0500 Subject: [PATCH 26/39] RDKEMW-11792 : FFV config file isolation (#165) --- CMakeLists.txt | 14 +++---- src/config/ctrlm_config.cpp | 48 ++++++++++++++++++++-- src/config/ctrlm_config.h | 8 +++- src/ctrlm_config_default.json | 4 -- src/ctrlm_main.cpp | 76 ++++++++++++++++++++++++++--------- src/voice/ctrlm_voice_obj.cpp | 60 ++------------------------- src/voice/ctrlm_voice_obj.h | 2 - 7 files changed, 120 insertions(+), 92 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c38b5657..565ab874 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -165,7 +165,7 @@ target_link_libraries( install(TARGETS controlMgr RUNTIME DESTINATION bin) -install(FILES ${CMAKE_BINARY_DIR}/ctrlm_config.json.template DESTINATION ${CMAKE_INSTALL_SYSCONFDIR} COMPONENT config ) +install(FILES ${CMAKE_BINARY_DIR}/ctrlm_config.json DESTINATION ${CMAKE_INSTALL_SYSCONFDIR} COMPONENT config ) # DEFINES FROM OPTIONS if(ANSI_CODES_DISABLED) @@ -260,7 +260,7 @@ endif() install(TARGETS controlMgr RUNTIME DESTINATION bin) -install(FILES ${CMAKE_BINARY_DIR}/ctrlm_config.json.template DESTINATION ${CMAKE_INSTALL_SYSCONFDIR} COMPONENT config ) +install(FILES ${CMAKE_BINARY_DIR}/ctrlm_config.json DESTINATION ${CMAKE_INSTALL_SYSCONFDIR} COMPONENT config ) # GENERATED FILES add_custom_command( OUTPUT ctrlm_version_build.h @@ -276,16 +276,16 @@ add_custom_command( OUTPUT ctrlm_version_build.h ) add_custom_command( - OUTPUT ${CMAKE_BINARY_DIR}/ctrlm_config.json.template - COMMAND python3 ${CTRLM_UTILS_JSON_COMBINE} -i ${CMAKE_CURRENT_SOURCE_DIR}/src/ctrlm_config_default.json -a ${CTRLM_CONFIG_JSON_VSDK}:vsdk -a ${CTRLM_CONFIG_JSON_CPC} -s ${CTRLM_CONFIG_JSON_CPC_SUB} -a ${CTRLM_CONFIG_JSON_CPC_ADD} -s ${CTRLM_CONFIG_JSON_OEM_SUB} -a ${CTRLM_CONFIG_JSON_OEM_ADD} -s ${CTRLM_CONFIG_JSON_MAIN_SUB} -a ${CTRLM_CONFIG_JSON_MAIN_ADD} -o ${CMAKE_BINARY_DIR}/ctrlm_config.json.template + OUTPUT ${CMAKE_BINARY_DIR}/ctrlm_config.json + COMMAND python3 ${CTRLM_UTILS_JSON_COMBINE} -i ${CMAKE_CURRENT_SOURCE_DIR}/src/ctrlm_config_default.json -a ${CTRLM_CONFIG_JSON_CPC} -s ${CTRLM_CONFIG_JSON_CPC_SUB} -a ${CTRLM_CONFIG_JSON_CPC_ADD} -s ${CTRLM_CONFIG_JSON_MAIN_SUB} -a ${CTRLM_CONFIG_JSON_MAIN_ADD} -o ${CMAKE_BINARY_DIR}/ctrlm_config.json DEPENDS src/ctrlm_config_default.json VERBATIM ) add_custom_command( OUTPUT ctrlm_config_default.h ${CMAKE_CURRENT_SOURCE_DIR}/src/ctrlm_config_default.c - COMMAND python3 ${CTRLM_UTILS_JSON_TO_HEADER} -i ${CMAKE_BINARY_DIR}/ctrlm_config.json.template -o ctrlm_config_default.h -c ${CMAKE_CURRENT_SOURCE_DIR}/src/ctrlm_config_default.c -v "ctrlm_global,network_rf4ce,network_ip,network_ble,ir,voice,device_update" -d "network_ble" - DEPENDS ${CMAKE_BINARY_DIR}/ctrlm_config.json.template + COMMAND python3 ${CTRLM_UTILS_JSON_TO_HEADER} -i ${CMAKE_BINARY_DIR}/ctrlm_config.json -o ctrlm_config_default.h -c ${CMAKE_CURRENT_SOURCE_DIR}/src/ctrlm_config_default.c -v "ctrlm_global,network_rf4ce,network_ip,network_ble,ir,voice,device_update" -d "network_ble" + DEPENDS ${CMAKE_BINARY_DIR}/ctrlm_config.json VERBATIM ) @@ -296,5 +296,5 @@ add_custom_command( ) add_custom_target( ctrlm_config - DEPENDS ${CMAKE_BINARY_DIR}/ctrlm_config.json.template + DEPENDS ${CMAKE_BINARY_DIR}/ctrlm_config.json ) diff --git a/src/config/ctrlm_config.cpp b/src/config/ctrlm_config.cpp index f49b523e..eb0ed60e 100644 --- a/src/config/ctrlm_config.cpp +++ b/src/config/ctrlm_config.cpp @@ -54,7 +54,7 @@ ctrlm_config_t::~ctrlm_config_t() { } } -bool ctrlm_config_t::load_config(const std::string &file_path) { +bool ctrlm_config_t::load_config(const std::string &file_path, bool verbose) { bool ret = false; std::string contents = file_to_string(file_path); if(this->root) { @@ -63,13 +63,19 @@ bool ctrlm_config_t::load_config(const std::string &file_path) { } if(!contents.empty()) { json_error_t json_error; - XLOGD_INFO_OPTS(XLOG_OPTS_DEFAULT, 20 * 1024, "Loading Configuration for <%s> <%s>", file_path.c_str(), contents.c_str()); + if(verbose) { + XLOGD_INFO_OPTS(XLOG_OPTS_DEFAULT, 20 * 1024, "Loading Configuration for <%s> <%s>", file_path.c_str(), contents.c_str()); + } else { + XLOGD_INFO("Loading Configuration for <%s>", file_path.c_str()); + } this->root = json_loads(contents.c_str(), JSON_REJECT_DUPLICATES, &json_error); if(this->root != NULL) { - XLOGD_INFO("config loaded successfully as JSON"); + if(verbose) { + XLOGD_INFO("config loaded successfully as JSON for <%s>", file_path.c_str()); + } ret = true; } else { - XLOGD_ERROR("JSON ERROR: Line <%u> Column <%u> Text <%s>", json_error.line, json_error.column, json_error.text); + XLOGD_ERROR("JSON ERROR: Line <%u> Column <%u> Text <%s> Contents <%s>", json_error.line, json_error.column, json_error.text, contents.c_str()); } } else { XLOGD_ERROR("no config file contents"); @@ -77,6 +83,40 @@ bool ctrlm_config_t::load_config(const std::string &file_path) { return(ret); } +bool ctrlm_config_t::append_config(const std::string &file_path, bool verbose) { + if(this->root == NULL) { + XLOGD_ERROR("no config file loaded"); + return(false); + } + bool ret = false; + std::string contents = file_to_string(file_path); + if(contents.empty()) { + XLOGD_ERROR("no config file contents"); + } else { + json_error_t json_error; + if(verbose) { + XLOGD_INFO_OPTS(XLOG_OPTS_DEFAULT, 20 * 1024, "Appending Configuration for <%s> <%s>", file_path.c_str(), contents.c_str()); + } else { + XLOGD_INFO("Appending Configuration for <%s>", file_path.c_str()); + } + json_t *append_root = json_loads(contents.c_str(), JSON_REJECT_DUPLICATES, &json_error); + if(append_root == NULL) { + XLOGD_ERROR("JSON ERROR: Line <%u> Column <%u> Text <%s> Contents <%s>", json_error.line, json_error.column, json_error.text, contents.c_str()); + } else { + if(json_object_update(this->root, append_root) != 0) { + XLOGD_ERROR("Failed to merge JSON objects"); + } else { + if(verbose) { + XLOGD_INFO("config appended successfully as JSON for <%s>", file_path.c_str()); + } + ret = true; + } + json_decref(append_root); + } + } + return(ret); +} + bool ctrlm_config_t::path_exists(const std::string &path) { return(ctrlm_utils_json_from_path(this->root, path, false) != NULL ? true : false); } diff --git a/src/config/ctrlm_config.h b/src/config/ctrlm_config.h index a64eb6f7..755e5b4b 100644 --- a/src/config/ctrlm_config.h +++ b/src/config/ctrlm_config.h @@ -49,7 +49,13 @@ class ctrlm_config_t { * @param file_path The path to the configuration file * @return True on success, otherwise False */ - bool load_config(const std::string &file_path); + bool load_config(const std::string &file_path, bool verbose = false); + /** + * Function which appends a configuration file into the configuration object. + * @param file_path The path to the configuration file + * @return True on success, otherwise False + */ + bool append_config(const std::string &file_path, bool verbose = false); /** * Function to check if object exists from a path * @param path A period seperated string used to navigate a JSON object i.e. "network_rf4ce.polling.enabled" diff --git a/src/ctrlm_config_default.json b/src/ctrlm_config_default.json index a30bde8a..af65c196 100755 --- a/src/ctrlm_config_default.json +++ b/src/ctrlm_config_default.json @@ -7,8 +7,6 @@ "authservice_poll_period" : 5, "authservice_fast_poll_period" : 1000, "authservice_fast_max_retries" : 25, - "keycode_logging_poll_period" : 30, - "keycode_logging_max_retries" : 5, "url_auth_service" : "", "timeout_recently_booted" : 1800000, "timeout_line_of_sight" : 10000, @@ -16,7 +14,6 @@ "timeout_button_binding" : 600000, "timeout_screen_bind" : 600000, "timeout_one_touch_autobind" : 600000, - "mask_key_codes" : false, "mask_pii" : [true, false], "crash_recovery_threshold" : 2, "device_id" : "", @@ -263,7 +260,6 @@ "utterance_path" : "/opt/logs/rf4ce_adpcm_header_vrex.raw", "force_voice_settings" : false, "vrex_response_timeout" : 10000, - "keyword_detect_sensitivity" : 0.3, "opus_encoder_params" : "4080084410", "packet_loss_threshold" : 5, "vrex_test_flag" : false, diff --git a/src/ctrlm_main.cpp b/src/ctrlm_main.cpp index 0794c861..4c9d9faa 100644 --- a/src/ctrlm_main.cpp +++ b/src/ctrlm_main.cpp @@ -1601,8 +1601,7 @@ gboolean ctrlm_load_authservice_data(void) { gboolean ctrlm_load_config(json_t **json_obj_root, json_t **json_obj_net_rf4ce, json_t **json_obj_voice, json_t **json_obj_device_update, json_t **json_obj_validation, json_t **json_obj_vsdk) { std::string config_fn_opt = "/opt/ctrlm_config.json"; - std::string config_fn_etc = "/etc/ctrlm_config.json"; - std::string config_fn_etc_override = "/etc/ctrlm_config.json.OVERRIDE"; + std::string config_fn_oem = "/etc/vendor/input/ctrlm_config.json"; json_t *json_obj_ctrlm; ctrlm_config_t *ctrlm_config = ctrlm_config_t::get_instance(); gboolean local_conf = false; @@ -1612,18 +1611,44 @@ gboolean ctrlm_load_config(json_t **json_obj_root, json_t **json_obj_net_rf4ce, if(ctrlm_config == NULL) { XLOGD_ERROR("Failed to get config manager instance"); return(false); - } else if(!ctrlm_is_production_build() && g_file_test(config_fn_opt.c_str(), G_FILE_TEST_EXISTS) && ctrlm_config->load_config(config_fn_opt)) { - XLOGD_INFO("Read configuration from <%s>", config_fn_opt.c_str()); - local_conf = true; - } else if(g_file_test(config_fn_etc.c_str(), G_FILE_TEST_EXISTS) && ctrlm_config->load_config(config_fn_etc)) { - XLOGD_INFO("Read configuration from <%s>", config_fn_etc.c_str()); - } else if(g_file_test(config_fn_etc_override.c_str(), G_FILE_TEST_EXISTS) && ctrlm_config->load_config(config_fn_etc_override)) { - XLOGD_INFO("Read configuration from <%s>", config_fn_etc_override.c_str()); - } else { - XLOGD_WARN("Configuration error. Configuration file(s) missing, using defaults"); + } + + bool oem_append = g_file_test(config_fn_oem.c_str(), G_FILE_TEST_EXISTS); + bool opt_append = ctrlm_is_production_build() ? false : g_file_test(config_fn_opt.c_str(), G_FILE_TEST_EXISTS); + + if(!oem_append && !opt_append) { + XLOGD_INFO("Using default configuration"); return(false); } + // Check for OEM config file override + if(oem_append) { + XLOGD_INFO("Loading OEM configuration from <%s>", config_fn_oem.c_str()); + if(!ctrlm_config->load_config(config_fn_oem)) { + XLOGD_ERROR("Failed to load OEM configuration from <%s>", config_fn_oem.c_str()); + return(false); + } + } + + // Check for OPT config file override + if(opt_append) { + if(!oem_append) { + XLOGD_INFO("Loading OPT configuration from <%s>", config_fn_opt.c_str()); + if(!ctrlm_config->load_config(config_fn_opt)) { + XLOGD_ERROR("Failed to load OPT configuration from <%s>", config_fn_opt.c_str()); + return(false); + } + } else { + XLOGD_INFO("Appending OPT configuration from <%s>", config_fn_opt.c_str()); + + if(!ctrlm_config->append_config(config_fn_opt)) { + XLOGD_ERROR("Failed to append OPT configuration from <%s>", config_fn_opt.c_str()); + return(false); + } + } + local_conf = true; + } + // Parse the JSON data *json_obj_root = ctrlm_config->json_from_path("", true); // Get root AND add ref to it, since this code derefs it if(*json_obj_root == NULL) { @@ -1637,37 +1662,52 @@ gboolean ctrlm_load_config(json_t **json_obj_root, json_t **json_obj_net_rf4ce, return(false); } + // Print the configuration since it was loaded from files + char *json_dump = json_dumps(*json_obj_root, JSON_INDENT(3) | JSON_SORT_KEYS); + if(json_dump == NULL) { + XLOGD_ERROR("unable to dump JSON object"); + json_decref(*json_obj_root); + *json_obj_root = NULL; + return(false); + } else { + XLOGD_INFO_OPTS(XLOG_OPTS_DEFAULT, 20 * 1024, "Final configuration:\n%s", json_dump); + free(json_dump); + } + // Extract the RF4CE network configuration object if(g_ctrlm.rf4ce_enabled) { *json_obj_net_rf4ce = json_object_get(*json_obj_root, JSON_OBJ_NAME_NETWORK_RF4CE); if(*json_obj_net_rf4ce == NULL || !json_is_object(*json_obj_net_rf4ce)) { - XLOGD_WARN("RF4CE network object not found"); + XLOGD_INFO("RF4CE network object not found"); + *json_obj_net_rf4ce = NULL; } } // Extract the voice configuration object *json_obj_voice = json_object_get(*json_obj_root, JSON_OBJ_NAME_VOICE); if(*json_obj_voice == NULL || !json_is_object(*json_obj_voice)) { - XLOGD_WARN("voice object not found"); + XLOGD_INFO("voice object not found"); + *json_obj_voice = NULL; } // Extract the device update configuration object *json_obj_device_update = json_object_get(*json_obj_root, JSON_OBJ_NAME_DEVICE_UPDATE); if(*json_obj_device_update == NULL || !json_is_object(*json_obj_device_update)) { - XLOGD_WARN("device update object not found"); + XLOGD_INFO("device update object not found"); + *json_obj_device_update = NULL; } //Extract the vsdk configuration object *json_obj_vsdk = json_object_get( *json_obj_root, JSON_OBJ_NAME_VSDK); if(*json_obj_vsdk == NULL || !json_is_object(*json_obj_vsdk)) { - XLOGD_WARN("vsdk object not found"); - json_obj_vsdk = NULL; + XLOGD_INFO("vsdk object not found"); + *json_obj_vsdk = NULL; } // Extract the ctrlm global configuration object json_obj_ctrlm = json_object_get(*json_obj_root, JSON_OBJ_NAME_CTRLM_GLOBAL); if(json_obj_ctrlm == NULL || !json_is_object(json_obj_ctrlm)) { - XLOGD_WARN("control manger object not found"); + XLOGD_INFO("control manager object not found"); } else { json_config conf_global; if(!conf_global.config_object_set(json_obj_ctrlm)) { @@ -1677,7 +1717,7 @@ gboolean ctrlm_load_config(json_t **json_obj_root, json_t **json_obj_net_rf4ce, // Extract the validation configuration object *json_obj_validation = json_object_get(json_obj_ctrlm, JSON_OBJ_NAME_CTRLM_GLOBAL_VALIDATION_CONFIG); if(*json_obj_validation == NULL || !json_is_object(*json_obj_validation)) { - XLOGD_WARN("validation object not found"); + XLOGD_INFO("validation object not found"); } // Now parse the control manager object diff --git a/src/voice/ctrlm_voice_obj.cpp b/src/voice/ctrlm_voice_obj.cpp index d114aeea..ba00c02b 100644 --- a/src/voice/ctrlm_voice_obj.cpp +++ b/src/voice/ctrlm_voice_obj.cpp @@ -205,7 +205,6 @@ ctrlm_voice_t::ctrlm_voice_t() { this->prefs.utterance_duration_min = JSON_INT_VALUE_VOICE_MINIMUM_DURATION; this->prefs.ffv_leading_samples = JSON_INT_VALUE_VOICE_FFV_LEADING_SAMPLES; this->prefs.force_voice_settings = JSON_BOOL_VALUE_VOICE_FORCE_VOICE_SETTINGS; - this->prefs.keyword_sensitivity = JSON_FLOAT_VALUE_VOICE_KEYWORD_DETECT_SENSITIVITY; this->prefs.vrex_test_flag = JSON_BOOL_VALUE_VOICE_VREX_TEST_FLAG; this->prefs.vrex_wuw_bypass_success_flag = JSON_BOOL_VALUE_VOICE_VREX_WUW_BYPASS_SUCCESS_FLAG; this->prefs.vrex_wuw_bypass_failure_flag = JSON_BOOL_VALUE_VOICE_VREX_WUW_BYPASS_FAILURE_FLAG; @@ -340,29 +339,12 @@ bool ctrlm_voice_t::vsdk_is_privacy_enabled(void) { return privacy; } -double ctrlm_voice_t::vsdk_keyword_sensitivity_limit_check(double sensitivity) { - float sensitivity_min; - float sensitivity_max; - - if(!xrsr_keyword_sensitivity_limits_get(&sensitivity_min, &sensitivity_max)) { - XLOGD_WARN("Unable to get keyword detector sensitivity limits. Using default sensitivity <%f>.", JSON_FLOAT_VALUE_VOICE_KEYWORD_DETECT_SENSITIVITY); - return(JSON_FLOAT_VALUE_VOICE_KEYWORD_DETECT_SENSITIVITY); - } else { - if(((float)(sensitivity) < sensitivity_min) || ((float)(sensitivity) > sensitivity_max)) { - XLOGD_WARN("Keyword detector sensitivity <%f> outside of range <%f to %f>. Using default sensitivity <%f>.", (float)(sensitivity), sensitivity_min, sensitivity_max, JSON_FLOAT_VALUE_VOICE_KEYWORD_DETECT_SENSITIVITY); - return(JSON_FLOAT_VALUE_VOICE_KEYWORD_DETECT_SENSITIVITY); - } - } - return(sensitivity); -} - void ctrlm_voice_t::voice_sdk_open(json_t *json_obj_vsdk) { if(this->xrsr_opened) { XLOGD_ERROR("already open"); return; } xrsr_route_t routes[1]; - xrsr_keyword_config_t kw_config; xrsr_capture_config_t capture_config = { .delete_files = !this->prefs.utterance_save, .enable = this->prefs.utterance_save, @@ -382,7 +364,6 @@ void ctrlm_voice_t::voice_sdk_open(json_t *json_obj_vsdk) { /* Open Voice SDK */ routes[0].src = XRSR_SRC_INVALID; routes[0].dst_qty = 0; - kw_config.sensitivity = this->prefs.keyword_sensitivity; char host_name[HOST_NAME_MAX]; host_name[0] = '\0'; @@ -398,7 +379,7 @@ void ctrlm_voice_t::voice_sdk_open(json_t *json_obj_vsdk) { ctrlm_power_state_t ctrlm_power_state = ctrlm_main_get_internal_power_state(); xrsr_power_mode_t xrsr_power_mode = voice_xrsr_power_map(ctrlm_power_state); - if(!xrsr_open(host_name, routes, &kw_config, &capture_config, xrsr_power_mode, privacy, this->mask_pii, json_obj_vsdk)) { + if(!xrsr_open(host_name, routes, NULL, &capture_config, xrsr_power_mode, privacy, this->mask_pii, json_obj_vsdk)) { XLOGD_ERROR("Failed to open speech router"); g_assert(0); } @@ -479,7 +460,6 @@ bool ctrlm_voice_t::voice_configure_config_file_json(json_t *obj_voice, json_t * conf.config_value_get(JSON_INT_NAME_VOICE_FFV_LEADING_SAMPLES, this->prefs.ffv_leading_samples, 0); conf.config_value_get(JSON_STR_NAME_VOICE_APP_ID_HTTP, this->prefs.app_id_http); conf.config_value_get(JSON_STR_NAME_VOICE_APP_ID_WS, this->prefs.app_id_ws); - conf.config_value_get(JSON_FLOAT_NAME_VOICE_KEYWORD_DETECT_SENSITIVITY, this->prefs.keyword_sensitivity, 0.0, DBL_MAX); conf.config_value_get(JSON_BOOL_NAME_VOICE_VREX_TEST_FLAG, this->prefs.vrex_test_flag); conf.config_value_get(JSON_BOOL_NAME_VOICE_VREX_WUW_BYPASS_SUCCESS_FLAG,this->prefs.vrex_wuw_bypass_success_flag); conf.config_value_get(JSON_BOOL_NAME_VOICE_VREX_WUW_BYPASS_FAILURE_FLAG,this->prefs.vrex_wuw_bypass_failure_flag); @@ -487,8 +467,9 @@ bool ctrlm_voice_t::voice_configure_config_file_json(json_t *obj_voice, json_t * conf.config_value_get(JSON_BOOL_NAME_VOICE_TELEMETRY_SESSION_STATS, this->prefs.telemetry_session_stats); std::string opus_encoder_params_str; - conf.config_value_get(JSON_STR_NAME_VOICE_OPUS_ENCODER_PARAMS, opus_encoder_params_str); - this->voice_params_opus_encoder_validate(opus_encoder_params_str); + if(conf.config_value_get(JSON_STR_NAME_VOICE_OPUS_ENCODER_PARAMS, opus_encoder_params_str)) { + this->voice_params_opus_encoder_validate(opus_encoder_params_str); + } conf.config_value_get(JSON_INT_NAME_VOICE_PAR_VOICE_EOS_METHOD, this->prefs.par_voice_eos_method); conf.config_value_get(JSON_INT_NAME_VOICE_PAR_VOICE_EOS_TIMEOUT, this->prefs.par_voice_eos_timeout); @@ -604,17 +585,6 @@ bool ctrlm_voice_t::voice_configure_config_file_json(json_t *obj_voice, json_t * if(privacy_enabled != this->vsdk_is_privacy_enabled()) { privacy_enabled ? this->voice_privacy_enable(false) : this->voice_privacy_disable(false); } - // Check keyword detector sensitivity value against limits; apply default if out of range. - double sensitivity_set = this->vsdk_keyword_sensitivity_limit_check(this->prefs.keyword_sensitivity); - if(sensitivity_set != this->prefs.keyword_sensitivity) { - xrsr_keyword_config_t kw_config; - kw_config.sensitivity = (float)sensitivity_set; - if(!xrsr_keyword_config_set(&kw_config)) { - XLOGD_ERROR("error updating keyword config"); - } else { - this->prefs.keyword_sensitivity = sensitivity_set; - } - } } } @@ -1011,12 +981,6 @@ void ctrlm_voice_t::process_xconf(json_t **json_obj_vsdk, bool local_conf) { // CTRLM_TR181_VOICE_PARAMS_AUDIO_DUCKING_BEEP doesn't exist because this is a user configurable setting via configureVoice thunder api - double keyword_sensitivity = 0.0; - result = ctrlm_tr181_real_get(CTRLM_TR181_VOICE_PARAMS_KEYWORD_SENSITIVITY, &keyword_sensitivity); - if(result == CTRLM_TR181_RESULT_SUCCESS) { - this->prefs.keyword_sensitivity = (keyword_sensitivity < 0.0) ? JSON_FLOAT_VALUE_VOICE_KEYWORD_DETECT_SENSITIVITY : keyword_sensitivity; - } - result = ctrlm_tr181_string_get(CTRLM_TR181_VOICE_PARAMS_VSDK_CONFIGURATION, &vsdk_config_str[0], CTRLM_RFC_MAX_PARAM_LEN); if(result == CTRLM_TR181_RESULT_SUCCESS) { json_error_t jerror; @@ -4038,22 +4002,6 @@ void ctrlm_voice_t::voice_rfc_retrieved_handler(const ctrlm_rfc_attr_t& attr) { attr.get_rfc_value(JSON_STR_NAME_VOICE_APP_ID_WS, this->prefs.app_id_ws); attr.get_rfc_value(JSON_STR_NAME_VOICE_LANGUAGE, this->prefs.guide_language); - double keyword_sensitivity = 0.0; - if(attr.get_rfc_value(JSON_FLOAT_NAME_VOICE_KEYWORD_DETECT_SENSITIVITY, keyword_sensitivity)) { - // Check keyword detector sensitivity value against limits; apply default if out of range. - double sensitivity_set = this->vsdk_keyword_sensitivity_limit_check(keyword_sensitivity); - if(sensitivity_set != keyword_sensitivity) { - XLOGD_ERROR("keyword sensitivity <%5.2f> out of limits", keyword_sensitivity); - } else { - this->prefs.keyword_sensitivity = keyword_sensitivity; - XLOGD_INFO("keyword sensitivity <%5.2f>", this->prefs.keyword_sensitivity); - xrsr_keyword_config_t kw_config; - kw_config.sensitivity = (float)this->prefs.keyword_sensitivity; - if(!xrsr_keyword_config_set(&kw_config)) { - XLOGD_ERROR("error updating keyword config"); - } - } - } attr.get_rfc_value(JSON_BOOL_NAME_VOICE_VREX_TEST_FLAG, this->prefs.vrex_test_flag); attr.get_rfc_value(JSON_BOOL_NAME_VOICE_VREX_WUW_BYPASS_SUCCESS_FLAG,this->prefs.vrex_wuw_bypass_success_flag); attr.get_rfc_value(JSON_BOOL_NAME_VOICE_VREX_WUW_BYPASS_FAILURE_FLAG,this->prefs.vrex_wuw_bypass_failure_flag); diff --git a/src/voice/ctrlm_voice_obj.h b/src/voice/ctrlm_voice_obj.h index 3976a62c..c4395b18 100644 --- a/src/voice/ctrlm_voice_obj.h +++ b/src/voice/ctrlm_voice_obj.h @@ -296,7 +296,6 @@ typedef struct { unsigned long utterance_duration_min; unsigned long ffv_leading_samples; bool force_voice_settings; - double keyword_sensitivity; bool vrex_test_flag; bool vrex_wuw_bypass_success_flag; bool vrex_wuw_bypass_failure_flag; @@ -745,7 +744,6 @@ class ctrlm_voice_t { void set_audio_mode(ctrlm_voice_audio_settings_t *settings); void audio_state_set(bool session); bool vsdk_is_privacy_enabled(void); - double vsdk_keyword_sensitivity_limit_check(double sensitivity); void pre_session_terminate(std::function cb_start_audio, ctrlm_voice_start_audio_params_t *cb_audio_start_params, ctrlm_voice_session_rsp_confirm_t *cb_confirm, From 517b50145dabb0e63c573d55cb5a76e008dc37b8 Mon Sep 17 00:00:00 2001 From: Gene Gallagher <129112619+egalla204@users.noreply.github.com> Date: Mon, 9 Feb 2026 14:12:00 -0500 Subject: [PATCH 27/39] RDKEMW-9474: ctrlm multiple simultaneous IR databases (#161) add support for having multiple IR database vendor implementations simultaneously --- src/ble/ctrlm_ble_controller.cpp | 29 ++++++++++++--- src/ble/ctrlm_ble_network.cpp | 3 +- .../bleservices/gatt/gatt_infraredservice.cpp | 8 +++- src/irdb/ctrlm_irdb_interface.cpp | 37 +++++++++++++++++++ src/irdb/ctrlm_irdb_interface.h | 1 + src/irdb/ctrlm_irdb_plugin.h | 6 +++ src/irdb/ctrlm_irdb_stub.cpp | 10 +++++ src/irdb/ctrlm_irdb_stub.h | 4 ++ 8 files changed, 90 insertions(+), 8 deletions(-) diff --git a/src/ble/ctrlm_ble_controller.cpp b/src/ble/ctrlm_ble_controller.cpp index fdbd155f..f1a87c22 100644 --- a/src/ble/ctrlm_ble_controller.cpp +++ b/src/ble/ctrlm_ble_controller.cpp @@ -531,13 +531,30 @@ void ctrlm_obj_controller_ble_t::setSupportedIrdbs(uint8_t vendor_support_bitmas this->irdbs_supported_ = vendor_support_bitmask; ctrlm_irdb_interface_t *irdb = ctrlm_main_irdb_get(); - ctrlm_irdb_vendor_info_t vendor_info; - if (irdb && irdb->get_vendor_info(vendor_info)) { - XLOGD_INFO("Controller <%s> IRDBs supported bitmask = <0x%X>, which %s support the loaded IRDB plugin vendor <%s>", - ieee_address_get().to_string().c_str(), vendor_support_bitmask, - isSupportedIrdb(vendor_info) ? "DOES" : "does NOT", vendor_info.name.c_str()); + + if (irdb == NULL) { + XLOGD_ERROR("IRDB interface is NULL!!!"); + return; + } + + ctrlm_irdb_vendor_info_t rcu_vendor_info{}; + rcu_vendor_info.rcu_support_bitmask = vendor_support_bitmask; + if (!irdb->set_vendor(rcu_vendor_info)) { + XLOGD_ERROR("Failed to set IRDB vendor info for controller <%s> with bitmask <0x%X>.", + ieee_address_get().to_string().c_str(), vendor_support_bitmask); + } + + ctrlm_irdb_vendor_info_t vendor_info{}; + if (irdb->get_vendor_info(vendor_info)) { + if (isSupportedIrdb(vendor_info)) { + XLOGD_INFO("Controller <%s> IRDBs supported bitmask = <0x%X>, which DOES support the loaded IRDB plugin vendor <%s>", + ieee_address_get().to_string().c_str(), vendor_support_bitmask, vendor_info.name.c_str()); + } else { + XLOGD_ERROR("Controller <%s> IRDBs supported bitmask = <0x%X>, which does NOT support the loaded IRDB plugin vendor <%s>", + ieee_address_get().to_string().c_str(), vendor_support_bitmask, vendor_info.name.c_str()); + } } else { - XLOGD_INFO("Controller <%s> IRDBs supported bitmask = <0x%X>, couldn't retrieve IRDB plugin vendor info.", + XLOGD_WARN("Controller <%s> IRDBs supported bitmask = <0x%X>, couldn't retrieve IRDB plugin vendor info.", ieee_address_get().to_string().c_str(), vendor_support_bitmask); } } diff --git a/src/ble/ctrlm_ble_network.cpp b/src/ble/ctrlm_ble_network.cpp index aff81aeb..03e1322f 100644 --- a/src/ble/ctrlm_ble_network.cpp +++ b/src/ble/ctrlm_ble_network.cpp @@ -2031,6 +2031,8 @@ ctrlm_controller_id_t ctrlm_obj_network_ble_t::controller_add(ctrlm_hal_ble_rcu_ controller->setName(string(rcu_data.name)); controller->setAudioCodecs(rcu_data.audio_codecs); controller->setConnected(rcu_data.connected); + controller->setSupportedIrdbs(rcu_data.irdbs_supported); + // only update these parameters if they are not empty or invalid. if (rcu_data.serial_number[0] != '\0') { controller->setSerialNumber(string(rcu_data.serial_number)); } if (rcu_data.manufacturer[0] != '\0') { controller->setManufacturer(string(rcu_data.manufacturer)); } @@ -2042,7 +2044,6 @@ ctrlm_controller_id_t ctrlm_obj_network_ble_t::controller_add(ctrlm_hal_ble_rcu_ if (rcu_data.battery_level != 0xFF) { controller->setBatteryPercent(rcu_data.battery_level); } if (rcu_data.wakeup_config != 0xFF) { controller->setWakeupConfig(rcu_data.wakeup_config); } if (rcu_data.wakeup_custom_list_size != 0) { controller->setWakeupCustomList(rcu_data.wakeup_custom_list, rcu_data.wakeup_custom_list_size); } - if (rcu_data.irdbs_supported != 0) { controller->setSupportedIrdbs(rcu_data.irdbs_supported); } if (rcu_data.last_wakeup_key != 0xFF) { controller->setLastWakeupKey(rcu_data.last_wakeup_key); } controller->db_store(); diff --git a/src/ble/hal/blercu/bleservices/gatt/gatt_infraredservice.cpp b/src/ble/hal/blercu/bleservices/gatt/gatt_infraredservice.cpp index 8d8061d5..40dff3c6 100644 --- a/src/ble/hal/blercu/bleservices/gatt/gatt_infraredservice.cpp +++ b/src/ble/hal/blercu/bleservices/gatt/gatt_infraredservice.cpp @@ -422,6 +422,11 @@ void GattInfraredService::requestIrSupport() // sanity check we actually have a ir support characteristic if (!m_irSupportCharacteristic || !m_irSupportCharacteristic->isValid()) { XLOGD_WARN("missing ir support characteristic"); + + // Set ir support back to invalid value and notify + m_irSupport = 0; + m_irSupportChangedSlots.invoke(m_irSupport); + return; } @@ -434,8 +439,9 @@ void GattInfraredService::requestIrSupport() XLOGD_ERROR("failed to get initial ir support code due to <%s>", reply->errorMessage().c_str()); + // Set ir support back to invalid value and notify m_irSupport = 0; - + m_irSupportChangedSlots.invoke(m_irSupport); } else { std::vector value; diff --git a/src/irdb/ctrlm_irdb_interface.cpp b/src/irdb/ctrlm_irdb_interface.cpp index 18a02e57..01fa6588 100644 --- a/src/irdb/ctrlm_irdb_interface.cpp +++ b/src/irdb/ctrlm_irdb_interface.cpp @@ -69,6 +69,8 @@ typedef struct { std::string (*pluginVersion)() = NULL; bool (*pluginInitialize)() = NULL; bool (*pluginGetVendorInfo)(ctrlm_irdb_vendor_info_t &info) = NULL; + bool (*pluginGetSupportedVendors)(std::vector &info) = NULL; + bool (*pluginSetPreferredVendor)(const ctrlm_irdb_vendor_info_t &vendor) = NULL; bool (*pluginGetManufacturers)(ctrlm_irdb_manufacturer_list_t &manufacturers, ctrlm_irdb_dev_type_t type, const std::string &prefix) = NULL; bool (*pluginGetModels)(ctrlm_irdb_model_list_t &models, ctrlm_irdb_dev_type_t type, const std::string &manufacturer, const std::string &prefix) = NULL; bool (*pluginGetEntryIds)(ctrlm_irdb_entry_id_list_t &codes, ctrlm_irdb_dev_type_t type, const std::string &manufacturer, const std::string &model) = NULL; @@ -133,6 +135,8 @@ ctrlm_irdb_interface_t::ctrlm_irdb_interface_t(bool platform_tv) { g_irdb.pluginVersion = STUB_irdb_version; g_irdb.pluginInitialize = STUB_ctrlm_irdb_initialize; g_irdb.pluginGetVendorInfo = STUB_ctrlm_irdb_get_vendor_info; + g_irdb.pluginSetPreferredVendor = STUB_ctrlm_irdb_set_preferred_vendor; + g_irdb.pluginGetSupportedVendors = STUB_ctrlm_irdb_get_supported_vendor_info; g_irdb.pluginGetManufacturers = STUB_ctrlm_irdb_get_manufacturers; g_irdb.pluginGetModels = STUB_ctrlm_irdb_get_models; g_irdb.pluginGetEntryIds = STUB_ctrlm_irdb_get_entry_ids; @@ -183,6 +187,20 @@ ctrlm_irdb_interface_t::ctrlm_irdb_interface_t(bool platform_tv) { } dlerror(); // Clear any existing error + *(void **) (&g_irdb.pluginGetSupportedVendors) = dlsym(m_irdbPluginHandle, "ctrlm_irdb_get_supported_vendor_info"); + if ((error = dlerror()) != NULL) { + XLOGD_ERROR("Failed to find plugin method (ctrlm_irdb_get_supported_vendor_info), error <%s>, Using STUB implementation", error); + g_irdb.pluginGetSupportedVendors = STUB_ctrlm_irdb_get_supported_vendor_info; + } + dlerror(); // Clear any existing error + + *(void **) (&g_irdb.pluginSetPreferredVendor) = dlsym(m_irdbPluginHandle, "ctrlm_irdb_set_preferred_vendor"); + if ((error = dlerror()) != NULL) { + XLOGD_ERROR("Failed to find plugin method (ctrlm_irdb_set_preferred_vendor), error <%s>, Using STUB implementation", error); + g_irdb.pluginSetPreferredVendor = STUB_ctrlm_irdb_set_preferred_vendor; + } + dlerror(); // Clear any existing error + *(void **) (&g_irdb.pluginGetManufacturers) = dlsym(m_irdbPluginHandle, "ctrlm_irdb_get_manufacturers"); if ((error = dlerror()) != NULL) { XLOGD_ERROR("Failed to find plugin method (ctrlm_irdb_get_manufacturers), error <%s>, Using STUB implementation", error); @@ -279,6 +297,17 @@ bool ctrlm_irdb_interface_t::open_plugin() { } } XLOGD_INFO("IRDB plugin opened, ret = <%s>", ret ? "SUCCESS" : "ERROR"); + + if (g_irdb.pluginGetSupportedVendors) { + std::vector supported_vendors; + if ((*g_irdb.pluginGetSupportedVendors)(supported_vendors) == true) { + for (const auto &it : supported_vendors) { + XLOGD_INFO("Found supported IRDB Vendor <%s, 0x%X>", it.name.c_str(), it.rcu_support_bitmask); + } + } else { + XLOGD_WARN("Unable to query IRDB plugin for list of supported vendors, check version of the plugin..."); + } + } return ret; } @@ -300,6 +329,14 @@ bool ctrlm_irdb_interface_t::get_vendor_info(ctrlm_irdb_vendor_info_t &info) { return false; } +bool ctrlm_irdb_interface_t::set_vendor(const ctrlm_irdb_vendor_info_t &info) { + std::unique_lock guard(m_mutex); + if (g_irdb.pluginSetPreferredVendor) { + return (*g_irdb.pluginSetPreferredVendor)(info); + } + return false; +} + void ctrlm_irdb_interface_t::on_thunder_ready() { #if defined(CTRLM_THUNDER) diff --git a/src/irdb/ctrlm_irdb_interface.h b/src/irdb/ctrlm_irdb_interface.h index 76669356..2f532b15 100644 --- a/src/irdb/ctrlm_irdb_interface.h +++ b/src/irdb/ctrlm_irdb_interface.h @@ -69,6 +69,7 @@ class ctrlm_irdb_interface_t { virtual ~ctrlm_irdb_interface_t(); bool get_vendor_info(ctrlm_irdb_vendor_info_t &info); + bool set_vendor(const ctrlm_irdb_vendor_info_t &info); bool get_manufacturers(ctrlm_irdb_manufacturer_list_t &manufacturers, ctrlm_irdb_dev_type_t type, const std::string &prefix = ""); bool get_models(ctrlm_irdb_model_list_t &models, ctrlm_irdb_dev_type_t type, const std::string &manufacturer, const std::string &prefix = ""); bool get_irdb_entry_ids(ctrlm_irdb_entry_id_list_t &codes, ctrlm_irdb_dev_type_t type, const std::string &manufacturer, const std::string &model = ""); diff --git a/src/irdb/ctrlm_irdb_plugin.h b/src/irdb/ctrlm_irdb_plugin.h index 7e1ced22..b115773d 100644 --- a/src/irdb/ctrlm_irdb_plugin.h +++ b/src/irdb/ctrlm_irdb_plugin.h @@ -88,6 +88,12 @@ bool ctrlm_irdb_close(); bool ctrlm_irdb_initialize(); +// Will return info on all the IRDB vendors currently installed, could be multiple vendors returned +bool ctrlm_irdb_get_supported_vendor_info(std::vector &info); + +// Tell the IRDB plugin which vendor(s) the RCU supports +bool ctrlm_irdb_set_preferred_vendor(const ctrlm_irdb_vendor_info_t &vendor); + bool ctrlm_irdb_get_vendor_info(ctrlm_irdb_vendor_info_t &info); bool ctrlm_irdb_get_manufacturers(ctrlm_irdb_manufacturer_list_t &manufacturers, ctrlm_irdb_dev_type_t type, const std::string &prefix); diff --git a/src/irdb/ctrlm_irdb_stub.cpp b/src/irdb/ctrlm_irdb_stub.cpp index 898cb4f0..8161e45c 100644 --- a/src/irdb/ctrlm_irdb_stub.cpp +++ b/src/irdb/ctrlm_irdb_stub.cpp @@ -46,6 +46,16 @@ bool STUB_ctrlm_irdb_get_vendor_info(ctrlm_irdb_vendor_info_t &info) XLOGD_ERROR("not implemented"); return(false); } +bool STUB_ctrlm_irdb_get_supported_vendor_info(std::vector &info) +{ + XLOGD_ERROR("not implemented"); + return(false); +} +bool STUB_ctrlm_irdb_set_preferred_vendor(const ctrlm_irdb_vendor_info_t &info) +{ + XLOGD_ERROR("not implemented"); + return(false); +} bool STUB_ctrlm_irdb_get_manufacturers(ctrlm_irdb_manufacturer_list_t &manufacturers, ctrlm_irdb_dev_type_t type, const std::string &prefix) { XLOGD_ERROR("not implemented"); diff --git a/src/irdb/ctrlm_irdb_stub.h b/src/irdb/ctrlm_irdb_stub.h index 477ec9f3..a03f6f83 100644 --- a/src/irdb/ctrlm_irdb_stub.h +++ b/src/irdb/ctrlm_irdb_stub.h @@ -32,6 +32,10 @@ bool STUB_ctrlm_irdb_initialize(); bool STUB_ctrlm_irdb_get_vendor_info(ctrlm_irdb_vendor_info_t &info); +bool STUB_ctrlm_irdb_get_supported_vendor_info(std::vector &info); + +bool STUB_ctrlm_irdb_set_preferred_vendor(const ctrlm_irdb_vendor_info_t &info); + bool STUB_ctrlm_irdb_get_manufacturers(ctrlm_irdb_manufacturer_list_t &manufacturers, ctrlm_irdb_dev_type_t type, const std::string &prefix); bool STUB_ctrlm_irdb_get_models(ctrlm_irdb_model_list_t &models, ctrlm_irdb_dev_type_t type, const std::string &manufacturer, const std::string &prefix); From 57a584043078aedc7dd28ef6489d27fc9b7a011c Mon Sep 17 00:00:00 2001 From: Gene Gallagher <129112619+egalla204@users.noreply.github.com> Date: Mon, 9 Feb 2026 18:51:20 -0500 Subject: [PATCH 28/39] RDKEMW-13049: remove RCU firmware upgrade retries on failure (#173) --- src/ctrlm_controller.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ctrlm_controller.cpp b/src/ctrlm_controller.cpp index 0d8b2154..8048ac2c 100644 --- a/src/ctrlm_controller.cpp +++ b/src/ctrlm_controller.cpp @@ -28,7 +28,7 @@ using namespace std; -#define OTA_MAX_RETRIES (2) +#define OTA_MAX_RETRIES (0) ctrlm_obj_controller_t::ctrlm_obj_controller_t(ctrlm_controller_id_t controller_id, ctrlm_obj_network_t &network, unsigned long long ieee_address) : controller_id_(controller_id), From a48ef129f9e8f4b560b3eb4ad2210be178319b4f Mon Sep 17 00:00:00 2001 From: Kelvin Lu <119349872+klu339@users.noreply.github.com> Date: Wed, 11 Feb 2026 11:16:58 -0500 Subject: [PATCH 29/39] RDKEMW-12828: device minor id, vendor, and product value updates (#175) --- src/input_event/ctrlm_input_event_writer.cpp | 67 ++++++++++++++++++-- src/input_event/ctrlm_input_event_writer.h | 5 +- src/rf4ce/ctrlm_rf4ce_controller.cpp | 18 +++++- src/rf4ce/ctrlm_rf4ce_pairing.cpp | 4 -- src/rf4ce/ctrlm_rf4ce_rib.cpp | 1 + 5 files changed, 84 insertions(+), 11 deletions(-) diff --git a/src/input_event/ctrlm_input_event_writer.cpp b/src/input_event/ctrlm_input_event_writer.cpp index c463a78e..007dd436 100644 --- a/src/input_event/ctrlm_input_event_writer.cpp +++ b/src/input_event/ctrlm_input_event_writer.cpp @@ -28,6 +28,8 @@ #include #include #include +#include +#include bool ctrlm_input_event_writer::init(std::string uinput_name, uint32_t vendor, uint32_t product) { if (initialized_) { @@ -59,8 +61,32 @@ bool ctrlm_input_event_writer::init(std::string uinput_name, uint32_t vendor, ui errno_t safec_rc = strcpy_s(usetup.name, sizeof(usetup.name), uinput_name.c_str()); ERR_CHK(safec_rc); - ioctl(fd, UI_DEV_SETUP, &usetup); - ioctl(fd, UI_DEV_CREATE); + int err = ioctl(fd, UI_DEV_SETUP, &usetup); + if (err == -1) { + int errsv = errno; + XLOGD_ERROR("UI_DEV_SETUP failed with errno %d (%s)", errsv, std::strerror(errsv)); + close(fd); + return false; + } + + err = ioctl(fd, UI_DEV_CREATE); + if (err == -1) { + int errsv = errno; + XLOGD_ERROR("UI_DEV_CREATE failed with errno %d (%s)", errsv, std::strerror(errsv)); + close(fd); + return false; + } + + char sysfs_name[16] = {0}; + err = ioctl(fd, UI_GET_SYSNAME(sizeof(sysfs_name)), sysfs_name); + if (err == -1) { + int errsv = errno; + XLOGD_ERROR("UI_GET_SYSNAME failed with errno %d (%s)", errsv, std::strerror(errsv)); + ioctl(fd, UI_DEV_DESTROY); + close(fd); + return false; + } + sysfs_name_ = sysfs_name; fd_ = fd; initialized_ = true; @@ -147,10 +173,43 @@ uint16_t ctrlm_input_event_writer::write_event(ctrlm_key_code_t code, ctrlm_key_ } bool ctrlm_input_event_writer::get_meta_data(struct stat &file_meta_data) { - int ret = fstat(fd_, &file_meta_data); + std::ostringstream oss; + oss << "/sys/devices/virtual/input/" << sysfs_name_; + std::string dir_path = oss.str(); + XLOGD_DEBUG("virtual input path = %s", dir_path.c_str()); + + DIR *dir = opendir(dir_path.c_str()); + if (dir == nullptr) { + int errsv = errno; + XLOGD_ERROR("Failed to open virtual input device dir at path <%s>: error = <%d>, <%s>", + dir_path.c_str(), errsv, strerror(errsv)); + return false; + } + + struct dirent *entry; + std::string stat_path = "/dev/input/"; + bool event_node_found = false; + + while ((entry = readdir(dir)) != nullptr) { + std::string filename = entry->d_name; + if (filename.find("event") == 0) { + event_node_found = true; + stat_path += filename; + break; + } + } + closedir(dir); + + XLOGD_DEBUG("dev input event path = %s", stat_path.c_str()); + if (!event_node_found) { + XLOGD_ERROR("no event node found in virtual device dir <%s>", dir_path.c_str()); + return false; + } + + int ret = stat(stat_path.c_str(), &file_meta_data); if (ret == -1) { int errsv = errno; - XLOGD_ERROR("fstat() failed: error = <%d>, <%s>", errsv, std::strerror(errsv)); + XLOGD_ERROR("stat() failed: error = <%d>, <%s>", errsv, std::strerror(errsv)); return false; } return true; diff --git a/src/input_event/ctrlm_input_event_writer.h b/src/input_event/ctrlm_input_event_writer.h index c05876e0..a9bc4064 100644 --- a/src/input_event/ctrlm_input_event_writer.h +++ b/src/input_event/ctrlm_input_event_writer.h @@ -105,8 +105,9 @@ const std::map ev_key_value_map = class ctrlm_input_event_writer { private: - bool initialized_ = false; - int fd_ = -1; + bool initialized_ = false; + int fd_ = -1; + std::string sysfs_name_ = ""; protected: bool write_event_internal(uint32_t scan_code, uint16_t key_code, key_stroke stroke); diff --git a/src/rf4ce/ctrlm_rf4ce_controller.cpp b/src/rf4ce/ctrlm_rf4ce_controller.cpp index 6dd7387d..08217279 100644 --- a/src/rf4ce/ctrlm_rf4ce_controller.cpp +++ b/src/rf4ce/ctrlm_rf4ce_controller.cpp @@ -3261,7 +3261,23 @@ bool ctrlm_obj_controller_rf4ce_t::init_uinput_writer() { } std::string uinput_name = product_name_get() + " " + std::to_string(controller_id_get()); - ret = uinput_writer_->init(uinput_name, version_hardware_->get_manufacturer(), version_hardware_->get_model()); + uint32_t vendor = 0x293c; + uint32_t product = 0; + uint32_t manufacturer = version_hardware_->get_manufacturer(); + uint32_t model = version_hardware_->get_model(); + uint32_t revision = version_hardware_->get_revision(); + uint32_t lot = version_hardware_->get_lot(); + + if (manufacturer > 0xF || model > 0xF || revision > 0xF || lot > 0xF) { + XLOGD_WARN("Controller <%s><%d> hardware revision fields exceed 4-bit range", ctrlm_rf4ce_controller_type_str(controller_type_), controller_id_get()); + } + + product |= ((manufacturer & 0xF) << 12); + product |= ((model & 0xF) << 8); + product |= ((revision & 0xF) << 4); + product |= (lot & 0xF); + + ret = uinput_writer_->init(uinput_name, vendor, product); if (!ret) { XLOGD_ERROR("Controller <%s><%d> failed to initialize a uinput device", ctrlm_rf4ce_controller_type_str(controller_type_), controller_id_get()); return ret; diff --git a/src/rf4ce/ctrlm_rf4ce_pairing.cpp b/src/rf4ce/ctrlm_rf4ce_pairing.cpp index e3bfa63c..a30d559e 100644 --- a/src/rf4ce/ctrlm_rf4ce_pairing.cpp +++ b/src/rf4ce/ctrlm_rf4ce_pairing.cpp @@ -244,7 +244,6 @@ void ctrlm_obj_network_rf4ce_t::ind_process_pair_stb(ctrlm_main_queue_msg_rf4ce_ user_string[CTRLM_HAL_RF4CE_USER_STRING_SIZE - 1] = '\0'; } controller_user_string_set(params.controller_id, (guchar*)user_string); - controller_init_uinput(params.controller_id); } controller_autobind_in_progress_set(params.controller_id, false); controller_binding_button_in_progress_set(params.controller_id, false); @@ -326,7 +325,6 @@ void ctrlm_obj_network_rf4ce_t::ind_process_pair_autobind(ctrlm_main_queue_msg_r // Create the controller object controller_insert(params.controller_id, dqm->params.src_ieee_addr, true); controller_user_string_set(params.controller_id, dqm->params.org_user_string); - controller_init_uinput(params.controller_id); } controller_autobind_in_progress_set(params.controller_id, true); controller_binding_button_in_progress_set(params.controller_id, false); @@ -423,7 +421,6 @@ void ctrlm_obj_network_rf4ce_t::ind_process_pair_binding_button(ctrlm_main_queue user_string[CTRLM_HAL_RF4CE_USER_STRING_SIZE - 1] = '\0'; } controller_user_string_set(params.controller_id, (guchar*)user_string); - controller_init_uinput(params.controller_id); } controller_autobind_in_progress_set(params.controller_id, false); controller_binding_button_in_progress_set(params.controller_id, true); @@ -506,7 +503,6 @@ void ctrlm_obj_network_rf4ce_t::ind_process_pair_screen_bind(ctrlm_main_queue_ms // Create the controller object controller_insert(params.controller_id, dqm->params.src_ieee_addr, true); controller_user_string_set(params.controller_id, dqm->params.org_user_string); - controller_init_uinput(params.controller_id); } controller_autobind_in_progress_set(params.controller_id, false); controller_binding_button_in_progress_set(params.controller_id, false); diff --git a/src/rf4ce/ctrlm_rf4ce_rib.cpp b/src/rf4ce/ctrlm_rf4ce_rib.cpp index 4eaab800..77b86293 100644 --- a/src/rf4ce/ctrlm_rf4ce_rib.cpp +++ b/src/rf4ce/ctrlm_rf4ce_rib.cpp @@ -294,6 +294,7 @@ void ctrlm_obj_controller_rf4ce_t::rf4ce_rib_get(gboolean target, ctrlm_timestam ctrlm_inform_configuration_complete(network_id_get(), controller_id_get(), CTRLM_RCU_CONFIGURATION_RESULT_SUCCESS); obj_network_rf4ce_->set_rf_pair_state(CTRLM_RF_PAIR_STATE_COMPLETE); obj_network_rf4ce_->iarm_event_rcu_status(); + init_uinput_writer(); } } } From 7706a0cfc7af9823854d5f6865bb5548a0543494 Mon Sep 17 00:00:00 2001 From: Gene Gallagher <129112619+egalla204@users.noreply.github.com> Date: Wed, 11 Feb 2026 13:47:15 -0500 Subject: [PATCH 30/39] RDKEMW-13881: update CHANGELOG for release v1.1.10 (#178) --- CHANGELOG.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2548677a..ef7ba7f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,21 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). -> 13 January 2026 +#### [1.1.10](https://github.com/rdkcentral/control/compare/1.1.9...1.1.10) + +> 11 February 2026 + +- RDKEMW-12828: device minor id, vendor, and product value updates [`#175`](https://github.com/rdkcentral/control/pull/175) +- RDKEMW-13049: remove RCU firmware upgrade retries on failure [`#173`](https://github.com/rdkcentral/control/pull/173) +- RDKEMW-9474: ctrlm multiple simultaneous IR databases [`#161`](https://github.com/rdkcentral/control/pull/161) +- RDKEMW-11792 : FFV config file isolation [`#165`](https://github.com/rdkcentral/control/pull/165) +- RDKEMW-12457: No longer ignoring device re-pair if it's already paired and connected. [`#171`](https://github.com/rdkcentral/control/pull/171) +- RDKEMW-9843: report loaded and unloaded voltage from RCU [`#163`](https://github.com/rdkcentral/control/pull/163) #### [1.1.9](https://github.com/rdkcentral/control/compare/1.1.8...1.1.9) +> 13 January 2026 + - RDKEMW-11471: Remove netType param [`#164`](https://github.com/rdkcentral/control/pull/164) - RDKEMW-10631: Filter out unpaired devices when reconnecting all devices [`fc1c94a`](https://github.com/rdkcentral/control/commit/fc1c94a8e2de9b196a5f274316eaee5c07c2fbf5) From d5d14f05aee9e76bf1a44660c743f4811f373677 Mon Sep 17 00:00:00 2001 From: Kelvin Lu <119349872+klu339@users.noreply.github.com> Date: Wed, 18 Feb 2026 11:27:05 -0500 Subject: [PATCH 31/39] RDKEMW-13833: Remove duplicate RFC fetch attempts in listeners (#179) --- src/ctrlm_main.cpp | 1 - src/voice/ctrlm_voice_obj.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/src/ctrlm_main.cpp b/src/ctrlm_main.cpp index 4c9d9faa..f76c3682 100644 --- a/src/ctrlm_main.cpp +++ b/src/ctrlm_main.cpp @@ -1986,7 +1986,6 @@ void ctrlm_global_rfc_values_retrieved(const ctrlm_rfc_attr_t &attr) { if(attr.get_rfc_value(JSON_ARRAY_NAME_CTRLM_GLOBAL_MASK_PII, g_ctrlm.mask_pii, ctrlm_is_production_build() ? CTRLM_JSON_ARRAY_INDEX_PRD : CTRLM_JSON_ARRAY_INDEX_DEV)) { g_ctrlm.voice_session->voice_stb_data_pii_mask_set(g_ctrlm.mask_pii); } - attr.get_rfc_value(JSON_INT_NAME_CTRLM_GLOBAL_AUTHSERVICE_POLL_PERIOD, g_ctrlm.authservice_poll_val); attr.get_rfc_value(JSON_INT_NAME_CTRLM_GLOBAL_AUTHSERVICE_FAST_POLL_PERIOD, g_ctrlm.authservice_fast_poll_val); attr.get_rfc_value(JSON_INT_NAME_CTRLM_GLOBAL_AUTHSERVICE_FAST_MAX_RETRIES, g_ctrlm.authservice_fast_retries_max); } diff --git a/src/voice/ctrlm_voice_obj.cpp b/src/voice/ctrlm_voice_obj.cpp index ba00c02b..1af6f059 100644 --- a/src/voice/ctrlm_voice_obj.cpp +++ b/src/voice/ctrlm_voice_obj.cpp @@ -4085,7 +4085,6 @@ void ctrlm_voice_t::voice_rfc_retrieved_handler(const ctrlm_rfc_attr_t& attr) { this->url_hostname_patterns(obj_server_hosts); } - attr.get_rfc_value(JSON_BOOL_NAME_VOICE_FORCE_VOICE_SETTINGS, this->prefs.force_voice_settings); if(attr.get_rfc_value(JSON_BOOL_NAME_VOICE_FORCE_VOICE_SETTINGS, this->prefs.force_voice_settings) && this->prefs.force_voice_settings) { attr.get_rfc_value(JSON_BOOL_NAME_VOICE_ENABLE, enabled); attr.get_rfc_value(JSON_STR_NAME_VOICE_URL_SRC_PTT, this->prefs.server_url_src_ptt); From 2eaa356a595428d56a4486dc6004c3a1b633f963 Mon Sep 17 00:00:00 2001 From: Kelvin Lu <119349872+klu339@users.noreply.github.com> Date: Thu, 19 Feb 2026 09:50:33 -0500 Subject: [PATCH 32/39] RDKEMW-12930: RF4CE network export XCONF on pair/unpair/etc. (#177) --- src/rf4ce/ctrlm_rf4ce_device_update.cpp | 8 ++++++++ src/rf4ce/ctrlm_rf4ce_network.cpp | 7 +++++++ src/rf4ce/ctrlm_rf4ce_pairing.cpp | 8 ++++++++ src/rf4ce/ctrlm_rf4ce_rcu.cpp | 15 +++++++++++++++ 4 files changed, 38 insertions(+) diff --git a/src/rf4ce/ctrlm_rf4ce_device_update.cpp b/src/rf4ce/ctrlm_rf4ce_device_update.cpp index 81391246..c2d232eb 100644 --- a/src/rf4ce/ctrlm_rf4ce_device_update.cpp +++ b/src/rf4ce/ctrlm_rf4ce_device_update.cpp @@ -549,6 +549,14 @@ void ctrlm_obj_controller_rf4ce_t::device_update_image_download_complete(ctrlm_t } } + ctrlm_main_queue_msg_header_t *msg = (ctrlm_main_queue_msg_header_t *)g_malloc(sizeof(ctrlm_main_queue_msg_header_t)); + if(msg == NULL) { + XLOGD_ERROR("Out of memory"); + } else { + msg->type = CTRLM_MAIN_QUEUE_MSG_TYPE_EXPORT_CONTROLLER_LIST; + ctrlm_main_queue_msg_push((gpointer)msg); + } + print_remote_firmware_debug_info(RF4CE_PRINT_FIRMWARE_LOG_IMAGE_DOWNLOAD_COMPLETE, log_string); if(download_in_progress_) { // End the download session since the controller has finished loading the image diff --git a/src/rf4ce/ctrlm_rf4ce_network.cpp b/src/rf4ce/ctrlm_rf4ce_network.cpp index de3adb73..5009c592 100644 --- a/src/rf4ce/ctrlm_rf4ce_network.cpp +++ b/src/rf4ce/ctrlm_rf4ce_network.cpp @@ -1445,6 +1445,13 @@ void ctrlm_obj_network_rf4ce_t::factory_reset(void) { // Delete control manager persistent data // TODO + ctrlm_main_queue_msg_header_t *msg = (ctrlm_main_queue_msg_header_t *)g_malloc(sizeof(ctrlm_main_queue_msg_header_t)); + if(msg == NULL) { + XLOGD_ERROR("Out of memory"); + } else { + msg->type = CTRLM_MAIN_QUEUE_MSG_TYPE_EXPORT_CONTROLLER_LIST; + ctrlm_main_queue_msg_push((gpointer)msg); + } } bool ctrlm_obj_network_rf4ce_t::controller_exists(ctrlm_controller_id_t controller_id) { diff --git a/src/rf4ce/ctrlm_rf4ce_pairing.cpp b/src/rf4ce/ctrlm_rf4ce_pairing.cpp index a30d559e..ae08132d 100644 --- a/src/rf4ce/ctrlm_rf4ce_pairing.cpp +++ b/src/rf4ce/ctrlm_rf4ce_pairing.cpp @@ -678,6 +678,14 @@ void ctrlm_obj_network_rf4ce_t::ind_process_unpair(void *data, int size) { //ctr controller_unbind(controller_id, CTRLM_UNBIND_REASON_CONTROLLER); params.result = CTRLM_HAL_RESULT_UNPAIR_SUCCESS; + + ctrlm_main_queue_msg_header_t *msg = (ctrlm_main_queue_msg_header_t *)g_malloc(sizeof(ctrlm_main_queue_msg_header_t)); + if(msg == NULL) { + XLOGD_ERROR("Out of memory"); + } else { + msg->type = CTRLM_MAIN_QUEUE_MSG_TYPE_EXPORT_CONTROLLER_LIST; + ctrlm_main_queue_msg_push((gpointer)msg); + } } ctrlm_network_queue_deliver_result_unpair(dqm, params); diff --git a/src/rf4ce/ctrlm_rf4ce_rcu.cpp b/src/rf4ce/ctrlm_rf4ce_rcu.cpp index 767f0ea3..ae352a67 100644 --- a/src/rf4ce/ctrlm_rf4ce_rcu.cpp +++ b/src/rf4ce/ctrlm_rf4ce_rcu.cpp @@ -479,6 +479,13 @@ void ctrlm_obj_network_rf4ce_t::ind_process_data_rcu(ctrlm_main_queue_msg_rf4ce_ function == CTRLM_RCU_FUNCTION_MODE_CLIP_DISCOVERY) { // Unbind the controller since it has effectively unpaired controller_unbind(dqm->controller_id, CTRLM_UNBIND_REASON_CONTROLLER_RESET); + ctrlm_main_queue_msg_header_t *msg = (ctrlm_main_queue_msg_header_t *)g_malloc(sizeof(ctrlm_main_queue_msg_header_t)); + if(msg == NULL) { + XLOGD_ERROR("Out of memory"); + } else { + msg->type = CTRLM_MAIN_QUEUE_MSG_TYPE_EXPORT_CONTROLLER_LIST; + ctrlm_main_queue_msg_push((gpointer)msg); + } } if((function != CTRLM_RCU_FUNCTION_INVALID) && (function != CTRLM_RCU_FUNCTION_INVALID_KEY_COMBO)) { @@ -579,6 +586,14 @@ void ctrlm_obj_network_rf4ce_t::ind_process_data_rcu(ctrlm_main_queue_msg_rf4ce_ controllers_[dqm->controller_id]->rib_configuration_complete(dqm->timestamp, (ctrlm_rf4ce_rib_configuration_complete_status_t)cmd_data[1]); set_rf_pair_state(CTRLM_RF_PAIR_STATE_COMPLETE); iarm_event_rcu_status(); + + ctrlm_main_queue_msg_header_t *msg = (ctrlm_main_queue_msg_header_t *)g_malloc(sizeof(ctrlm_main_queue_msg_header_t)); + if(msg == NULL) { + XLOGD_ERROR("Out of memory"); + } else { + msg->type = CTRLM_MAIN_QUEUE_MSG_TYPE_EXPORT_CONTROLLER_LIST; + ctrlm_main_queue_msg_push((gpointer)msg); + } break; } default: { From add759e3a88fd6cddee80b7f9996ef0ecdb1f427 Mon Sep 17 00:00:00 2001 From: Kelvin Lu <119349872+klu339@users.noreply.github.com> Date: Thu, 19 Feb 2026 09:59:53 -0500 Subject: [PATCH 33/39] RDKEMW-13753: Report manually set IRDB codes RF4CE remotes (#176) --- src/rf4ce/ctrlm_rf4ce_controller.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/rf4ce/ctrlm_rf4ce_controller.cpp b/src/rf4ce/ctrlm_rf4ce_controller.cpp index 08217279..960b3fd2 100644 --- a/src/rf4ce/ctrlm_rf4ce_controller.cpp +++ b/src/rf4ce/ctrlm_rf4ce_controller.cpp @@ -2756,6 +2756,12 @@ void ctrlm_obj_controller_rf4ce_t::controller_product_name_updated(const ctrlm_r void ctrlm_obj_controller_rf4ce_t::controller_irdb_status_updated(const ctrlm_rf4ce_controller_irdb_status_t& status) { if(controller_type_ != RF4CE_CONTROLLER_TYPE_XR19) { obj_network_rf4ce_->target_irdb_status_set(*controller_irdb_status_); + if(controller_irdb_status_->is_flag_set(ctrlm_rf4ce_controller_irdb_status_t::flag::IR_DB_CODE_TV)) { + irdb_entry_id_name_set(CTRLM_IRDB_DEV_TYPE_TV, controller_irdb_status_->get_tv_code_str()); + } + if(controller_irdb_status_->is_flag_set(ctrlm_rf4ce_controller_irdb_status_t::flag::IR_DB_CODE_AVR)) { + irdb_entry_id_name_set(CTRLM_IRDB_DEV_TYPE_AVR, controller_irdb_status_->get_avr_code_str()); + } } } From 5a90734ed30bbd6087df9f2c8d75fe05bbce4184 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Thu, 19 Feb 2026 12:02:47 -0500 Subject: [PATCH 34/39] RDKEMW-11359: Logging proximity key as debug instead of telemetry (#167) --- src/ctrlm_controller.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/ctrlm_controller.cpp b/src/ctrlm_controller.cpp index 8048ac2c..15496dd3 100644 --- a/src/ctrlm_controller.cpp +++ b/src/ctrlm_controller.cpp @@ -172,11 +172,18 @@ void ctrlm_obj_controller_t::process_event_key(ctrlm_key_status_t key_status, ui last_key_code_->set_value((uint64_t)key_code); last_key_time_update(); - XLOGD_AUTOMATION_TELEMETRY("ind_process_keypress: %s - MAC Address <%s>, code = <%d> (%s key), status = <%s>", controller_type_str_get().c_str(), - ieee_address_get().to_string().c_str(), - mask ? -1 : key_code, - ctrlm_linux_key_code_str(key_code, mask), - ctrlm_key_status_str(key_status)); + xlog_level_t level = XLOG_LEVEL_TELEMETRY; + const char *color = XLOG_COLOR_BLU; + // Proximity key (KEY_F17) is logged to debug while the rest is logged to telemetry + if(key_code == KEY_F17) { + level = XLOG_LEVEL_DEBUG; + color = XLOG_COLOR_GRN; + } + XLOGD(level, XLOG_OPTS_DEFAULT, color, XLOG_BUF_SIZE_DEFAULT, "ind_process_keypress: %s - MAC Address <%s>, code = <%d> (%s key), status = <%s>", controller_type_str_get().c_str(), + ieee_address_get().to_string().c_str(), + mask ? -1 : key_code, + ctrlm_linux_key_code_str(key_code, mask), + ctrlm_key_status_str(key_status)); } ctrlm_controller_capabilities_t ctrlm_obj_controller_t::get_capabilities() const { From 1f68214bb3c6d62be72ea3c8cbde7ae86747cd2d Mon Sep 17 00:00:00 2001 From: jthomp007c Date: Thu, 5 Mar 2026 11:04:42 -0500 Subject: [PATCH 35/39] RDKEMW-14445 : Add session end and protocol return to telemetry (#182) * RDKEMW-14445 : Add session end and protocol return to telemetry Reason for change: ctrlm currently does not know why xrsr might have ended a session. Also it does not know what protocol error may have occurred only that one did. Test Procedure: check telemetry for new fields, parse them, confirm that new data exists and is correct Priority: P0 Signed-off-by: Jason Thomson * Fixing whitespace * Order of vars * Update telemetry markers version number * Reverting enum name change * Renaming vars for clarity, reordering vars for consistency * Fix whitespace * Adding stream end reason to telemetry log * Adding stream reason end to telemetry --------- Signed-off-by: Jason Thomson --- include/ctrlm_ipc_voice.h | 2 +- src/telemetry/ctrlm_telemetry_markers.h | 2 +- src/voice/ctrlm_voice_obj.cpp | 28 +++++++++---------- src/voice/ctrlm_voice_obj.h | 2 +- .../endpoints/ctrlm_voice_endpoint_http.cpp | 2 +- .../ctrlm_voice_endpoint_ws_nextgen.cpp | 2 +- .../endpoints/ctrlm_voice_endpoint_ws_nsp.cpp | 2 +- .../ctrlm_voice_telemetry_events.cpp | 21 ++++++++------ .../telemetry/ctrlm_voice_telemetry_events.h | 8 ++++-- 9 files changed, 38 insertions(+), 31 deletions(-) diff --git a/include/ctrlm_ipc_voice.h b/include/ctrlm_ipc_voice.h index 270b92d9..665ffaa5 100644 --- a/include/ctrlm_ipc_voice.h +++ b/include/ctrlm_ipc_voice.h @@ -228,7 +228,7 @@ typedef struct { ctrlm_network_type_t network_type; ///< Type of network on which the controller is bound ctrlm_controller_id_t controller_id; ///< A unique identifier of the remote unsigned long session_id; ///< A unique id for the voice session. - ctrlm_voice_session_end_reason_t reason; ///< The reason for ending + ctrlm_voice_session_end_reason_t reason; ///< The reason for ending session unsigned char is_voice_assistant; ///< Boolean indicating if the device is a far-field device (1) as opposed to a hand-held remote (0). } ctrlm_voice_iarm_event_session_end_t; diff --git a/src/telemetry/ctrlm_telemetry_markers.h b/src/telemetry/ctrlm_telemetry_markers.h index 9c0ba3a3..23c0f775 100644 --- a/src/telemetry/ctrlm_telemetry_markers.h +++ b/src/telemetry/ctrlm_telemetry_markers.h @@ -117,7 +117,7 @@ // - server message. // - flag to indicate if session was successful. #define MARKER_VOICE_SESSION_STATS "ctrlm.voice.session.stats" -#define MARKER_VOICE_SESSION_STATS_VERSION "1" +#define MARKER_VOICE_SESSION_STATS_VERSION "2" // End Voice Session Statistics diff --git a/src/voice/ctrlm_voice_obj.cpp b/src/voice/ctrlm_voice_obj.cpp index 1af6f059..6e4b354f 100644 --- a/src/voice/ctrlm_voice_obj.cpp +++ b/src/voice/ctrlm_voice_obj.cpp @@ -95,7 +95,7 @@ ctrlm_voice_t::ctrlm_voice_t() { session->session_active_controller = false; session->state_src = CTRLM_VOICE_STATE_SRC_INVALID; session->state_dst = CTRLM_VOICE_STATE_DST_INVALID; - session->end_reason = CTRLM_VOICE_SESSION_END_REASON_DONE; + session->end_reason_rcu = CTRLM_VOICE_SESSION_END_REASON_DONE; session->audio_pipe[PIPE_READ] = -1; session->audio_pipe[PIPE_WRITE] = -1; @@ -1872,7 +1872,7 @@ void ctrlm_voice_t::voice_session_end(ctrlm_voice_session_t *session, ctrlm_voic return; } - session->end_reason = reason; + session->end_reason_rcu = reason; if(timestamp != NULL) { session->session_timing.ctrl_stop = *timestamp; @@ -2522,7 +2522,7 @@ void ctrlm_voice_t::voice_session_begin_callback(ctrlm_voice_session_begin_cb_t session->ipc_common_data.voice_assistant = is_voice_assistant(session->voice_device); session->ipc_common_data.device_type = session->voice_device; session->endpoint_current = session_begin->endpoint; - session->end_reason = CTRLM_VOICE_SESSION_END_REASON_DONE; + session->end_reason_rcu = CTRLM_VOICE_SESSION_END_REASON_DONE; errno_t safec_rc = memset_s(&session->status, sizeof(session->status), 0 , sizeof(session->status)); ERR_CHK(safec_rc); @@ -2625,7 +2625,7 @@ void ctrlm_voice_t::voice_session_end_callback(ctrlm_voice_session_end_cb_t *ses if(command_status == VOICE_COMMAND_STATUS_PENDING) { switch(session->voice_device) { case CTRLM_VOICE_DEVICE_FF: { - session->status.status = (stats->reason == XRSR_SESSION_END_REASON_EOS) ? VOICE_COMMAND_STATUS_SUCCESS : VOICE_COMMAND_STATUS_FAILURE; + session->status.status = (stats->session_end_reason == XRSR_SESSION_END_REASON_EOS) ? VOICE_COMMAND_STATUS_SUCCESS : VOICE_COMMAND_STATUS_FAILURE; command_status = session->status.status; this->voice_status_set(session); break; @@ -2642,9 +2642,9 @@ void ctrlm_voice_t::voice_session_end_callback(ctrlm_voice_session_end_cb_t *ses } if(session->voice_device == CTRLM_VOICE_DEVICE_MICROPHONE || session->voice_device == CTRLM_VOICE_DEVICE_MICROPHONE_TAP) { - XLOGD_INFO("src <%s> reason <%s> voice command status <%s>", ctrlm_voice_device_str(session->voice_device), xrsr_session_end_reason_str(stats->reason), ctrlm_voice_command_status_str(command_status)); + XLOGD_INFO("src <%s> reason <%s> voice command status <%s>", ctrlm_voice_device_str(session->voice_device), xrsr_session_end_reason_str(stats->session_end_reason), ctrlm_voice_command_status_str(command_status)); } else { - XLOGD_INFO("src <%s> audio sent bytes <%u> samples <%u> reason <%s> voice command status <%s>", ctrlm_voice_device_str(session->voice_device), session->audio_sent_bytes, session->audio_sent_samples, xrsr_session_end_reason_str(stats->reason), ctrlm_voice_command_status_str(command_status)); + XLOGD_INFO("src <%s> audio sent bytes <%u> samples <%u> reason <%s> voice command status <%s>", ctrlm_voice_device_str(session->voice_device), session->audio_sent_bytes, session->audio_sent_samples, xrsr_session_end_reason_str(stats->session_end_reason), ctrlm_voice_command_status_str(command_status)); } // Update device status @@ -2657,18 +2657,18 @@ void ctrlm_voice_t::voice_session_end_callback(ctrlm_voice_session_end_cb_t *ses // Send Results IARM Event if(this->voice_ipc) { - if(stats->reason == XRSR_SESSION_END_REASON_ERROR_AUDIO_DURATION) { + if(stats->session_end_reason == XRSR_SESSION_END_REASON_ERROR_AUDIO_DURATION) { ctrlm_voice_ipc_event_session_end_t end; end.common = session->ipc_common_data; end.result = SESSION_END_SHORT_UTTERANCE; - end.reason = (int)session->end_reason; + end.reason = (int)session->end_reason_rcu; this->voice_ipc->session_end(end); } else { ctrlm_voice_ipc_event_session_end_server_stats_t server_stats; ctrlm_voice_ipc_event_session_end_t end; end.common = session->ipc_common_data; end.result = (session_end->success ? SESSION_END_SUCCESS : SESSION_END_FAILURE); - end.reason = stats->reason; + end.reason = stats->session_end_reason; end.return_code_protocol = stats->ret_code_protocol; end.return_code_protocol_library = stats->ret_code_library; end.return_code_server = session->server_ret_code; @@ -2690,7 +2690,7 @@ void ctrlm_voice_t::voice_session_end_callback(ctrlm_voice_session_end_cb_t *ses // Update controller metrics ctrlm_main_queue_msg_controller_voice_metrics_t metrics = {0}; metrics.controller_id = session->controller_id; - metrics.short_utterance = (stats->reason == XRSR_SESSION_END_REASON_ERROR_AUDIO_DURATION ? 1 : 0); + metrics.short_utterance = (stats->session_end_reason == XRSR_SESSION_END_REASON_ERROR_AUDIO_DURATION ? 1 : 0); metrics.packets_total = session->packets_processed + session->packets_lost; metrics.packets_lost = session->packets_lost; @@ -2719,8 +2719,8 @@ void ctrlm_voice_t::voice_session_end_callback(ctrlm_voice_session_end_cb_t *ses if(telemetry) { ctrlm_telemetry_event_t vs_marker(MARKER_VOICE_SESSION_TOTAL, 1); ctrlm_telemetry_event_t vs_status_marker(session_end->success ? MARKER_VOICE_SESSION_SUCCESS : MARKER_VOICE_SESSION_FAILURE, 1); - ctrlm_telemetry_event_t vs_end_reason_marker(MARKER_VOICE_END_REASON_PREFIX + std::string(ctrlm_voice_session_end_reason_str(session->end_reason)), 1); - ctrlm_telemetry_event_t vs_xrsr_end_reason_marker(MARKER_VOICE_XRSR_END_REASON_PREFIX + std::string(xrsr_session_end_reason_str(stats->reason)), 1); + ctrlm_telemetry_event_t vs_end_reason_marker(MARKER_VOICE_END_REASON_PREFIX + std::string(ctrlm_voice_session_end_reason_str(session->end_reason_rcu)), 1); + ctrlm_telemetry_event_t vs_xrsr_end_reason_marker(MARKER_VOICE_XRSR_END_REASON_PREFIX + std::string(xrsr_session_end_reason_str(stats->session_end_reason)), 1); // Handle all VSRsp error telemetry if(session->current_vsr_err_string != "") { @@ -2745,7 +2745,7 @@ void ctrlm_voice_t::voice_session_end_callback(ctrlm_voice_session_end_cb_t *ses telemetry->event(ctrlm_telemetry_report_t::VOICE, vs_xrsr_end_reason_marker); if(this->prefs.telemetry_session_stats) { - if(!session->telemetry_session_stats.update_on_session_end(session_end->success, session->end_reason, stats->reason, session->server_ret_code, session->server_message, session->stats_session.voice_key_held_ms)) { + if(!session->telemetry_session_stats.update_on_session_end(session_end->success, session->end_reason_rcu, stats->session_end_reason, session->server_ret_code, session->server_message, session->stats_session.voice_key_held_ms, stats->ret_code_protocol, stats->stream_end_reason)) { XLOGD_ERROR("failed to generate session stats event"); } } @@ -2980,7 +2980,7 @@ void ctrlm_voice_t::voice_stream_end_callback(ctrlm_voice_stream_end_cb_t *strea // This is a STREAM end.. ctrlm_voice_ipc_event_stream_end_t end; end.common = session->ipc_common_data; - end.reason = (int)session->end_reason; + end.reason = (int)session->end_reason_rcu; this->voice_ipc->stream_end(end); } diff --git a/src/voice/ctrlm_voice_obj.h b/src/voice/ctrlm_voice_obj.h index c4395b18..38699a6b 100644 --- a/src/voice/ctrlm_voice_obj.h +++ b/src/voice/ctrlm_voice_obj.h @@ -443,7 +443,7 @@ typedef struct { uint32_t packets_lost; uint32_t lqi_total; - ctrlm_voice_session_end_reason_t end_reason; + ctrlm_voice_session_end_reason_t end_reason_rcu; bool is_press_and_release; bool is_session_by_text; diff --git a/src/voice/endpoints/ctrlm_voice_endpoint_http.cpp b/src/voice/endpoints/ctrlm_voice_endpoint_http.cpp index 93396a4b..1ec3e647 100644 --- a/src/voice/endpoints/ctrlm_voice_endpoint_http.cpp +++ b/src/voice/endpoints/ctrlm_voice_endpoint_http.cpp @@ -286,7 +286,7 @@ void ctrlm_voice_endpoint_http_t::voice_session_end_callback_http(void *data, in } // Check if HTTP was successful - if((stats->reason != XRSR_SESSION_END_REASON_EOS && stats->reason != XRSR_SESSION_END_REASON_TERMINATE && stats->reason != XRSR_SESSION_END_REASON_EOT) + if((stats->session_end_reason != XRSR_SESSION_END_REASON_EOS && stats->session_end_reason != XRSR_SESSION_END_REASON_TERMINATE && stats->session_end_reason != XRSR_SESSION_END_REASON_EOT) || (stats->ret_code_library != 0) || (stats->ret_code_protocol != 200) || (this->server_ret_code != 0)) { success = false; } diff --git a/src/voice/endpoints/ctrlm_voice_endpoint_ws_nextgen.cpp b/src/voice/endpoints/ctrlm_voice_endpoint_ws_nextgen.cpp index fcf9b12a..e5165cd7 100644 --- a/src/voice/endpoints/ctrlm_voice_endpoint_ws_nextgen.cpp +++ b/src/voice/endpoints/ctrlm_voice_endpoint_ws_nextgen.cpp @@ -460,7 +460,7 @@ void ctrlm_voice_endpoint_ws_nextgen_t::voice_session_end_callback_ws_nextgen(vo } // Check if WS was successful - if((stats->reason != XRSR_SESSION_END_REASON_EOS && stats->reason != XRSR_SESSION_END_REASON_EOT) || (this->server_ret_code != 0 && this->server_ret_code != 200)) { + if((stats->session_end_reason != XRSR_SESSION_END_REASON_EOS && stats->session_end_reason != XRSR_SESSION_END_REASON_EOT) || (this->server_ret_code != 0 && this->server_ret_code != 200)) { success = false; } diff --git a/src/voice/endpoints/ctrlm_voice_endpoint_ws_nsp.cpp b/src/voice/endpoints/ctrlm_voice_endpoint_ws_nsp.cpp index da4d4035..a123c0d6 100644 --- a/src/voice/endpoints/ctrlm_voice_endpoint_ws_nsp.cpp +++ b/src/voice/endpoints/ctrlm_voice_endpoint_ws_nsp.cpp @@ -203,7 +203,7 @@ void ctrlm_voice_endpoint_ws_nsp_t::voice_session_end_callback_ws_nsp(void *data } // Check if WS was successful - if((stats->reason != XRSR_SESSION_END_REASON_DISCONNECT_REMOTE) || (this->server_ret_code != 0 && this->server_ret_code != 200)) { + if((stats->session_end_reason != XRSR_SESSION_END_REASON_DISCONNECT_REMOTE) || (this->server_ret_code != 0 && this->server_ret_code != 200)) { success = false; } diff --git a/src/voice/telemetry/ctrlm_voice_telemetry_events.cpp b/src/voice/telemetry/ctrlm_voice_telemetry_events.cpp index e7ac6e71..d5f6bba3 100644 --- a/src/voice/telemetry/ctrlm_voice_telemetry_events.cpp +++ b/src/voice/telemetry/ctrlm_voice_telemetry_events.cpp @@ -206,11 +206,13 @@ bool ctrlm_voice_telemetry_session_t::event() { ss << m_samples_lost << ","; ss << m_decoder_failures << ","; ss << m_samples_buffered_max << ","; - ss << m_end_reason_stream << ","; - ss << m_end_reason_protocol << ","; + ss << m_end_reason_rcu << ","; + ss << m_end_reason_session << ","; ss << m_end_reason_server << ","; ss << "\"" << m_server_message << "\","; - ss << m_result << "]]"; + ss << m_result << ","; + ss << m_end_reason_stream << ","; + ss << m_ret_code_protocol << "]]"; if(m_event_list.length() + ss.str().length() > m_event_list_max_size) { // Maximum data size exceeded XLOGD_WARN("telemetry event exceeds max size <%s,%s>", val_marker.c_str(), ss.str().c_str()); @@ -279,12 +281,14 @@ void ctrlm_voice_telemetry_session_t::update_on_stream_end(uint32_t time_stream_ } } -bool ctrlm_voice_telemetry_session_t::update_on_session_end(bool result, int32_t end_reason_stream, int32_t end_reason_protocol, int32_t end_reason_server, const std::string &server_message, int32_t time_stream_len_exp) { +bool ctrlm_voice_telemetry_session_t::update_on_session_end(bool result, int32_t end_reason_rcu, int32_t end_reason_session, int32_t end_reason_server, const std::string &server_message, int32_t time_stream_len_exp, int32_t ret_code_protocol, int32_t stream_end_reason) { m_result = result; - m_end_reason_stream = end_reason_stream; - m_end_reason_protocol = end_reason_protocol; + m_end_reason_rcu = end_reason_rcu; + m_end_reason_session = end_reason_session; m_end_reason_server = end_reason_server; m_server_message = server_message; + m_ret_code_protocol = ret_code_protocol; + m_end_reason_stream = stream_end_reason; if(!m_has_key_release) { // if there is no key release, the start time and end time are not known rdkx_timestamp_get(&m_time_prev_session_end); @@ -310,10 +314,11 @@ void ctrlm_voice_telemetry_session_t::reset_stats() { m_decoder_failures = 0; m_samples_buffered_max = 0; - m_end_reason_stream = 0; - m_end_reason_protocol = 0; + m_end_reason_rcu = 0; + m_end_reason_session = 0; m_end_reason_server = 0; m_result = false; + m_ret_code_protocol = 0; m_server_message.clear(); m_device_type.clear(); diff --git a/src/voice/telemetry/ctrlm_voice_telemetry_events.h b/src/voice/telemetry/ctrlm_voice_telemetry_events.h index d8bf90dd..adadfde6 100644 --- a/src/voice/telemetry/ctrlm_voice_telemetry_events.h +++ b/src/voice/telemetry/ctrlm_voice_telemetry_events.h @@ -76,7 +76,7 @@ class ctrlm_voice_telemetry_session_t : public ctrlm_telemetry_event_t Date: Thu, 5 Mar 2026 13:36:54 -0500 Subject: [PATCH 36/39] RDKEMW-14589: No UI action with "Info" keypress from rf4ce remote in RF mode (#181) --- src/input_event/ctrlm_input_event_writer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/input_event/ctrlm_input_event_writer.h b/src/input_event/ctrlm_input_event_writer.h index a9bc4064..2f6c89cc 100644 --- a/src/input_event/ctrlm_input_event_writer.h +++ b/src/input_event/ctrlm_input_event_writer.h @@ -66,7 +66,7 @@ const std::map ctrlm_key_to_linux_map {CTRLM_KEY_CODE_CH_DOWN, linux_ui_code_values_t(KEY_PAGEDOWN, 0x59, KEY_LEFTCTRL)}, {CTRLM_KEY_CODE_LAST, linux_ui_code_values_t(KEY_ESC, 0x0, KEY_LEFTCTRL)}, {CTRLM_KEY_CODE_INPUT_SELECT, linux_ui_code_values_t(KEY_F15, 0x0, KEY_RESERVED)}, - {CTRLM_KEY_CODE_INFO, linux_ui_code_values_t(KEY_F20, 0x0, KEY_RESERVED)}, + {CTRLM_KEY_CODE_INFO, linux_ui_code_values_t(KEY_F9, 0x0, KEY_RESERVED)}, {CTRLM_KEY_CODE_VOL_UP, linux_ui_code_values_t(KEY_KPPLUS, 0x0, KEY_RESERVED)}, {CTRLM_KEY_CODE_VOL_DOWN, linux_ui_code_values_t(KEY_KPMINUS, 0x0, KEY_RESERVED)}, {CTRLM_KEY_CODE_MUTE, linux_ui_code_values_t(KEY_KPASTERISK, 0x0, KEY_RESERVED)}, From 6dcab578a94365e2da2619c05ed85bc817711f86 Mon Sep 17 00:00:00 2001 From: Gene Gallagher Date: Thu, 5 Mar 2026 14:42:15 -0500 Subject: [PATCH 37/39] 1.1.11 release changelog updates --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef7ba7f2..be2c769d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [1.1.11](https://github.com/rdkcentral/control/compare/1.1.10...1.1.11) + +- RDKEMW-14589: No UI action with "Info" keypress from rf4ce remote in RF mode [`#181`](https://github.com/rdkcentral/control/pull/181) +- RDKEMW-14445 : Add session end and protocol return to telemetry [`#182`](https://github.com/rdkcentral/control/pull/182) +- RDKEMW-11359: Logging proximity key as debug instead of telemetry [`#167`](https://github.com/rdkcentral/control/pull/167) +- RDKEMW-13753: Report manually set IRDB codes RF4CE remotes [`#176`](https://github.com/rdkcentral/control/pull/176) +- RDKEMW-12930: RF4CE network export XCONF on pair/unpair/etc. [`#177`](https://github.com/rdkcentral/control/pull/177) +- RDKEMW-13833: Remove duplicate RFC fetch attempts in listeners [`#179`](https://github.com/rdkcentral/control/pull/179) + #### [1.1.10](https://github.com/rdkcentral/control/compare/1.1.9...1.1.10) From f3b6611c6fd22cff65a2a7cb96b14a669ecc24b4 Mon Sep 17 00:00:00 2001 From: Gene Gallagher Date: Thu, 5 Mar 2026 16:18:54 -0500 Subject: [PATCH 38/39] add date' --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index be2c769d..52e8cb2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). #### [1.1.11](https://github.com/rdkcentral/control/compare/1.1.10...1.1.11) +> 5 March 2026 + - RDKEMW-14589: No UI action with "Info" keypress from rf4ce remote in RF mode [`#181`](https://github.com/rdkcentral/control/pull/181) - RDKEMW-14445 : Add session end and protocol return to telemetry [`#182`](https://github.com/rdkcentral/control/pull/182) - RDKEMW-11359: Logging proximity key as debug instead of telemetry [`#167`](https://github.com/rdkcentral/control/pull/167) From ecd0f6dc4aa5d4a9b4ccb61ced5acfd54a72497c Mon Sep 17 00:00:00 2001 From: jthomp007c Date: Tue, 17 Mar 2026 11:30:03 -0400 Subject: [PATCH 39/39] RDKEMW-5849 : remove deprecated "experience" code (#185) * RDKEMW-5849 : remove deprecated "experience" code Reason for change: the app controls experience, ctrlm does is no longer involved Test Procedure: nothing new to test. Check that normal functionality is not affected Priority; P2 Signed-off-by: Jason Thomson * Align CTRLM_VOICE_QUERY_STRING_MAX_PAIRS with xrsr without including xrsr.h --------- Signed-off-by: Jason Thomson --- CMakeLists.txt | 2 - include/ctrlm_ipc_voice.h | 2 +- src/auth/ctrlm_auth.h | 1 - src/auth/ctrlm_auth_thunder.cpp | 5 -- src/auth/ctrlm_auth_thunder.h | 1 - src/auth/ctrlm_thunder_plugin_authservice.cpp | 18 -------- src/auth/ctrlm_thunder_plugin_authservice.h | 7 --- src/ctrlm.h | 1 - src/ctrlm_controller.cpp | 4 -- src/ctrlm_controller.h | 1 - src/ctrlm_main.cpp | 46 ------------------- src/ctrlm_network.cpp | 10 ---- src/ctrlm_network.h | 3 -- src/voice/ctrlm_voice_obj.cpp | 18 -------- src/voice/ctrlm_voice_obj.h | 3 -- src/voice/endpoints/ctrlm_voice_endpoint.cpp | 1 - src/voice/endpoints/ctrlm_voice_endpoint.h | 1 - .../endpoints/ctrlm_voice_endpoint_http.cpp | 8 ---- .../endpoints/ctrlm_voice_endpoint_http.h | 1 - .../ctrlm_voice_endpoint_ws_nextgen.cpp | 8 ---- .../ctrlm_voice_endpoint_ws_nextgen.h | 1 - 21 files changed, 1 insertion(+), 141 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 565ab874..112b3c00 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -234,8 +234,6 @@ if(THUNDER) if(AUTH_ACTIVATION_STATUS) add_compile_definitions(AUTH_ACTIVATION_STATUS) endif() - #By default disabled but can be enabled - #add_compile_definitions(AUTH_EXPERIENCE) target_link_libraries(controlMgr RdkCertSelector) endif() endif() diff --git a/include/ctrlm_ipc_voice.h b/include/ctrlm_ipc_voice.h index 665ffaa5..ed96c951 100644 --- a/include/ctrlm_ipc_voice.h +++ b/include/ctrlm_ipc_voice.h @@ -64,7 +64,7 @@ #define CTRLM_VOICE_SESSION_TEXT_MAX_LENGTH (512) ///< Session text string maximum length #define CTRLM_VOICE_SESSION_MSG_MAX_LENGTH (128) ///< Session message string maximum length #define CTRLM_VOICE_QUERY_STRING_MAX_LENGTH (128) ///< Query string maximum name or value length -#define CTRLM_VOICE_QUERY_STRING_MAX_PAIRS (16) ///< Query string maximum number of name/value pairs +#define CTRLM_VOICE_QUERY_STRING_MAX_PAIRS (24) ///< Query string maximum number of name/value pairs #define CTRLM_VOICE_REQUEST_IP_MAX_LENGTH (48) ///< cURL request primary IP address string maximum length (big enough for IPv6) #define CTRLM_VOICE_MIN_UTTERANCE_DURATION_MAXIMUM (600) ///< Maximum value of the utterance duration minimum setting (in milliseconds) diff --git a/src/auth/ctrlm_auth.h b/src/auth/ctrlm_auth.h index 0964335f..bda34998 100644 --- a/src/auth/ctrlm_auth.h +++ b/src/auth/ctrlm_auth.h @@ -34,7 +34,6 @@ class ctrlm_auth_t { virtual bool get_device_id(std::string &device_id) = 0; virtual bool get_account_id(std::string &account_id) = 0; virtual bool get_partner_id(std::string &partner_id) = 0; - virtual bool get_experience(std::string &experience) = 0; virtual bool get_sat(std::string &sat, time_t &expiration) = 0; virtual bool supports_sat_expiration() const = 0; diff --git a/src/auth/ctrlm_auth_thunder.cpp b/src/auth/ctrlm_auth_thunder.cpp index 2f954df3..7e37f8b4 100644 --- a/src/auth/ctrlm_auth_thunder.cpp +++ b/src/auth/ctrlm_auth_thunder.cpp @@ -48,11 +48,6 @@ bool ctrlm_auth_thunder_t::get_partner_id(std::string &partner_id) { return(ret); } -bool ctrlm_auth_thunder_t::get_experience(std::string &experience) { - bool ret = this->plugin->get_experience(experience); - return(ret); -} - bool ctrlm_auth_thunder_t::get_sat(std::string &sat, time_t &expiration) { bool ret = this->plugin->get_sat(sat, expiration); return(ret); diff --git a/src/auth/ctrlm_auth_thunder.h b/src/auth/ctrlm_auth_thunder.h index 3a476e67..67a385db 100644 --- a/src/auth/ctrlm_auth_thunder.h +++ b/src/auth/ctrlm_auth_thunder.h @@ -13,7 +13,6 @@ class ctrlm_auth_thunder_t : public ctrlm_auth_t { virtual bool get_device_id(std::string &device_id); virtual bool get_account_id(std::string &account_id); virtual bool get_partner_id(std::string &partner_id); - virtual bool get_experience(std::string &experience); virtual bool get_sat(std::string &sat, time_t &expiration); virtual bool supports_sat_expiration() const; diff --git a/src/auth/ctrlm_thunder_plugin_authservice.cpp b/src/auth/ctrlm_thunder_plugin_authservice.cpp index 60c57d7a..e5913d07 100644 --- a/src/auth/ctrlm_thunder_plugin_authservice.cpp +++ b/src/auth/ctrlm_thunder_plugin_authservice.cpp @@ -125,24 +125,6 @@ bool ctrlm_thunder_plugin_authservice_t::get_account_id(std::string &account_id) return(ret); } -bool ctrlm_thunder_plugin_authservice_t::get_experience(std::string &experience) { - bool ret = false; - JsonObject params, response; - if(this->call_plugin("getExperience", (void *)¶ms, (void *)&response)) { - if(response["success"].Boolean()) { // If success doesn't exist, it defaults to false which is fine. - experience = response["experience"].String(); - if(!experience.empty()) { - ret = true; - } - } else { - XLOGD_WARN("Success for getExperience was false"); - } - } else { - XLOGD_WARN("Call for getExperience failed"); - } - return(ret); -} - bool ctrlm_thunder_plugin_authservice_t::get_sat(std::string &sat, time_t &expiration) { bool ret = false; JsonObject params, response; diff --git a/src/auth/ctrlm_thunder_plugin_authservice.h b/src/auth/ctrlm_thunder_plugin_authservice.h index c39de41d..169cee88 100644 --- a/src/auth/ctrlm_thunder_plugin_authservice.h +++ b/src/auth/ctrlm_thunder_plugin_authservice.h @@ -75,13 +75,6 @@ class ctrlm_thunder_plugin_authservice_t : public Thunder::Plugin::ctrlm_thunder */ bool get_account_id(std::string &account_id); - /** - * Function that retrieves the Experience String from Authservice. - * @param experience The reference to a string which will contain the Experience String. - * @return True on success otherwise False. - */ - bool get_experience(std::string &experience); - /** * Function that retrieves the SAT Token from Authservice. * @param sat The reference to a string which will contain the SAT Token. diff --git a/src/ctrlm.h b/src/ctrlm.h index 905803d1..376608b3 100644 --- a/src/ctrlm.h +++ b/src/ctrlm.h @@ -458,7 +458,6 @@ gboolean ctrlm_main_has_device_id_get(void); gboolean ctrlm_main_has_device_type_get(void); gboolean ctrlm_main_has_service_account_id_get(void); gboolean ctrlm_main_has_partner_id_get(void); -gboolean ctrlm_main_has_experience_get(void); gboolean ctrlm_main_needs_service_access_token_get(void); void ctrlm_main_invalidate_service_access_token(void); void ctrlm_main_sat_enabled_set(gboolean sat_enabled); diff --git a/src/ctrlm_controller.cpp b/src/ctrlm_controller.cpp index 15496dd3..60173d47 100644 --- a/src/ctrlm_controller.cpp +++ b/src/ctrlm_controller.cpp @@ -118,10 +118,6 @@ string ctrlm_obj_controller_t::partner_id_get() const { return(obj_network_->partner_id_get()); } -string ctrlm_obj_controller_t::experience_get() const { - return(obj_network_->experience_get()); -} - string ctrlm_obj_controller_t::stb_name_get() const { return(obj_network_->stb_name_get()); } diff --git a/src/ctrlm_controller.h b/src/ctrlm_controller.h index 66749062..ae9b800b 100644 --- a/src/ctrlm_controller.h +++ b/src/ctrlm_controller.h @@ -63,7 +63,6 @@ class ctrlm_obj_controller_t std::string device_id_get() const; std::string service_account_id_get() const; std::string partner_id_get() const; - std::string experience_get() const; std::string stb_name_get() const; void set_device_minor_id(int device_minor_id); int get_device_minor_id() const; diff --git a/src/ctrlm_main.cpp b/src/ctrlm_main.cpp index f76c3682..c3da8d6d 100644 --- a/src/ctrlm_main.cpp +++ b/src/ctrlm_main.cpp @@ -302,10 +302,6 @@ static void ctrlm_main_has_service_account_id_set(gboolean has_id); static gboolean ctrlm_load_partner_id(void); static void ctrlm_main_has_partner_id_set(gboolean has_id); #endif -#ifdef AUTH_EXPERIENCE -static gboolean ctrlm_load_experience(void); -static void ctrlm_main_has_experience_set(gboolean has_experience); -#endif #ifdef AUTH_SAT_TOKEN static gboolean ctrlm_load_service_access_token(void); static void ctrlm_main_has_service_access_token_set(gboolean has_token); @@ -1421,30 +1417,6 @@ gboolean ctrlm_load_partner_id(void) { } #endif -#ifdef AUTH_EXPERIENCE -gboolean ctrlm_main_has_experience_get(void) { - return(g_ctrlm.has_experience); -} - -void ctrlm_main_has_experience_set(gboolean has_experience) { - g_ctrlm.has_experience = has_experience; -} - -gboolean ctrlm_load_experience(void) { - if(!g_ctrlm.authservice->get_experience(g_ctrlm.experience)) { - ctrlm_main_has_experience_set(false); - return(false); - } - g_ctrlm.voice_session->voice_stb_data_experience_set(g_ctrlm.experience); - - for(auto const &itr : g_ctrlm.networks) { - itr.second->experience_set(g_ctrlm.experience); - } - ctrlm_main_has_experience_set(true); - return(true); -} -#endif - #ifdef AUTH_SAT_TOKEN gboolean ctrlm_main_needs_service_access_token_get(void) { gboolean ret = false; @@ -1510,12 +1482,6 @@ gboolean ctrlm_has_authservice_data(void) { } #endif -#ifdef AUTH_EXPERIENCE - if(!ctrlm_main_has_experience_get()) { - ret = FALSE; - } -#endif - #ifdef AUTH_SAT_TOKEN if(ctrlm_main_needs_service_access_token_get()) { ret = FALSE; @@ -1566,18 +1532,6 @@ gboolean ctrlm_load_authservice_data(void) { } #endif -#ifdef AUTH_EXPERIENCE - if(!ctrlm_main_has_experience_get()) { - XLOGD_INFO("load experience"); - if(!ctrlm_load_experience()) { - XLOGD_TELEMETRY("failed to load experience"); - ret = FALSE; - } else { - XLOGD_INFO("load experience successfully <%s>", ctrlm_is_pii_mask_enabled() ? "***" : g_ctrlm.experience.c_str()); - } - } -#endif - #ifdef AUTH_SAT_TOKEN if(ctrlm_main_needs_service_access_token_get()) { XLOGD_INFO("load sat token"); diff --git a/src/ctrlm_network.cpp b/src/ctrlm_network.cpp index e8f591c3..26201231 100644 --- a/src/ctrlm_network.cpp +++ b/src/ctrlm_network.cpp @@ -187,16 +187,6 @@ string ctrlm_obj_network_t::partner_id_get() const { return(partner_id_); } -void ctrlm_obj_network_t::experience_set(const string& experience) { - THREAD_ID_VALIDATE(); - experience_ = experience; -} - -string ctrlm_obj_network_t::experience_get() const { - THREAD_ID_VALIDATE(); - return(experience_); -} - void ctrlm_obj_network_t::stb_name_set(const string& stb_name) { THREAD_ID_VALIDATE(); XLOGD_INFO("STB Name <%s>", stb_name.c_str()); diff --git a/src/ctrlm_network.h b/src/ctrlm_network.h index 90ea909f..ca6ad547 100644 --- a/src/ctrlm_network.h +++ b/src/ctrlm_network.h @@ -192,8 +192,6 @@ class ctrlm_obj_network_t std::string service_account_id_get() const; void partner_id_set(const std::string& partner_id); std::string partner_id_get() const; - void experience_set(const std::string& experience); - std::string experience_get() const; void mask_key_codes_set(gboolean mask_key_codes); gboolean mask_key_codes_get() const; void stb_name_set(const std::string& stb_name); @@ -325,7 +323,6 @@ class ctrlm_obj_network_t std::string device_id_; std::string service_account_id_; std::string partner_id_; - std::string experience_; std::string stb_name_; ctrlm_rcu_validation_result_t validation_result_ = CTRLM_RCU_VALIDATION_RESULT_MAX; ctrlm_key_code_t validation_key_ = CTRLM_KEY_CODE_INVALID; diff --git a/src/voice/ctrlm_voice_obj.cpp b/src/voice/ctrlm_voice_obj.cpp index 6e4b354f..a6787b1e 100644 --- a/src/voice/ctrlm_voice_obj.cpp +++ b/src/voice/ctrlm_voice_obj.cpp @@ -2252,18 +2252,6 @@ std::string ctrlm_voice_t::voice_stb_data_partner_id_get() const { return(this->partner_id); } -void ctrlm_voice_t::voice_stb_data_experience_set(std::string &experience) { - XLOGD_DEBUG("Experience Tag set to %s", experience.c_str()); - this->experience = experience; - for(const auto &itr : this->endpoints) { - itr->voice_stb_data_experience_set(experience); - } -} - -std::string ctrlm_voice_t::voice_stb_data_experience_get() const { - return(this->experience); -} - std::string ctrlm_voice_t::voice_stb_data_app_id_http_get() const { return(this->prefs.app_id_http); } @@ -2427,12 +2415,6 @@ bool ctrlm_voice_t::voice_session_has_stb_data() { return(false); } #endif -#ifdef AUTH_EXPERIENCE - if(this->experience == "") { - XLOGD_INFO("No experience tag"); - return(false); - } -#endif #ifdef AUTH_SAT_TOKEN if(this->sat_token_required && this->sat_token[0] == '\0') { XLOGD_INFO("No SAT token"); diff --git a/src/voice/ctrlm_voice_obj.h b/src/voice/ctrlm_voice_obj.h index 38699a6b..3ec217b2 100644 --- a/src/voice/ctrlm_voice_obj.h +++ b/src/voice/ctrlm_voice_obj.h @@ -525,8 +525,6 @@ class ctrlm_voice_t { ctrlm_device_type_t voice_stb_data_device_type_get() const; virtual void voice_stb_data_partner_id_set(std::string &partner_id); std::string voice_stb_data_partner_id_get() const; - virtual void voice_stb_data_experience_set(std::string &experience); - std::string voice_stb_data_experience_get() const; std::string voice_stb_data_app_id_http_get() const; std::string voice_stb_data_app_id_ws_get() const; virtual void voice_stb_data_guide_language_set(const char *language); @@ -662,7 +660,6 @@ class ctrlm_voice_t { std::string device_id; ctrlm_device_type_t device_type; std::string partner_id; - std::string experience; char sat_token[XRSR_SAT_TOKEN_LEN_MAX]; bool sat_token_required; bool mtls_required; diff --git a/src/voice/endpoints/ctrlm_voice_endpoint.cpp b/src/voice/endpoints/ctrlm_voice_endpoint.cpp index 7815cd27..1aed8d46 100644 --- a/src/voice/endpoints/ctrlm_voice_endpoint.cpp +++ b/src/voice/endpoints/ctrlm_voice_endpoint.cpp @@ -63,7 +63,6 @@ void ctrlm_voice_endpoint_t::voice_stb_data_account_number_set(std::string &acco void ctrlm_voice_endpoint_t::voice_stb_data_device_id_set(std::string &device_id) {} void ctrlm_voice_endpoint_t::voice_stb_data_device_type_set(ctrlm_device_type_t device_type) {} void ctrlm_voice_endpoint_t::voice_stb_data_partner_id_set(std::string &partner_id) {} -void ctrlm_voice_endpoint_t::voice_stb_data_experience_set(std::string &experience) {} void ctrlm_voice_endpoint_t::voice_stb_data_guide_language_set(const char *language) {} void ctrlm_voice_endpoint_t::voice_stb_data_mask_pii_set(bool enable) {} diff --git a/src/voice/endpoints/ctrlm_voice_endpoint.h b/src/voice/endpoints/ctrlm_voice_endpoint.h index ac881880..3298348f 100644 --- a/src/voice/endpoints/ctrlm_voice_endpoint.h +++ b/src/voice/endpoints/ctrlm_voice_endpoint.h @@ -50,7 +50,6 @@ class ctrlm_voice_endpoint_t { virtual void voice_stb_data_device_id_set(std::string &device_id); virtual void voice_stb_data_device_type_set(ctrlm_device_type_t device_type); virtual void voice_stb_data_partner_id_set(std::string &partner_id); - virtual void voice_stb_data_experience_set(std::string &experience); virtual void voice_stb_data_guide_language_set(const char *language); virtual void voice_stb_data_mask_pii_set(bool enable); // End Data Setters diff --git a/src/voice/endpoints/ctrlm_voice_endpoint_http.cpp b/src/voice/endpoints/ctrlm_voice_endpoint_http.cpp index 1ec3e647..c119ee43 100644 --- a/src/voice/endpoints/ctrlm_voice_endpoint_http.cpp +++ b/src/voice/endpoints/ctrlm_voice_endpoint_http.cpp @@ -72,14 +72,12 @@ bool ctrlm_voice_endpoint_http_t::open() { std::string device_id = this->voice_obj->voice_stb_data_device_id_get(); std::string partner_id = this->voice_obj->voice_stb_data_partner_id_get(); - std::string experience = this->voice_obj->voice_stb_data_experience_get(); std::string app_id = this->voice_obj->voice_stb_data_app_id_http_get(); std::string language = this->voice_obj->voice_stb_data_guide_language_get().c_str(); xrsv_http_params_t params_http = { .device_id = device_id.c_str(), .partner_id = partner_id.c_str(), - .experience = experience.c_str(), .app_id = app_id.c_str(), .language = language.c_str(), .test_flag = this->voice_obj->voice_stb_data_test_get(), @@ -138,12 +136,6 @@ void ctrlm_voice_endpoint_http_t::voice_stb_data_partner_id_set(std::string &par } } -void ctrlm_voice_endpoint_http_t::voice_stb_data_experience_set(std::string &experience) { - if(this->xrsv_obj_http) { - xrsv_http_update_experience(this->xrsv_obj_http, experience.c_str()); - } -} - void ctrlm_voice_endpoint_http_t::voice_stb_data_guide_language_set(const char *language) { if(this->xrsv_obj_http) { xrsv_http_update_language(this->xrsv_obj_http, language); diff --git a/src/voice/endpoints/ctrlm_voice_endpoint_http.h b/src/voice/endpoints/ctrlm_voice_endpoint_http.h index 9338e20d..79a0d50d 100644 --- a/src/voice/endpoints/ctrlm_voice_endpoint_http.h +++ b/src/voice/endpoints/ctrlm_voice_endpoint_http.h @@ -32,7 +32,6 @@ class ctrlm_voice_endpoint_http_t : public ctrlm_voice_endpoint_t { public: void voice_stb_data_device_id_set(std::string &device_id); void voice_stb_data_partner_id_set(std::string &partner_id); - void voice_stb_data_experience_set(std::string &experience); void voice_stb_data_guide_language_set(const char *language); void voice_stb_data_pii_mask_set(bool enable); diff --git a/src/voice/endpoints/ctrlm_voice_endpoint_ws_nextgen.cpp b/src/voice/endpoints/ctrlm_voice_endpoint_ws_nextgen.cpp index e5165cd7..9abc27db 100644 --- a/src/voice/endpoints/ctrlm_voice_endpoint_ws_nextgen.cpp +++ b/src/voice/endpoints/ctrlm_voice_endpoint_ws_nextgen.cpp @@ -86,7 +86,6 @@ bool ctrlm_voice_endpoint_ws_nextgen_t::open() { } std::string device_id = this->voice_obj->voice_stb_data_device_id_get(); std::string partner_id = this->voice_obj->voice_stb_data_partner_id_get(); - std::string experience = this->voice_obj->voice_stb_data_experience_get(); std::string language = this->voice_obj->voice_stb_data_guide_language_get().c_str(); std::string account_number = this->voice_obj->voice_stb_data_account_number_get(); std::string device_mac = ctrlm_device_mac_get(); @@ -96,7 +95,6 @@ bool ctrlm_voice_endpoint_ws_nextgen_t::open() { .device_id = (device_id.empty() == false ? device_id.c_str() : NULL), .account_id = (account_number.empty() == false ? account_number.c_str() : NULL), .partner_id = (partner_id.empty() == false ? partner_id.c_str() : NULL), - .experience = (experience.empty() == false ? experience.c_str() : NULL), .audio_profile = controller_name_to_audio_profile(""), .audio_model = controller_name_to_audio_model(""), .language = language.c_str(), @@ -235,12 +233,6 @@ void ctrlm_voice_endpoint_ws_nextgen_t::voice_stb_data_partner_id_set(std::strin } } -void ctrlm_voice_endpoint_ws_nextgen_t::voice_stb_data_experience_set(std::string &experience) { - if(this->xrsv_obj_ws_nextgen) { - xrsv_ws_nextgen_update_experience(this->xrsv_obj_ws_nextgen, experience.c_str()); - } -} - void ctrlm_voice_endpoint_ws_nextgen_t::voice_stb_data_guide_language_set(const char *language) { if(this->xrsv_obj_ws_nextgen) { xrsv_ws_nextgen_update_language(this->xrsv_obj_ws_nextgen, language); diff --git a/src/voice/endpoints/ctrlm_voice_endpoint_ws_nextgen.h b/src/voice/endpoints/ctrlm_voice_endpoint_ws_nextgen.h index 16667f2f..218e1d39 100644 --- a/src/voice/endpoints/ctrlm_voice_endpoint_ws_nextgen.h +++ b/src/voice/endpoints/ctrlm_voice_endpoint_ws_nextgen.h @@ -37,7 +37,6 @@ class ctrlm_voice_endpoint_ws_nextgen_t : public ctrlm_voice_endpoint_t { void voice_stb_data_device_id_set(std::string &device_id); void voice_stb_data_device_type_set(ctrlm_device_type_t device_type); void voice_stb_data_partner_id_set(std::string &partner_id); - void voice_stb_data_experience_set(std::string &experience); void voice_stb_data_guide_language_set(const char *language); void voice_stb_data_mask_pii_set(bool enable);