diff --git a/src/ble/ctrlm_ble_network.cpp b/src/ble/ctrlm_ble_network.cpp index 03e1322f..2378db60 100644 --- a/src/ble/ctrlm_ble_network.cpp +++ b/src/ble/ctrlm_ble_network.cpp @@ -794,10 +794,29 @@ void ctrlm_obj_network_ble_t::req_process_program_ir_codes(void *data, int size) } else { if(dqm->ir_codes) { + if (dqm->ir_codes->type == CTRLM_IRDB_DEV_TYPE_TV && (ir_rf_database_.get_avr_ir_vendor_id() != 0 && ir_rf_database_.get_avr_ir_vendor_id() != dqm->vendor_info.rcu_support_bitmask) ) { + // if we are programming TV codes but the previous AVR codes are from a different IRDB vendor, then clear out the AVR codes. + // the remote cannot send different codes from different IRDB vendors at the same time. + XLOGD_INFO("Programming TV codes from vendor %s(0x%X), but currently have AVR codes from %s(0x%X). Clearing AVR codes.", + dqm->vendor_info.name.c_str(), (unsigned int)dqm->vendor_info.rcu_support_bitmask, + ir_rf_database_.get_avr_ir_vendor_name().c_str(), (unsigned int)ir_rf_database_.get_avr_ir_vendor_id()); + + ir_rf_database_.clear_avr_ir_codes(); + + } else if (dqm->ir_codes->type == CTRLM_IRDB_DEV_TYPE_AVR && (ir_rf_database_.get_tv_ir_vendor_id() != 0 && ir_rf_database_.get_tv_ir_vendor_id() != dqm->vendor_info.rcu_support_bitmask) ) { + // if we are programming AVR codes but the previous TV codes are from a different IRDB vendor, then clear out the TV codes. + // the remote cannot send different codes from different IRDB vendors at the same time. + XLOGD_INFO("Programming AVR codes from vendor %s(0x%X), but currently have TV codes from %s(0x%X). Clearing TV codes.", + dqm->vendor_info.name.c_str(), (unsigned int)dqm->vendor_info.rcu_support_bitmask, + ir_rf_database_.get_tv_ir_vendor_name().c_str(), (unsigned int)ir_rf_database_.get_tv_ir_vendor_id()); + + ir_rf_database_.clear_tv_ir_codes(); + } + std::map> ir_codes; // First add IR Codes to the IR RF Database (this contains all of the logic for maintaining TV vs AVR codes) - ir_rf_database_.add_irdb_codes(dqm->ir_codes); + ir_rf_database_.add_irdb_codes(dqm->ir_codes, dqm->vendor_info.rcu_support_bitmask, dqm->vendor_info.name); XLOGD_INFO("\n%s", this->ir_rf_database_.to_string(true).c_str()); // Now get the IR codes for the BLE IR slots for(auto key : ctrlm_ble_ir_key_names) { diff --git a/src/database/ctrlm_database.cpp b/src/database/ctrlm_database.cpp index dfe2bb21..11ce9833 100644 --- a/src/database/ctrlm_database.cpp +++ b/src/database/ctrlm_database.cpp @@ -71,7 +71,11 @@ using namespace std; #define CTRLM_DB_IR_COMMAND_REPEATS "ir_command_repeats" #define CTRLM_DB_DEVICE_UPDATE_SESSION_STATE "du_session_state" #define CTRLM_DB_TV_IR_CODE_ID "tv_ir_code_id" +#define CTRLM_DB_TV_IR_VENDOR_ID "tv_ir_vendor_id" +#define CTRLM_DB_TV_IR_VENDOR_NAME "tv_ir_vendor_name" #define CTRLM_DB_AVR_IR_CODE_ID "avr_ir_code_id" +#define CTRLM_DB_AVR_IR_VENDOR_ID "avr_ir_vendor_id" +#define CTRLM_DB_AVR_IR_VENDOR_NAME "avr_ir_vendor_name" #define CTRLM_DB_TABLE_VOICE "ctrlm_voice" @@ -706,11 +710,13 @@ void ctrlm_db_ir_command_repeats_read(guchar **data, guint32 *length) { ctrlm_db_read_blob(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_IR_COMMAND_REPEATS, data, length); } -void ctrlm_db_tv_ir_code_id_write(const std::string id) { +void ctrlm_db_tv_ir_code_id_write(const std::string id, unsigned char vendor_id, const std::string vendor_name) { ctrlm_db_write_blob(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_TV_IR_CODE_ID, (const guchar*) id.c_str(), id.length()); + ctrlm_db_write_uint64(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_TV_IR_VENDOR_ID, vendor_id); + ctrlm_db_write_blob(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_TV_IR_VENDOR_NAME, (const guchar*) vendor_name.c_str(), vendor_name.length()); } -void ctrlm_db_tv_ir_code_id_read(std::string &id) { +void ctrlm_db_tv_ir_code_id_read(std::string &id, unsigned char &vendor_id, std::string &vendor_name) { guchar *data = NULL; guint32 length = 0; ctrlm_db_read_blob(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_TV_IR_CODE_ID, &data, &length); @@ -718,15 +724,31 @@ void ctrlm_db_tv_ir_code_id_read(std::string &id) { id.assign((char *)data, length); ctrlm_db_free(data); } else { - XLOGD_WARN("Failed to load tv_ir_code_id from db"); + XLOGD_WARN("Failed to load %s from db", CTRLM_DB_TV_IR_CODE_ID); + } + + guint64 vendor_id_64 = 0; + ctrlm_db_read_uint64(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_TV_IR_VENDOR_ID, (sqlite_uint64*)&vendor_id_64); + vendor_id = vendor_id_64; + + data = NULL; + length = 0; + ctrlm_db_read_blob(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_TV_IR_VENDOR_NAME, &data, &length); + if(NULL != data) { + vendor_name.assign((char *)data, length); + ctrlm_db_free(data); + } else { + XLOGD_WARN("Failed to load %s from db", CTRLM_DB_TV_IR_VENDOR_NAME); } } -void ctrlm_db_avr_ir_code_id_write(const std::string id) { +void ctrlm_db_avr_ir_code_id_write(const std::string id, unsigned char vendor_id, const std::string vendor_name) { ctrlm_db_write_blob(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_AVR_IR_CODE_ID, (const guchar*) id.c_str(), id.length()); + ctrlm_db_write_uint64(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_AVR_IR_VENDOR_ID, vendor_id); + ctrlm_db_write_blob(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_AVR_IR_VENDOR_NAME, (const guchar*) vendor_name.c_str(), vendor_name.length()); } -void ctrlm_db_avr_ir_code_id_read(std::string &id) { +void ctrlm_db_avr_ir_code_id_read(std::string &id, unsigned char &vendor_id, std::string &vendor_name) { guchar *data = NULL; guint32 length = 0; ctrlm_db_read_blob(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_AVR_IR_CODE_ID, &data, &length); @@ -734,7 +756,21 @@ void ctrlm_db_avr_ir_code_id_read(std::string &id) { id.assign((char *)data, length); ctrlm_db_free(data); } else { - XLOGD_WARN("Failed to load avr_ir_code_id from db"); + XLOGD_WARN("Failed to load %s from db", CTRLM_DB_AVR_IR_CODE_ID); + } + + guint64 vendor_id_64 = 0; + ctrlm_db_read_uint64(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_AVR_IR_VENDOR_ID, (sqlite_uint64*)&vendor_id_64); + vendor_id = vendor_id_64; + + data = NULL; + length = 0; + ctrlm_db_read_blob(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_AVR_IR_VENDOR_NAME, &data, &length); + if(NULL != data) { + vendor_name.assign((char *)data, length); + ctrlm_db_free(data); + } else { + XLOGD_WARN("Failed to load %s from db", CTRLM_DB_AVR_IR_VENDOR_NAME); } } diff --git a/src/database/ctrlm_database.h b/src/database/ctrlm_database.h index 4716b075..f842c71f 100644 --- a/src/database/ctrlm_database.h +++ b/src/database/ctrlm_database.h @@ -77,10 +77,10 @@ void ctrlm_db_chime_volume_write(guchar *data, guint32 length); void ctrlm_db_chime_volume_read(guchar **data, guint32 *length); void ctrlm_db_ir_command_repeats_write(guchar *data, guint32 length); void ctrlm_db_ir_command_repeats_read(guchar **data, guint32 *length); -void ctrlm_db_tv_ir_code_id_write(const std::string id); -void ctrlm_db_tv_ir_code_id_read(std::string &id); -void ctrlm_db_avr_ir_code_id_write(const std::string id); -void ctrlm_db_avr_ir_code_id_read(std::string &id); +void ctrlm_db_tv_ir_code_id_write(const std::string id, unsigned char vendor_id, const std::string vendor_name); +void ctrlm_db_tv_ir_code_id_read(std::string &id, unsigned char &vendor_id, std::string &vendor_name); +void ctrlm_db_avr_ir_code_id_write(const std::string id, unsigned char vendor_id, const std::string vendor_name); +void ctrlm_db_avr_ir_code_id_read(std::string &id, unsigned char &vendor_id, std::string &vendor_name); void ctrlm_db_rf4ce_networks_list(std::vector *network_ids); void ctrlm_db_rf4ce_controllers_list(ctrlm_network_id_t network_id, std::vector *controller_ids); diff --git a/src/network/ctrlm_ir_rf_db.cpp b/src/network/ctrlm_ir_rf_db.cpp index 126e57cb..6c821f5a 100644 --- a/src/network/ctrlm_ir_rf_db.cpp +++ b/src/network/ctrlm_ir_rf_db.cpp @@ -42,7 +42,11 @@ ctrlm_ir_rf_db_t::ctrlm_ir_rf_db_t(bool power_toggle_favor_tv, bool power_discre this->power_toggle_favor_tv = power_toggle_favor_tv; this->power_discrete_favor_tv = power_discrete_favor_tv; this->tv_ir_code_id_ = "0"; + this->tv_ir_vendor_id_ = 0; + this->tv_ir_vendor_name_ = "INVALID"; this->avr_ir_code_id_ = "0"; + this->avr_ir_vendor_id_ = 0; + this->avr_ir_vendor_name_ = "INVALID"; } ctrlm_ir_rf_db_t::~ctrlm_ir_rf_db_t() { @@ -174,17 +178,21 @@ ctrlm_key_code_t to_ctrlm_keycode(ctrlm_irdb_key_code_t irdb_code) { } } -bool ctrlm_ir_rf_db_t::add_irdb_codes(ctrlm_irdb_ir_code_set_t *ir_codes) { +bool ctrlm_ir_rf_db_t::add_irdb_codes(ctrlm_irdb_ir_code_set_t *ir_codes, unsigned char ir_vendor_id, const std::string &ir_vendor_name) { bool ret = false; if(ir_codes) { ctrlm_ir_rf_db_dev_type_t type = ctrlm_ir_rf_db_entry_t::type_from_irdb(ir_codes->type); switch(type) { case CTRLM_IR_RF_DB_DEV_TV: { this->tv_ir_code_id_ = ir_codes->id; + this->tv_ir_vendor_id_ = ir_vendor_id; + this->tv_ir_vendor_name_ = ir_vendor_name; break; } case CTRLM_IR_RF_DB_DEV_AVR: { this->avr_ir_code_id_ = ir_codes->id; + this->avr_ir_vendor_id_ = ir_vendor_id; + this->avr_ir_vendor_name_ = ir_vendor_name; break; } default: { @@ -205,52 +213,75 @@ bool ctrlm_ir_rf_db_t::add_irdb_codes(ctrlm_irdb_ir_code_set_t *ir_codes) { } void ctrlm_ir_rf_db_t::clear_tv_ir_codes() { + ctrlm_db_ir_rf_database_delete(CTRLM_KEY_CODE_TV_POWER_ON); this->remove_entry(CTRLM_KEY_CODE_TV_POWER_ON); + + ctrlm_db_ir_rf_database_delete(CTRLM_KEY_CODE_TV_POWER_OFF); this->remove_entry(CTRLM_KEY_CODE_TV_POWER_OFF); + + ctrlm_db_ir_rf_database_delete(CTRLM_KEY_CODE_TV_POWER); this->remove_entry(CTRLM_KEY_CODE_TV_POWER); + if(this->has_entry(CTRLM_KEY_CODE_VOL_UP)) { if(this->ir_rf_db[CTRLM_KEY_CODE_VOL_UP]->get_type() == CTRLM_IR_RF_DB_DEV_TV) { + ctrlm_db_ir_rf_database_delete(CTRLM_KEY_CODE_VOL_UP); this->remove_entry(CTRLM_KEY_CODE_VOL_UP); } } if(this->has_entry(CTRLM_KEY_CODE_VOL_DOWN)) { if(this->ir_rf_db[CTRLM_KEY_CODE_VOL_DOWN]->get_type() == CTRLM_IR_RF_DB_DEV_TV) { + ctrlm_db_ir_rf_database_delete(CTRLM_KEY_CODE_VOL_DOWN); this->remove_entry(CTRLM_KEY_CODE_VOL_DOWN); } } if(this->has_entry(CTRLM_KEY_CODE_MUTE)) { if(this->ir_rf_db[CTRLM_KEY_CODE_MUTE]->get_type() == CTRLM_IR_RF_DB_DEV_TV) { + ctrlm_db_ir_rf_database_delete(CTRLM_KEY_CODE_MUTE); this->remove_entry(CTRLM_KEY_CODE_MUTE); } } + ctrlm_db_ir_rf_database_delete(CTRLM_KEY_CODE_INPUT_SELECT); this->remove_entry(CTRLM_KEY_CODE_INPUT_SELECT); this->fix_common_slots_and_ir_flags(); this->tv_ir_code_id_ = "0"; + this->tv_ir_vendor_id_ = 0; + this->tv_ir_vendor_name_ = "INVALID"; } void ctrlm_ir_rf_db_t::clear_avr_ir_codes() { + ctrlm_db_ir_rf_database_delete(CTRLM_KEY_CODE_AVR_POWER_ON); this->remove_entry(CTRLM_KEY_CODE_AVR_POWER_ON); + + ctrlm_db_ir_rf_database_delete(CTRLM_KEY_CODE_AVR_POWER_OFF); this->remove_entry(CTRLM_KEY_CODE_AVR_POWER_OFF); + + ctrlm_db_ir_rf_database_delete(CTRLM_KEY_CODE_AVR_POWER_TOGGLE); this->remove_entry(CTRLM_KEY_CODE_AVR_POWER_TOGGLE); + if(this->has_entry(CTRLM_KEY_CODE_VOL_UP)) { if(this->ir_rf_db[CTRLM_KEY_CODE_VOL_UP]->get_type() == CTRLM_IR_RF_DB_DEV_AVR) { + ctrlm_db_ir_rf_database_delete(CTRLM_KEY_CODE_VOL_UP); this->remove_entry(CTRLM_KEY_CODE_VOL_UP); } } if(this->has_entry(CTRLM_KEY_CODE_VOL_DOWN)) { if(this->ir_rf_db[CTRLM_KEY_CODE_VOL_DOWN]->get_type() == CTRLM_IR_RF_DB_DEV_AVR) { + ctrlm_db_ir_rf_database_delete(CTRLM_KEY_CODE_VOL_DOWN); this->remove_entry(CTRLM_KEY_CODE_VOL_DOWN); } } if(this->has_entry(CTRLM_KEY_CODE_MUTE)) { if(this->ir_rf_db[CTRLM_KEY_CODE_MUTE]->get_type() == CTRLM_IR_RF_DB_DEV_AVR) { + ctrlm_db_ir_rf_database_delete(CTRLM_KEY_CODE_MUTE); this->remove_entry(CTRLM_KEY_CODE_MUTE); } } this->fix_common_slots_and_ir_flags(); this->avr_ir_code_id_ = "0"; + this->avr_ir_vendor_id_ = 0; + this->avr_ir_vendor_name_ = "INVALID"; } void ctrlm_ir_rf_db_t::clear_ir_codes() { @@ -259,7 +290,11 @@ void ctrlm_ir_rf_db_t::clear_ir_codes() { this->remove_entry(itr->first); } this->tv_ir_code_id_ = "0"; + this->tv_ir_vendor_id_ = 0; + this->tv_ir_vendor_name_ = "INVALID"; this->avr_ir_code_id_ = "0"; + this->avr_ir_vendor_id_ = 0; + this->avr_ir_vendor_name_ = "INVALID"; } ctrlm_ir_rf_db_entry_t *ctrlm_ir_rf_db_t::get_ir_code(ctrlm_key_code_t key) { @@ -274,7 +309,9 @@ std::string ctrlm_ir_rf_db_t::to_string(bool debug) const { std::stringstream ss; ss << "IR RF Database: "<< std::endl; ss << "\tTV IR Code ID <" << tv_ir_code_id_ << ">" << std::endl; + ss << "\tTV IR Vendor Info <" << tv_ir_vendor_name_ << ": " << (unsigned int)tv_ir_vendor_id_ << ">" << std::endl; ss << "\tAVR IR Code ID <" << avr_ir_code_id_ << ">" << std::endl; + ss << "\tAVR IR Vendor Info <" << avr_ir_vendor_name_ << ": " << (unsigned int)avr_ir_vendor_id_ << ">" << std::endl; for(auto itr = this->ir_rf_db.begin(); itr != this->ir_rf_db.end(); itr++) { if(itr->second != NULL) { ss << "\tKeySlot <" << ctrlm_key_code_str(itr->first) << ">, " << itr->second->to_string(debug) << std::endl; @@ -373,16 +410,16 @@ void ctrlm_ir_rf_db_t::load_db() { this->replace_entry(itr->first, entry); } } - ctrlm_db_tv_ir_code_id_read(tv_ir_code_id_); - ctrlm_db_avr_ir_code_id_read(avr_ir_code_id_); + ctrlm_db_tv_ir_code_id_read(tv_ir_code_id_, tv_ir_vendor_id_, tv_ir_vendor_name_); + ctrlm_db_avr_ir_code_id_read(avr_ir_code_id_, avr_ir_vendor_id_, avr_ir_vendor_name_); } bool ctrlm_ir_rf_db_t::store_db() { for(auto itr = this->ir_rf_db.begin(); itr != this->ir_rf_db.end(); itr++) { this->store_entry(itr->first); } - ctrlm_db_tv_ir_code_id_write(tv_ir_code_id_); - ctrlm_db_avr_ir_code_id_write(avr_ir_code_id_); + ctrlm_db_tv_ir_code_id_write(tv_ir_code_id_, tv_ir_vendor_id_, tv_ir_vendor_name_); + ctrlm_db_avr_ir_code_id_write(avr_ir_code_id_, avr_ir_vendor_id_, avr_ir_vendor_name_); return(true); // TODO, maybe change to void } @@ -449,7 +486,22 @@ std::string ctrlm_ir_rf_db_t::get_tv_ir_code_id() { return tv_ir_code_id_; } +unsigned char ctrlm_ir_rf_db_t::get_tv_ir_vendor_id() { + return tv_ir_vendor_id_; +} + +std::string ctrlm_ir_rf_db_t::get_tv_ir_vendor_name() { + return tv_ir_vendor_name_; +} + std::string ctrlm_ir_rf_db_t::get_avr_ir_code_id() { return avr_ir_code_id_; } +unsigned char ctrlm_ir_rf_db_t::get_avr_ir_vendor_id() { + return avr_ir_vendor_id_; +} + +std::string ctrlm_ir_rf_db_t::get_avr_ir_vendor_name() { + return avr_ir_vendor_name_; +} diff --git a/src/network/ctrlm_ir_rf_db.h b/src/network/ctrlm_ir_rf_db.h index c9f489a2..098a69e9 100644 --- a/src/network/ctrlm_ir_rf_db.h +++ b/src/network/ctrlm_ir_rf_db.h @@ -60,7 +60,7 @@ class ctrlm_ir_rf_db_t { * @param ir_codes A keymap supplied from the CTRLM IRDB component * @reutrn True if the entries were added to the IRRF Database, False otherwise. */ - bool add_irdb_codes(ctrlm_irdb_ir_code_set_t *ir_codes); + bool add_irdb_codes(ctrlm_irdb_ir_code_set_t *ir_codes, unsigned char ir_vendor_id = 0, const std::string &ir_vendor_name = ""); /** * Function to clear all TV IR codes stored in the IR RF Database @@ -120,11 +120,36 @@ class ctrlm_ir_rf_db_t { */ std::string get_tv_ir_code_id(); + /** + * Function used to get the TV IR vendor ID in the ControlMgr Database. + * @return the TV IR vendor ID as unsigned char + */ + unsigned char get_tv_ir_vendor_id(); + + /** + * Function used to get the TV IR vendor name in the ControlMgr Database. + * @return the TV IR vendor name in string form. + */ + std::string get_tv_ir_vendor_name(); + /** * Function used to get the AVR IR code ID in the ControlMgr Database. * @return the AVR IR code ID in string form. */ std::string get_avr_ir_code_id(); + + /** + * Function used to get the AVR IR vendor ID in the ControlMgr Database. + * @return the AVR IR vendor ID as unsigned char + */ + unsigned char get_avr_ir_vendor_id(); + + /** + * Function used to get the AVR IR vendor name in the ControlMgr Database. + * @return the AVR IR vendor name in string form. + */ + std::string get_avr_ir_vendor_name(); + private: /** @@ -157,7 +182,11 @@ class ctrlm_ir_rf_db_t { bool power_toggle_favor_tv; bool power_discrete_favor_tv; std::string tv_ir_code_id_; + unsigned char tv_ir_vendor_id_; + std::string tv_ir_vendor_name_; std::string avr_ir_code_id_; + unsigned char avr_ir_vendor_id_; + std::string avr_ir_vendor_name_; };