From 91bf56c48d8276688e2163d892b984468f06ca03 Mon Sep 17 00:00:00 2001 From: dwolav200 Date: Thu, 6 Aug 2026 12:38:53 -0400 Subject: [PATCH 1/6] RDKEMW-22184 : fetch controller link key --- include/ctrlm_ipc_rcu.h | 9 --- src/ctrlm_network.cpp | 15 ----- src/ctrlm_network.h | 1 - src/ctrlm_rcu.cpp | 32 ----------- src/ctrlm_rcu.h | 8 --- src/ctrlm_rcu_iarm.cpp | 7 --- src/rf4ce/ctrlm_rf4ce_controller.cpp | 5 ++ src/rf4ce/ctrlm_rf4ce_network.cpp | 85 +++++++++++++++++----------- src/rf4ce/ctrlm_rf4ce_network.h | 5 +- 9 files changed, 61 insertions(+), 106 deletions(-) diff --git a/include/ctrlm_ipc_rcu.h b/include/ctrlm_ipc_rcu.h index 18247c12..167350eb 100644 --- a/include/ctrlm_ipc_rcu.h +++ b/include/ctrlm_ipc_rcu.h @@ -22,7 +22,6 @@ #define _CTRLM_IPC_RCU_H_ #define CTRLM_RCU_IARM_CALL_CONTROLLER_STATUS "Rcu_ControllerStatus" ///< IARM Call to get controller information -#define CTRLM_RCU_IARM_CALL_CONTROLLER_LINK_KEY "Rcu_ControllerLinkKey" ///< IARM Call to get controller link key #define CTRLM_RCU_IARM_CALL_RIB_REQUEST_GET "Rcu_RibRequestGet" ///< IARM Call to retrieves an attribute from the controller's RIB #define CTRLM_RCU_IARM_CALL_RIB_REQUEST_SET "Rcu_RibRequestSet" ///< IARM Call to set an attribute in the controller's RIB #define CTRLM_RCU_IARM_CALL_RF4CE_POLLING_ACTION "Rcu_Rf4cePollingAction" ///< IARM Call to Send Remote Heartbeat Response Polling Action @@ -433,14 +432,6 @@ typedef struct { char data[CTRLM_RCU_MAX_RIB_ATTRIBUTE_SIZE]; ///< RIB entry's data } ctrlm_rcu_iarm_call_rib_request_t; -typedef struct { - unsigned char api_revision; ///< Revision of this API - ctrlm_iarm_call_result_t result; ///< Result of the IARM call - ctrlm_network_id_t network_id; ///< IN The identifier of network on which the controller is bound - ctrlm_controller_id_t controller_id; ///< IN - unsigned char link_key[16]; ///< OUT The link key for the controller -} ctrlm_rcu_iarm_call_controller_link_key_t; - typedef struct { unsigned char api_revision; ///< Revision of this API ctrlm_network_id_t network_id; ///< identifier of network on which the controller is bound diff --git a/src/ctrlm_network.cpp b/src/ctrlm_network.cpp index fc7035a0..448194ef 100644 --- a/src/ctrlm_network.cpp +++ b/src/ctrlm_network.cpp @@ -510,21 +510,6 @@ void ctrlm_obj_network_t::network_destroy() { XLOGD_INFO("Destroying %s network", name_get()); } -void ctrlm_obj_network_t::req_process_controller_link_key(void *data, int size) { - ctrlm_main_queue_msg_controller_link_key_t *dqm = (ctrlm_main_queue_msg_controller_link_key_t *)data; - - g_assert(dqm); - g_assert(size == sizeof(ctrlm_main_queue_msg_controller_link_key_t)); - - if(dqm->cmd_result && *dqm->cmd_result == CTRLM_CONTROLLER_STATUS_REQUEST_PENDING) { - XLOGD_WARN("not implemented for %s network", name_get()); - *dqm->cmd_result = CTRLM_CONTROLLER_STATUS_REQUEST_ERROR; - } - if(dqm->semaphore) { - sem_post(dqm->semaphore); - } -} - void ctrlm_obj_network_t::req_process_controller_status(void *data, int size) { ctrlm_main_queue_msg_controller_status_t *dqm = (ctrlm_main_queue_msg_controller_status_t *)data; diff --git a/src/ctrlm_network.h b/src/ctrlm_network.h index cb877123..05edb0f0 100644 --- a/src/ctrlm_network.h +++ b/src/ctrlm_network.h @@ -253,7 +253,6 @@ class ctrlm_obj_network_t virtual ctrlm_rf_pair_state_t get_rf_pair_state() const; virtual void req_process_network_status(void *data, int size); - virtual void req_process_controller_link_key(void *data, int size); virtual void req_process_controller_status(void *data, int size); virtual void req_process_controller_product_name(void *data, int size); virtual void req_process_voice_session_begin(void *data, int size); diff --git a/src/ctrlm_rcu.cpp b/src/ctrlm_rcu.cpp index 3e7f0a24..03124bb3 100644 --- a/src/ctrlm_rcu.cpp +++ b/src/ctrlm_rcu.cpp @@ -166,38 +166,6 @@ gboolean ctrlm_rcu_rib_request_set(ctrlm_rcu_iarm_call_rib_request_t *params) { return(false); } -gboolean ctrlm_rcu_controller_link_key(ctrlm_rcu_iarm_call_controller_link_key_t *params) { - XLOGD_INFO("(%u, %u)", params->network_id, params->controller_id); - - if(params->network_id == CTRLM_MAIN_NETWORK_ID_ALL || params->controller_id == CTRLM_MAIN_CONTROLLER_ID_ALL) { - XLOGD_ERROR("Cannot get status for multiple controllers"); - return(false); - } - sem_t semaphore; - ctrlm_controller_status_cmd_result_t cmd_result = CTRLM_CONTROLLER_STATUS_REQUEST_PENDING; - - // Allocate a message and send it to Control Manager's queue - ctrlm_main_queue_msg_controller_link_key_t msg = {0}; - - sem_init(&semaphore, 0, 0); - - msg.controller_id = params->controller_id; - msg.link_key = params->link_key; - msg.semaphore = &semaphore; - msg.cmd_result = &cmd_result; - - ctrlm_main_queue_handler_push(CTRLM_HANDLER_NETWORK, (ctrlm_msg_handler_network_t)&ctrlm_obj_network_t::req_process_controller_link_key, &msg, sizeof(msg), NULL, params->network_id); - - // Wait for the result semaphore to be signaled - sem_wait(&semaphore); - sem_destroy(&semaphore); - - if(cmd_result == CTRLM_CONTROLLER_STATUS_REQUEST_SUCCESS) { - return(true); - } - return(false); -} - gboolean ctrlm_rcu_controller_type_get(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_rcu_controller_type_t *type) { XLOGD_INFO("(%u, %u)", network_id, controller_id); diff --git a/src/ctrlm_rcu.h b/src/ctrlm_rcu.h index 7b3729ff..11d2eb57 100644 --- a/src/ctrlm_rcu.h +++ b/src/ctrlm_rcu.h @@ -40,13 +40,6 @@ typedef struct { ctrlm_controller_status_cmd_result_t *cmd_result; } ctrlm_main_queue_msg_controller_status_t; -typedef struct { - ctrlm_controller_id_t controller_id; - unsigned char * link_key; - sem_t * semaphore; - ctrlm_controller_status_cmd_result_t *cmd_result; -} ctrlm_main_queue_msg_controller_link_key_t; - typedef struct { ctrlm_main_queue_msg_header_t header; ctrlm_controller_id_t controller_id; @@ -142,7 +135,6 @@ void ctrlm_rcu_iarm_event_reverse_cmd(ctrlm_network_id_t network_id, ctrlm_c gboolean ctrlm_rcu_controller_status(ctrlm_rcu_iarm_call_controller_status_t *params); gboolean ctrlm_rcu_rib_request_get(ctrlm_rcu_iarm_call_rib_request_t *params); gboolean ctrlm_rcu_rib_request_set(ctrlm_rcu_iarm_call_rib_request_t *params); -gboolean ctrlm_rcu_controller_link_key(ctrlm_rcu_iarm_call_controller_link_key_t *params); gboolean ctrlm_rcu_controller_type_get(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_rcu_controller_type_t *type); gboolean ctrlm_rcu_rf4ce_polling_action(ctrlm_rcu_iarm_call_rf4ce_polling_action_t *params); diff --git a/src/ctrlm_rcu_iarm.cpp b/src/ctrlm_rcu_iarm.cpp index a28ea82e..0ed58446 100644 --- a/src/ctrlm_rcu_iarm.cpp +++ b/src/ctrlm_rcu_iarm.cpp @@ -31,7 +31,6 @@ static IARM_Result_t ctrlm_rcu_iarm_call_controller_status(void *arg); static IARM_Result_t ctrlm_rcu_iarm_call_rib_request_get(void *arg); static IARM_Result_t ctrlm_rcu_iarm_call_rib_request_set(void *arg); -static IARM_Result_t ctrlm_rcu_iarm_call_controller_link_key(void *arg); static IARM_Result_t ctrlm_rcu_iarm_call_rf4ce_polling_action(void *arg); typedef struct { @@ -43,7 +42,6 @@ static iarm_call_handler_t handlers[] = { { CTRLM_RCU_IARM_CALL_CONTROLLER_STATUS, &ctrlm_rcu_iarm_call_controller_status }, { CTRLM_RCU_IARM_CALL_RIB_REQUEST_GET, &ctrlm_rcu_iarm_call_rib_request_get }, { CTRLM_RCU_IARM_CALL_RIB_REQUEST_SET, &ctrlm_rcu_iarm_call_rib_request_set }, - { CTRLM_RCU_IARM_CALL_CONTROLLER_LINK_KEY, &ctrlm_rcu_iarm_call_controller_link_key }, { CTRLM_RCU_IARM_CALL_RF4CE_POLLING_ACTION, &ctrlm_rcu_iarm_call_rf4ce_polling_action } }; @@ -237,11 +235,6 @@ IARM_Result_t ctrlm_rcu_iarm_call_rib_request_set(void *arg) { return ctrlm_rcu_iarm_call_dispatch(params, &ctrlm_rcu_rib_request_set); } -IARM_Result_t ctrlm_rcu_iarm_call_controller_link_key(void *arg) { - ctrlm_rcu_iarm_call_controller_link_key_t *params = (ctrlm_rcu_iarm_call_controller_link_key_t *) arg; - return ctrlm_rcu_iarm_call_dispatch(params, &ctrlm_rcu_controller_link_key); -} - IARM_Result_t ctrlm_rcu_iarm_call_rf4ce_polling_action(void *arg) { ctrlm_rcu_iarm_call_rf4ce_polling_action_t *params = (ctrlm_rcu_iarm_call_rf4ce_polling_action_t *) arg; return ctrlm_rcu_iarm_call_dispatch(params, &ctrlm_rcu_rf4ce_polling_action); diff --git a/src/rf4ce/ctrlm_rf4ce_controller.cpp b/src/rf4ce/ctrlm_rf4ce_controller.cpp index 8ae0119d..3d6bdcd3 100644 --- a/src/rf4ce/ctrlm_rf4ce_controller.cpp +++ b/src/rf4ce/ctrlm_rf4ce_controller.cpp @@ -1035,6 +1035,11 @@ void ctrlm_obj_controller_rf4ce_t::validation_result_set(ctrlm_rcu_binding_type_ validation_type_ = validation_type; db_create(); db_store(); + + unsigned long long network_ieee = 0; + obj_network_rf4ce_->ieee_address_get(&network_ieee); + rf4ce_info_file_write(network_ieee, ieee_address_get().get_value()); + // possible duplicate pairing needs_reset_ = false; did_reset_ = false; diff --git a/src/rf4ce/ctrlm_rf4ce_network.cpp b/src/rf4ce/ctrlm_rf4ce_network.cpp index 8dce469e..f4149710 100644 --- a/src/rf4ce/ctrlm_rf4ce_network.cpp +++ b/src/rf4ce/ctrlm_rf4ce_network.cpp @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include "ctrlm.h" #include "ctrlm_log.h" #include "ctrlm_utils.h" @@ -55,6 +57,47 @@ #include "ctrlm_voice_obj.h" #include "comcastIrKeyCodes.h" +#define CTRLM_RF4CE_CONTROLLER_INFO_BASE_DIR "/opt/lib/rf4ce" + +void rf4ce_info_file_write(unsigned long long network_ieee, unsigned long long controller_ieee) { + char dir_path[128]; + char file_path[160]; + snprintf(dir_path, sizeof(dir_path), "%s/%016llX:%016llX", CTRLM_RF4CE_CONTROLLER_INFO_BASE_DIR, network_ieee, controller_ieee); + snprintf(file_path, sizeof(file_path), "%s/info", dir_path); + + if(mkdir(CTRLM_RF4CE_CONTROLLER_INFO_BASE_DIR, 0755) != 0 && errno != EEXIST) { + XLOGD_ERROR("Failed to create base dir <%s> errno %d", CTRLM_RF4CE_CONTROLLER_INFO_BASE_DIR, errno); + return; + } + if(mkdir(dir_path, 0755) != 0 && errno != EEXIST) { + XLOGD_ERROR("Failed to create dir <%s> errno %d", dir_path, errno); + return; + } + FILE *f = fopen(file_path, "w"); + if(f == NULL) { + XLOGD_ERROR("Failed to create info file <%s> errno %d", file_path, errno); + return; + } + fclose(f); + XLOGD_INFO("Created info file <%s>", file_path); +} + +static void rf4ce_info_file_delete(unsigned long long network_ieee, unsigned long long controller_ieee) { + char dir_path[128]; + char file_path[160]; + snprintf(dir_path, sizeof(dir_path), "%s/%016llX:%016llX", CTRLM_RF4CE_CONTROLLER_INFO_BASE_DIR, network_ieee, controller_ieee); + snprintf(file_path, sizeof(file_path), "%s/info", dir_path); + + if(unlink(file_path) != 0 && errno != ENOENT) { + XLOGD_ERROR("Failed to delete info file <%s> errno %d", file_path, errno); + } else { + XLOGD_INFO("Deleted info file <%s>", file_path); + } + if(rmdir(dir_path) != 0 && errno != ENOENT) { + XLOGD_WARN("Failed to remove dir <%s> errno %d", dir_path, errno); + } +} + #if (JSON_INT_VALUE_NETWORK_RF4CE_AUTOBIND_CONFIG_QTY_PASS > 7) || (JSON_INT_VALUE_NETWORK_RF4CE_AUTOBIND_CONFIG_QTY_PASS < 1) #error RF4CE AUTOBIND PASS THRESHOLD IS OUT OF RANGE #endif @@ -501,6 +544,7 @@ void ctrlm_obj_network_rf4ce_t::controller_unbind(ctrlm_controller_id_t controll } // Telemetry needs to keep track of unbinding. controllers_[controller_id]->log_unbinding_for_telemetry(); + rf4ce_info_file_delete(ieee_address_, controllers_[controller_id]->ieee_address_get().get_value()); // Remove the controller from the controller list and delete the DB entry controller_remove(controller_id, true); @@ -1798,39 +1842,6 @@ void ctrlm_obj_network_rf4ce_t::req_process_controller_product_name(void *data, ctrlm_obj_network_t::req_process_controller_product_name(data, size); } -void ctrlm_obj_network_rf4ce_t::req_process_controller_link_key(void *data, int size) { - THREAD_ID_VALIDATE(); - ctrlm_main_queue_msg_controller_link_key_t *dqm = (ctrlm_main_queue_msg_controller_link_key_t *)data; - - g_assert(dqm); - g_assert(size == sizeof(ctrlm_main_queue_msg_controller_link_key_t)); - g_assert(dqm->cmd_result); - - ctrlm_hal_network_property_encryption_key_t property = {0}; - - if(!controller_exists(dqm->controller_id)) { - XLOGD_WARN("Controller %u NOT present.", dqm->controller_id); - *dqm->cmd_result = CTRLM_CONTROLLER_STATUS_REQUEST_ERROR; - ctrlm_obj_network_t::req_process_controller_link_key(data, size); - return; - } - - XLOGD_INFO("Getting Link Key for Controller %u", dqm->controller_id); - - // Get Link key - property.controller_id = dqm->controller_id; - if(CTRLM_HAL_RESULT_SUCCESS != property_get(CTRLM_HAL_NETWORK_PROPERTY_ENCRYPTION_KEY, (void **)&property)) { - XLOGD_ERROR("Failed to get Link Key from HAL"); - *dqm->cmd_result = CTRLM_CONTROLLER_STATUS_REQUEST_ERROR; - ctrlm_obj_network_t::req_process_controller_link_key(data, size); - return; - } - - errno_t safec_rc = memcpy_s(dqm->link_key, CTRLM_HAL_NETWORK_AES128_KEY_SIZE, property.aes128_key, CTRLM_HAL_NETWORK_AES128_KEY_SIZE); - ERR_CHK(safec_rc); - *dqm->cmd_result = CTRLM_CONTROLLER_STATUS_REQUEST_SUCCESS; - ctrlm_obj_network_t::req_process_controller_link_key(data, size); -} ctrlm_rib_request_cmd_result_t ctrlm_obj_network_rf4ce_t::req_process_rib_export(ctrlm_controller_id_t controller_id, uint8_t identifier, unsigned char index, unsigned char length, unsigned char *data) { THREAD_ID_VALIDATE(); @@ -4087,6 +4098,14 @@ void ctrlm_obj_network_rf4ce_t::hal_init_cfm(void *data, int size) { hal_init_confirm(dqm->params.rf4ce); + if(dqm->params.rf4ce.result == CTRLM_HAL_RESULT_SUCCESS) { + for(auto &kv : controllers_) { + if(kv.second->is_bound()) { + rf4ce_info_file_write(ieee_address_, kv.second->ieee_address_get().get_value()); + } + } + } + ctrlm_obj_network_t::hal_init_cfm(data, size); } diff --git a/src/rf4ce/ctrlm_rf4ce_network.h b/src/rf4ce/ctrlm_rf4ce_network.h index f9b49ad5..09b67f69 100644 --- a/src/rf4ce/ctrlm_rf4ce_network.h +++ b/src/rf4ce/ctrlm_rf4ce_network.h @@ -348,7 +348,7 @@ class ctrlm_obj_network_rf4ce_t : public ctrlm_obj_network_t void req_process_controller_status(void *dqm, int size); void req_process_controller_product_name(void *data, int size); void req_process_network_status(void *data, int size); - void req_process_controller_link_key(void *data, int size); + void req_process_dpi_control(void *data, int size); void req_process_polling_action_push(void *data, int size); virtual ctrlm_controller_status_cmd_result_t req_process_reverse_cmd(ctrlm_main_queue_msg_rcu_reverse_cmd_t *dqm); @@ -661,4 +661,7 @@ class ctrlm_obj_network_rf4ce_t : public ctrlm_obj_network_t #endif void controller_init_uinput(ctrlm_controller_id_t controller_id); }; + +void rf4ce_info_file_write(unsigned long long network_ieee, unsigned long long controller_ieee); + #endif From 773e62c04e48592f10f37e02e6e32baa70b6aca3 Mon Sep 17 00:00:00 2001 From: dwolav200 Date: Fri, 7 Aug 2026 17:46:32 -0400 Subject: [PATCH 2/6] reworked stuff --- src/rf4ce/ctrlm_rf4ce_controller.cpp | 4 - src/rf4ce/ctrlm_rf4ce_network.cpp | 189 ++++++++++++++++++++------- src/rf4ce/ctrlm_rf4ce_network.h | 7 +- src/rf4ce/ctrlm_rf4ce_validation.cpp | 7 + 4 files changed, 154 insertions(+), 53 deletions(-) diff --git a/src/rf4ce/ctrlm_rf4ce_controller.cpp b/src/rf4ce/ctrlm_rf4ce_controller.cpp index 3d6bdcd3..fc47ba35 100644 --- a/src/rf4ce/ctrlm_rf4ce_controller.cpp +++ b/src/rf4ce/ctrlm_rf4ce_controller.cpp @@ -1036,10 +1036,6 @@ void ctrlm_obj_controller_rf4ce_t::validation_result_set(ctrlm_rcu_binding_type_ db_create(); db_store(); - unsigned long long network_ieee = 0; - obj_network_rf4ce_->ieee_address_get(&network_ieee); - rf4ce_info_file_write(network_ieee, ieee_address_get().get_value()); - // possible duplicate pairing needs_reset_ = false; did_reset_ = false; diff --git a/src/rf4ce/ctrlm_rf4ce_network.cpp b/src/rf4ce/ctrlm_rf4ce_network.cpp index f4149710..ff17d5ab 100644 --- a/src/rf4ce/ctrlm_rf4ce_network.cpp +++ b/src/rf4ce/ctrlm_rf4ce_network.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include "ctrlm.h" #include "ctrlm_log.h" #include "ctrlm_utils.h" @@ -57,45 +58,13 @@ #include "ctrlm_voice_obj.h" #include "comcastIrKeyCodes.h" -#define CTRLM_RF4CE_CONTROLLER_INFO_BASE_DIR "/opt/lib/rf4ce" +#define CTRLM_RF4CE_CONTROLLER_INFO_LIB_DIR "/opt/secure/lib" +#define CTRLM_RF4CE_CONTROLLER_INFO_BASE_DIR "/opt/secure/lib/rf4ce" -void rf4ce_info_file_write(unsigned long long network_ieee, unsigned long long controller_ieee) { - char dir_path[128]; - char file_path[160]; - snprintf(dir_path, sizeof(dir_path), "%s/%016llX:%016llX", CTRLM_RF4CE_CONTROLLER_INFO_BASE_DIR, network_ieee, controller_ieee); - snprintf(file_path, sizeof(file_path), "%s/info", dir_path); - - if(mkdir(CTRLM_RF4CE_CONTROLLER_INFO_BASE_DIR, 0755) != 0 && errno != EEXIST) { - XLOGD_ERROR("Failed to create base dir <%s> errno %d", CTRLM_RF4CE_CONTROLLER_INFO_BASE_DIR, errno); - return; - } - if(mkdir(dir_path, 0755) != 0 && errno != EEXIST) { - XLOGD_ERROR("Failed to create dir <%s> errno %d", dir_path, errno); - return; - } - FILE *f = fopen(file_path, "w"); - if(f == NULL) { - XLOGD_ERROR("Failed to create info file <%s> errno %d", file_path, errno); - return; - } - fclose(f); - XLOGD_INFO("Created info file <%s>", file_path); -} - -static void rf4ce_info_file_delete(unsigned long long network_ieee, unsigned long long controller_ieee) { - char dir_path[128]; - char file_path[160]; - snprintf(dir_path, sizeof(dir_path), "%s/%016llX:%016llX", CTRLM_RF4CE_CONTROLLER_INFO_BASE_DIR, network_ieee, controller_ieee); - snprintf(file_path, sizeof(file_path), "%s/info", dir_path); - - if(unlink(file_path) != 0 && errno != ENOENT) { - XLOGD_ERROR("Failed to delete info file <%s> errno %d", file_path, errno); - } else { - XLOGD_INFO("Deleted info file <%s>", file_path); - } - if(rmdir(dir_path) != 0 && errno != ENOENT) { - XLOGD_WARN("Failed to remove dir <%s> errno %d", dir_path, errno); - } +static void rf4ce_ieee_to_str(unsigned long long ieee, char *buf, size_t buf_size) { + snprintf(buf, buf_size, "%02llX:%02llX:%02llX:%02llX:%02llX:%02llX:%02llX:%02llX", + (ieee >> 56) & 0xFF, (ieee >> 48) & 0xFF, (ieee >> 40) & 0xFF, (ieee >> 32) & 0xFF, + (ieee >> 24) & 0xFF, (ieee >> 16) & 0xFF, (ieee >> 8) & 0xFF, ieee & 0xFF); } #if (JSON_INT_VALUE_NETWORK_RF4CE_AUTOBIND_CONFIG_QTY_PASS > 7) || (JSON_INT_VALUE_NETWORK_RF4CE_AUTOBIND_CONFIG_QTY_PASS < 1) @@ -544,7 +513,7 @@ void ctrlm_obj_network_rf4ce_t::controller_unbind(ctrlm_controller_id_t controll } // Telemetry needs to keep track of unbinding. controllers_[controller_id]->log_unbinding_for_telemetry(); - rf4ce_info_file_delete(ieee_address_, controllers_[controller_id]->ieee_address_get().get_value()); + info_file_delete(controllers_[controller_id]->ieee_address_get().get_value()); // Remove the controller from the controller list and delete the DB entry controller_remove(controller_id, true); @@ -978,6 +947,9 @@ void ctrlm_obj_network_rf4ce_t::hal_init_complete() { controller_init_uinput(it->first); } + // Consolidate the info files + info_file_consolidation(); + // Free the memory associated with the request ctrlm_hal_free(list); } @@ -4098,14 +4070,6 @@ void ctrlm_obj_network_rf4ce_t::hal_init_cfm(void *data, int size) { hal_init_confirm(dqm->params.rf4ce); - if(dqm->params.rf4ce.result == CTRLM_HAL_RESULT_SUCCESS) { - for(auto &kv : controllers_) { - if(kv.second->is_bound()) { - rf4ce_info_file_write(ieee_address_, kv.second->ieee_address_get().get_value()); - } - } - } - ctrlm_obj_network_t::hal_init_cfm(data, size); } @@ -4852,6 +4816,137 @@ void ctrlm_obj_network_rf4ce_t::controller_init_uinput(ctrlm_controller_id_t con } } +void ctrlm_obj_network_rf4ce_t::info_file_write(unsigned long long controller_ieee, const unsigned char *key) { + char network_mac[32]; + char controller_mac[32]; + char network_dir[128]; + char controller_dir[160]; + char file_path[192]; + + rf4ce_ieee_to_str(ieee_address_, network_mac, sizeof(network_mac)); + rf4ce_ieee_to_str(controller_ieee, controller_mac, sizeof(controller_mac)); + snprintf(network_dir, sizeof(network_dir), "%s/%s", CTRLM_RF4CE_CONTROLLER_INFO_BASE_DIR, network_mac); + snprintf(controller_dir, sizeof(controller_dir), "%s/%s", network_dir, controller_mac); + snprintf(file_path, sizeof(file_path), "%s/info", controller_dir); + + if(mkdir(CTRLM_RF4CE_CONTROLLER_INFO_LIB_DIR, 0755) != 0 && errno != EEXIST) { + XLOGD_ERROR("Failed to create lib dir <%s> errno %d", CTRLM_RF4CE_CONTROLLER_INFO_LIB_DIR, errno); + return; + } + if(mkdir(CTRLM_RF4CE_CONTROLLER_INFO_BASE_DIR, 0755) != 0 && errno != EEXIST) { + XLOGD_ERROR("Failed to create base dir <%s> errno %d", CTRLM_RF4CE_CONTROLLER_INFO_BASE_DIR, errno); + return; + } + if(mkdir(network_dir, 0755) != 0 && errno != EEXIST) { + XLOGD_ERROR("Failed to create network dir <%s> errno %d", network_dir, errno); + return; + } + if(mkdir(controller_dir, 0755) != 0 && errno != EEXIST) { + XLOGD_ERROR("Failed to create controller dir <%s> errno %d", controller_dir, errno); + return; + } + FILE *f = fopen(file_path, "w"); + if(f == NULL) { + XLOGD_ERROR("Failed to create info file <%s> errno %d", file_path, errno); + return; + } + fprintf(f, "[ControllerKey]\nKey="); + for(int i = 0; i < CTRLM_HAL_NETWORK_AES128_KEY_SIZE; i++) { + fprintf(f, "%02X", key[i]); + } + fprintf(f, "\n"); + fclose(f); + XLOGD_INFO("Created info file <%s>", file_path); +} + +void ctrlm_obj_network_rf4ce_t::info_file_delete(unsigned long long controller_ieee) { + char network_mac[32]; + char controller_mac[32]; + char network_dir[128]; + char controller_dir[160]; + char file_path[192]; + + rf4ce_ieee_to_str(ieee_address_, network_mac, sizeof(network_mac)); + rf4ce_ieee_to_str(controller_ieee, controller_mac, sizeof(controller_mac)); + snprintf(network_dir, sizeof(network_dir), "%s/%s", CTRLM_RF4CE_CONTROLLER_INFO_BASE_DIR, network_mac); + snprintf(controller_dir, sizeof(controller_dir), "%s/%s", network_dir, controller_mac); + snprintf(file_path, sizeof(file_path), "%s/info", controller_dir); + + if(unlink(file_path) != 0 && errno != ENOENT) { + XLOGD_ERROR("Failed to delete info file <%s> errno %d", file_path, errno); + } else { + XLOGD_INFO("Deleted info file <%s>", file_path); + } + if(rmdir(controller_dir) != 0 && errno != ENOENT) { + XLOGD_WARN("Failed to remove controller dir <%s> errno %d", controller_dir, errno); + } + rmdir(network_dir); +} + +void ctrlm_obj_network_rf4ce_t::info_file_consolidation(void) { + char network_mac[32]; + char network_dir[128]; + rf4ce_ieee_to_str(ieee_address_, network_mac, sizeof(network_mac)); + snprintf(network_dir, sizeof(network_dir), "%s/%s", CTRLM_RF4CE_CONTROLLER_INFO_BASE_DIR, network_mac); + + // Track which bound controllers already have a valid info file + std::set found_on_disk; + + // Iterate over the directories in the network dir + DIR *dir = opendir(network_dir); + if(dir != NULL) { + struct dirent *entry; + while((entry = readdir(dir)) != NULL) { + if(entry->d_name[0] == '.') { + continue; + } + + // Parse the controller MAC string back to a 64-bit value + unsigned int b[8] = {0}; + if(sscanf(entry->d_name, "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", + &b[0], &b[1], &b[2], &b[3], &b[4], &b[5], &b[6], &b[7]) != 8) { + XLOGD_WARN("Unexpected entry in network dir: <%s>, skipping", entry->d_name); + continue; + } + unsigned long long controller_ieee = ((unsigned long long)b[0] << 56) | ((unsigned long long)b[1] << 48) | + ((unsigned long long)b[2] << 40) | ((unsigned long long)b[3] << 32) | + ((unsigned long long)b[4] << 24) | ((unsigned long long)b[5] << 16) | + ((unsigned long long)b[6] << 8) | (unsigned long long)b[7]; + + for(map::iterator it = controllers_.begin(); it != controllers_.end(); it++) { + if(it->second->ieee_address_get().get_value() == controller_ieee) { + // Matching controller exists + found_on_disk.insert(controller_ieee); + break; + } + } + + // Remove info file if no matching bound controller exists + if(found_on_disk.find(controller_ieee) == found_on_disk.end()) { + XLOGD_INFO("Removing stale info file for controller <%s>", entry->d_name); + info_file_delete(controller_ieee); + } + } + closedir(dir); + } + + // Add info files for any bound controllers not found on disk + for(map::iterator it = controllers_.begin(); it != controllers_.end(); it++) { + unsigned long long controller_ieee = it->second->ieee_address_get().get_value(); + if(found_on_disk.find(controller_ieee) == found_on_disk.end()) { + XLOGD_INFO("Adding missing info file for controller 0x%016llX", controller_ieee); + + ctrlm_hal_network_property_encryption_key_t key_prop = {0}; + key_prop.controller_id = it->first; + if(CTRLM_HAL_RESULT_SUCCESS != property_get(CTRLM_HAL_NETWORK_PROPERTY_ENCRYPTION_KEY, (void **)&key_prop)) { + XLOGD_ERROR("Failed to get link key from HAL"); + } + + info_file_write(controller_ieee, key_prop.aes128_key); + } + } +} + void ctrlm_obj_network_rf4ce_t::start_controller_audio_streaming(ctrlm_voice_start_audio_params_t *params) { THREAD_ID_VALIDATE(); params->m_started = false; diff --git a/src/rf4ce/ctrlm_rf4ce_network.h b/src/rf4ce/ctrlm_rf4ce_network.h index 09b67f69..79e3a738 100644 --- a/src/rf4ce/ctrlm_rf4ce_network.h +++ b/src/rf4ce/ctrlm_rf4ce_network.h @@ -21,6 +21,7 @@ #define _CTRLM_RF4CE_NETWORK_H_ #include +#include #include #include #include @@ -660,8 +661,10 @@ class ctrlm_obj_network_rf4ce_t : public ctrlm_obj_network_t static ctrlm_hal_result_t hal_rf4ce_decrypt_callback(ctrlm_hal_rf4ce_decrypt_params_t* param); #endif void controller_init_uinput(ctrlm_controller_id_t controller_id); -}; -void rf4ce_info_file_write(unsigned long long network_ieee, unsigned long long controller_ieee); + void info_file_write(unsigned long long controller_ieee, const unsigned char *key); + void info_file_delete(unsigned long long controller_ieee); + void info_file_consolidation(); +}; #endif diff --git a/src/rf4ce/ctrlm_rf4ce_validation.cpp b/src/rf4ce/ctrlm_rf4ce_validation.cpp index b05b77be..b9b04698 100644 --- a/src/rf4ce/ctrlm_rf4ce_validation.cpp +++ b/src/rf4ce/ctrlm_rf4ce_validation.cpp @@ -117,6 +117,13 @@ void ctrlm_obj_network_rf4ce_t::bind_validation_end(ctrlm_main_queue_msg_bind_va blackout_bind_fail(); XLOGD_INFO("Failed pairing, MAC address: 0x%016llX", controllers_[dqm->controller_id]->ieee_address_get()); } else { + ctrlm_hal_network_property_encryption_key_t key_prop = {0}; + key_prop.controller_id = dqm->controller_id; + if(CTRLM_HAL_RESULT_SUCCESS != property_get(CTRLM_HAL_NETWORK_PROPERTY_ENCRYPTION_KEY, (void **)&key_prop)) { + XLOGD_ERROR("Failed to get link key from HAL"); + } + info_file_write(controllers_[dqm->controller_id]->ieee_address_get().get_value(), key_prop.aes128_key); + if(controller_id_to_remove_ != CTRLM_HAL_CONTROLLER_ID_INVALID) { // no space in the pairing table XLOGD_WARN("Out of space in the pairing table. Will kick out Controller Id <%u>", controller_id_to_remove_); From 84946d671c427ead6a92dd2f7d0e0bbf67cae5f9 Mon Sep 17 00:00:00 2001 From: dwolav200 Date: Mon, 10 Aug 2026 16:15:46 -0400 Subject: [PATCH 3/6] no print pii --- src/rf4ce/ctrlm_rf4ce_network.cpp | 50 +++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/src/rf4ce/ctrlm_rf4ce_network.cpp b/src/rf4ce/ctrlm_rf4ce_network.cpp index ff17d5ab..b012d318 100644 --- a/src/rf4ce/ctrlm_rf4ce_network.cpp +++ b/src/rf4ce/ctrlm_rf4ce_network.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include "ctrlm.h" #include "ctrlm_log.h" @@ -4829,34 +4830,52 @@ void ctrlm_obj_network_rf4ce_t::info_file_write(unsigned long long controller_ie snprintf(controller_dir, sizeof(controller_dir), "%s/%s", network_dir, controller_mac); snprintf(file_path, sizeof(file_path), "%s/info", controller_dir); + XLOGD_INFO("Creating info file <%s>", file_path); + + errno = 0; if(mkdir(CTRLM_RF4CE_CONTROLLER_INFO_LIB_DIR, 0755) != 0 && errno != EEXIST) { - XLOGD_ERROR("Failed to create lib dir <%s> errno %d", CTRLM_RF4CE_CONTROLLER_INFO_LIB_DIR, errno); + int errsv = errno; + XLOGD_ERROR("Failed to create lib dir <%s> error <%s>", CTRLM_RF4CE_CONTROLLER_INFO_LIB_DIR, strerror(errsv)); return; } if(mkdir(CTRLM_RF4CE_CONTROLLER_INFO_BASE_DIR, 0755) != 0 && errno != EEXIST) { - XLOGD_ERROR("Failed to create base dir <%s> errno %d", CTRLM_RF4CE_CONTROLLER_INFO_BASE_DIR, errno); + int errsv = errno; + XLOGD_ERROR("Failed to create base dir <%s> error <%s>", CTRLM_RF4CE_CONTROLLER_INFO_BASE_DIR, strerror(errsv)); return; } if(mkdir(network_dir, 0755) != 0 && errno != EEXIST) { - XLOGD_ERROR("Failed to create network dir <%s> errno %d", network_dir, errno); + int errsv = errno; + XLOGD_ERROR("Failed to create network dir <%s> error <%s>", ctrlm_is_pii_mask_enabled() ? "***" : network_dir, strerror(errsv)); return; } if(mkdir(controller_dir, 0755) != 0 && errno != EEXIST) { - XLOGD_ERROR("Failed to create controller dir <%s> errno %d", controller_dir, errno); + int errsv = errno; + XLOGD_ERROR("Failed to create controller dir <%s> error <%s>", ctrlm_is_pii_mask_enabled() ? "***" : controller_dir, strerror(errsv)); return; } - FILE *f = fopen(file_path, "w"); + + errno = 0; + int fd = open(file_path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); + if(fd < 0) { + int errsv = errno; + XLOGD_ERROR("Failed to create info file <%s> error <%s>", ctrlm_is_pii_mask_enabled() ? "***" : file_path, strerror(errsv)); + return; + } + FILE *f = fdopen(fd, "w"); if(f == NULL) { - XLOGD_ERROR("Failed to create info file <%s> errno %d", file_path, errno); + int errsv = errno; + XLOGD_ERROR("Failed to create info file stream <%s> error <%s>", ctrlm_is_pii_mask_enabled() ? "***" : file_path, strerror(errsv)); + close(fd); return; } + fprintf(f, "[ControllerKey]\nKey="); for(int i = 0; i < CTRLM_HAL_NETWORK_AES128_KEY_SIZE; i++) { fprintf(f, "%02X", key[i]); } fprintf(f, "\n"); fclose(f); - XLOGD_INFO("Created info file <%s>", file_path); + close(fd); } void ctrlm_obj_network_rf4ce_t::info_file_delete(unsigned long long controller_ieee) { @@ -4872,13 +4891,16 @@ void ctrlm_obj_network_rf4ce_t::info_file_delete(unsigned long long controller_i snprintf(controller_dir, sizeof(controller_dir), "%s/%s", network_dir, controller_mac); snprintf(file_path, sizeof(file_path), "%s/info", controller_dir); + XLOGD_INFO("Deleting info file <%s>", file_path); + + errno = 0; if(unlink(file_path) != 0 && errno != ENOENT) { - XLOGD_ERROR("Failed to delete info file <%s> errno %d", file_path, errno); - } else { - XLOGD_INFO("Deleted info file <%s>", file_path); + int errsv = errno; + XLOGD_ERROR("Failed to delete info file <%s> error <%s>", ctrlm_is_pii_mask_enabled() ? "***" : file_path, strerror(errsv)); } if(rmdir(controller_dir) != 0 && errno != ENOENT) { - XLOGD_WARN("Failed to remove controller dir <%s> errno %d", controller_dir, errno); + int errsv = errno; + XLOGD_WARN("Failed to remove controller dir <%s> error <%s>", ctrlm_is_pii_mask_enabled() ? "***" : controller_dir, strerror(errsv)); } rmdir(network_dir); } @@ -4889,6 +4911,8 @@ void ctrlm_obj_network_rf4ce_t::info_file_consolidation(void) { rf4ce_ieee_to_str(ieee_address_, network_mac, sizeof(network_mac)); snprintf(network_dir, sizeof(network_dir), "%s/%s", CTRLM_RF4CE_CONTROLLER_INFO_BASE_DIR, network_mac); + XLOGD_INFO("Consolidating info files"); + // Track which bound controllers already have a valid info file std::set found_on_disk; @@ -4923,7 +4947,7 @@ void ctrlm_obj_network_rf4ce_t::info_file_consolidation(void) { // Remove info file if no matching bound controller exists if(found_on_disk.find(controller_ieee) == found_on_disk.end()) { - XLOGD_INFO("Removing stale info file for controller <%s>", entry->d_name); + XLOGD_INFO("Removing stale info file for controller <%s>", ctrlm_is_pii_mask_enabled() ? "***" : entry->d_name); info_file_delete(controller_ieee); } } @@ -4934,7 +4958,7 @@ void ctrlm_obj_network_rf4ce_t::info_file_consolidation(void) { for(map::iterator it = controllers_.begin(); it != controllers_.end(); it++) { unsigned long long controller_ieee = it->second->ieee_address_get().get_value(); if(found_on_disk.find(controller_ieee) == found_on_disk.end()) { - XLOGD_INFO("Adding missing info file for controller 0x%016llX", controller_ieee); + XLOGD_INFO("Adding missing info file for controller 0x%016llX", ctrlm_is_pii_mask_enabled() ? 0 : controller_ieee); ctrlm_hal_network_property_encryption_key_t key_prop = {0}; key_prop.controller_id = it->first; From 20b5abc63b02fc1844a9c0b14d32031765a517eb Mon Sep 17 00:00:00 2001 From: dwolav200 Date: Mon, 10 Aug 2026 16:27:33 -0400 Subject: [PATCH 4/6] fix copilot concerns --- src/rf4ce/ctrlm_rf4ce_network.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/rf4ce/ctrlm_rf4ce_network.cpp b/src/rf4ce/ctrlm_rf4ce_network.cpp index b012d318..16bec31f 100644 --- a/src/rf4ce/ctrlm_rf4ce_network.cpp +++ b/src/rf4ce/ctrlm_rf4ce_network.cpp @@ -4830,7 +4830,7 @@ void ctrlm_obj_network_rf4ce_t::info_file_write(unsigned long long controller_ie snprintf(controller_dir, sizeof(controller_dir), "%s/%s", network_dir, controller_mac); snprintf(file_path, sizeof(file_path), "%s/info", controller_dir); - XLOGD_INFO("Creating info file <%s>", file_path); + XLOGD_INFO("Creating info file <%s>", ctrlm_is_pii_mask_enabled() ? "***" : file_path); errno = 0; if(mkdir(CTRLM_RF4CE_CONTROLLER_INFO_LIB_DIR, 0755) != 0 && errno != EEXIST) { @@ -4875,7 +4875,6 @@ void ctrlm_obj_network_rf4ce_t::info_file_write(unsigned long long controller_ie } fprintf(f, "\n"); fclose(f); - close(fd); } void ctrlm_obj_network_rf4ce_t::info_file_delete(unsigned long long controller_ieee) { From de6d02e206acdd53f6315fbcf9626e33996b150c Mon Sep 17 00:00:00 2001 From: dwolav200 Date: Mon, 10 Aug 2026 16:39:29 -0400 Subject: [PATCH 5/6] fix copilot concern --- src/rf4ce/ctrlm_rf4ce_network.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rf4ce/ctrlm_rf4ce_network.cpp b/src/rf4ce/ctrlm_rf4ce_network.cpp index 16bec31f..4e7e1c9a 100644 --- a/src/rf4ce/ctrlm_rf4ce_network.cpp +++ b/src/rf4ce/ctrlm_rf4ce_network.cpp @@ -4838,17 +4838,17 @@ void ctrlm_obj_network_rf4ce_t::info_file_write(unsigned long long controller_ie XLOGD_ERROR("Failed to create lib dir <%s> error <%s>", CTRLM_RF4CE_CONTROLLER_INFO_LIB_DIR, strerror(errsv)); return; } - if(mkdir(CTRLM_RF4CE_CONTROLLER_INFO_BASE_DIR, 0755) != 0 && errno != EEXIST) { + if(mkdir(CTRLM_RF4CE_CONTROLLER_INFO_BASE_DIR, 0700) != 0 && errno != EEXIST) { int errsv = errno; XLOGD_ERROR("Failed to create base dir <%s> error <%s>", CTRLM_RF4CE_CONTROLLER_INFO_BASE_DIR, strerror(errsv)); return; } - if(mkdir(network_dir, 0755) != 0 && errno != EEXIST) { + if(mkdir(network_dir, 0700) != 0 && errno != EEXIST) { int errsv = errno; XLOGD_ERROR("Failed to create network dir <%s> error <%s>", ctrlm_is_pii_mask_enabled() ? "***" : network_dir, strerror(errsv)); return; } - if(mkdir(controller_dir, 0755) != 0 && errno != EEXIST) { + if(mkdir(controller_dir, 0700) != 0 && errno != EEXIST) { int errsv = errno; XLOGD_ERROR("Failed to create controller dir <%s> error <%s>", ctrlm_is_pii_mask_enabled() ? "***" : controller_dir, strerror(errsv)); return; From 4ee43304ad24bd50188b29706db8db09c5472d58 Mon Sep 17 00:00:00 2001 From: dwolav200 Date: Mon, 10 Aug 2026 17:01:27 -0400 Subject: [PATCH 6/6] fix pii print --- src/rf4ce/ctrlm_rf4ce_network.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rf4ce/ctrlm_rf4ce_network.cpp b/src/rf4ce/ctrlm_rf4ce_network.cpp index 4e7e1c9a..f77dfb81 100644 --- a/src/rf4ce/ctrlm_rf4ce_network.cpp +++ b/src/rf4ce/ctrlm_rf4ce_network.cpp @@ -4890,7 +4890,7 @@ void ctrlm_obj_network_rf4ce_t::info_file_delete(unsigned long long controller_i snprintf(controller_dir, sizeof(controller_dir), "%s/%s", network_dir, controller_mac); snprintf(file_path, sizeof(file_path), "%s/info", controller_dir); - XLOGD_INFO("Deleting info file <%s>", file_path); + XLOGD_INFO("Deleting info file <%s>", ctrlm_is_pii_mask_enabled() ? "***" : file_path); errno = 0; if(unlink(file_path) != 0 && errno != ENOENT) { @@ -4928,7 +4928,7 @@ void ctrlm_obj_network_rf4ce_t::info_file_consolidation(void) { unsigned int b[8] = {0}; if(sscanf(entry->d_name, "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", &b[0], &b[1], &b[2], &b[3], &b[4], &b[5], &b[6], &b[7]) != 8) { - XLOGD_WARN("Unexpected entry in network dir: <%s>, skipping", entry->d_name); + XLOGD_WARN("Unexpected entry in network dir: <%s>, skipping", ctrlm_is_pii_mask_enabled() ? "***" : entry->d_name); continue; } unsigned long long controller_ieee = ((unsigned long long)b[0] << 56) | ((unsigned long long)b[1] << 48) |