diff --git a/CHANGELOG.md b/CHANGELOG.md index b216bc5c..08c6b307 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,15 @@ All notable changes to this project will be documented in this file. * In the future, generate this file by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +## [1.1.3] - 2025-08-19 + +### Changed +- Modify Remote Control plugin for RF4CE support (#80) +- Mac address fetch (#92) + +### Added +- Runtime detection of ASB (#96) + ## [1.1.2] - 2025-08-04 ### Changed diff --git a/CMakeLists.txt b/CMakeLists.txt index f12caebc..90f4cfee 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,7 +37,6 @@ project(ctrlm-main) 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(ASB "Enable ASB" OFF) option(AUTH_ENABLED "Enable AUTH" OFF) option(BLE_ENABLED "Enable BLE" ON) option(BLE_SERVICES "Enable BLE Services" OFF) @@ -196,11 +195,6 @@ if(ANSI_CODES_DISABLED) add_compile_definitions(ANSI_CODES_DISABLED) endif() -if(ASB) - add_compile_definitions(ASB) - target_link_libraries(controlMgr ${ASB_LIBS}) -endif() - if(ASSERT_ON_WRONG_THREAD) add_compile_definitions(ASSERT_ON_WRONG_THREAD) endif() diff --git a/include/ctrlm_ipc.h b/include/ctrlm_ipc.h index 75d4eee2..341d4ff9 100644 --- a/include/ctrlm_ipc.h +++ b/include/ctrlm_ipc.h @@ -133,6 +133,7 @@ #define CTRLM_MAIN_IARM_CALL_GET_RCU_STATUS "Main_GetRcuStatus" ///< IARM Call get the RCU status info (same as what's provided by CTRLM_RCU_IARM_EVENT_RCU_STATUS) #define CTRLM_MAIN_IARM_CALL_START_PAIRING "Main_StartPairing" ///< IARM Call to initiate searching for a remote to pair with #define CTRLM_MAIN_IARM_CALL_START_PAIR_WITH_CODE "Main_StartPairWithCode" ///< IARM Call to initiate searching for a remote to pair with +#define CTRLM_MAIN_IARM_CALL_STOP_PAIRING "Main_StopPairing" ///< IARM Call to cancel an active search for a remote to pair with #define CTRLM_MAIN_IARM_CALL_FIND_MY_REMOTE "Main_FindMyRemote" ///< IARM Call to trigger the Find My Remote alarm on a specified remote #define CTRLM_MAIN_IARM_CALL_WRITE_RCU_WAKEUP_CONFIG "Main_WriteAdvertisingConfig" ///< IARM Call to write the advertising configuration on all connected remotes #define CTRLM_MAIN_IARM_CALL_START_FIRMWARE_UPDATE "Main_StartFirmwareUpdate" ///< IARM Call to start a firmware update session @@ -193,9 +194,7 @@ #define CTRLM_MIN_IR_COMMAND_REPEATS (1) #define CTRLM_MAX_IR_COMMAND_REPEATS (10) -#ifdef ASB #define CTRLM_ASB_ENABLED_DEFAULT (false) -#endif #define CTRLM_OPEN_CHIME_ENABLED_DEFAULT (false) #define CTRLM_CLOSE_CHIME_ENABLED_DEFAULT (true) #define CTRLM_PRIVACY_CHIME_ENABLED_DEFAULT (true) @@ -203,9 +202,7 @@ #define CTRLM_CHIME_VOLUME_DEFAULT (CTRLM_CHIME_VOLUME_MEDIUM) #define CTRLM_IR_COMMAND_REPEATS_DEFAULT (3) -#ifdef ASB #define CTRLM_ASB_ENABLED_LEN (1) -#endif #define CTRLM_OPEN_CHIME_ENABLED_LEN (1) #define CTRLM_CLOSE_CHIME_ENABLED_LEN (1) #define CTRLM_PRIVACY_CHIME_ENABLED_LEN (1) @@ -304,7 +301,8 @@ typedef enum { CTRLM_RCU_IARM_EVENT_RCU_STATUS = 34, ///< Generated when something changes in the BLE remote CTRLM_RCU_IARM_EVENT_RF4CE_PAIRING_WINDOW_TIMEOUT = 35, ///< Indicates that a battery milestone event occured CTRLM_RCU_IARM_EVENT_FIRMWARE_UPDATE_PROGRESS = 36, ///< Generated when an milestone is reached for remote firmware upgrade - CTRLM_MAIN_IARM_EVENT_MAX = 37 ///< Placeholder for the last event (used in registration) + CTRLM_RCU_IARM_EVENT_VALIDATION_STATUS = 37, ///< Generated when the validation status changes + CTRLM_MAIN_IARM_EVENT_MAX = 38 ///< Placeholder for the last event (used in registration) } ctrlm_main_iarm_event_t; /// @brief Remote Control Key Status @@ -699,6 +697,7 @@ typedef struct { ctrlm_network_id_t network_id; ///< Identifier of network or CTRLM_MAIN_NETWORK_ID_ALL for all networks unsigned char pairing_mode; ///< Indicates the pairing mode unsigned char restrict_by_remote; ///< Indicates the remote bucket (no restrictions, only voice remotes, only voice assistants) + unsigned char use_timeout; ///< Indicates whether to use a timeout for the pairing mode (0 - do not use timeout, otherwise use timeout) unsigned int bind_status; ///< OUT - The bind status of the pairing session } ctrlm_main_iarm_call_control_service_pairing_mode_t; diff --git a/src/asb/ctrlm_asb.h b/src/asb/ctrlm_asb.h index d0b9d659..0d0f3f3b 100644 --- a/src/asb/ctrlm_asb.h +++ b/src/asb/ctrlm_asb.h @@ -34,6 +34,10 @@ typedef uint8_t asb_key_derivation_bitmask_t; */ typedef uint8_t asb_key_derivation_method_t; +#ifdef __cplusplus +extern "C" { +#endif + /* -- API Function Declarations -- */ /** * @brief The ASB Library init function. @@ -51,7 +55,7 @@ int asb_init(); * * @return The bitmask of supported key derivation methods. */ -asb_key_derivation_bitmask_t asb_key_derivation_methods_get(); +asb_key_derivation_bitmask_t asb_key_derivation_methods_get(void); /** * @brief The ASB Library API for key derivation. * @@ -66,11 +70,20 @@ int asb_key_derivation(uint8_t *input, uint8_t *output, * This function writes over the secrets with null data and then cleans up resources. * */ -void asb_destroy(); +void asb_destroy(void); + +#ifdef __cplusplus +} +#endif /* -- Defines -- */ #define AES_KEY_LEN (16) ///< AES Key Length #define ASB_KEY_DERIVATION_NONE (0b00000000) ///< Key Derivation Method None bit #define ASB_KEY_DERIVATION_1 (0b10000000) ///< Key Derivation Method 1 bit +typedef int (*ctrlm_hal_rf4ce_asb_init_t)(void); +typedef asb_key_derivation_bitmask_t (*ctrlm_hal_rf4ce_asb_methods_get_t)(void); +typedef int (*ctrlm_hal_rf4ce_asb_key_derive_t)(uint8_t *input, uint8_t *output, asb_key_derivation_method_t method); +typedef void (*ctrlm_hal_rf4ce_asb_destroy_t)(void); + #endif diff --git a/src/ble/ctrlm_ble_network.cpp b/src/ble/ctrlm_ble_network.cpp index 3f089e1f..3de8077f 100644 --- a/src/ble/ctrlm_ble_network.cpp +++ b/src/ble/ctrlm_ble_network.cpp @@ -609,28 +609,32 @@ void ctrlm_obj_network_ble_t::req_process_start_pairing(void *data, int size) { g_assert(dqm); g_assert(size == sizeof(ctrlm_main_queue_msg_start_pairing_t)); - dqm->params->set_result(CTRLM_IARM_CALL_RESULT_ERROR, network_id_get()); - if (!ready_) { XLOGD_FATAL("Network is not ready!"); + dqm->params->set_result(CTRLM_IARM_CALL_RESULT_ERROR, network_id_get()); + } else if(!dqm->params->scan_enable) { + XLOGD_INFO("scan enable is not requested"); + dqm->params->set_result(CTRLM_IARM_CALL_RESULT_SUCCESS, network_id_get()); } else { if (ble_rcu_interface_) { - bool ret = true; if (dqm->params->ieee_address_list.size() == 0) { if(!ble_rcu_interface_->pairAutoWithTimeout(dqm->params->timeout * 1000)) { XLOGD_ERROR("failed to start BLE remote scan"); - ret = false; + dqm->params->set_result(CTRLM_IARM_CALL_RESULT_ERROR, network_id_get()); + } else { + dqm->params->set_result(CTRLM_IARM_CALL_RESULT_SUCCESS, network_id_get()); } } else { XLOGD_INFO("Starting pairing with a list of mac addresses! Pairing with first available..."); if(!ble_rcu_interface_->pairWithMacAddrs(dqm->params->ieee_address_list)) { XLOGD_ERROR("failed to start BLE remote scan"); - ret = false; + dqm->params->set_result(CTRLM_IARM_CALL_RESULT_ERROR, network_id_get()); + } else { + dqm->params->set_result(CTRLM_IARM_CALL_RESULT_SUCCESS, network_id_get()); } } - if (ret) { - dqm->params->set_result(CTRLM_IARM_CALL_RESULT_SUCCESS, network_id_get()); - } + } else { + dqm->params->set_result(CTRLM_IARM_CALL_RESULT_ERROR, network_id_get()); } } if(dqm->semaphore) { @@ -638,6 +642,37 @@ void ctrlm_obj_network_ble_t::req_process_start_pairing(void *data, int size) { } } +void ctrlm_obj_network_ble_t::req_process_stop_pairing(void *data, int size) { + XLOGD_DEBUG("Enter..."); + THREAD_ID_VALIDATE(); + ctrlm_main_queue_msg_stop_pairing_t *dqm = (ctrlm_main_queue_msg_stop_pairing_t *)data; + + g_assert(dqm); + g_assert(size == sizeof(ctrlm_main_queue_msg_stop_pairing_t)); + + if (!ready_) { + XLOGD_FATAL("Network is not ready!"); + dqm->params->set_result(CTRLM_IARM_CALL_RESULT_ERROR, network_id_get()); + } else if(!dqm->params->scan_disable) { + XLOGD_INFO("scan disable is not requested"); + dqm->params->set_result(CTRLM_IARM_CALL_RESULT_SUCCESS, network_id_get()); + } else { + if (ble_rcu_interface_) { + XLOGD_INFO("Cancel pairing operations."); + if(!ble_rcu_interface_->pairCancel()) { + XLOGD_ERROR("failed to cancel BLE remote scan"); + dqm->params->set_result(CTRLM_IARM_CALL_RESULT_ERROR, network_id_get()); + } else { + dqm->params->set_result(CTRLM_IARM_CALL_RESULT_SUCCESS, network_id_get()); + } + } else { + dqm->params->set_result(CTRLM_IARM_CALL_RESULT_ERROR, network_id_get()); + } + } + if(dqm->semaphore) { + sem_post(dqm->semaphore); + } +} void ctrlm_obj_network_ble_t::req_process_pair_with_code(void *data, int size) { XLOGD_DEBUG("Enter..."); diff --git a/src/ble/ctrlm_ble_network.h b/src/ble/ctrlm_ble_network.h index 7d9912b9..cd804015 100644 --- a/src/ble/ctrlm_ble_network.h +++ b/src/ble/ctrlm_ble_network.h @@ -145,6 +145,7 @@ class ctrlm_obj_network_ble_t : public ctrlm_obj_network_t { virtual void req_process_voice_session_end(void *data, int size); virtual void req_process_start_pairing(void *data, int size); + virtual void req_process_stop_pairing(void *data, int size); virtual void req_process_pair_with_code(void *data, int size); virtual void req_process_program_ir_codes(void *data, int size); virtual void req_process_ir_clear_codes(void *data, int size); diff --git a/src/ble/ctrlm_ble_rcu_interface.cpp b/src/ble/ctrlm_ble_rcu_interface.cpp index 363fe26c..6abecad1 100644 --- a/src/ble/ctrlm_ble_rcu_interface.cpp +++ b/src/ble/ctrlm_ble_rcu_interface.cpp @@ -760,6 +760,22 @@ bool ctrlm_ble_rcu_interface_t::pairAutoWithTimeout(int timeoutMs) return true; } +bool ctrlm_ble_rcu_interface_t::pairCancel() +{ + if (!m_controller) { + XLOGD_ERROR("m_controller is NULL!!!"); + return false; + } + + XLOGD_INFO("Canceling BLE pairing operations."); + if (!m_controller->cancelPairing()) { + BleRcuError error = m_controller->lastError(); + XLOGD_ERROR("controller failed to cancel pairing, %s: %s", error.name().c_str(), error.message().c_str()); + return false; + } + return true; +} + bool ctrlm_ble_rcu_interface_t::unpairDevice(uint64_t ieee_address) { BleAddress address(ieee_address); diff --git a/src/ble/ctrlm_ble_rcu_interface.h b/src/ble/ctrlm_ble_rcu_interface.h index d0b79659..a6526e1b 100644 --- a/src/ble/ctrlm_ble_rcu_interface.h +++ b/src/ble/ctrlm_ble_rcu_interface.h @@ -95,6 +95,7 @@ class ctrlm_ble_rcu_interface_t bool pairWithMacHash(unsigned int code); bool pairWithMacAddrs(const std::vector &macAddrList); bool pairAutoWithTimeout(int timeoutMs); + bool pairCancel(); bool unpairDevice(uint64_t ieee_address); bool findMe(uint64_t ieee_address, ctrlm_fmr_alarm_level_t level); diff --git a/src/ctrlm.h b/src/ctrlm.h index 86cf02b3..18d0f99c 100644 --- a/src/ctrlm.h +++ b/src/ctrlm.h @@ -62,6 +62,7 @@ typedef enum { typedef enum { // Network based messages CTRLM_MAIN_QUEUE_MSG_TYPE_BIND_VALIDATION_BEGIN = 0, + CTRLM_MAIN_QUEUE_MSG_TYPE_BIND_VALIDATION_KEY, CTRLM_MAIN_QUEUE_MSG_TYPE_BIND_VALIDATION_END, CTRLM_MAIN_QUEUE_MSG_TYPE_BIND_CONFIGURATION_COMPLETE, CTRLM_MAIN_QUEUE_MSG_TYPE_NETWORK_PROPERTY_SET, @@ -431,6 +432,7 @@ gboolean ctrlm_main_iarm_init(void); void ctrlm_main_iarm_terminate(void); gboolean ctrlm_is_production_build(void); gboolean ctrlm_is_rf4ce_enabled(void); +gboolean ctrlm_is_rf4ce_asb_supported(void); void ctrlm_network_list_get(std::vector *list); gboolean ctrlm_network_id_is_valid(ctrlm_network_id_t network_id); gboolean ctrlm_controller_id_is_valid(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id); @@ -489,6 +491,7 @@ gboolean ctrlm_main_iarm_call_control_service_can_find_my_remote(ctrlm_main_iarm gboolean ctrlm_main_iarm_call_control_service_start_pairing_mode(ctrlm_main_iarm_call_control_service_pairing_mode_t *pairing); void ctrlm_main_iarm_call_control_service_start_pairing_mode_(ctrlm_main_iarm_call_control_service_pairing_mode_t *pairing); gboolean ctrlm_main_iarm_call_control_service_end_pairing_mode(ctrlm_main_iarm_call_control_service_pairing_mode_t *pairing); +void ctrlm_main_iarm_call_control_service_end_pairing_mode_(ctrlm_main_iarm_call_control_service_pairing_mode_t *pairing); gboolean ctrlm_main_iarm_call_chip_status_get(ctrlm_main_iarm_call_chip_status_t *status); ctrlm_power_state_t ctrlm_main_get_system_power_state(void); diff --git a/src/ctrlm_main.cpp b/src/ctrlm_main.cpp index 4eee576b..f0be11e5 100644 --- a/src/ctrlm_main.cpp +++ b/src/ctrlm_main.cpp @@ -57,6 +57,7 @@ #include "ctrlm_powermanager.h" #ifdef CTRLM_THUNDER #include "ctrlm_thunder_plugin_device_info.h" +#include "ctrlm_thunder_plugin_system.h" #include "ctrlm_rcp_ipc_iarm_thunder.h" #endif #ifdef AUTH_ENABLED @@ -214,8 +215,16 @@ typedef struct { gboolean sat_enabled; gboolean production_build; bool rf4ce_enabled; - void * rf4ce_handle; + void * rf4ce_hal_handle; ctrlm_hal_rf4ce_main_t rf4ce_hal_main; + bool rf4ce_asb_supported; + void * rf4ce_asb_handle; + + ctrlm_hal_rf4ce_asb_init_t rf4ce_hal_asb_init; + ctrlm_hal_rf4ce_asb_methods_get_t rf4ce_hal_asb_methods_get; + ctrlm_hal_rf4ce_asb_key_derive_t rf4ce_hal_asb_key_derive; + ctrlm_hal_rf4ce_asb_destroy_t rf4ce_hal_asb_destroy; + guint thread_monitor_timeout_val; guint thread_monitor_timeout_tag; guint thread_monitor_index; @@ -273,6 +282,7 @@ typedef struct { #endif #ifdef CTRLM_THUNDER Thunder::DeviceInfo::ctrlm_thunder_plugin_device_info_t *thunder_device_info; + Thunder::System::ctrlm_thunder_plugin_system_t *thunder_system; #endif ctrlm_powermanager_t *power_manager; ctrlm_power_state_t power_state; @@ -319,9 +329,11 @@ static void ctrlm_device_type_loaded(ctrlm_device_type_t device_type); static void ctrlm_main_has_device_type_set(gboolean has_type); #ifdef CTRLM_THUNDER static void ctrlm_device_info_activated(void *user_data); +static void ctrlm_system_activated(Thunder::plugin_state_t state, void *user_data); #endif -static void * ctrlm_load_hal_rf4ce(void); +static void * ctrlm_load_plugin_rf4ce_hal(void); +static void * ctrlm_load_plugin_rf4ce_asb(void); static 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); static gboolean ctrlm_iarm_init(void); @@ -362,7 +374,6 @@ static void ctrlm_main_update_export_controller_list(void); static void ctrlm_main_iarm_call_ir_remote_usage_get_(ctrlm_main_iarm_call_ir_remote_usage_t *ir_remote_usage); static void ctrlm_main_iarm_call_pairing_metrics_get_(ctrlm_main_iarm_call_pairing_metrics_t *pairing_metrics); static void ctrlm_main_iarm_call_last_key_info_get_(ctrlm_main_iarm_call_last_key_info_t *last_key_info); -static void ctrlm_main_iarm_call_control_service_end_pairing_mode_(ctrlm_main_iarm_call_control_service_pairing_mode_t *pairing); static void ctrlm_stop_one_touch_autobind_(ctrlm_network_id_t network_id); static void ctrlm_close_pairing_window_(ctrlm_network_id_t network_id, ctrlm_close_pairing_window_reason reason); static void ctrlm_pairing_window_bind_status_set_(ctrlm_bind_status_t bind_status); @@ -522,8 +533,19 @@ int main(int argc, char *argv[]) { g_ctrlm.main_thread = NULL; g_ctrlm.queue = NULL; g_ctrlm.production_build = true; - g_ctrlm.rf4ce_handle = ctrlm_load_hal_rf4ce(); - g_ctrlm.rf4ce_enabled = (NULL == g_ctrlm.rf4ce_handle) ? false : true; + g_ctrlm.rf4ce_hal_handle = ctrlm_load_plugin_rf4ce_hal(); + g_ctrlm.rf4ce_enabled = (NULL == g_ctrlm.rf4ce_hal_handle) ? false : true; + if(g_ctrlm.rf4ce_enabled) { // Check for ASB support + g_ctrlm.rf4ce_asb_handle = ctrlm_load_plugin_rf4ce_asb(); + g_ctrlm.rf4ce_asb_supported = (NULL == g_ctrlm.rf4ce_asb_handle) ? false : true; + } else { + g_ctrlm.rf4ce_asb_handle = NULL; + g_ctrlm.rf4ce_asb_supported = false; + g_ctrlm.rf4ce_hal_asb_init = NULL; + g_ctrlm.rf4ce_hal_asb_methods_get = NULL; + g_ctrlm.rf4ce_hal_asb_key_derive = NULL; + g_ctrlm.rf4ce_hal_asb_destroy = NULL; + } g_ctrlm.has_service_access_token = false; g_ctrlm.sat_enabled = true; g_ctrlm.service_access_token_expiration_tag = 0; @@ -871,10 +893,16 @@ int main(int argc, char *argv[]) { ctrlm_powermanager_t::destroy_instance(); ctrlm_irdb_interface_t::destroy_instance(); - if(g_ctrlm.rf4ce_handle != NULL) { + if(g_ctrlm.rf4ce_asb_handle != NULL) { + XLOGD_INFO("unload rf4ce asb hal"); + dlclose(g_ctrlm.rf4ce_asb_handle); + g_ctrlm.rf4ce_asb_handle = NULL; + } + + if(g_ctrlm.rf4ce_hal_handle != NULL) { XLOGD_INFO("unload rf4ce hal"); - dlclose(g_ctrlm.rf4ce_handle); - g_ctrlm.rf4ce_handle = NULL; + dlclose(g_ctrlm.rf4ce_hal_handle); + g_ctrlm.rf4ce_hal_handle = NULL; } XLOGD_INFO("exit program"); @@ -1288,31 +1316,25 @@ gboolean ctrlm_load_version(void) { return(ret_val == 0); } -gboolean ctrlm_load_device_mac(void) { - gboolean ret = false; +#ifdef CTRLM_THUNDER +void ctrlm_system_activated(Thunder::plugin_state_t state, void *user_data) { std::string mac; - std::string file; - std::ifstream ifs; - const char *interface = NULL; - - // First check environment variable to find ESTB interface, or fall back to default - interface = getenv("ESTB_INTERFACE"); - file = "/sys/class/net/" + std::string((interface != NULL ? interface : CTRLM_DEFAULT_DEVICE_MAC_INTERFACE)) + "/address"; - - // Open file and read mac address - ifs.open(file.c_str(), std::ifstream::in); - if(ifs.is_open()) { - ifs >> mac; - std::transform(mac.begin(), mac.end(), mac.begin(), ::toupper); - g_ctrlm.device_mac = mac; - ret = true; - XLOGD_INFO("Device Mac set to <%s>", ctrlm_is_pii_mask_enabled() ? "***" : mac.c_str()); + if (!g_ctrlm.thunder_system->get_device_info_mac(mac)) { + g_ctrlm.device_mac = ""; + XLOGD_ERROR("Failed to get MAC address for device mac"); } else { - XLOGD_ERROR("Failed to get MAC address for device mac"); - g_ctrlm.device_mac = ""; + g_ctrlm.device_mac = mac; + XLOGD_INFO("Device Mac set to <%s>", ctrlm_is_pii_mask_enabled() ? "***" : mac.c_str()); } +} +#endif - return(ret); +gboolean ctrlm_load_device_mac(void) { +#ifdef CTRLM_THUNDER + g_ctrlm.thunder_system = Thunder::System::ctrlm_thunder_plugin_system_t::getInstance(); + g_ctrlm.thunder_system->add_activation_handler((Thunder::Plugin::plugin_activation_handler_t)ctrlm_system_activated); +#endif + return(true); } #ifdef CTRLM_THUNDER @@ -2080,6 +2102,11 @@ gboolean ctrlm_networks_pre_init(json_t *json_obj_net_rf4ce, json_t *json_config ctrlm_obj_network_rf4ce_t *obj_net_rf4ce = new ctrlm_obj_network_rf4ce_t(CTRLM_NETWORK_TYPE_RF4CE, network_id, "RF4CE", g_ctrlm.mask_pii, json_obj_net_rf4ce, g_thread_self()); // Set main function for the RF4CE Network object obj_net_rf4ce->hal_api_main_set(g_ctrlm.rf4ce_hal_main); + + if(ctrlm_is_rf4ce_asb_supported()) { + // Set ASB function for the RF4CE Network object + obj_net_rf4ce->hal_api_asb_set(g_ctrlm.rf4ce_hal_asb_init, g_ctrlm.rf4ce_hal_asb_methods_get, g_ctrlm.rf4ce_hal_asb_key_derive, g_ctrlm.rf4ce_hal_asb_destroy); + } g_ctrlm.networks[network_id] = obj_net_rf4ce; //g_ctrlm.networks[network_id].net.rf4ce = obj_net_rf4ce; g_ctrlm.network_type[network_id] = g_ctrlm.networks[network_id]->type_get(); @@ -2404,7 +2431,16 @@ gpointer ctrlm_main_thread(gpointer param) { ctrlm_validation_begin(hdr->network_id, dqm->controller_id, obj_net->ctrlm_controller_type_get(dqm->controller_id)); obj_net->bind_validation_begin(dqm); - obj_net->iarm_event_rcu_status(); + obj_net->iarm_event_rcu_validation_status(); + break; + } + case CTRLM_MAIN_QUEUE_MSG_TYPE_BIND_VALIDATION_KEY: { + ctrlm_main_queue_msg_bind_validation_key_t *dqm = (ctrlm_main_queue_msg_bind_validation_key_t *)msg; + XLOGD_DEBUG("message type CTRLM_MAIN_QUEUE_MSG_TYPE_BIND_VALIDATION_KEY"); + + ctrlm_validation_key(hdr->network_id, dqm->controller_id, obj_net->ctrlm_controller_type_get(dqm->controller_id), dqm->key_code); + obj_net->bind_validation_key(dqm); + obj_net->iarm_event_rcu_validation_status(); break; } case CTRLM_MAIN_QUEUE_MSG_TYPE_BIND_VALIDATION_END: { @@ -2413,7 +2449,7 @@ gpointer ctrlm_main_thread(gpointer param) { ctrlm_validation_end(hdr->network_id, dqm->controller_id, obj_net->ctrlm_controller_type_get(dqm->controller_id), dqm->binding_type, dqm->validation_type, dqm->result, dqm->semaphore, dqm->cmd_result); obj_net->bind_validation_end(dqm); - obj_net->iarm_event_rcu_status(); + obj_net->iarm_event_rcu_validation_status(); break; } case CTRLM_MAIN_QUEUE_MSG_TYPE_BIND_VALIDATION_FAILED_TIMEOUT: { @@ -2797,14 +2833,14 @@ gpointer ctrlm_main_thread(gpointer param) { XLOGD_DEBUG("message type CTRLM_MAIN_QUEUE_MSG_TYPE_MAIN_CONTROL_SERVICE_SET_VALUES"); if(settings->available & CTRLM_MAIN_CONTROL_SERVICE_SETTINGS_ASB_ENABLED) { -#ifdef ASB - // Write new asb_enabled flag to NVM - ctrlm_db_asb_enabled_write(&settings->asb_enabled, CTRLM_ASB_ENABLED_LEN); - g_ctrlm.cs_values.asb_enable = settings->asb_enabled; - XLOGD_INFO("ASB Enabled Set Values <%s>", g_ctrlm.cs_values.asb_enable ? "true" : "false"); -#else - XLOGD_INFO("ASB Enabled Set Values , ASB Not Supported"); -#endif + if(ctrlm_is_rf4ce_asb_supported()) { + // Write new asb_enabled flag to NVM + ctrlm_db_asb_enabled_write(&settings->asb_enabled, CTRLM_ASB_ENABLED_LEN); + g_ctrlm.cs_values.asb_enable = settings->asb_enabled; + XLOGD_INFO("ASB Enabled Set Values <%s>", g_ctrlm.cs_values.asb_enable ? "true" : "false"); + } else { + XLOGD_INFO("ASB Enabled Set Values , ASB Not Supported"); + } } if(settings->available & CTRLM_MAIN_CONTROL_SERVICE_SETTINGS_OPEN_CHIME_ENABLED) { // Write new open_chime_enabled flag to NVM @@ -2871,12 +2907,13 @@ gpointer ctrlm_main_thread(gpointer param) { ctrlm_main_queue_msg_main_control_service_settings_t *dqm = (ctrlm_main_queue_msg_main_control_service_settings_t *) msg; ctrlm_main_iarm_call_control_service_settings_t *settings = dqm->settings; XLOGD_DEBUG("message type CTRLM_MAIN_QUEUE_MSG_TYPE_MAIN_CONTROL_SERVICE_GET_VALUES"); -#ifdef ASB - settings->asb_supported = true; -#else - settings->asb_supported = false; -#endif - settings->asb_enabled = g_ctrlm.cs_values.asb_enable; + if(ctrlm_is_rf4ce_asb_supported()) { + settings->asb_supported = true; + } else { + settings->asb_supported = false; + } + + settings->asb_enabled = g_ctrlm.cs_values.asb_enable; settings->open_chime_enabled = g_ctrlm.cs_values.chime_open_enable; settings->close_chime_enabled = g_ctrlm.cs_values.chime_close_enable; settings->privacy_chime_enabled = g_ctrlm.cs_values.chime_privacy_enable; @@ -5335,8 +5372,9 @@ void ctrlm_main_iarm_call_control_service_start_pairing_mode_(ctrlm_main_iarm_ca case CTRLM_PAIRING_MODE_SCREEN_BIND: { pairing->result = CTRLM_IARM_CALL_RESULT_SUCCESS; g_ctrlm.binding_screen_active = true; - // Set a timer to limit the binding mode window - g_ctrlm.screen_bind_timeout_tag = ctrlm_timeout_create(g_ctrlm.screen_bind_timeout_val, ctrlm_timeout_screen_bind, NULL); + if(pairing->use_timeout != 0) { // Set a timer to limit the binding mode window + g_ctrlm.screen_bind_timeout_tag = ctrlm_timeout_create(g_ctrlm.screen_bind_timeout_val, ctrlm_timeout_screen_bind, NULL); + } XLOGD_INFO("SCREEN BIND STATE "); break; } @@ -5872,22 +5910,23 @@ void control_service_values_read_from_db() { guchar *data = NULL; guint32 length; -#ifdef ASB - //ASB enabled - gboolean asb_enabled = CTRLM_ASB_ENABLED_DEFAULT; - ctrlm_db_asb_enabled_read(&data, &length); - if(data == NULL) { - XLOGD_WARN("Not read from DB - ASB Enabled. Using default of <%s>.", asb_enabled ? "true" : "false"); - // Write new asb_enabled flag to NVM - ctrlm_db_asb_enabled_write((guchar *)&asb_enabled, CTRLM_ASB_ENABLED_LEN); - } else { - asb_enabled = data[0]; - ctrlm_db_free(data); - data = NULL; - XLOGD_INFO("ASB Enabled read from DB <%s>", asb_enabled ? "YES" : "NO"); + if(ctrlm_is_rf4ce_asb_supported()) { + //ASB enabled + gboolean asb_enabled = CTRLM_ASB_ENABLED_DEFAULT; + ctrlm_db_asb_enabled_read(&data, &length); + if(data == NULL) { + XLOGD_WARN("Not read from DB - ASB Enabled. Using default of <%s>.", asb_enabled ? "true" : "false"); + // Write new asb_enabled flag to NVM + ctrlm_db_asb_enabled_write((guchar *)&asb_enabled, CTRLM_ASB_ENABLED_LEN); + } else { + asb_enabled = data[0]; + ctrlm_db_free(data); + data = NULL; + XLOGD_INFO("ASB Enabled read from DB <%s>", asb_enabled ? "YES" : "NO"); + } + g_ctrlm.cs_values.asb_enable = asb_enabled; } - g_ctrlm.cs_values.asb_enable = asb_enabled; -#endif + // Open Chime Enabled gboolean open_chime_enabled = CTRLM_OPEN_CHIME_ENABLED_DEFAULT; ctrlm_db_open_chime_enabled_read(&data, &length); @@ -6041,14 +6080,21 @@ void ctrlm_trigger_startup_actions(void) { } } -void *ctrlm_load_hal_rf4ce(void) { - void *handle = dlopen("libctrlm_hal_rf4ce.so", RTLD_NOW); +void *ctrlm_load_plugin_rf4ce_hal(void) { + void *handle = NULL; + const char *so_path_vd = "/vendor/lib/libctrlm_hal_rf4ce.so"; + const char *so_path_mw = "/usr/lib/libctrlm_hal_rf4ce.so"; + if(ctrlm_file_exists(so_path_vd)) { + handle = dlopen(so_path_vd, RTLD_NOW); + } else if(ctrlm_file_exists(so_path_mw)) { + handle = dlopen(so_path_mw, RTLD_NOW); + } else { + XLOGD_INFO("RF4CE HAL plugin is not present."); + return(NULL); + } + if(NULL == handle) { - if(ctrlm_file_exists("/usr/lib/libctrlm_hal_rf4ce.so") || ctrlm_file_exists("/vendor/lib/libctrlm_hal_rf4ce.so")) { - XLOGD_ERROR("Failed to load RF4CE HAL plugin <%s>", dlerror()); - } else { - XLOGD_INFO("RF4CE HAL is not present."); - } + XLOGD_ERROR("Failed to load RF4CE HAL plugin <%s>", dlerror()); return(NULL); } @@ -6062,6 +6108,8 @@ void *ctrlm_load_hal_rf4ce(void) { dlclose(handle); return(NULL); } + + XLOGD_INFO("RF4CE HAL plugin is loaded."); return(handle); } @@ -6069,3 +6117,73 @@ void *ctrlm_load_hal_rf4ce(void) { gboolean ctrlm_is_rf4ce_enabled(void) { return(g_ctrlm.rf4ce_enabled); } + +void *ctrlm_load_plugin_rf4ce_asb(void) { + void *handle = NULL; + const char *so_path_vd = "/vendor/lib/libctrlm-rf4ce-asb-plugin.so"; + const char *so_path_mw = "/usr/lib/libctrlm-rf4ce-asb-plugin.so"; + if(ctrlm_file_exists(so_path_vd)) { + handle = dlopen(so_path_vd, RTLD_NOW); + } else if(ctrlm_file_exists(so_path_mw)) { + handle = dlopen(so_path_mw, RTLD_NOW); + } else { + XLOGD_INFO("RF4CE ASB plugin is not present."); + return(NULL); + } + + if(NULL == handle) { + XLOGD_ERROR("Failed to load RF4CE ASB plugin <%s>", dlerror()); + return(NULL); + } + + dlerror(); // Clear any existing error + + ctrlm_hal_rf4ce_asb_init_t asb_init = (ctrlm_hal_rf4ce_asb_init_t)dlsym(handle, "asb_init"); + char *error = dlerror(); + + if(error != NULL) { + XLOGD_ERROR("Failed to find plugin method (asb_init), error <%s>", error); + dlclose(handle); + return(NULL); + } + + ctrlm_hal_rf4ce_asb_methods_get_t asb_methods_get = (ctrlm_hal_rf4ce_asb_methods_get_t)dlsym(handle, "asb_key_derivation_methods_get"); + error = dlerror(); + + if(error != NULL) { + XLOGD_ERROR("Failed to find plugin method (asb_key_derivation_methods_get), error <%s>", error); + dlclose(handle); + return(NULL); + } + + ctrlm_hal_rf4ce_asb_key_derive_t asb_key_derive = (ctrlm_hal_rf4ce_asb_key_derive_t)dlsym(handle, "asb_key_derivation"); + error = dlerror(); + + if(error != NULL) { + XLOGD_ERROR("Failed to find plugin method (asb_key_derivation), error <%s>", error); + dlclose(handle); + return(NULL); + } + + ctrlm_hal_rf4ce_asb_destroy_t asb_destroy = (ctrlm_hal_rf4ce_asb_destroy_t)dlsym(handle, "asb_destroy"); + error = dlerror(); + + if(error != NULL) { + XLOGD_ERROR("Failed to find plugin method (asb_destroy), error <%s>", error); + dlclose(handle); + return(NULL); + } + + g_ctrlm.rf4ce_hal_asb_init = asb_init; + g_ctrlm.rf4ce_hal_asb_methods_get = asb_methods_get; + g_ctrlm.rf4ce_hal_asb_key_derive = asb_key_derive; + g_ctrlm.rf4ce_hal_asb_destroy = asb_destroy; + + XLOGD_INFO("RF4CE ASB plugin is loaded."); + + return(handle); +} + +gboolean ctrlm_is_rf4ce_asb_supported(void) { + return(g_ctrlm.rf4ce_asb_supported); +} diff --git a/src/ctrlm_network.cpp b/src/ctrlm_network.cpp index 955a937a..31d04b7d 100644 --- a/src/ctrlm_network.cpp +++ b/src/ctrlm_network.cpp @@ -206,6 +206,23 @@ string ctrlm_obj_network_t::stb_name_get() const { return(stb_name_); } +void ctrlm_obj_network_t::validation_result_set(ctrlm_rcu_validation_result_t result) { + validation_result_ = result; +} + +void ctrlm_obj_network_t::validation_key_set(ctrlm_key_code_t key) { + validation_key_ = key; +} + +void ctrlm_obj_network_t::validation_status_get(ctrlm_rcu_validation_result_t *result, ctrlm_key_code_t *key) const { + if(result) { + *result = validation_result_; + } + if(key) { + *key = validation_key_; + } +} + bool ctrlm_obj_network_t::is_ready() const { THREAD_ID_VALIDATE(); return(ready_); @@ -646,6 +663,18 @@ void ctrlm_obj_network_t::req_process_start_pairing(void *data, int size){ } } +void ctrlm_obj_network_t::req_process_stop_pairing(void *data, int size){ + XLOGD_WARN("request is not valid for %s network", name_get()); + ctrlm_main_queue_msg_stop_pairing_t *dqm = (ctrlm_main_queue_msg_stop_pairing_t *)data; + g_assert(dqm); + g_assert(size == sizeof(ctrlm_main_queue_msg_stop_pairing_t)); + + // post the semaphore just to ensure nothing blocks + if(dqm->semaphore) { + sem_post(dqm->semaphore); + } +} + void ctrlm_obj_network_t::req_process_pair_with_code(void *data, int size){ XLOGD_WARN("request is not valid for %s network", name_get()); ctrlm_main_queue_msg_pair_with_code_t *dqm = (ctrlm_main_queue_msg_pair_with_code_t *)data; @@ -932,6 +961,10 @@ void ctrlm_obj_network_t::bind_validation_begin(ctrlm_main_queue_msg_bind_valida XLOGD_WARN("not implemented for %s network", name_get()); } +void ctrlm_obj_network_t::bind_validation_key(ctrlm_main_queue_msg_bind_validation_key_t *dqm) { + XLOGD_WARN("not implemented for %s network", name_get()); +} + void ctrlm_obj_network_t::bind_validation_end(ctrlm_main_queue_msg_bind_validation_end_t *dqm) { XLOGD_WARN("not implemented for %s network", name_get()); } @@ -999,6 +1032,21 @@ void ctrlm_obj_network_t::iarm_event_rcu_status(void) { } } +void ctrlm_obj_network_t::iarm_event_rcu_validation_status(void) { + XLOGD_DEBUG("Enter..."); + + ctrlm_rcp_ipc_validation_status_t msg; + msg.populate_status(*this); + + XLOGD_INFO("Broadcasting IARM message %s RCU Validation Status....", name_get()); + XLOGD_DEBUG("%s", msg.to_string()); + + ctrlm_rcp_ipc_iarm_thunder_t *rcp_ipc = ctrlm_rcp_ipc_iarm_thunder_t::get_instance(); + if (!rcp_ipc->on_validation_status(msg)) { + XLOGD_ERROR("Error broadcasting IARM message"); + } +} + void ctrlm_obj_network_t::iarm_event_rcu_firmware_status(const ctrlm_obj_controller_t &rcu) { XLOGD_DEBUG("Enter..."); ctrlm_rcp_ipc_iarm_thunder_t *rcp_ipc = ctrlm_rcp_ipc_iarm_thunder_t::get_instance(); diff --git a/src/ctrlm_network.h b/src/ctrlm_network.h index 3fe15c99..ab22b51b 100644 --- a/src/ctrlm_network.h +++ b/src/ctrlm_network.h @@ -39,9 +39,17 @@ typedef struct : public ctrlm_network_all_ipc_result_wrapper_t { unsigned char api_revision; unsigned int timeout; + bool screen_bind_enable; + bool scan_enable; std::vector ieee_address_list; } ctrlm_iarm_call_StartPairing_params_t; +typedef struct : public ctrlm_network_all_ipc_result_wrapper_t { + unsigned char api_revision; + bool screen_bind_disable; + bool scan_disable; +} ctrlm_iarm_call_StopPairing_params_t; + typedef struct : public ctrlm_network_all_ipc_result_wrapper_t { ctrlm_fmr_alarm_level_t level; unsigned int duration; @@ -93,6 +101,12 @@ typedef struct { sem_t * semaphore; } ctrlm_main_queue_msg_start_pairing_t; +typedef struct { + ctrlm_main_queue_msg_header_t header; + std::shared_ptr params; + sem_t * semaphore; +} ctrlm_main_queue_msg_stop_pairing_t; + typedef struct { ctrlm_main_queue_msg_header_t header; ctrlm_iarm_call_StartPairWithCode_params_t *params; @@ -179,6 +193,9 @@ class ctrlm_obj_network_t gboolean mask_key_codes_get() const; void stb_name_set(const std::string& stb_name); std::string stb_name_get() const; + void validation_result_set(ctrlm_rcu_validation_result_t result); + void validation_key_set(ctrlm_key_code_t key); + void validation_status_get(ctrlm_rcu_validation_result_t *result, ctrlm_key_code_t *key) const; virtual ctrlm_hal_result_t network_init(GThread *ctrlm_main_thread); virtual void network_destroy(); void hal_api_main_set(ctrlm_hal_network_main_t main); @@ -224,6 +241,7 @@ class ctrlm_obj_network_t virtual void recovery_set(ctrlm_recovery_type_t recovery); virtual bool backup_hal_nvm(); virtual void bind_validation_begin(ctrlm_main_queue_msg_bind_validation_begin_t *dqm); + virtual void bind_validation_key(ctrlm_main_queue_msg_bind_validation_key_t *dqm); virtual void bind_validation_end(ctrlm_main_queue_msg_bind_validation_end_t *dqm); virtual bool bind_validation_timeout(ctrlm_controller_id_t controller_id); virtual std::vector get_controller_obj_list() const; @@ -240,6 +258,7 @@ class ctrlm_obj_network_t virtual void req_process_voice_session_end(void *data, int size); virtual void req_process_start_pairing(void *data, int size); + virtual void req_process_stop_pairing(void *data, int size); virtual void req_process_pair_with_code(void *data, int size); virtual void req_process_get_rcu_status(void *data, int size); virtual void req_process_get_last_keypress(void *data, int size); @@ -267,6 +286,7 @@ class ctrlm_obj_network_t time_t stale_remote_time_threshold_get(); virtual void iarm_event_rcu_status(void); + virtual void iarm_event_rcu_validation_status(void); virtual void iarm_event_rcu_firmware_status(const ctrlm_obj_controller_t &rcu); // Internal methods @@ -293,16 +313,19 @@ class ctrlm_obj_network_t 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); private: - gboolean mask_key_codes_ = true; - std::string device_id_; - std::string service_account_id_; - std::string partner_id_; - std::string experience_; - std::string stb_name_; - ctrlm_hal_network_main_t hal_api_main_ = NULL; - ctrlm_hal_req_property_get_t hal_api_property_get_ = NULL; - ctrlm_hal_req_property_set_t hal_api_property_set_ = NULL; - ctrlm_hal_req_term_t hal_api_term_ = NULL; + gboolean mask_key_codes_ = true; + 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; + + ctrlm_hal_network_main_t hal_api_main_ = NULL; + ctrlm_hal_req_property_get_t hal_api_property_get_ = NULL; + ctrlm_hal_req_property_set_t hal_api_property_set_ = NULL; + ctrlm_hal_req_term_t hal_api_term_ = NULL; static gpointer terminate_hal(gpointer data); }; diff --git a/src/ctrlm_rcu.h b/src/ctrlm_rcu.h index 7689584b..80cb0bf0 100644 --- a/src/ctrlm_rcu.h +++ b/src/ctrlm_rcu.h @@ -131,7 +131,6 @@ gboolean ctrlm_rcu_init_iarm(void); void ctrlm_rcu_terminate(void); void ctrlm_rcu_terminate_iarm(void); void ctrlm_rcu_iarm_event_key_press(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_key_status_t key_status, ctrlm_key_code_t key_code); -void ctrlm_rcu_iarm_event_key_press_validation(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_rcu_controller_type_t controller_type, ctrlm_rcu_binding_type_t binding_type, ctrlm_key_status_t key_status, ctrlm_key_code_t key_code); void ctrlm_rcu_iarm_event_function(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_rcu_function_t function, unsigned long value); void ctrlm_rcu_iarm_event_key_ghost(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_remote_keypad_config remote_keypad_config, ctrlm_rcu_ghost_code_t ghost_code); void ctrlm_rcu_iarm_event_control(int controller_id, const char *event_source, const char *event_type, const char *event_data, int event_value, int spare_value); diff --git a/src/ctrlm_rcu_iarm.cpp b/src/ctrlm_rcu_iarm.cpp index ef593545..ca4a0e7c 100644 --- a/src/ctrlm_rcu_iarm.cpp +++ b/src/ctrlm_rcu_iarm.cpp @@ -110,26 +110,6 @@ void ctrlm_rcu_iarm_event_key_press(ctrlm_network_id_t network_id, ctrlm_control } } -void ctrlm_rcu_iarm_event_key_press_validation(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_rcu_controller_type_t controller_type, ctrlm_rcu_binding_type_t binding_type, ctrlm_key_status_t key_status, ctrlm_key_code_t key_code) { - ctrlm_rcu_iarm_event_key_press_t msg; - init_iarm_event_struct(msg, network_id, controller_id); - msg.binding_type = binding_type; - msg.key_status = key_status; - msg.key_code = key_code; - errno_t safec_rc = strncpy_s(msg.controller_type, sizeof(msg.controller_type), ctrlm_rcu_controller_type_str(controller_type), CTRLM_RCU_MAX_USER_STRING_LENGTH - 1); - ERR_CHK(safec_rc); - msg.controller_type[CTRLM_RCU_MAX_USER_STRING_LENGTH - 1] = '\0'; - if(ctrlm_is_pii_mask_enabled()) { - XLOGD_INFO("(%u, %u) Controller Type <%s> key %s *", network_id, controller_id, msg.controller_type, ctrlm_key_status_str(key_status)); - } else { - XLOGD_INFO("(%u, %u) Controller Type <%s> key %s (0x%02X) %s", network_id, controller_id, msg.controller_type, ctrlm_key_status_str(key_status), (guchar)key_code, ctrlm_key_code_str(key_code)); - } - IARM_Result_t result = IARM_Bus_BroadcastEvent(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_RCU_IARM_EVENT_VALIDATION_KEY_PRESS, &msg, sizeof(msg)); - if(IARM_RESULT_SUCCESS != result) { - XLOGD_ERROR("IARM Bus Error!"); - } -} - void ctrlm_rcu_iarm_event_function(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_rcu_function_t function, unsigned long value) { ctrlm_rcu_iarm_event_function_t msg; init_iarm_event_struct(msg, network_id, controller_id); diff --git a/src/ctrlm_utils.cpp b/src/ctrlm_utils.cpp index dabab1f8..cc94fa02 100644 --- a/src/ctrlm_utils.cpp +++ b/src/ctrlm_utils.cpp @@ -1265,6 +1265,27 @@ const char *ctrlm_key_code_str(ctrlm_key_code_t key_code) { return(ctrlm_invalid_return(key_code)); } +static const map ctrlm_key_code_to_linux_key_map { + {CTRLM_KEY_CODE_DIGIT_0, KEY_0}, + {CTRLM_KEY_CODE_DIGIT_1, KEY_1}, + {CTRLM_KEY_CODE_DIGIT_2, KEY_2}, + {CTRLM_KEY_CODE_DIGIT_3, KEY_3}, + {CTRLM_KEY_CODE_DIGIT_4, KEY_4}, + {CTRLM_KEY_CODE_DIGIT_5, KEY_5}, + {CTRLM_KEY_CODE_DIGIT_6, KEY_6}, + {CTRLM_KEY_CODE_DIGIT_7, KEY_7}, + {CTRLM_KEY_CODE_DIGIT_8, KEY_8}, + {CTRLM_KEY_CODE_DIGIT_9, KEY_9} +}; + +uint16_t ctrlm_key_code_to_linux_key(ctrlm_key_code_t code) { + if (ctrlm_key_code_to_linux_key_map.end() != ctrlm_key_code_to_linux_key_map.find(code)) { + return ctrlm_key_code_to_linux_key_map.at(code); + } else { + return KEY_RESERVED; + } +} + // map to convert a key code to its identifiable name on the remote. // map> static const map> ctrlm_linux_key_names { diff --git a/src/ctrlm_utils.h b/src/ctrlm_utils.h index b9870183..5e984a1e 100644 --- a/src/ctrlm_utils.h +++ b/src/ctrlm_utils.h @@ -162,7 +162,7 @@ void ctrlm_print_controller_status(const char *prefix, ctrlm_controller_status_t const char *ctrlm_main_queue_msg_type_str(ctrlm_main_queue_msg_type_t type); const char *ctrlm_controller_status_cmd_result_str(ctrlm_controller_status_cmd_result_t result); - +uint16_t ctrlm_key_code_to_linux_key(ctrlm_key_code_t code); const char *ctrlm_key_status_str(ctrlm_key_status_t key_status); const char *ctrlm_key_code_str(ctrlm_key_code_t key_code); const char *ctrlm_linux_key_code_str(uint16_t code, bool mask); diff --git a/src/ctrlm_validation.cpp b/src/ctrlm_validation.cpp index 2b481240..f7f71e29 100644 --- a/src/ctrlm_validation.cpp +++ b/src/ctrlm_validation.cpp @@ -312,6 +312,9 @@ void ctrlm_validation_begin(ctrlm_network_id_t network_id, ctrlm_controller_id_t } } +void ctrlm_validation_key(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_rcu_controller_type_t controller_type, ctrlm_key_code_t key_code) { +} + gboolean ctrlm_validation_end(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_rcu_controller_type_t controller_type, ctrlm_rcu_binding_type_t binding_type, ctrlm_rcu_validation_type_t validation_type, ctrlm_rcu_validation_result_t validation_result, sem_t *semaphore, ctrlm_validation_end_cmd_result_t *cmd_result) { XLOGD_INFO("(%u, %u) Type <%s> result <%s>", network_id, controller_id, ctrlm_rcu_validation_type_str(validation_type), ctrlm_rcu_validation_result_str(validation_result)); @@ -438,6 +441,23 @@ void ctrlm_inform_validation_begin(ctrlm_network_id_t network_id, ctrlm_controll ctrlm_main_queue_msg_push(msg); } +void ctrlm_inform_validation_key(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_key_code_t key_code) { + // Allocate a message and send it to Control Manager's queue + ctrlm_main_queue_msg_bind_validation_key_t *msg = (ctrlm_main_queue_msg_bind_validation_key_t *)g_malloc(sizeof(ctrlm_main_queue_msg_bind_validation_key_t)); + + if(NULL == msg) { + XLOGD_FATAL("Out of memory"); + g_assert(0); + return; + } + msg->header.type = CTRLM_MAIN_QUEUE_MSG_TYPE_BIND_VALIDATION_KEY; + msg->header.network_id = network_id; + msg->controller_id = controller_id; + msg->key_code = key_code; + + ctrlm_main_queue_msg_push(msg); +} + gboolean ctrlm_inform_validation_end(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_rcu_binding_type_t binding_type, ctrlm_rcu_validation_type_t validation_type, ctrlm_rcu_validation_result_t validation_result, sem_t *semaphore, ctrlm_validation_end_cmd_result_t *cmd_result) { g_ctrlm_validation.golden_index = 0; g_ctrlm_validation.num_wrong_keypresses = 0; @@ -502,7 +522,7 @@ gboolean ctrlm_validation_key_sniff(ctrlm_network_id_t network_id, ctrlm_control ctrlm_validation_timeout_update(g_ctrlm_validation.timeout_subsequent); // Send the validation key as a broadcast event - ctrlm_rcu_iarm_event_key_press_validation(network_id, controller_id, controller_type, CTRLM_RCU_BINDING_TYPE_INTERACTIVE, key_status, key_code); + ctrlm_inform_validation_key(network_id, controller_id, key_code); if(!g_ctrlm_validation.app_based_validation) { if(g_ctrlm_validation.golden_index < 3) {// Check the input diff --git a/src/ctrlm_validation.h b/src/ctrlm_validation.h index 129c5886..e4192b8a 100644 --- a/src/ctrlm_validation.h +++ b/src/ctrlm_validation.h @@ -34,6 +34,12 @@ typedef struct { unsigned long long ieee_address; } ctrlm_main_queue_msg_bind_validation_begin_t; +typedef struct { + ctrlm_main_queue_msg_header_t header; + ctrlm_controller_id_t controller_id; + ctrlm_key_code_t key_code; +} ctrlm_main_queue_msg_bind_validation_key_t; + typedef struct { ctrlm_main_queue_msg_header_t header; ctrlm_controller_id_t controller_id; @@ -69,10 +75,12 @@ void ctrlm_validation_max_attempts_set(guint value); std::vector ctrlm_validation_golden_code_get(void); void ctrlm_inform_validation_begin(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, unsigned long long ieee_address); +void ctrlm_inform_validation_key(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_key_code_t key_code); gboolean ctrlm_inform_validation_end(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_rcu_binding_type_t binding_type, ctrlm_rcu_validation_type_t validation_type, ctrlm_rcu_validation_result_t validation_result, sem_t *semaphore, ctrlm_validation_end_cmd_result_t *cmd_result); gboolean ctrlm_inform_configuration_complete(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_rcu_configuration_result_t configuration_result); void ctrlm_validation_begin(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_rcu_controller_type_t controller_type); +void ctrlm_validation_key(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_rcu_controller_type_t controller_type, ctrlm_key_code_t key_code); gboolean ctrlm_validation_end(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_rcu_controller_type_t controller_type, ctrlm_rcu_binding_type_t binding_type, ctrlm_rcu_validation_type_t validation_type, ctrlm_rcu_validation_result_t validation_result, sem_t *semaphore, ctrlm_validation_end_cmd_result_t *cmd_result); gboolean ctrlm_configuration_complete(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_rcu_controller_type_t controller_type, ctrlm_rcu_binding_type_t binding_type, ctrlm_controller_status_t *status, ctrlm_rcu_configuration_result_t configuration_result); gboolean ctrlm_validation_key_sniff(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_rcu_controller_type_t controller_type, ctrlm_key_status_t key_status, ctrlm_key_code_t key_code, gboolean auto_bind_in_progress); diff --git a/src/database/ctrlm_database.cpp b/src/database/ctrlm_database.cpp index e399a3c3..c334cc7a 100644 --- a/src/database/ctrlm_database.cpp +++ b/src/database/ctrlm_database.cpp @@ -62,9 +62,7 @@ using namespace std; #define CTRLM_DB_PAIRING_METRICS "pairing_metrics" #define CTRLM_DB_LAST_KEY_INFO "last_key_info" #define CTRLM_DB_SHUTDOWN_TIME "shutdown_time" -#ifdef ASB #define CTRLM_DB_ASB_ENABLED "asb_enabled" -#endif #define CTRLM_DB_OPEN_CHIME_ENABLED "open_chime_enabled" #define CTRLM_DB_CLOSE_CHIME_ENABLED "close_chime_enabled" #define CTRLM_DB_PRIVACY_CHIME_ENABLED "privacy_chime_enabled" @@ -663,7 +661,6 @@ void ctrlm_db_shutdown_time_read(guchar **data, guint32 *length) { ctrlm_db_read_blob(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_SHUTDOWN_TIME, data, length); } -#ifdef ASB void ctrlm_db_asb_enabled_write(guchar *data, guint32 length) { ctrlm_db_write_blob(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_ASB_ENABLED, data, length); } @@ -671,7 +668,6 @@ void ctrlm_db_asb_enabled_write(guchar *data, guint32 length) { void ctrlm_db_asb_enabled_read(guchar **data, guint32 *length) { ctrlm_db_read_blob(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_ASB_ENABLED, data, length); } -#endif void ctrlm_db_open_chime_enabled_write(guchar *data, guint32 length) { ctrlm_db_write_blob(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_OPEN_CHIME_ENABLED, data, length); @@ -1930,7 +1926,6 @@ void ctrlm_db_rf4ce_write_binding_security_type(ctrlm_network_id_t network_id, c ctrlm_db_write_uint64(table, "binding_security_type", type); } -#ifdef ASB void ctrlm_db_rf4ce_read_asb_key_derivation_method(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, unsigned char *method) { char table[CONTROLLER_TABLE_NAME_MAX_LEN]; ctrlm_db_rf4ce_controller_entry_table_name(network_id, controller_id, table); @@ -1945,7 +1940,6 @@ void ctrlm_db_rf4ce_write_asb_key_derivation_method(ctrlm_network_id_t network_i ctrlm_db_write_uint64(table, "asb_key_derivation_method", method); } -#endif void ctrlm_db_rf4ce_read_privacy(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, guchar **data, guint32 *length) { char table[CONTROLLER_TABLE_NAME_MAX_LEN]; diff --git a/src/database/ctrlm_database.h b/src/database/ctrlm_database.h index 799acff4..4716b075 100644 --- a/src/database/ctrlm_database.h +++ b/src/database/ctrlm_database.h @@ -63,10 +63,8 @@ void ctrlm_db_last_key_info_write(guchar *data, guint32 length); void ctrlm_db_last_key_info_read(guchar **data, guint32 *length); void ctrlm_db_shutdown_time_write(guchar *data, guint32 length); void ctrlm_db_shutdown_time_read(guchar **data, guint32 *length); -#ifdef ASB void ctrlm_db_asb_enabled_write(guchar *data, guint32 length); void ctrlm_db_asb_enabled_read(guchar **data, guint32 *length); -#endif void ctrlm_db_open_chime_enabled_write(guchar *data, guint32 length); void ctrlm_db_open_chime_enabled_read(guchar **data, guint32 *length); void ctrlm_db_close_chime_enabled_write(guchar *data, guint32 length); @@ -113,9 +111,7 @@ void ctrlm_db_rf4ce_read_controller_capabilities(ctrlm_network_id_t network_id, void ctrlm_db_rf4ce_read_far_field_metrics(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, guchar **data, guint32 *length); void ctrlm_db_rf4ce_read_dsp_metrics(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, guchar **data, guint32 *length); void ctrlm_db_rf4ce_read_time_metrics(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, time_t *time_metrics); -#ifdef ASB void ctrlm_db_rf4ce_read_asb_key_derivation_method(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, unsigned char *method); -#endif void ctrlm_db_rf4ce_read_device_update_session_state(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, guchar **data, guint32 *length); void ctrlm_db_rf4ce_read_ota_failures_type_z_count(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, guchar **data, guint32 *length); @@ -140,9 +136,7 @@ void ctrlm_db_rf4ce_write_dsp_metrics(ctrlm_network_id_t network_id, ctrlm_contr void ctrlm_db_rf4ce_write_time_metrics(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, time_t time_metrics); void ctrlm_db_rf4ce_read_uptime_privacy_info(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, guchar **data, guint32 *length); void ctrlm_db_rf4ce_write_uptime_privacy_info(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, guchar *data, guint32 length); -#ifdef ASB void ctrlm_db_rf4ce_write_asb_key_derivation_method(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, unsigned char method); -#endif void ctrlm_db_rf4ce_write_device_update_session_state(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, guchar *data, guint32 length); void ctrlm_db_rf4ce_write_file(const char *path, guchar *data, guint32 length); void ctrlm_db_rf4ce_read_mfg_test_result(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, guchar **data, guint32 *length); diff --git a/src/ipc/ctrlm_rcp_ipc_event.cpp b/src/ipc/ctrlm_rcp_ipc_event.cpp index 82f67a35..0ce44bae 100644 --- a/src/ipc/ctrlm_rcp_ipc_event.cpp +++ b/src/ipc/ctrlm_rcp_ipc_event.cpp @@ -98,7 +98,6 @@ json_t *ctrlm_rcp_ipc_net_status_t::to_json() const json_t *status = json_object(); json_t *net_type_supported = json_array(); json_t *remote_data_array = json_array(); - json_t *manual_pair_code = json_array(); int err = 0; for (auto const &it : ctrlm_network_types_get()) { @@ -115,14 +114,6 @@ json_t *ctrlm_rcp_ipc_net_status_t::to_json() const err |= json_object_set_new_nocheck(status, PAIRING_STATE, json_string(ctrlm_rf_pair_state_str(pair_state_))); err |= json_object_set_new_nocheck(status, IR_PROG_STATE, json_string(ctrlm_ir_state_str(irdb_state_))); - std::vector golden_code = ctrlm_validation_golden_code_get(); - if (!golden_code.empty()) { - for (auto digit : golden_code) { - err |= json_array_append_new(manual_pair_code, json_integer(atoi(ctrlm_key_code_str(digit)))); - } - err |= json_object_set_new_nocheck(status, MANUAL_PAIR_CODE, manual_pair_code); - } - return (err) ? NULL : status; } @@ -183,3 +174,50 @@ 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() +{ +} + +void ctrlm_rcp_ipc_validation_status_t::populate_status(const ctrlm_obj_network_t &network) +{ + ctrlm_rcu_validation_result_t status = CTRLM_RCU_VALIDATION_RESULT_MAX; + ctrlm_key_code_t key = CTRLM_KEY_CODE_INVALID; + + network.validation_status_get(&status, &key); + + set_status(status); + set_key(key); +} + +json_t *ctrlm_rcp_ipc_validation_status_t::to_json() const +{ + json_t *status = json_object(); + int err = 0; + + err |= json_object_set_new_nocheck(status, VALIDATION_STATUS, json_string(ctrlm_rcu_validation_result_str(validation_status_))); + + if(validation_status_ == CTRLM_RCU_VALIDATION_RESULT_PENDING) { + if(validation_key_ == CTRLM_KEY_CODE_INVALID) { + std::vector golden_code = ctrlm_validation_golden_code_get(); + if (!golden_code.empty()) { + json_t *code = json_array(); + for (auto digit : golden_code) { + // convert from CTRLM_KEY_CODE_DIGIT_0 - 9 to KEY_0 - 9 + err |= json_array_append_new(code, json_integer(ctrlm_key_code_to_linux_key(digit))); + } + err |= json_object_set_new_nocheck(status, VALIDATION_CODE, code); + } + } else { + // convert from CTRLM_KEY_CODE_DIGIT_0 - 9 to KEY_0 - 9 + err |= json_object_set_new_nocheck(status, VALIDATION_KEY, json_integer(ctrlm_key_code_to_linux_key(validation_key_))); + } + } + + 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 332242a6..ae257af6 100644 --- a/src/ipc/ctrlm_rcp_ipc_event.h +++ b/src/ipc/ctrlm_rcp_ipc_event.h @@ -33,7 +33,9 @@ namespace rcp_net_status_json_keys constexpr char const* NET_TYPES_SUPPORTED = "netTypesSupported"; constexpr char const* PAIRING_STATE = "pairingState"; constexpr char const* IR_PROG_STATE = "irProgState"; - constexpr char const* MANUAL_PAIR_CODE = "manualPairCode"; + constexpr char const* VALIDATION_STATUS = "status"; + constexpr char const* VALIDATION_CODE = "code"; + constexpr char const* VALIDATION_KEY = "key"; constexpr char const* REMOTE_DATA = "remoteData"; constexpr char const* MAC_ADDRESS = "macAddress"; @@ -154,6 +156,28 @@ class ctrlm_rcp_ipc_upgrade_status_t : public ctrlm_virtual_json_t ctrlm_iarm_call_result_t result_ = CTRLM_IARM_CALL_RESULT_INVALID; }; +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; } + void set_status(ctrlm_rcu_validation_result_t status) { validation_status_ = status; } + void set_key(ctrlm_key_code_t key) { (key >= CTRLM_KEY_CODE_DIGIT_0 && key <= CTRLM_KEY_CODE_DIGIT_9) ? validation_key_ = key : validation_key_ = CTRLM_KEY_CODE_INVALID; } + void populate_status(const ctrlm_obj_network_t &network); + +private: + uint8_t api_revision_ = CTRLM_MAIN_IARM_BUS_API_REVISION; + ctrlm_rcu_validation_result_t validation_status_ = CTRLM_RCU_VALIDATION_RESULT_MAX; + ctrlm_key_code_t validation_key_ = CTRLM_KEY_CODE_INVALID; + ctrlm_iarm_call_result_t result_ = CTRLM_IARM_CALL_RESULT_INVALID; +}; + class ctrlm_network_all_ipc_result_wrapper_t { private: ctrlm_network_id_t network_id_; diff --git a/src/ipc/ctrlm_rcp_ipc_iarm_thunder.cpp b/src/ipc/ctrlm_rcp_ipc_iarm_thunder.cpp index c526bd00..02f4128d 100644 --- a/src/ipc/ctrlm_rcp_ipc_iarm_thunder.cpp +++ b/src/ipc/ctrlm_rcp_ipc_iarm_thunder.cpp @@ -76,6 +76,7 @@ bool ctrlm_rcp_ipc_iarm_thunder_t::register_ipc() const } if(!register_iarm_call(CTRLM_MAIN_IARM_CALL_START_PAIRING, start_pairing)) { ret = false; } + if(!register_iarm_call(CTRLM_MAIN_IARM_CALL_STOP_PAIRING, stop_pairing)) { ret = false; } if(!register_iarm_call(CTRLM_MAIN_IARM_CALL_GET_RCU_STATUS, get_net_status)) { ret = false; } if(!register_iarm_call(CTRLM_MAIN_IARM_CALL_LAST_KEYPRESS_GET, get_last_keypress)) { ret = false; } if(!register_iarm_call(CTRLM_MAIN_IARM_CALL_FIND_MY_REMOTE, find_my_remote)) { ret = false; } @@ -127,6 +128,32 @@ bool ctrlm_rcp_ipc_iarm_thunder_t::on_status(const ctrlm_rcp_ipc_net_status_t &n 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 +{ + if (!is_running(atomic_running_)) { + XLOGD_ERROR("IARM Call received when IARM component in stopped/terminated state"); + return(false); + } + + if (validation_status.get_api_revision() != CTRLM_MAIN_IARM_BUS_API_REVISION) { + XLOGD_ERROR("Wrong ctrlm API revision - should be %d, event is %d", CTRLM_MAIN_IARM_BUS_API_REVISION, validation_status.get_api_revision()); + return(false); + } + + 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 { if (!is_running(atomic_running_)) { @@ -153,6 +180,27 @@ bool ctrlm_rcp_ipc_iarm_thunder_t::on_firmware_update_progress(const ctrlm_rcp_i 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 +{ + if (!is_running(atomic_running_)) { + XLOGD_ERROR("IARM Call received when IARM component in stopped/terminated state"); + return(false); + } + + 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); +} + IARM_Result_t ctrlm_rcp_ipc_iarm_thunder_t::start_pairing(void *arg) { XLOGD_INFO(""); @@ -177,16 +225,21 @@ IARM_Result_t ctrlm_rcp_ipc_iarm_thunder_t::start_pairing(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); - } - int timeout = 0; if (!config.config_value_get(TIMEOUT, timeout)) { XLOGD_INFO("Missing %s parameter - defaulting to no timeout (0s)", TIMEOUT); } + bool screenBindEnable = true; + if (!config.config_value_get(SCREEN_BIND_ENABLE, screenBindEnable)) { + XLOGD_INFO("Missing %s parameter - defaulting to %s", SCREEN_BIND_ENABLE, screenBindEnable ? "true" : "false"); + } + + bool scanEnable = true; + if (!config.config_value_get(SCAN_ENABLE, scanEnable)) { + XLOGD_INFO("Missing %s parameter - defaulting to %s", SCAN_ENABLE, scanEnable ? "true" : "false"); + } + json_t *mac_addr_array = nullptr; std::vector mac_addr_list; if (config.config_array_get(MAC_ADDRESS_LIST, &mac_addr_array)) { @@ -208,20 +261,102 @@ IARM_Result_t ctrlm_rcp_ipc_iarm_thunder_t::start_pairing(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->timeout = timeout; - params->ieee_address_list = mac_addr_list; + if(!scanEnable && mac_addr_list.size() > 0) { + XLOGD_WARN("scanEnable is false but macAddressList is not empty. Ignoring macAddressList."); + mac_addr_list.clear(); + } - sync_send_netw_handler_to_main_queue_new - (params, - (ctrlm_msg_handler_network_t)&ctrlm_obj_network_t::req_process_start_pairing); + bool result = true; + if(!screenBindEnable && !scanEnable) { + XLOGD_WARN("screen bind and scan enable are both false. Nothing to do."); + } else { + std::shared_ptr params = std::make_shared(); + params->set_net_id(CTRLM_MAIN_NETWORK_ID_ALL); + params->timeout = timeout; + params->screen_bind_enable = screenBindEnable; + params->scan_enable = scanEnable; + params->ieee_address_list = mac_addr_list; + + sync_send_netw_handler_to_main_queue_new + (params, + (ctrlm_msg_handler_network_t)&ctrlm_obj_network_t::req_process_start_pairing); + result = params->get_result(); + } json_t *ret = json_object(); int err = 0; - err |= json_object_set_new_nocheck(ret, SUCCESS, json_boolean(params->get_result())); + err |= json_object_set_new_nocheck(ret, SUCCESS, json_boolean(result)); + + if (err) { + XLOGD_ERROR("JSON object set error"); + json_decref(ret); + return(IARM_RESULT_INVALID_STATE); + } + + if (!ctrlm_json_to_iarm_call_data_result(ret, call_data)) { + json_decref(ret); + return(IARM_RESULT_INVALID_STATE); + } + + return(IARM_RESULT_SUCCESS); +} + +IARM_Result_t ctrlm_rcp_ipc_iarm_thunder_t::stop_pairing(void *arg) +{ + XLOGD_INFO(""); + + if (!is_running(atomic_running_)) { + XLOGD_ERROR("IARM Call received when IARM component in stopped/terminated state"); + return(IARM_RESULT_INVALID_STATE); + } + + ctrlm_main_iarm_call_json_t *call_data = static_cast(arg); + + if (!call_data || call_data->api_revision != CTRLM_MAIN_IARM_BUS_API_REVISION) { + XLOGD_ERROR("NULL parameter"); + return(IARM_RESULT_INVALID_PARAM); + } + + json_t *payload = json_loads(call_data->payload, JSON_DECODE_ANY, NULL); + json_config config(payload); + + if (!payload || !config.current_object_get()) { + XLOGD_ERROR("Bad payload from call data"); + return(IARM_RESULT_INVALID_PARAM); + } + + bool screenBindDisable = true; + if (!config.config_value_get(SCREEN_BIND_DISABLE, screenBindDisable)) { + XLOGD_INFO("Missing %s parameter - defaulting to %s", SCREEN_BIND_DISABLE, screenBindDisable ? "true" : "false"); + } + + bool scanDisable = true; + if (!config.config_value_get(SCAN_DISABLE, scanDisable)) { + XLOGD_INFO("Missing %s parameter - defaulting to %s", SCAN_DISABLE, scanDisable ? "true" : "false"); + } + + bool result = true; + if(!screenBindDisable && !scanDisable) { + XLOGD_WARN("screen bind and scan disable are both false. Nothing to do."); + } else { + std::shared_ptr params = std::make_shared(); + params->set_net_id(CTRLM_MAIN_NETWORK_ID_ALL); + params->screen_bind_disable = screenBindDisable; + params->scan_disable = scanDisable; + + sync_send_netw_handler_to_main_queue_new + (params, + (ctrlm_msg_handler_network_t)&ctrlm_obj_network_t::req_process_stop_pairing); + result = params->get_result(); + } + + json_t *ret = json_object(); + int err = 0; + + err |= json_object_set_new_nocheck(ret, SUCCESS, json_boolean(result)); if (err) { XLOGD_ERROR("JSON object set error"); diff --git a/src/ipc/ctrlm_rcp_ipc_iarm_thunder.h b/src/ipc/ctrlm_rcp_ipc_iarm_thunder.h index f6ecd617..384df5ae 100644 --- a/src/ipc/ctrlm_rcp_ipc_iarm_thunder.h +++ b/src/ipc/ctrlm_rcp_ipc_iarm_thunder.h @@ -46,6 +46,10 @@ namespace rcp_json_keys constexpr char const* SESSION_ID = "sessionId"; constexpr char const* SESSION_ID_LIST = "sessionIdList"; constexpr char const* MAC_ADDRESS_LIST = "macAddressList"; + constexpr char const* SCREEN_BIND_ENABLE = "screenBindEnable"; + constexpr char const* SCREEN_BIND_DISABLE = "screenBindDisable"; + constexpr char const* SCAN_ENABLE = "scanEnable"; + constexpr char const* SCAN_DISABLE = "scanDisable"; constexpr char const* SUCCESS = "success"; } @@ -73,10 +77,13 @@ class ctrlm_rcp_ipc_iarm_thunder_t : public ctrlm_ipc_iarm_t bool is_thunder_device_update_enabled() const; bool on_status(const ctrlm_rcp_ipc_net_status_t &net_status) const; + bool on_validation_status(const ctrlm_rcp_ipc_validation_status_t &validation_status) const; bool on_firmware_update_progress(const ctrlm_rcp_ipc_upgrade_status_t &upgrade_status) const; + bool on_validation(const ctrlm_rcp_ipc_validation_status_t &validation_status) const; protected: static IARM_Result_t start_pairing(void *arg); + static IARM_Result_t stop_pairing(void *arg); static IARM_Result_t get_net_status(void *arg); static IARM_Result_t get_last_keypress(void *arg); static IARM_Result_t find_my_remote(void *arg); diff --git a/src/rf4ce/ctrlm_rf4ce_controller.cpp b/src/rf4ce/ctrlm_rf4ce_controller.cpp index bd0b5539..c2babdb8 100644 --- a/src/rf4ce/ctrlm_rf4ce_controller.cpp +++ b/src/rf4ce/ctrlm_rf4ce_controller.cpp @@ -35,9 +35,7 @@ #include "ctrlm_device_update.h" #include "ctrlm_database.h" #include "ctrlm_validation.h" -#ifdef ASB #include "ctrlm_asb.h" -#endif using namespace std; @@ -135,9 +133,7 @@ ctrlm_obj_controller_rf4ce_t::ctrlm_obj_controller_rf4ce_t(ctrlm_controller_id_t polling_methods_(0), time_last_heartbeat_(0), rib_configuration_complete_status_(RF4CE_RIB_CONFIGURATION_COMPLETE_PAIRING_INCOMPLETE), -#ifdef ASB asb_key_derivation_method_used_(ASB_KEY_DERIVATION_NONE), -#endif metrics_tag_ (0), #ifdef XR15_704 needs_reset_(false), @@ -712,9 +708,9 @@ void ctrlm_obj_controller_rf4ce_t::db_load() { ctrlm_db_rf4ce_read_binding_type(network_id, controller_id, &binding_type_); ctrlm_db_rf4ce_read_validation_type(network_id, controller_id, &validation_type_); ctrlm_db_rf4ce_read_binding_security_type(network_id, controller_id, &binding_security_type_); -#ifdef ASB - ctrlm_db_rf4ce_read_asb_key_derivation_method(network_id, controller_id, &asb_key_derivation_method_used_); -#endif + if(ctrlm_is_rf4ce_asb_supported()) { + ctrlm_db_rf4ce_read_asb_key_derivation_method(network_id, controller_id, &asb_key_derivation_method_used_); + } ctrlm_db_rf4ce_read_peripheral_id(network_id, controller_id, &data, &length); if(data == NULL) { @@ -894,9 +890,9 @@ void ctrlm_obj_controller_rf4ce_t::db_store() { ctrlm_db_rf4ce_write_binding_type(network_id, controller_id, binding_type_); ctrlm_db_rf4ce_write_validation_type(network_id, controller_id, validation_type_); ctrlm_db_rf4ce_write_binding_security_type(network_id, controller_id, binding_security_type_); -#ifdef ASB - ctrlm_db_rf4ce_write_asb_key_derivation_method(network_id, controller_id, asb_key_derivation_method_used_); -#endif + if(ctrlm_is_rf4ce_asb_supported()) { + ctrlm_db_rf4ce_write_asb_key_derivation_method(network_id, controller_id, asb_key_derivation_method_used_); + } if(CTRLM_RF4CE_RIB_ATTR_LEN_PERIPHERAL_ID == property_read_peripheral_id(data, CTRLM_RF4CE_RIB_ATTR_LEN_PERIPHERAL_ID)) { ctrlm_db_rf4ce_write_peripheral_id(network_id, controller_id, data, CTRLM_RF4CE_RIB_ATTR_LEN_PERIPHERAL_ID); @@ -2918,9 +2914,7 @@ void ctrlm_obj_controller_rf4ce_t::rf4ce_heartbeat(ctrlm_timestamp_t timestamp, guint8 response_len = sizeof(response); errno_t safec_rc = -1; -#ifdef ASB bool link_key_validation = false; -#endif if(CTRLM_RF4CE_RESULT_VALIDATION_SUCCESS == validation_result_) { // Set last heartbeat time @@ -2950,18 +2944,14 @@ void ctrlm_obj_controller_rf4ce_t::rf4ce_heartbeat(ctrlm_timestamp_t timestamp, } else { XLOGD_INFO("Controller %u Heartbeat Response: Action <%s> Poll Again <%s>", controller_id_get(), ctrlm_rf4ce_polling_action_str(action), (flags & HEARTBEAT_RESPONSE_FLAG_POLL_AGAIN ? "YES" : "NO")); } - } -#ifdef ASB - else if(POLLING_TRIGGER_FLAG_STATUS == trigger && CTRLM_RF4CE_RESULT_VALIDATION_PENDING == validation_result_) { + } else if(ctrlm_is_rf4ce_asb_supported() && POLLING_TRIGGER_FLAG_STATUS == trigger && CTRLM_RF4CE_RESULT_VALIDATION_PENDING == validation_result_) { XLOGD_INFO("Controller %u Heartbeat for Link Key Validation, respond with NO ACTION", controller_id_get()); // Cancel timeout ctrlm_timeout_destroy(&asb_tag_); asb_tag_ = 0; link_key_validation = true; response_len = 3; // Backwards compatiability for XR15v2 - } -#endif - else { + } else { XLOGD_INFO("Heartbeat from controller that is not bound.. Ignore..."); return; } @@ -2989,16 +2979,17 @@ void ctrlm_obj_controller_rf4ce_t::rf4ce_heartbeat(ctrlm_timestamp_t timestamp, // Send the response back to the controller req_data(CTRLM_RF4CE_PROFILE_ID_COMCAST_RCU, timestamp, response_len, response, NULL, NULL); -#ifdef ASB + if(link_key_validation) { obj_network_rf4ce_->process_pair_result(controller_id_get(), ieee_address_->get_value(), CTRLM_HAL_RESULT_PAIR_SUCCESS); } -#endif + if(NULL != action_msg) { free(action_msg); action_msg = NULL; } } + void ctrlm_obj_controller_rf4ce_t::rib_configuration_complete(ctrlm_timestamp_t timestamp, ctrlm_rf4ce_rib_configuration_complete_status_t status) { XLOGD_INFO("Controller %u Configuration Complete: Status <%u>", controller_id_get(), status); switch(status) { @@ -3061,7 +3052,6 @@ ctrlm_rcu_binding_security_type_t ctrlm_obj_controller_rf4ce_t::binding_security return(binding_security_type_); } -#ifdef ASB typedef struct { ctrlm_network_id_t network_id; ctrlm_controller_id_t controller_id; @@ -3125,9 +3115,9 @@ void ctrlm_obj_controller_rf4ce_t::asb_key_derivation_perform() { } // Perform link key derivation - if(asb_key_derivation(property.aes128_key, new_aes128_key, asb_key_derivation_method_used_)) { + if(obj_network_rf4ce_->hal_asb_key_derive(property.aes128_key, new_aes128_key, asb_key_derivation_method_used_)) { XLOGD_ERROR("Failed to perform key derivation"); - asb_destroy(); + obj_network_rf4ce_->hal_asb_destroy(); return; } // Set New Link key @@ -3148,7 +3138,6 @@ void ctrlm_obj_controller_rf4ce_t::asb_key_derivation_perform() { // Destroy ASB ctrlm_main_queue_handler_push(CTRLM_HANDLER_NETWORK, (ctrlm_msg_handler_network_t)&ctrlm_obj_network_rf4ce_t::rf4ce_asb_destroy, (void *)NULL, 0, obj_network_rf4ce_); } -#endif void ctrlm_obj_controller_rf4ce_t::metrics_tag_reset() { metrics_tag_ = 0; diff --git a/src/rf4ce/ctrlm_rf4ce_controller.h b/src/rf4ce/ctrlm_rf4ce_controller.h index 54fe9565..8420f95c 100644 --- a/src/rf4ce/ctrlm_rf4ce_controller.h +++ b/src/rf4ce/ctrlm_rf4ce_controller.h @@ -31,9 +31,9 @@ #include "rf4ce/controller/attributes/ctrlm_rf4ce_controller_attr_battery.h" #include "rf4ce/controller/attributes/ctrlm_rf4ce_controller_attr_voice.h" #include "rf4ce/controller/attributes/ctrlm_rf4ce_controller_attr_irdb.h" -#ifdef ASB + #include "ctrlm_asb.h" -#endif + #include "ctrlm_voice_obj.h" #include "ctrlm_input_event_writer.h" @@ -45,9 +45,8 @@ class ctrlm_obj_network_rf4ce_t; #define CTRLM_RF4CE_CONST_RESPONSE_IDLE_TIME (50) // time a device must wait after the successful transmission of a request command frame before enabling its receiver to receive a response command frame #define CTRLM_RF4CE_CONST_RESPONSE_IDLE_TIME_FF (15) // time a device must wait after the successful transmission of a request command frame before enabling its receiver to receive a response command frame for Far Field Devices #define CTRLM_RF4CE_CONST_RESPONSE_WAIT_TIME (100) // The maximum time in ms a device MUST wait after the aplcResponseIdle WaitTime expired, to receive a response command frame following a request command frame -#ifdef ASB + #define CTRLM_RF4CE_CONST_ASB_BLACKOUT_TIME (50) // The time dedicated to ASB key derivation during the pairing process. -#endif #define CTRLM_RF4CE_VENDOR_ID_COMCAST (0x109D) // @@ -655,12 +654,12 @@ class ctrlm_obj_controller_rf4ce_t : public ctrlm_obj_controller_t void binding_security_type_set(ctrlm_rcu_binding_security_type_t type); ctrlm_rcu_binding_security_type_t binding_security_type_get(); -#ifdef ASB + void asb_key_derivation_method_set(asb_key_derivation_method_t method); asb_key_derivation_method_t asb_key_derivation_method_get(); void asb_key_derivation_start(ctrlm_network_id_t network_id); void asb_key_derivation_perform(); -#endif + ctrlm_timestamp_t last_mac_poll_checkin_time_get(); void handle_controller_metrics(void *data = NULL, int size = 0); @@ -762,13 +761,12 @@ class ctrlm_obj_controller_rf4ce_t : public ctrlm_obj_controller_t // End Polling variables ctrlm_rf4ce_rib_configuration_complete_status_t rib_configuration_complete_status_; // NEXT -#ifdef ASB // ASB variables asb_key_derivation_method_t asb_key_derivation_method_used_; // NEXT ctrlm_timestamp_t asb_key_derivation_ts_start_; guint asb_tag_; // End ASB variables -#endif + guint metrics_tag_; // HACK for XR15-704 diff --git a/src/rf4ce/ctrlm_rf4ce_discovery.cpp b/src/rf4ce/ctrlm_rf4ce_discovery.cpp index f76647b8..d36f6349 100644 --- a/src/rf4ce/ctrlm_rf4ce_discovery.cpp +++ b/src/rf4ce/ctrlm_rf4ce_discovery.cpp @@ -120,34 +120,36 @@ void ctrlm_obj_network_rf4ce_t::ind_process_discovery(void *data, int size) { safec_rc = strncpy_s((char *)params.rec_user_string, sizeof(params.rec_user_string), user_string_.c_str(), 9); ERR_CHK(safec_rc); params.rec_user_string[9] = '\0'; // Null -#ifdef ASB - if(is_asb_enabled() && (dqm->params.org_user_string[10] & CTRLM_RF4CE_DISCOVERY_ASB_OCTET_ENABLED)) { - if(asb_fallback_count_ >= asb_fallback_count_threshold_) { - XLOGD_TELEMETRY("ASB Fail Count >= to threshold, falling back to normal pairing"); - params.rec_user_string[10] = 0x00; // ASB Octet - } else { - params.rec_user_string[10] = CTRLM_RF4CE_DISCOVERY_ASB_OCTET_ENABLED; // ASB Octet - // store timestamp for ieee address for discovery deadline - ctrlm_rf4ce_discovery_deadline_t discovery_deadline; - ctrlm_timestamp_get(&discovery_deadline.timestamp); - // replace older timestamp for the same ieee address - asb_discovery_deadlines_.erase(dqm->params.src_ieee_addr); - asb_discovery_deadlines_.insert(std::make_pair(dqm->params.src_ieee_addr, discovery_deadline)); - // clean up expired discovery deadlines - for(auto it = asb_discovery_deadlines_.begin(), end_it = asb_discovery_deadlines_.end(); it != end_it;) { - if(CTRLM_RF4CE_DISCOVERY_ASB_EXPIRATION_TIME_MS < ctrlm_timestamp_since_ms(it->second.timestamp)) { - asb_discovery_deadlines_.erase(it++); - } else { - ++it; + + gboolean asb_supported = ctrlm_is_rf4ce_asb_supported(); + if(asb_supported) { + if(is_asb_enabled() && (dqm->params.org_user_string[10] & CTRLM_RF4CE_DISCOVERY_ASB_OCTET_ENABLED)) { + if(asb_fallback_count_ >= asb_fallback_count_threshold_) { + XLOGD_TELEMETRY("ASB Fail Count >= to threshold, falling back to normal pairing"); + params.rec_user_string[10] = 0x00; // ASB Octet + } else { + params.rec_user_string[10] = CTRLM_RF4CE_DISCOVERY_ASB_OCTET_ENABLED; // ASB Octet + // store timestamp for ieee address for discovery deadline + ctrlm_rf4ce_discovery_deadline_t discovery_deadline; + ctrlm_timestamp_get(&discovery_deadline.timestamp); + // replace older timestamp for the same ieee address + asb_discovery_deadlines_.erase(dqm->params.src_ieee_addr); + asb_discovery_deadlines_.insert(std::make_pair(dqm->params.src_ieee_addr, discovery_deadline)); + // clean up expired discovery deadlines + for(auto it = asb_discovery_deadlines_.begin(), end_it = asb_discovery_deadlines_.end(); it != end_it;) { + if(CTRLM_RF4CE_DISCOVERY_ASB_EXPIRATION_TIME_MS < ctrlm_timestamp_since_ms(it->second.timestamp)) { + asb_discovery_deadlines_.erase(it++); + } else { + ++it; + } } } + } else { + params.rec_user_string[10] = 0x00; // ASB Octet } } else { params.rec_user_string[10] = 0x00; // ASB Octet } -#else - params.rec_user_string[10] = 0x00; // ASB Octet -#endif // Primary / Secondary descriptors are handled in Discovery specific functions params.rec_user_string[13] = FULL_ROLLBACK_ENABLED; // Strict LQI Threshold and Full Rollback enabled params.rec_user_string[14] = LQI_THRESHOLD_NONE; // LQI Threshold @@ -166,11 +168,11 @@ void ctrlm_obj_network_rf4ce_t::ind_process_discovery(void *data, int size) { ctrlm_network_queue_deliver_result(dqm, params); user_string = (char *)dqm->params.org_user_string; -#ifdef ASB - XLOGD_INFO("Discovery Type <%s>, Respond? <%s>, MSO User String <%s>, Full Roll Back Enabled <%s>, Binding Initiation Indicator <%s>, MAC Address <0x%016llx>, ASB Enabled <%s>", ctrlm_rf4ce_discovery_type_str(dqm->params.search_dev_type), (CTRLM_HAL_RESULT_DISCOVERY_RESPOND == params.result ? "YES" : "NO"), user_string, (user_string[13] & RF4CE_BINDING_CONFIG_FULL_ROLLBACK_ENABLED) ? "YES" : "NO", ctrlm_rf4ce_binding_initiation_indicator_str((ctrlm_rf4ce_binding_initiation_indicator_t)(user_string[14])), dqm->params.src_ieee_addr, (user_string[10] & CTRLM_RF4CE_DISCOVERY_ASB_OCTET_ENABLED ? "YES" : "NO")); -#else - XLOGD_INFO("Discovery Type <%s>, Respond? <%s>, MSO User String <%s>, Full Roll Back Enabled <%s>, Binding Initiation Indicator <%s>, MAC Address <0x%016llx>", ctrlm_rf4ce_discovery_type_str(dqm->params.search_dev_type), (CTRLM_HAL_RESULT_DISCOVERY_RESPOND == params.result ? "YES" : "NO"), user_string, (user_string[13] & RF4CE_BINDING_CONFIG_FULL_ROLLBACK_ENABLED) ? "YES" : "NO", ctrlm_rf4ce_binding_initiation_indicator_str((ctrlm_rf4ce_binding_initiation_indicator_t)(user_string[14])), dqm->params.src_ieee_addr); -#endif + if(asb_supported) { + XLOGD_INFO("Discovery Type <%s>, Respond? <%s>, MSO User String <%s>, Full Roll Back Enabled <%s>, Binding Initiation Indicator <%s>, MAC Address <0x%016llx>, ASB Enabled <%s>", ctrlm_rf4ce_discovery_type_str(dqm->params.search_dev_type), (CTRLM_HAL_RESULT_DISCOVERY_RESPOND == params.result ? "YES" : "NO"), user_string, (user_string[13] & RF4CE_BINDING_CONFIG_FULL_ROLLBACK_ENABLED) ? "YES" : "NO", ctrlm_rf4ce_binding_initiation_indicator_str((ctrlm_rf4ce_binding_initiation_indicator_t)(user_string[14])), dqm->params.src_ieee_addr, (user_string[10] & CTRLM_RF4CE_DISCOVERY_ASB_OCTET_ENABLED ? "YES" : "NO")); + } else { + XLOGD_INFO("Discovery Type <%s>, Respond? <%s>, MSO User String <%s>, Full Roll Back Enabled <%s>, Binding Initiation Indicator <%s>, MAC Address <0x%016llx>", ctrlm_rf4ce_discovery_type_str(dqm->params.search_dev_type), (CTRLM_HAL_RESULT_DISCOVERY_RESPOND == params.result ? "YES" : "NO"), user_string, (user_string[13] & RF4CE_BINDING_CONFIG_FULL_ROLLBACK_ENABLED) ? "YES" : "NO", ctrlm_rf4ce_binding_initiation_indicator_str((ctrlm_rf4ce_binding_initiation_indicator_t)(user_string[14])), dqm->params.src_ieee_addr); + } ctrlm_discovery_remote_type_set((const char *)user_string); } @@ -390,7 +392,6 @@ gboolean ctrlm_obj_network_rf4ce_t::is_screen_bind_active(ctrlm_hal_rf4ce_ieee_a return false; } -#ifdef ASB gboolean ctrlm_obj_network_rf4ce_t::is_asb_active(ctrlm_hal_rf4ce_ieee_address_t ieee_address) { for(auto it = asb_discovery_deadlines_.begin(), end_it = asb_discovery_deadlines_.end(); it != end_it;) { if(CTRLM_RF4CE_DISCOVERY_ASB_EXPIRATION_TIME_MS < ctrlm_timestamp_since_ms(it->second.timestamp)) { @@ -404,4 +405,3 @@ gboolean ctrlm_obj_network_rf4ce_t::is_asb_active(ctrlm_hal_rf4ce_ieee_address_t } return false; } -#endif diff --git a/src/rf4ce/ctrlm_rf4ce_network.cpp b/src/rf4ce/ctrlm_rf4ce_network.cpp index 5677a74e..e43fe6b9 100644 --- a/src/rf4ce/ctrlm_rf4ce_network.cpp +++ b/src/rf4ce/ctrlm_rf4ce_network.cpp @@ -48,9 +48,7 @@ #include "ctrlm_config_default.h" #include "ctrlm_tr181.h" #include "ctrlm_rcu.h" -#ifdef ASB #include "ctrlm_asb.h" -#endif #include #include "ctrlm_voice_obj.h" #include "comcastIrKeyCodes.h" @@ -124,6 +122,12 @@ ctrlm_obj_network_rf4ce_t::ctrlm_obj_network_rf4ce_t(ctrlm_network_type_t type, hal_api_data_ = NULL; hal_api_rib_data_import_ = NULL; hal_api_rib_data_export_ = NULL; + + hal_api_asb_init_ = NULL; + hal_api_asb_methods_get_ = NULL; + hal_api_asb_key_derive_ = NULL; + hal_api_asb_destroy_ = NULL; + errno_t safec_rc = -1; discovery_config_normal_.enabled = JSON_BOOL_VALUE_NETWORK_RF4CE_DISCOVERY_CONFIG_ENABLE; @@ -197,7 +201,6 @@ ctrlm_obj_network_rf4ce_t::ctrlm_obj_network_rf4ce_t(ctrlm_network_type_t type, default_polling_configuration(); -#ifdef ASB // ASB Config asb_enabled_ = JSON_BOOL_VALUE_NETWORK_RF4CE_ASB_ENABLE; // DEFAULT FALSE asb_key_derivation_methods_ = JSON_INT_VALUE_NETWORK_RF4CE_ASB_DERIVATION_METHODS; @@ -205,7 +208,6 @@ ctrlm_obj_network_rf4ce_t::ctrlm_obj_network_rf4ce_t(ctrlm_network_type_t type, asb_fallback_count_threshold_ = JSON_INT_VALUE_NETWORK_RF4CE_ASB_FALLBACK_THRESHOLD; asb_force_settings_ = JSON_BOOL_VALUE_NETWORK_RF4CE_ASB_FORCE_SETTINGS; // DEFAULT FALSE // End ASB Config -#endif voice_session_rsp_confirm_ = NULL; voice_session_rsp_confirm_param_ = NULL; @@ -333,6 +335,17 @@ void ctrlm_obj_network_rf4ce_t::hal_api_main_set(ctrlm_hal_rf4ce_network_main_t hal_api_main_ = main; } +void ctrlm_obj_network_rf4ce_t::hal_api_asb_set(ctrlm_hal_rf4ce_asb_init_t init, + ctrlm_hal_rf4ce_asb_methods_get_t methods_get, + ctrlm_hal_rf4ce_asb_key_derive_t key_derive, + ctrlm_hal_rf4ce_asb_destroy_t destroy) { + THREAD_ID_VALIDATE(); + hal_api_asb_init_ = init; + hal_api_asb_methods_get_ = methods_get; + hal_api_asb_key_derive_ = key_derive; + hal_api_asb_destroy_ = destroy; +} + ctrlm_hal_result_t ctrlm_obj_network_rf4ce_t::hal_init_request(GThread *ctrlm_main_thread) { ctrlm_hal_rf4ce_main_init_t main_init; ctrlm_main_thread_ = ctrlm_main_thread; @@ -650,13 +663,11 @@ gboolean ctrlm_obj_network_rf4ce_t::load_config(json_t *json_obj_net_rf4ce) { polling_config_read(&sub_conf); } -#ifdef ASB if(conf.config_object_get(JSON_OBJ_NAME_NETWORK_RF4CE_ASB, sub_conf)) { asb_configuration(&sub_conf); } else { asb_configuration(NULL); } -#endif if(conf.config_object_get(JSON_OBJ_NAME_NETWORK_RF4CE_VOICE, sub_conf)) { sub_conf.config_value_get(JSON_INT_NAME_NETWORK_RF4CE_VOICE_STREAM_BEGIN, stream_begin_, 0); @@ -737,10 +748,10 @@ gboolean ctrlm_obj_network_rf4ce_t::load_config(json_t *json_obj_net_rf4ce) { #if (CTRLM_HAL_RF4CE_API_VERSION >= 11) XLOGD_INFO("DPI Pattern List %u", dpi_pattern_list); #endif -#ifdef ASB + if(ctrlm_is_rf4ce_asb_supported()) { XLOGD_INFO("ASB Force Settings <%s>", (asb_force_settings_ ? "YES" : "NO")); XLOGD_INFO("ASB Enabled <%s>", (asb_enabled_ ? "YES" : "NO")); -#endif + } XLOGD_INFO("FF Voice Stream Begin %d", (int)stream_begin_); XLOGD_INFO("FF Voice Stream Offset %d", stream_offset_); @@ -3396,13 +3407,13 @@ void ctrlm_obj_network_rf4ce_t::process_xconf() { } // ASB Functions -#ifdef ASB bool ctrlm_obj_network_rf4ce_t::rf4ce_asb_init(void *data, int size) { - if(asb_init()) { + + if(hal_api_asb_init_ == NULL || (*hal_api_asb_init_)()) { XLOGD_ERROR("Failed to init ASB"); return false; } - return true; + return true; } bool ctrlm_obj_network_rf4ce_t::is_asb_force_settings() { @@ -3418,7 +3429,11 @@ void ctrlm_obj_network_rf4ce_t::asb_enable_set(bool asb_enabled) { } asb_key_derivation_method_t ctrlm_obj_network_rf4ce_t::key_derivation_method_get(asb_key_derivation_bitmask_t bitmask_controller) { - asb_key_derivation_bitmask_t supported_methods = bitmask_controller & asb_key_derivation_methods_ & asb_key_derivation_methods_get(); + if(hal_api_asb_methods_get_ == NULL) { + XLOGD_ERROR("Failed to get ASB key derivation method"); + return(ASB_KEY_DERIVATION_NONE); + } + asb_key_derivation_bitmask_t supported_methods = bitmask_controller & asb_key_derivation_methods_ & (*hal_api_asb_methods_get_)(); asb_key_derivation_method_t ret = ASB_KEY_DERIVATION_NONE; if(ASB_KEY_DERIVATION_NONE != supported_methods) { // Get greatest support key derivation method.. Stored in least sig bit @@ -3497,9 +3512,23 @@ void ctrlm_obj_network_rf4ce_t::asb_configuration(json_config *conf) { } void ctrlm_obj_network_rf4ce_t::rf4ce_asb_destroy(void *data, int size) { - asb_destroy(); + if(hal_api_asb_destroy_ != NULL) { + (*hal_api_asb_destroy_)(); + } +} + +int ctrlm_obj_network_rf4ce_t::hal_asb_key_derive(uint8_t *input, uint8_t *output, asb_key_derivation_method_t method) { + if(hal_api_asb_key_derive_ != NULL) { + return (*hal_api_asb_key_derive_)(input, output, method); + } + return(-1); +} + +void ctrlm_obj_network_rf4ce_t::hal_asb_destroy(void) { + if(hal_api_asb_destroy_ != NULL) { + (*hal_api_asb_destroy_)(); + } } -#endif // End ASB Functions void ctrlm_obj_network_rf4ce_t::open_chime_enable_set(bool open_chime_enabled) { @@ -4357,13 +4386,13 @@ void ctrlm_obj_network_rf4ce_t::cs_values_set(const ctrlm_cs_values_t *values, b } // ASB -#ifdef ASB - if(!is_asb_force_settings()) { - asb_enabled_ = values->asb_enable; - } else { - XLOGD_WARN("%s network not using ASB cs_value due to force settings set to TRUE", name_get()); + if(ctrlm_is_rf4ce_asb_supported()) { + if(!is_asb_force_settings()) { + asb_enabled_ = values->asb_enable; + } else { + XLOGD_WARN("%s network not using ASB cs_value due to force settings set to TRUE", name_get()); + } } -#endif // Far Field Configuration far_field_configuration_t temp = ff_configuration_; @@ -4827,22 +4856,22 @@ void ctrlm_obj_network_rf4ce_t::rfc_retrieved_handler(const ctrlm_rfc_attr_t& at ctrlm_main_queue_handler_push(CTRLM_HANDLER_NETWORK, &ctrlm_obj_network_rf4ce_t::notify_controllers_polling_configuration, NULL, 0, (void*)this); // ASB -#ifdef ASB - if(attr.get_rfc_value(JSON_OBJ_NAME_NETWORK_RF4CE_ASB JSON_PATH_SEPERATOR JSON_BOOL_NAME_NETWORK_RF4CE_ASB_ENABLE, asb_enabled_)) { - XLOGD_INFO("TR181 ASB Enable set to %s", (asb_enabled_ ? "TRUE" : "FALSE")); - } - if(asb_enabled_) { - if(attr.get_rfc_value(JSON_OBJ_NAME_NETWORK_RF4CE_ASB JSON_PATH_SEPERATOR JSON_INT_NAME_NETWORK_RF4CE_ASB_DERIVATION_METHODS, asb_key_derivation_methods_, 0x01, 0xFF)) { - XLOGD_INFO("TR181 ASB Key Derivation Method set to %d", asb_key_derivation_methods_); + if(ctrlm_is_rf4ce_asb_supported()) { + if(attr.get_rfc_value(JSON_OBJ_NAME_NETWORK_RF4CE_ASB JSON_PATH_SEPERATOR JSON_BOOL_NAME_NETWORK_RF4CE_ASB_ENABLE, asb_enabled_)) { + XLOGD_INFO("TR181 ASB Enable set to %s", (asb_enabled_ ? "TRUE" : "FALSE")); } - if(attr.get_rfc_value(JSON_OBJ_NAME_NETWORK_RF4CE_ASB JSON_PATH_SEPERATOR JSON_INT_NAME_NETWORK_RF4CE_ASB_FALLBACK_THRESHOLD, asb_fallback_count_threshold_, 0x01, 0xFF)) { - XLOGD_INFO("TR181 ASB Fallback Threshold set to %d", asb_fallback_count_threshold_); - } - if(attr.get_rfc_value(JSON_OBJ_NAME_NETWORK_RF4CE_ASB JSON_PATH_SEPERATOR JSON_BOOL_NAME_NETWORK_RF4CE_ASB_FORCE_SETTINGS, asb_force_settings_)) { - XLOGD_INFO("TR181 ASB Force Settings set to %s", (asb_force_settings_ ? "TRUE" : "FALSE")); + if(asb_enabled_) { + if(attr.get_rfc_value(JSON_OBJ_NAME_NETWORK_RF4CE_ASB JSON_PATH_SEPERATOR JSON_INT_NAME_NETWORK_RF4CE_ASB_DERIVATION_METHODS, asb_key_derivation_methods_, 0x01, 0xFF)) { + XLOGD_INFO("TR181 ASB Key Derivation Method set to %d", asb_key_derivation_methods_); + } + if(attr.get_rfc_value(JSON_OBJ_NAME_NETWORK_RF4CE_ASB JSON_PATH_SEPERATOR JSON_INT_NAME_NETWORK_RF4CE_ASB_FALLBACK_THRESHOLD, asb_fallback_count_threshold_, 0x01, 0xFF)) { + XLOGD_INFO("TR181 ASB Fallback Threshold set to %d", asb_fallback_count_threshold_); + } + if(attr.get_rfc_value(JSON_OBJ_NAME_NETWORK_RF4CE_ASB JSON_PATH_SEPERATOR JSON_BOOL_NAME_NETWORK_RF4CE_ASB_FORCE_SETTINGS, asb_force_settings_)) { + XLOGD_INFO("TR181 ASB Force Settings set to %s", (asb_force_settings_ ? "TRUE" : "FALSE")); + } } } -#endif // End ASB // Voice @@ -4892,48 +4921,85 @@ void ctrlm_obj_network_rf4ce_t::req_process_start_pairing(void *data, int size) g_assert(dqm); g_assert(size == sizeof(ctrlm_main_queue_msg_start_pairing_t)); - dqm->params->set_result(CTRLM_IARM_CALL_RESULT_SUCCESS, network_id_get()); - - ctrlm_main_iarm_call_property_t property = {}; - property.api_revision = CTRLM_MAIN_IARM_BUS_API_REVISION; - property.result = CTRLM_IARM_CALL_RESULT_INVALID; - property.network_id = CTRLM_MAIN_NETWORK_ID_ALL; - property.name = CTRLM_PROPERTY_ACTIVE_PERIOD_SCREENBIND; - property.value = dqm->params->timeout * 1000; - - ctrlm_main_iarm_call_property_set_(&property); - if (property.result != CTRLM_IARM_CALL_RESULT_SUCCESS) { - XLOGD_ERROR("Failed to set ACTIVE PERIOD SCREENBIND property"); - set_rf_pair_state(CTRLM_RF_PAIR_STATE_FAILED); - dqm->params->set_result(CTRLM_IARM_CALL_RESULT_ERROR, network_id_get()); + if(!dqm->params->screen_bind_enable) { + XLOGD_INFO("screen bind enable is not requested"); + dqm->params->set_result(CTRLM_IARM_CALL_RESULT_SUCCESS, network_id_get()); + } else { + if(dqm->params->timeout != 0) { // use a timeout + ctrlm_main_iarm_call_property_t property = {}; + property.api_revision = CTRLM_MAIN_IARM_BUS_API_REVISION; + property.result = CTRLM_IARM_CALL_RESULT_INVALID; + property.network_id = CTRLM_MAIN_NETWORK_ID_ALL; + property.name = CTRLM_PROPERTY_ACTIVE_PERIOD_SCREENBIND; + property.value = dqm->params->timeout * 1000; + + ctrlm_main_iarm_call_property_set_(&property); + if (property.result != CTRLM_IARM_CALL_RESULT_SUCCESS) { + XLOGD_ERROR("Failed to set ACTIVE PERIOD SCREENBIND property"); + set_rf_pair_state(CTRLM_RF_PAIR_STATE_FAILED); + dqm->params->set_result(CTRLM_IARM_CALL_RESULT_ERROR, network_id_get()); + + if (dqm->semaphore) { + sem_post(dqm->semaphore); + } + return; + } + } - if (dqm->semaphore) { - sem_post(dqm->semaphore); - } - return ; + ctrlm_main_iarm_call_control_service_pairing_mode_t pairing = {}; + pairing.api_revision = CTRLM_MAIN_IARM_BUS_API_REVISION; + pairing.network_id = network_id_get(); + pairing.pairing_mode = 1; + pairing.restrict_by_remote = 0; + pairing.use_timeout = (dqm->params->timeout == 0) ? 0 : 1; + pairing.result = CTRLM_IARM_CALL_RESULT_INVALID; + + ctrlm_main_iarm_call_control_service_start_pairing_mode_(&pairing); + if (pairing.result != CTRLM_IARM_CALL_RESULT_SUCCESS) { + XLOGD_ERROR("Failed to start pairing mode timer"); + set_rf_pair_state(CTRLM_RF_PAIR_STATE_FAILED); + dqm->params->set_result(CTRLM_IARM_CALL_RESULT_ERROR, network_id_get()); + } else { + set_rf_pair_state(CTRLM_RF_PAIR_STATE_SEARCHING); + iarm_event_rcu_status(); + dqm->params->set_result(CTRLM_IARM_CALL_RESULT_SUCCESS, network_id_get()); + } + } + if (dqm->semaphore) { + sem_post(dqm->semaphore); } +} - ctrlm_main_iarm_call_control_service_pairing_mode_t pairing = {}; - pairing.api_revision = CTRLM_MAIN_IARM_BUS_API_REVISION; - pairing.network_id = network_id_get(); - pairing.pairing_mode = 1; - pairing.restrict_by_remote = 0; - pairing.result = CTRLM_IARM_CALL_RESULT_INVALID; +void ctrlm_obj_network_rf4ce_t::req_process_stop_pairing(void *data, int size) { + THREAD_ID_VALIDATE(); + ctrlm_main_queue_msg_stop_pairing_t *dqm = (ctrlm_main_queue_msg_stop_pairing_t *)data; - ctrlm_main_iarm_call_control_service_start_pairing_mode_(&pairing); - if (pairing.result != CTRLM_IARM_CALL_RESULT_SUCCESS) { - XLOGD_ERROR("Failed to start pairing mode timer"); - set_rf_pair_state(CTRLM_RF_PAIR_STATE_FAILED); - dqm->params->set_result(CTRLM_IARM_CALL_RESULT_ERROR, network_id_get()); + g_assert(dqm); + g_assert(size == sizeof(ctrlm_main_queue_msg_stop_pairing_t)); - if (dqm->semaphore) { - sem_post(dqm->semaphore); - } - return ; + if(!dqm->params->screen_bind_disable) { + XLOGD_INFO("screen bind disable is not requested"); + dqm->params->set_result(CTRLM_IARM_CALL_RESULT_SUCCESS, network_id_get()); + } else { + ctrlm_main_iarm_call_control_service_pairing_mode_t pairing = {}; + pairing.api_revision = CTRLM_MAIN_IARM_BUS_API_REVISION; + pairing.network_id = network_id_get(); + pairing.pairing_mode = 1; + pairing.restrict_by_remote = 0; + pairing.use_timeout = 0; + pairing.result = CTRLM_IARM_CALL_RESULT_INVALID; + + ctrlm_main_iarm_call_control_service_end_pairing_mode_(&pairing); + if (pairing.result != CTRLM_IARM_CALL_RESULT_SUCCESS) { + XLOGD_ERROR("Failed to end pairing mode"); + set_rf_pair_state(CTRLM_RF_PAIR_STATE_FAILED); + dqm->params->set_result(CTRLM_IARM_CALL_RESULT_ERROR, network_id_get()); + } else { + set_rf_pair_state(CTRLM_RF_PAIR_STATE_SEARCHING); + iarm_event_rcu_status(); + dqm->params->set_result(CTRLM_IARM_CALL_RESULT_SUCCESS, network_id_get()); + } } - - set_rf_pair_state(CTRLM_RF_PAIR_STATE_SEARCHING); - iarm_event_rcu_status(); if (dqm->semaphore) { sem_post(dqm->semaphore); } diff --git a/src/rf4ce/ctrlm_rf4ce_network.h b/src/rf4ce/ctrlm_rf4ce_network.h index 9b217a03..1e4ce251 100644 --- a/src/rf4ce/ctrlm_rf4ce_network.h +++ b/src/rf4ce/ctrlm_rf4ce_network.h @@ -36,6 +36,7 @@ #include "ctrlm_ir_rf_db.h" #include "network/attributes/ctrlm_rf4ce_network_attr_config.h" #include "ctrlm_rfc.h" +#include "ctrlm_asb.h" #define CTRLM_RF4CE_AUTOBIND_OCTET ((JSON_INT_VALUE_NETWORK_RF4CE_AUTOBIND_CONFIG_QTY_FAIL << 3) | JSON_INT_VALUE_NETWORK_RF4CE_AUTOBIND_CONFIG_QTY_PASS) #define CTRLM_RF4CE_AUTOBIND_OCTET_RESET (0x40 | (JSON_INT_VALUE_NETWORK_RF4CE_AUTOBIND_CONFIG_QTY_FAIL << 3) | JSON_INT_VALUE_NETWORK_RF4CE_AUTOBIND_CONFIG_QTY_PASS) @@ -53,10 +54,9 @@ #define CTRLM_RF4CE_DISCOVERY_USER_STRING_EXPIRATION_TIME_MS (300000) // 5 min in msec #define CTRLM_RF4CE_DISCOVERY_EXPIRATION_TIME_MS (2000) // 2 sec in msec -#ifdef ASB + #define CTRLM_RF4CE_DISCOVERY_ASB_EXPIRATION_TIME_MS (2000) // 250ms #define CTRLM_RF4CE_DISCOVERY_ASB_OCTET_ENABLED (0x80) -#endif #define IR_RF_DATABASE_STATUS_FORCE_DOWNLOAD (0x01) #define IR_RF_DATABASE_STATUS_DOWNLOAD_TV_5_DIGIT_CODE (0x02) @@ -266,6 +266,12 @@ class ctrlm_obj_network_rf4ce_t : public ctrlm_obj_network_t ctrlm_hal_result_t hal_init_request(GThread *ctrlm_main_thread); void hal_init_confirm(ctrlm_hal_rf4ce_cfm_init_params_t params); void hal_api_main_set(ctrlm_hal_rf4ce_network_main_t main); + + void hal_api_asb_set(ctrlm_hal_rf4ce_asb_init_t init, + ctrlm_hal_rf4ce_asb_methods_get_t methods_get, + ctrlm_hal_rf4ce_asb_key_derive_t key_derive, + ctrlm_hal_rf4ce_asb_destroy_t destroy); + void hal_rf4ce_api_set(ctrlm_hal_rf4ce_req_pair_t pair, ctrlm_hal_rf4ce_req_unpair_t unpair, ctrlm_hal_rf4ce_req_data_t data, @@ -319,6 +325,7 @@ class ctrlm_obj_network_rf4ce_t : public ctrlm_obj_network_t void process_pair_result(ctrlm_controller_id_t controller_id, unsigned long long ieee_address, ctrlm_hal_result_pair_t result); void bind_validation_begin(ctrlm_main_queue_msg_bind_validation_begin_t *dqm); + void bind_validation_key(ctrlm_main_queue_msg_bind_validation_key_t *dqm); void bind_validation_end(ctrlm_main_queue_msg_bind_validation_end_t *dqm); bool bind_validation_timeout(ctrlm_controller_id_t controller_id); bool remove_validation_failed_controller(ctrlm_controller_id_t controller_id); @@ -399,7 +406,7 @@ class ctrlm_obj_network_rf4ce_t : public ctrlm_obj_network_t void polling_action_push(void *data, int size); virtual bool is_fmr_supported() const; // End Polling Functions -#ifdef ASB + // ASB Functions bool rf4ce_asb_init(void *data, int size); void asb_configuration(json_config *conf); @@ -411,8 +418,11 @@ class ctrlm_obj_network_rf4ce_t : public ctrlm_obj_network_t void asb_link_key_derivation_perform(void *data, int size); void asb_link_key_validation_timeout(void *data, int size); void rf4ce_asb_destroy(void *data, int size); + + int hal_asb_key_derive(uint8_t *input, uint8_t *output, asb_key_derivation_method_t method); + void hal_asb_destroy(void); // End ASB Functions -#endif + void open_chime_enable_set(bool open_chime_enabled); bool open_chime_enable_get(); void close_chime_enable_set(bool close_chime_enabled); @@ -447,6 +457,7 @@ class ctrlm_obj_network_rf4ce_t : public ctrlm_obj_network_t void req_process_program_ir_codes(void *data, int size); void req_process_ir_clear_codes(void *data, int size); virtual void req_process_start_pairing(void *data, int size) override; + virtual void req_process_stop_pairing(void *data, int size) override; virtual void req_process_find_my_remote(void *data, int size); virtual std::vector get_controller_obj_list() const; void rcu_timeout_key_release(void *data, int data_size); @@ -456,6 +467,12 @@ class ctrlm_obj_network_rf4ce_t : public ctrlm_obj_network_t private: ctrlm_hal_rf4ce_network_main_t hal_api_main_; + + ctrlm_hal_rf4ce_asb_init_t hal_api_asb_init_; + ctrlm_hal_rf4ce_asb_methods_get_t hal_api_asb_methods_get_; + ctrlm_hal_rf4ce_asb_key_derive_t hal_api_asb_key_derive_; + ctrlm_hal_rf4ce_asb_destroy_t hal_api_asb_destroy_; + ctrlm_hal_rf4ce_req_pair_t hal_api_pair_; ctrlm_hal_rf4ce_req_unpair_t hal_api_unpair_; ctrlm_hal_rf4ce_req_data_t hal_api_data_; @@ -534,7 +551,6 @@ class ctrlm_obj_network_rf4ce_t : public ctrlm_obj_network_t ctrlm_rf4ce_polling_generic_config_t controller_generic_polling_configuration_; // End Polling Variables -#ifdef ASB // ASB Variables bool asb_enabled_; asb_key_derivation_bitmask_t asb_key_derivation_methods_; @@ -543,7 +559,6 @@ class ctrlm_obj_network_rf4ce_t : public ctrlm_obj_network_t discovery_deadlines_t asb_discovery_deadlines_; bool asb_force_settings_; // End ASB Variables -#endif ctrlm_voice_session_rsp_confirm_t voice_session_rsp_confirm_; void * voice_session_rsp_confirm_param_; @@ -619,10 +634,8 @@ class ctrlm_obj_network_rf4ce_t : public ctrlm_obj_network_t void dsp_configuration_xconf(); -#ifdef ASB gboolean is_asb_active(ctrlm_hal_rf4ce_ieee_address_t ieee_address); static gboolean asb_link_validation_timeout(gpointer user_data); -#endif bool reverse_cmd_begin_event(void*, int data_size); bool reverse_cmd_end_event(void*, int data_size); diff --git a/src/rf4ce/ctrlm_rf4ce_pairing.cpp b/src/rf4ce/ctrlm_rf4ce_pairing.cpp index d4c13d09..e3bfa63c 100644 --- a/src/rf4ce/ctrlm_rf4ce_pairing.cpp +++ b/src/rf4ce/ctrlm_rf4ce_pairing.cpp @@ -173,17 +173,17 @@ void ctrlm_obj_network_rf4ce_t::ind_process_pair_stb(ctrlm_main_queue_msg_rf4ce_ ctrlm_hal_rf4ce_rsp_pair_params_t params; ctrlm_controller_id_t controller_id; errno_t safec_rc = -1; -#ifdef ASB bool asb = false; asb_key_derivation_method_t key_derivation_method = ASB_KEY_DERIVATION_NONE; - // Check to make sure IF this is a ASB session that there is a common Key Derivation method - if(is_asb_enabled() && is_asb_active(dqm->params.src_ieee_addr)) { - asb = true; + if(ctrlm_is_rf4ce_asb_supported()) { + // Check to make sure IF this is a ASB session that there is a common Key Derivation method + if(is_asb_enabled() && is_asb_active(dqm->params.src_ieee_addr)) { + asb = true; + } + XLOGD_INFO("Normal Pair Request, status <%s>, MAC Address <0x%016llx>, ASB Enabled <%s>", ctrlm_hal_rf4ce_result_str(status), dqm->params.src_ieee_addr, (asb ? "YES" : "NO")); + } else { + XLOGD_INFO("Normal Pair Request, status <%s>, MAC Address <0x%016llx>", ctrlm_hal_rf4ce_result_str(status), dqm->params.src_ieee_addr); } - XLOGD_INFO("Normal Pair Request, status <%s>, MAC Address <0x%016llx>, ASB Enabled <%s>", ctrlm_hal_rf4ce_result_str(status), dqm->params.src_ieee_addr, (asb ? "YES" : "NO")); -#else - XLOGD_INFO("Normal Pair Request, status <%s>, MAC Address <0x%016llx>", ctrlm_hal_rf4ce_result_str(status), dqm->params.src_ieee_addr); -#endif controller_id = controller_id_get_by_ieee(dqm->params.src_ieee_addr); if(0 != controller_id) { @@ -204,7 +204,7 @@ void ctrlm_obj_network_rf4ce_t::ind_process_pair_stb(ctrlm_main_queue_msg_rf4ce_ #if (CTRLM_HAL_RF4CE_API_VERSION >= 12) safec_rc = strncpy_s((char *)params.rec_user_string, sizeof(params.rec_user_string), user_string_.c_str(), 9); ERR_CHK(safec_rc); -#ifdef ASB + if(asb) { params.rec_user_string[10] = key_derivation_method_get(dqm->params.org_user_string[10]); if(ASB_KEY_DERIVATION_NONE == params.rec_user_string[10]) { @@ -217,7 +217,6 @@ void ctrlm_obj_network_rf4ce_t::ind_process_pair_stb(ctrlm_main_queue_msg_rf4ce_ } key_derivation_method = params.rec_user_string[10]; } -#endif #endif params.rec_dev_type_list[0] = CTRLM_RF4CE_DEVICE_TYPE_STB; params.rec_dev_type_list[1] = CTRLM_RF4CE_DEVICE_TYPE_AUTOBIND; @@ -252,36 +251,36 @@ void ctrlm_obj_network_rf4ce_t::ind_process_pair_stb(ctrlm_main_queue_msg_rf4ce_ controller_screen_bind_in_progress_set(params.controller_id, false); // Set security type -#ifdef ASB - controller_set_binding_security_type(params.controller_id, (asb ? CTRLM_RCU_BINDING_SECURITY_TYPE_ADVANCED : CTRLM_RCU_BINDING_SECURITY_TYPE_NORMAL)); - controller_set_key_derivation_method(params.controller_id, (asb ? key_derivation_method : ASB_KEY_DERIVATION_NONE)); -#else - controller_set_binding_security_type(params.controller_id, CTRLM_RCU_BINDING_SECURITY_TYPE_NORMAL); -#endif + if(ctrlm_is_rf4ce_asb_supported()) { + controller_set_binding_security_type(params.controller_id, (asb ? CTRLM_RCU_BINDING_SECURITY_TYPE_ADVANCED : CTRLM_RCU_BINDING_SECURITY_TYPE_NORMAL)); + controller_set_key_derivation_method(params.controller_id, (asb ? key_derivation_method : ASB_KEY_DERIVATION_NONE)); + } else { + controller_set_binding_security_type(params.controller_id, CTRLM_RCU_BINDING_SECURITY_TYPE_NORMAL); + } // Send the parameters for the pair response ctrlm_network_queue_deliver_result_pair(dqm, params); -#ifdef ASB + if(CTRLM_HAL_RF4CE_RESULT_SUCCESS == status && asb) { ctrlm_main_queue_handler_push(CTRLM_HANDLER_NETWORK, (ctrlm_msg_handler_network_t)&ctrlm_obj_network_rf4ce_t::rf4ce_asb_init, (void *)NULL, 0, this); } -#endif } void ctrlm_obj_network_rf4ce_t::ind_process_pair_autobind(ctrlm_main_queue_msg_rf4ce_ind_pair_t *dqm, ctrlm_hal_rf4ce_result_t status) { THREAD_ID_VALIDATE(); ctrlm_hal_rf4ce_rsp_pair_params_t params; ctrlm_controller_id_t controller_id; -#ifdef ASB + bool asb = false; asb_key_derivation_method_t key_derivation_method = ASB_KEY_DERIVATION_NONE; - // Check to make sure IF this is a ASB session that there is a common Key Derivation method - if(is_asb_enabled() && is_asb_active(dqm->params.src_ieee_addr)) { - asb = true; + if(ctrlm_is_rf4ce_asb_supported()) { + // Check to make sure IF this is a ASB session that there is a common Key Derivation method + if(is_asb_enabled() && is_asb_active(dqm->params.src_ieee_addr)) { + asb = true; + } + XLOGD_INFO("Autobind Pair Request, status <%s>, MAC Address <0x%016llx>, ASB Enabled <%s>", ctrlm_hal_rf4ce_result_str(status), dqm->params.src_ieee_addr, (asb ? "YES" : "NO")); + } else { + XLOGD_INFO("Autobind Pair Request, status <%s>, MAC Address <0x%016llx>", ctrlm_hal_rf4ce_result_str(status), dqm->params.src_ieee_addr); } - XLOGD_INFO("Autobind Pair Request, status <%s>, MAC Address <0x%016llx>, ASB Enabled <%s>", ctrlm_hal_rf4ce_result_str(status), dqm->params.src_ieee_addr, (asb ? "YES" : "NO")); -#else - XLOGD_INFO("Autobind Pair Request, status <%s>, MAC Address <0x%016llx>", ctrlm_hal_rf4ce_result_str(status), dqm->params.src_ieee_addr); -#endif controller_id = controller_id_get_by_ieee(dqm->params.src_ieee_addr); if(0 != controller_id) { controller_bind_update(dqm, controller_id, status); @@ -301,7 +300,7 @@ void ctrlm_obj_network_rf4ce_t::ind_process_pair_autobind(ctrlm_main_queue_msg_r #if (CTRLM_HAL_RF4CE_API_VERSION >= 12) errno_t safec_rc = strncpy_s((char *)params.rec_user_string, sizeof(params.rec_user_string), user_string_.c_str(), 9); ERR_CHK(safec_rc); -#ifdef ASB + if(asb) { params.rec_user_string[10] = key_derivation_method_get(dqm->params.org_user_string[10]); if(ASB_KEY_DERIVATION_NONE == params.rec_user_string[10]) { @@ -315,7 +314,6 @@ void ctrlm_obj_network_rf4ce_t::ind_process_pair_autobind(ctrlm_main_queue_msg_r } key_derivation_method = params.rec_user_string[10]; } -#endif #endif params.rec_dev_type_list[0] = CTRLM_RF4CE_DEVICE_TYPE_STB; params.rec_dev_type_list[1] = CTRLM_RF4CE_DEVICE_TYPE_AUTOBIND; @@ -335,20 +333,19 @@ void ctrlm_obj_network_rf4ce_t::ind_process_pair_autobind(ctrlm_main_queue_msg_r controller_screen_bind_in_progress_set(params.controller_id, false); // Set security type -#ifdef ASB - controller_set_binding_security_type(params.controller_id, (asb ? CTRLM_RCU_BINDING_SECURITY_TYPE_ADVANCED : CTRLM_RCU_BINDING_SECURITY_TYPE_NORMAL)); - controller_set_key_derivation_method(params.controller_id, (asb ? key_derivation_method : ASB_KEY_DERIVATION_NONE)); -#else - controller_set_binding_security_type(params.controller_id, CTRLM_RCU_BINDING_SECURITY_TYPE_NORMAL); -#endif + if(ctrlm_is_rf4ce_asb_supported()) { + controller_set_binding_security_type(params.controller_id, (asb ? CTRLM_RCU_BINDING_SECURITY_TYPE_ADVANCED : CTRLM_RCU_BINDING_SECURITY_TYPE_NORMAL)); + controller_set_key_derivation_method(params.controller_id, (asb ? key_derivation_method : ASB_KEY_DERIVATION_NONE)); + } else { + controller_set_binding_security_type(params.controller_id, CTRLM_RCU_BINDING_SECURITY_TYPE_NORMAL); + } // Send the parameters for the pair response ctrlm_network_queue_deliver_result_pair(dqm, params); -#ifdef ASB + if(CTRLM_HAL_RF4CE_RESULT_SUCCESS == status && asb) { ctrlm_main_queue_handler_push(CTRLM_HANDLER_NETWORK, (ctrlm_msg_handler_network_t)&ctrlm_obj_network_rf4ce_t::rf4ce_asb_init, (void *)NULL, 0, this); } -#endif } void ctrlm_obj_network_rf4ce_t::ind_process_pair_binding_button(ctrlm_main_queue_msg_rf4ce_ind_pair_t *dqm, ctrlm_hal_rf4ce_result_t status) { @@ -356,17 +353,18 @@ void ctrlm_obj_network_rf4ce_t::ind_process_pair_binding_button(ctrlm_main_queue ctrlm_hal_rf4ce_rsp_pair_params_t params; ctrlm_controller_id_t controller_id; errno_t safec_rc = -1; -#ifdef ASB + bool asb = false; asb_key_derivation_method_t key_derivation_method = ASB_KEY_DERIVATION_NONE; - // Check to make sure IF this is a ASB session that there is a common Key Derivation method - if(is_asb_enabled() && is_asb_active(dqm->params.src_ieee_addr)) { - asb = true; + if(ctrlm_is_rf4ce_asb_supported()) { + // Check to make sure IF this is a ASB session that there is a common Key Derivation method + if(is_asb_enabled() && is_asb_active(dqm->params.src_ieee_addr)) { + asb = true; + } + XLOGD_INFO("Button Binding Pair Request, status <%s>, MAC Address <0x%016llx>, ASB Enabled <%s>", ctrlm_hal_rf4ce_result_str(status), dqm->params.src_ieee_addr, (asb ? "YES" : "NO")); + } else { + XLOGD_INFO("Button Binding Pair Request, status <%s>, MAC Address <0x%016llx>", ctrlm_hal_rf4ce_result_str(status), dqm->params.src_ieee_addr); } - XLOGD_INFO("Button Binding Pair Request, status <%s>, MAC Address <0x%016llx>, ASB Enabled <%s>", ctrlm_hal_rf4ce_result_str(status), dqm->params.src_ieee_addr, (asb ? "YES" : "NO")); -#else - XLOGD_INFO("Button Binding Pair Request, status <%s>, MAC Address <0x%016llx>", ctrlm_hal_rf4ce_result_str(status), dqm->params.src_ieee_addr); -#endif controller_id = controller_id_get_by_ieee(dqm->params.src_ieee_addr); if(0 != controller_id) { controller_bind_update(dqm, controller_id, status); @@ -386,7 +384,6 @@ void ctrlm_obj_network_rf4ce_t::ind_process_pair_binding_button(ctrlm_main_queue #if (CTRLM_HAL_RF4CE_API_VERSION >= 12) safec_rc = strncpy_s((char *)params.rec_user_string, sizeof(params.rec_user_string), user_string_.c_str(), 9); ERR_CHK(safec_rc); -#ifdef ASB if(asb) { params.rec_user_string[10] = key_derivation_method_get(dqm->params.org_user_string[10]); if(ASB_KEY_DERIVATION_NONE == params.rec_user_string[10]) { @@ -400,7 +397,6 @@ void ctrlm_obj_network_rf4ce_t::ind_process_pair_binding_button(ctrlm_main_queue } key_derivation_method = params.rec_user_string[10]; } -#endif #endif params.rec_dev_type_list[0] = CTRLM_RF4CE_DEVICE_TYPE_STB; params.rec_dev_type_list[1] = CTRLM_RF4CE_DEVICE_TYPE_AUTOBIND; @@ -434,37 +430,37 @@ void ctrlm_obj_network_rf4ce_t::ind_process_pair_binding_button(ctrlm_main_queue controller_screen_bind_in_progress_set(params.controller_id, false); // Set security type -#ifdef ASB - controller_set_binding_security_type(params.controller_id, (asb ? CTRLM_RCU_BINDING_SECURITY_TYPE_ADVANCED : CTRLM_RCU_BINDING_SECURITY_TYPE_NORMAL)); - controller_set_key_derivation_method(params.controller_id, (asb ? key_derivation_method : ASB_KEY_DERIVATION_NONE)); -#else - controller_set_binding_security_type(params.controller_id, CTRLM_RCU_BINDING_SECURITY_TYPE_NORMAL); -#endif + if(ctrlm_is_rf4ce_asb_supported()) { + controller_set_binding_security_type(params.controller_id, (asb ? CTRLM_RCU_BINDING_SECURITY_TYPE_ADVANCED : CTRLM_RCU_BINDING_SECURITY_TYPE_NORMAL)); + controller_set_key_derivation_method(params.controller_id, (asb ? key_derivation_method : ASB_KEY_DERIVATION_NONE)); + } else { + controller_set_binding_security_type(params.controller_id, CTRLM_RCU_BINDING_SECURITY_TYPE_NORMAL); + } // Send the parameters for the pair response ctrlm_network_queue_deliver_result_pair(dqm, params); -#ifdef ASB + if(CTRLM_HAL_RF4CE_RESULT_SUCCESS == status && asb) { ctrlm_main_queue_handler_push(CTRLM_HANDLER_NETWORK, (ctrlm_msg_handler_network_t)&ctrlm_obj_network_rf4ce_t::rf4ce_asb_init, (void *)NULL, 0, this); } -#endif } void ctrlm_obj_network_rf4ce_t::ind_process_pair_screen_bind(ctrlm_main_queue_msg_rf4ce_ind_pair_t *dqm, ctrlm_hal_rf4ce_result_t status) { THREAD_ID_VALIDATE(); ctrlm_hal_rf4ce_rsp_pair_params_t params; ctrlm_controller_id_t controller_id; -#ifdef ASB + bool asb = false; asb_key_derivation_method_t key_derivation_method = ASB_KEY_DERIVATION_NONE; - // Check to make sure IF this is a ASB session that there is a common Key Derivation method - if(is_asb_enabled() && is_asb_active(dqm->params.src_ieee_addr)) { - asb = true; + if(ctrlm_is_rf4ce_asb_supported()) { + // Check to make sure IF this is a ASB session that there is a common Key Derivation method + if(is_asb_enabled() && is_asb_active(dqm->params.src_ieee_addr)) { + asb = true; + } + XLOGD_INFO("Screen Bind Pair Request, status <%s>, MAC Address <0x%016llx>, ASB Enabled <%s>", ctrlm_hal_rf4ce_result_str(status), dqm->params.src_ieee_addr, (asb ? "YES" : "NO")); + } else { + XLOGD_INFO("Screen Bind Pair Request, status <%s>, MAC Address <0x%016llx>", ctrlm_hal_rf4ce_result_str(status), dqm->params.src_ieee_addr); } - XLOGD_INFO("Screen Bind Pair Request, status <%s>, MAC Address <0x%016llx>, ASB Enabled <%s>", ctrlm_hal_rf4ce_result_str(status), dqm->params.src_ieee_addr, (asb ? "YES" : "NO")); -#else - XLOGD_INFO("Screen Bind Pair Request, status <%s>, MAC Address <0x%016llx>", ctrlm_hal_rf4ce_result_str(status), dqm->params.src_ieee_addr); -#endif controller_id = controller_id_get_by_ieee(dqm->params.src_ieee_addr); if(0 != controller_id) { controller_bind_update(dqm, controller_id, status); @@ -484,7 +480,7 @@ void ctrlm_obj_network_rf4ce_t::ind_process_pair_screen_bind(ctrlm_main_queue_ms #if (CTRLM_HAL_RF4CE_API_VERSION >= 12) errno_t safec_rc = strncpy_s((char *)params.rec_user_string, sizeof(params.rec_user_string), user_string_.c_str(), 9); ERR_CHK(safec_rc); -#ifdef ASB + if(asb) { params.rec_user_string[10] = key_derivation_method_get(dqm->params.org_user_string[10]); if(ASB_KEY_DERIVATION_NONE == params.rec_user_string[10]) { @@ -498,7 +494,6 @@ void ctrlm_obj_network_rf4ce_t::ind_process_pair_screen_bind(ctrlm_main_queue_ms } key_derivation_method = params.rec_user_string[10]; } -#endif #endif params.rec_dev_type_list[0] = CTRLM_RF4CE_DEVICE_TYPE_STB; params.rec_dev_type_list[1] = CTRLM_RF4CE_DEVICE_TYPE_AUTOBIND; @@ -518,20 +513,19 @@ void ctrlm_obj_network_rf4ce_t::ind_process_pair_screen_bind(ctrlm_main_queue_ms controller_screen_bind_in_progress_set(params.controller_id, true); // Set security type -#ifdef ASB - controller_set_binding_security_type(params.controller_id, (asb ? CTRLM_RCU_BINDING_SECURITY_TYPE_ADVANCED : CTRLM_RCU_BINDING_SECURITY_TYPE_NORMAL)); - controller_set_key_derivation_method(params.controller_id, (asb ? key_derivation_method : ASB_KEY_DERIVATION_NONE)); -#else - controller_set_binding_security_type(params.controller_id, CTRLM_RCU_BINDING_SECURITY_TYPE_NORMAL); -#endif + if(ctrlm_is_rf4ce_asb_supported()) { + controller_set_binding_security_type(params.controller_id, (asb ? CTRLM_RCU_BINDING_SECURITY_TYPE_ADVANCED : CTRLM_RCU_BINDING_SECURITY_TYPE_NORMAL)); + controller_set_key_derivation_method(params.controller_id, (asb ? key_derivation_method : ASB_KEY_DERIVATION_NONE)); + } else { + controller_set_binding_security_type(params.controller_id, CTRLM_RCU_BINDING_SECURITY_TYPE_NORMAL); + } // Send the parameters for the pair response ctrlm_network_queue_deliver_result_pair(dqm, params); -#ifdef ASB + if(CTRLM_HAL_RF4CE_RESULT_SUCCESS == status && asb) { ctrlm_main_queue_handler_push(CTRLM_HANDLER_NETWORK, (ctrlm_msg_handler_network_t)&ctrlm_obj_network_rf4ce_t::rf4ce_asb_init, (void *)NULL, 0, this); } -#endif } void ctrlm_obj_network_rf4ce_t::process_pair_result(ctrlm_controller_id_t controller_id, unsigned long long ieee_address, ctrlm_hal_result_pair_t result) { @@ -636,15 +630,15 @@ void ctrlm_obj_network_rf4ce_t::ind_process_pair_result(void *data, int size) { g_assert(dqm); g_assert(size == sizeof(ctrlm_main_queue_msg_rf4ce_ind_pair_result_t)); -#ifdef ASB - if(CTRLM_HAL_RESULT_PAIR_SUCCESS == dqm->result && controller_exists(dqm->controller_id)) { - if(CTRLM_RCU_BINDING_SECURITY_TYPE_ADVANCED == controllers_[dqm->controller_id]->binding_security_type_get()) { - controller_stats_update(dqm->controller_id); - controllers_[dqm->controller_id]->asb_key_derivation_start(network_id_get()); - return; + if(ctrlm_is_rf4ce_asb_supported()) { + if(CTRLM_HAL_RESULT_PAIR_SUCCESS == dqm->result && controller_exists(dqm->controller_id)) { + if(CTRLM_RCU_BINDING_SECURITY_TYPE_ADVANCED == controllers_[dqm->controller_id]->binding_security_type_get()) { + controller_stats_update(dqm->controller_id); + controllers_[dqm->controller_id]->asb_key_derivation_start(network_id_get()); + return; + } } } -#endif process_pair_result(dqm->controller_id, dqm->ieee_address, dqm->result); } diff --git a/src/rf4ce/ctrlm_rf4ce_validation.cpp b/src/rf4ce/ctrlm_rf4ce_validation.cpp index 5724b551..b05b77be 100644 --- a/src/rf4ce/ctrlm_rf4ce_validation.cpp +++ b/src/rf4ce/ctrlm_rf4ce_validation.cpp @@ -34,11 +34,27 @@ void ctrlm_obj_network_rf4ce_t::bind_validation_begin(ctrlm_main_queue_msg_bind_ return; } set_rf_pair_state(CTRLM_RF_PAIR_STATE_PAIRING); + // Set the result for validation status + validation_result_set(CTRLM_RCU_VALIDATION_RESULT_PENDING); + validation_key_set(CTRLM_KEY_CODE_INVALID); + XLOGD_INFO("Controller Id %u 0x%016llX", dqm->controller_id, dqm->ieee_address); // Destroy the timeout because we switch the state at validation end ctrlm_timeout_destroy(&binding_in_progress_tag_); } +void ctrlm_obj_network_rf4ce_t::bind_validation_key(ctrlm_main_queue_msg_bind_validation_key_t *dqm) { + THREAD_ID_VALIDATE(); + if(NULL == dqm) { + XLOGD_ERROR("dqm is null"); + return; + } + // Set key code for validation status + validation_key_set(dqm->key_code); + + XLOGD_INFO("Controller Id %u key <%s>", dqm->controller_id, ctrlm_key_code_str(dqm->key_code)); +} + // Validation finish from control manager void ctrlm_obj_network_rf4ce_t::bind_validation_end(ctrlm_main_queue_msg_bind_validation_end_t *dqm) { THREAD_ID_VALIDATE(); @@ -70,6 +86,10 @@ void ctrlm_obj_network_rf4ce_t::bind_validation_end(ctrlm_main_queue_msg_bind_va default: result_rf4ce = CTRLM_RF4CE_RESULT_VALIDATION_FAILURE; set_rf_pair_state(CTRLM_RF_PAIR_STATE_FAILED); break; } + // Set the result for validation status + validation_result_set(dqm->result); + validation_key_set(CTRLM_KEY_CODE_INVALID); + if(!controller_exists(dqm->controller_id)) { XLOGD_INFO("Controller Id %u does not exist!", dqm->controller_id); return; diff --git a/src/thunder/ctrlm_thunder_plugin.cpp b/src/thunder/ctrlm_thunder_plugin.cpp index 9bc0b1bc..3040fae5 100644 --- a/src/thunder/ctrlm_thunder_plugin.cpp +++ b/src/thunder/ctrlm_thunder_plugin.cpp @@ -29,6 +29,15 @@ using namespace Thunder; using namespace Plugin; using namespace WPEFramework; +struct on_plugin_activated_params_t { + ctrlm_thunder_plugin_t *plugin_; + Thunder::plugin_state_t state_; + + on_plugin_activated_params_t(ctrlm_thunder_plugin_t *plugin, Thunder::plugin_state_t state) + : plugin_(plugin) + , state_(state) {} +}; + #define REGISTER_EVENTS_RETRY_MAX (5) static void _on_activation_change(Thunder::plugin_state_t state, void *data) { @@ -138,7 +147,8 @@ void ctrlm_thunder_plugin_t::remove_activation_handler(plugin_activation_handler int ctrlm_thunder_plugin_t::on_plugin_activated(void *data) { bool ret = 0; - ctrlm_thunder_plugin_t *plugin = (ctrlm_thunder_plugin_t *)data; + on_plugin_activated_params_t *params = (on_plugin_activated_params_t *)data; + ctrlm_thunder_plugin_t *plugin = params->plugin_; if(plugin) { XLOGD_INFO("%s activated, registering events", plugin->name.c_str()); ret = (plugin->register_events() ? 0 : 1); // If this fails, try to register again. @@ -150,6 +160,20 @@ int ctrlm_thunder_plugin_t::on_plugin_activated(void *data) { } } else { plugin->on_initial_activation(); + if (params->state_ == PLUGIN_BOOT_ACTIVATED) { + /* If this is first time the thunder plugin has been + * activated AND it was from boot/ctrlm start up then we + * need to run the activation callbacks here because the + * vector of callbacks will always be empty at the time + * of the first call to on_activation_change from + * on_thunder_ready(boot = true) in the constructor. + * + * There is no time between plugin construction and + * controller ready for users to register an activation + * callback. + */ + plugin->iterate_activation_callbacks(params->state_); + } } } else { XLOGD_ERROR("Plugin is NULL"); @@ -159,11 +183,10 @@ int ctrlm_thunder_plugin_t::on_plugin_activated(void *data) { void ctrlm_thunder_plugin_t::on_activation_change(plugin_state_t state) { if(state == PLUGIN_ACTIVATED || state == PLUGIN_BOOT_ACTIVATED) { - g_timeout_add(100, &ctrlm_thunder_plugin_t::on_plugin_activated, (void *)this); - } - for(auto &itr : this->activation_callbacks) { - itr.first(state, itr.second); + on_plugin_activated_params_t *params = new on_plugin_activated_params_t(this, state); + g_timeout_add(100, &ctrlm_thunder_plugin_t::on_plugin_activated, (void *)params); } + this->iterate_activation_callbacks(state); } void ctrlm_thunder_plugin_t::on_thunder_ready(bool boot) { @@ -254,5 +277,11 @@ bool ctrlm_thunder_plugin_t::register_events() { } void ctrlm_thunder_plugin_t::on_initial_activation() { - // Nothing needed here for now + // Nothing needed for now +} + +void ctrlm_thunder_plugin_t::iterate_activation_callbacks(plugin_state_t state) { + for (auto &itr : this->activation_callbacks) { + itr.first(state, itr.second); + } } diff --git a/src/thunder/ctrlm_thunder_plugin.h b/src/thunder/ctrlm_thunder_plugin.h index 07db858b..f1a3944a 100644 --- a/src/thunder/ctrlm_thunder_plugin.h +++ b/src/thunder/ctrlm_thunder_plugin.h @@ -83,6 +83,13 @@ class ctrlm_thunder_plugin_t { */ virtual void on_thunder_ready(bool boot = false); + + /** + * This function is technically used internally but from static function. + * This function is called on activation state changes to iterate through all registered callbacks. + * */ + void iterate_activation_callbacks(plugin_state_t state); + protected: /** * This is the Constructor for the base class object. It is protected, as the derived Thunder Plugins will be Singletons. diff --git a/src/thunder/plugins/ctrlm_thunder_plugin_system.cpp b/src/thunder/plugins/ctrlm_thunder_plugin_system.cpp index aee94703..ad2cd22d 100644 --- a/src/thunder/plugins/ctrlm_thunder_plugin_system.cpp +++ b/src/thunder/plugins/ctrlm_thunder_plugin_system.cpp @@ -32,6 +32,7 @@ static void _on_firmware_update_state_change(ctrlm_thunder_plugin_system_t *plug ctrlm_thunder_plugin_system_t::ctrlm_thunder_plugin_system_t() : ctrlm_thunder_plugin_t("System", "org.rdk.System", 1) { this->registered_events = false; + this->estb_mac = ""; } ctrlm_thunder_plugin_system_t::~ctrlm_thunder_plugin_system_t() { @@ -68,7 +69,6 @@ void ctrlm_thunder_plugin_system_t::remove_event_handler(system_event_handler_t } } - void ctrlm_thunder_plugin_system_t::on_firmware_update_state_change(firmware_update_state_t state) { XLOGD_INFO("state: %s", system_firmware_update_state_str(state)); for(auto &itr : this->event_callbacks) { @@ -118,3 +118,34 @@ const char *Thunder::System::system_firmware_update_state_str(firmware_update_st } return("UNKNOWN"); } + +void ctrlm_thunder_plugin_system_t::_get_device_info_mac() { + JsonObject params, response; + JsonArray param_array; + + XLOGD_INFO("Invoking getDeviceInfo call for estb_mac"); + + param_array.Add("estb_mac"); + params["params"] = param_array; + if (!this->call_plugin("getDeviceInfo", ¶ms, &response) || + !response.HasLabel("success") || !response["success"].Boolean() || + !response.HasLabel("estb_mac")) { + XLOGD_ERROR("Failed to get estb mac address from %s", this->name.c_str()); + this->estb_mac = ""; + } + + this->estb_mac = response["estb_mac"].String(); +} + +bool ctrlm_thunder_plugin_system_t::get_device_info_mac(std::string &mac_addr) { + if (this->estb_mac.empty()) { + _get_device_info_mac(); + } + mac_addr = this->estb_mac; + return(!mac_addr.empty()); +} + +void ctrlm_thunder_plugin_system_t::on_initial_activation() { + this->_get_device_info_mac(); + ctrlm_thunder_plugin_t::on_initial_activation(); +} diff --git a/src/thunder/plugins/ctrlm_thunder_plugin_system.h b/src/thunder/plugins/ctrlm_thunder_plugin_system.h index 12e82baf..18898671 100644 --- a/src/thunder/plugins/ctrlm_thunder_plugin_system.h +++ b/src/thunder/plugins/ctrlm_thunder_plugin_system.h @@ -70,6 +70,13 @@ class ctrlm_thunder_plugin_system_t : public Thunder::Plugin::ctrlm_thunder_plug */ void remove_event_handler(system_event_handler_t handler); + /** + * This function is used to get the estb mac address from this System Thunder object + * @param mac_addr MAC address string in AA:BB:CC:DD:EE:FF format and empty string if method failed + * @return True if the mac address string is non-empty, otherwise False. + */ + bool get_device_info_mac(std::string &mac_addr); + public: /** * This function is technically used internally but from static function. This is used to broadcast System update state change events. @@ -86,9 +93,19 @@ class ctrlm_thunder_plugin_system_t : public Thunder::Plugin::ctrlm_thunder_plug * @return True if the events were registered for successfully otherwise False. */ virtual bool register_events(); + /** + * This function is an internal function that calls the System Plugin for device mac + */ + void _get_device_info_mac(); + /** + * This function is called when the initial activation of the plugin occurs. + */ + virtual void on_initial_activation(); + private: std::vector > event_callbacks; + std::string estb_mac; bool registered_events; };