Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions include/ctrlm_ipc_rcu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
15 changes: 0 additions & 15 deletions src/ctrlm_network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
1 change: 0 additions & 1 deletion src/ctrlm_network.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
32 changes: 0 additions & 32 deletions src/ctrlm_rcu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
8 changes: 0 additions & 8 deletions src/ctrlm_rcu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand Down
7 changes: 0 additions & 7 deletions src/ctrlm_rcu_iarm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 }
};

Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/rf4ce/ctrlm_rf4ce_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,7 @@ void ctrlm_obj_controller_rf4ce_t::validation_result_set(ctrlm_rcu_binding_type_
validation_type_ = validation_type;
db_create();
db_store();

// possible duplicate pairing
needs_reset_ = false;
did_reset_ = false;
Expand Down
203 changes: 170 additions & 33 deletions src/rf4ce/ctrlm_rf4ce_network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@
#include <limits.h>
#include <errno.h>
#include <sys/sysinfo.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include "ctrlm.h"
#include "ctrlm_log.h"
#include "ctrlm_utils.h"
Expand All @@ -55,6 +59,15 @@
#include "ctrlm_voice_obj.h"
#include "comcastIrKeyCodes.h"

#define CTRLM_RF4CE_CONTROLLER_INFO_LIB_DIR "/opt/secure/lib"
#define CTRLM_RF4CE_CONTROLLER_INFO_BASE_DIR "/opt/secure/lib/rf4ce"

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)
#error RF4CE AUTOBIND PASS THRESHOLD IS OUT OF RANGE
#endif
Expand Down Expand Up @@ -501,6 +514,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();
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);

Expand Down Expand Up @@ -934,6 +948,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);
}
Expand Down Expand Up @@ -1798,39 +1815,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();
Expand Down Expand Up @@ -4833,6 +4817,159 @@ 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);

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) {
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, 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, 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, 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;
}

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) {
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);
}

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);

XLOGD_INFO("Deleting info file <%s>", file_path);

errno = 0;
if(unlink(file_path) != 0 && errno != ENOENT) {
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) {
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);
}

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);

XLOGD_INFO("Consolidating info files");

// Track which bound controllers already have a valid info file
std::set<unsigned long long> 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<ctrlm_controller_id_t, ctrlm_obj_controller_rf4ce_t *>::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>", ctrlm_is_pii_mask_enabled() ? "***" : entry->d_name);
info_file_delete(controller_ieee);
}
}
closedir(dir);
}

// Add info files for any bound controllers not found on disk
for(map<ctrlm_controller_id_t, ctrlm_obj_controller_rf4ce_t *>::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", ctrlm_is_pii_mask_enabled() ? 0 : 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);
Comment thread
dwolaver marked this conversation as resolved.
}
}
}

void ctrlm_obj_network_rf4ce_t::start_controller_audio_streaming(ctrlm_voice_start_audio_params_t *params) {
THREAD_ID_VALIDATE();
params->m_started = false;
Expand Down
Loading
Loading