Skip to content
4 changes: 3 additions & 1 deletion src/attributes/ctrlm_attr_general.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ bool ctrlm_string_db_attr_t::write_db(ctrlm_db_ctx_t ctx) {
bool ret = false;
ctrlm_db_blob_t blob(this->get_key(), this->get_table());

if(blob.from_string(this->value)) {
if (this->value.empty()) {
XLOGD_DEBUG("value is empty for db key <%s>", this->get_name().c_str());
} else if(blob.from_string(this->value)) {
Comment on lines +90 to +92
if(blob.write_db(ctx)) {
ret = true;
XLOGD_DEBUG("%s written to database: %s", this->get_name().c_str(), this->to_string().c_str());
Expand Down
6 changes: 4 additions & 2 deletions src/ble/ctrlm_ble_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -692,8 +692,10 @@ void ctrlm_obj_controller_ble_t::print_status() {
} else {
XLOGD_INFO("IR Database Support : N/A");
}
XLOGD_INFO("Programmed TV IRDB Code : %s", irdb_entry_id_name_tv_->to_string().c_str());
XLOGD_INFO("Programmed AVR IRDB Code : %s", irdb_entry_id_name_avr_->to_string().c_str());
XLOGD_INFO("Programmed TV IRDB Code : %s (Manufacturer = %s, Model = %s)",
irdb_entry_id_name_tv_->to_string().c_str(), irdb_manufacturer_tv_->to_string().c_str(), irdb_model_tv_->to_string().c_str());
XLOGD_INFO("Programmed AVR IRDB Code : %s (Manufacturer = %s, Model = %s)",
irdb_entry_id_name_avr_->to_string().c_str(), irdb_manufacturer_avr_->to_string().c_str(), irdb_model_avr_->to_string().c_str());
XLOGD_INFO("");
voice_metrics_->print(__FUNCTION__);
XLOGD_WARN("------------------------------------------------------------");
Expand Down
7 changes: 4 additions & 3 deletions src/ble/ctrlm_ble_network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -806,7 +806,7 @@ void ctrlm_obj_network_ble_t::req_process_program_ir_codes(void *data, int size)
} else {
ctrlm_controller_id_t controller_id = dqm->controller_id;
if (!is_managed_by_network(controller_id)) {
XLOGD_ERROR("Controller %d is not managed by the %s network", controller_id, name_get());
XLOGD_WARN("Controller %d is not managed by the %s network", controller_id, name_get());
} else if (!controller_exists(controller_id)) {
XLOGD_ERROR("Controller doesn't exist!");
} else if (!controllers_[controller_id]->isSupportedIrdb(dqm->vendor_info)) {
Expand Down Expand Up @@ -839,7 +839,7 @@ void ctrlm_obj_network_ble_t::req_process_program_ir_codes(void *data, int size)
std::map<ctrlm_key_code_t, std::vector<uint8_t>> 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, dqm->vendor_info.rcu_support_bitmask, dqm->vendor_info.name);
ir_rf_database_.add_irdb_codes(dqm->ir_codes, dqm->manufacturer, dqm->model, dqm->vendor_info.rcu_support_bitmask, dqm->vendor_info.name);
XLOGD_INFO("\n%s", this->ir_rf_database_.to_string(false).c_str());
XLOGD_DEBUG("\n%s", this->ir_rf_database_.to_string(true).c_str());
// Now get the IR codes for the BLE IR slots
Expand All @@ -864,7 +864,8 @@ void ctrlm_obj_network_ble_t::req_process_program_ir_codes(void *data, int size)
success = true;
controllers_[controller_id]->irdb_entry_id_name_set(CTRLM_IRDB_DEV_TYPE_TV, ir_rf_database_.get_tv_ir_code_id());
controllers_[controller_id]->irdb_entry_id_name_set(CTRLM_IRDB_DEV_TYPE_AVR, ir_rf_database_.get_avr_ir_code_id());
XLOGD_INFO("irdb_entry_id_name = <%s>", dqm->ir_codes->id.c_str());
controllers_[controller_id]->irdb_manufacturer_model_set(dqm->ir_codes->type, dqm->manufacturer, dqm->model);
XLOGD_INFO("irdb_entry_id_name = <%s>, manufacturer/model = <%s / %s>", dqm->ir_codes->id.c_str(), dqm->manufacturer.c_str(), dqm->model.c_str());
}
}
// Store the IR codes in the database
Expand Down
44 changes: 44 additions & 0 deletions src/ctrlm_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ ctrlm_obj_controller_t::ctrlm_obj_controller_t(ctrlm_controller_id_t controller_
last_key_code_(std::make_shared<ctrlm_uint64_db_attr_t>("Last Keypress Code", CTRLM_KEY_CODE_INVALID, &network, controller_id, "last_key_code")),
irdb_entry_id_name_tv_(std::make_shared<ctrlm_string_db_attr_t>("TV IRDB Code", "0", &network, controller_id, "irdb_entry_id_name_tv")),
irdb_entry_id_name_avr_(std::make_shared<ctrlm_string_db_attr_t>("AVR IRDB Code", "0", &network, controller_id, "irdb_entry_id_name_avr")),
irdb_manufacturer_tv_(std::make_shared<ctrlm_string_db_attr_t>("TV IRDB Manufacturer", "", &network, controller_id, "irdb_manufacturer_tv")),
irdb_model_tv_(std::make_shared<ctrlm_string_db_attr_t>("TV IRDB Model", "", &network, controller_id, "irdb_model_tv")),
irdb_manufacturer_avr_(std::make_shared<ctrlm_string_db_attr_t>("AVR IRDB Manufacturer", "", &network, controller_id, "irdb_manufacturer_avr")),
irdb_model_avr_(std::make_shared<ctrlm_string_db_attr_t>("AVR IRDB Model", "", &network, controller_id, "irdb_model_avr")),
voice_metrics_(std::make_shared<ctrlm_voice_metrics_t>(&network, controller_id)),
ota_failure_cnt_from_last_success_(std::make_shared<ctrlm_uint64_db_attr_t>("OTA Failure Count From Last Success", 0, &network, controller_id, "ota_failure_cnt_last_success"))
{
Expand Down Expand Up @@ -69,6 +73,10 @@ void ctrlm_obj_controller_t::db_load() {
ctrlm_db_attr_read(last_key_code_.get());
ctrlm_db_attr_read(irdb_entry_id_name_tv_.get());
ctrlm_db_attr_read(irdb_entry_id_name_avr_.get());
ctrlm_db_attr_read(irdb_manufacturer_tv_.get());
ctrlm_db_attr_read(irdb_model_tv_.get());
ctrlm_db_attr_read(irdb_manufacturer_avr_.get());
ctrlm_db_attr_read(irdb_model_avr_.get());
ctrlm_db_attr_read(voice_metrics_.get());

ctrlm_db_attr_read(ota_failure_cnt_from_last_success_.get());
Expand All @@ -85,6 +93,10 @@ void ctrlm_obj_controller_t::db_store() {
ctrlm_db_attr_write(last_key_code_);
ctrlm_db_attr_write(irdb_entry_id_name_tv_);
ctrlm_db_attr_write(irdb_entry_id_name_avr_);
ctrlm_db_attr_write(irdb_manufacturer_tv_);
ctrlm_db_attr_write(irdb_model_tv_);
ctrlm_db_attr_write(irdb_manufacturer_avr_);
ctrlm_db_attr_write(irdb_model_avr_);
ctrlm_db_attr_write(voice_metrics_);
}

Expand Down Expand Up @@ -208,6 +220,34 @@ void ctrlm_obj_controller_t::irdb_entry_id_name_set(ctrlm_irdb_dev_type_t type,
}
}

void ctrlm_obj_controller_t::irdb_manufacturer_model_set(ctrlm_irdb_dev_type_t type, const std::string &manufacturer, const std::string &model) {
switch(type) {
case CTRLM_IRDB_DEV_TYPE_TV:
if (irdb_manufacturer_tv_->to_string() != manufacturer) {
irdb_manufacturer_tv_->set_value(manufacturer);
ctrlm_db_attr_write(irdb_manufacturer_tv_);
}
if (irdb_model_tv_->to_string() != model) {
irdb_model_tv_->set_value(model);
ctrlm_db_attr_write(irdb_model_tv_);
}
break;
Comment on lines +225 to +234
case CTRLM_IRDB_DEV_TYPE_AVR:
if (irdb_manufacturer_avr_->to_string() != manufacturer) {
irdb_manufacturer_avr_->set_value(manufacturer);
ctrlm_db_attr_write(irdb_manufacturer_avr_);
}
if (irdb_model_avr_->to_string() != model) {
irdb_model_avr_->set_value(model);
ctrlm_db_attr_write(irdb_model_avr_);
}
break;
default:
XLOGD_WARN("Invalid type <%d>", type);
break;
}
}

std::string ctrlm_obj_controller_t::get_irdb_entry_id_name_tv() const {
return irdb_entry_id_name_tv_->to_string();
}
Expand Down Expand Up @@ -427,6 +467,10 @@ void ctrlm_obj_controller_t::update_controller_id_and_db_entry(std::string db_na
last_key_code_->set_table(new_table);
irdb_entry_id_name_tv_->set_table(new_table);
irdb_entry_id_name_avr_->set_table(new_table);
irdb_manufacturer_tv_->set_table(new_table);
irdb_model_tv_->set_table(new_table);
irdb_manufacturer_avr_->set_table(new_table);
irdb_model_avr_->set_table(new_table);
voice_metrics_->set_table(new_table);
ota_failure_cnt_from_last_success_->set_table(new_table);
}
5 changes: 5 additions & 0 deletions src/ctrlm_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class ctrlm_obj_controller_t

void send_to(unsigned long delay, unsigned long length, char *data);
virtual void irdb_entry_id_name_set(ctrlm_irdb_dev_type_t type, const std::string &irdb_ir_entry_id);
virtual void irdb_manufacturer_model_set(ctrlm_irdb_dev_type_t type, const std::string &manufacturer, const std::string &model);
std::string get_irdb_entry_id_name_tv() const;
std::string get_irdb_entry_id_name_avr() const;

Expand Down Expand Up @@ -125,6 +126,10 @@ class ctrlm_obj_controller_t

std::shared_ptr<ctrlm_string_db_attr_t> irdb_entry_id_name_tv_;
std::shared_ptr<ctrlm_string_db_attr_t> irdb_entry_id_name_avr_;
std::shared_ptr<ctrlm_string_db_attr_t> irdb_manufacturer_tv_;
std::shared_ptr<ctrlm_string_db_attr_t> irdb_model_tv_;
std::shared_ptr<ctrlm_string_db_attr_t> irdb_manufacturer_avr_;
std::shared_ptr<ctrlm_string_db_attr_t> irdb_model_avr_;

std::shared_ptr<ctrlm_voice_metrics_t> voice_metrics_;

Expand Down
70 changes: 69 additions & 1 deletion src/database/ctrlm_database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ using namespace std;
#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_TV_MANUFACTURER "tv_manufacturer"
#define CTRLM_DB_TV_MODEL "tv_model"
#define CTRLM_DB_AVR_MANUFACTURER "avr_manufacturer"
#define CTRLM_DB_AVR_MODEL "avr_model"

#define CTRLM_DB_TABLE_VOICE "ctrlm_voice"

Expand Down Expand Up @@ -476,7 +480,7 @@ gpointer ctrlm_db_thread(gpointer param) {
case CTRLM_DB_QUEUE_MSG_TYPE_WRITE_BLOB: {
ctrlm_db_queue_msg_write_blob_t *blob = (ctrlm_db_queue_msg_write_blob_t *)msg;
XLOGD_DEBUG("WRITE BLOB %s:%s:%u", blob->table, blob->key, blob->length);
ctrlm_print_data_hex(__FUNCTION__, blob->value, blob->length, 16);
// ctrlm_print_data_hex(__FUNCTION__, blob->value, blob->length, 16);
ctrlm_db_write_blob_(blob->table, blob->key, blob->value, blob->length);
break;
}
Expand Down Expand Up @@ -774,6 +778,70 @@ void ctrlm_db_avr_ir_code_id_read(std::string &id, unsigned char &vendor_id, std
}
}

void ctrlm_db_tv_manufacturer_write(const std::string manufacturer) {
ctrlm_db_write_blob(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_TV_MANUFACTURER, (const guchar*) manufacturer.c_str(), manufacturer.length());
}

void ctrlm_db_tv_manufacturer_read(std::string &manufacturer) {
guchar *data = NULL;
guint32 length = 0;
ctrlm_db_read_blob(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_TV_MANUFACTURER, &data, &length);
if(NULL != data) {
manufacturer.assign((char *)data, length);
ctrlm_db_free(data);
} else {
XLOGD_WARN("Failed to load tv_manufacturer from db");
}
}

void ctrlm_db_tv_model_write(const std::string model) {
ctrlm_db_write_blob(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_TV_MODEL, (const guchar*) model.c_str(), model.length());
}

void ctrlm_db_tv_model_read(std::string &model) {
guchar *data = NULL;
guint32 length = 0;
ctrlm_db_read_blob(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_TV_MODEL, &data, &length);
if(NULL != data) {
model.assign((char *)data, length);
ctrlm_db_free(data);
} else {
XLOGD_WARN("Failed to load tv_model from db");
}
}

void ctrlm_db_avr_manufacturer_write(const std::string manufacturer) {
ctrlm_db_write_blob(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_AVR_MANUFACTURER, (const guchar*) manufacturer.c_str(), manufacturer.length());
}

void ctrlm_db_avr_manufacturer_read(std::string &manufacturer) {
guchar *data = NULL;
guint32 length = 0;
ctrlm_db_read_blob(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_AVR_MANUFACTURER, &data, &length);
if(NULL != data) {
manufacturer.assign((char *)data, length);
ctrlm_db_free(data);
} else {
XLOGD_WARN("Failed to load avr_manufacturer from db");
}
}

void ctrlm_db_avr_model_write(const std::string model) {
ctrlm_db_write_blob(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_AVR_MODEL, (const guchar*) model.c_str(), model.length());
}

void ctrlm_db_avr_model_read(std::string &model) {
guchar *data = NULL;
guint32 length = 0;
ctrlm_db_read_blob(CTRLM_DB_TABLE_CTRLMGR, CTRLM_DB_AVR_MODEL, &data, &length);
if(NULL != data) {
model.assign((char *)data, length);
ctrlm_db_free(data);
} else {
XLOGD_WARN("Failed to load avr_model from db");
}
}

const char *ctrlm_db_errmsg(int rc) {
if(rc == SQLITE_ROW || rc == SQLITE_DONE) { // these are non-error result codes
return("");
Expand Down
8 changes: 8 additions & 0 deletions src/database/ctrlm_database.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ void ctrlm_db_tv_ir_code_id_write(const std::string id, unsigned char vendor_id,
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_tv_manufacturer_write(const std::string manufacturer);
void ctrlm_db_tv_manufacturer_read(std::string &manufacturer);
void ctrlm_db_tv_model_write(const std::string model);
void ctrlm_db_tv_model_read(std::string &model);
void ctrlm_db_avr_manufacturer_write(const std::string manufacturer);
void ctrlm_db_avr_manufacturer_read(std::string &manufacturer);
void ctrlm_db_avr_model_write(const std::string model);
void ctrlm_db_avr_model_read(std::string &model);
Comment on lines +84 to +91

void ctrlm_db_rf4ce_networks_list(std::vector<ctrlm_network_id_t> *network_ids);
void ctrlm_db_rf4ce_controllers_list(ctrlm_network_id_t network_id, std::vector<ctrlm_controller_id_t> *controller_ids);
Expand Down
52 changes: 49 additions & 3 deletions src/irdb/ctrlm_irdb_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,11 @@
if (g_irdb.pluginGetEntryIds) {
ret = (*g_irdb.pluginGetEntryIds)(codes, type, manufacturer, model);
}
if(ret) {
m_last_entry_id_manufacturer[type] = manufacturer;
m_last_entry_id_model[type] = model;
m_last_entry_ids[type] = codes;
}
return ret;
}

Expand Down Expand Up @@ -604,6 +609,25 @@
codes[CTRLM_IRDB_DEV_TYPE_AVR].erase( unique( codes[CTRLM_IRDB_DEV_TYPE_AVR].begin(), codes[CTRLM_IRDB_DEV_TYPE_AVR].end() ), codes[CTRLM_IRDB_DEV_TYPE_AVR].end() );
}

m_last_entry_ids.clear();
m_last_entry_id_manufacturer.clear();
m_last_entry_id_model.clear();
for(const auto &type_codes : codes) {
ctrlm_irdb_entry_id_list_t entry_ids;
entry_ids.reserve(type_codes.second.size());
for(const auto &entry : type_codes.second) {
entry_ids.push_back(entry.id);
}
m_last_entry_ids[type_codes.first] = entry_ids;

// The different auto lookup methods may return a different manufacturer and model for the same device.
// There is no way of knowing which one is correct. For now, just use the highest ranked which is the first one in the list.
if(!type_codes.second.empty()) {
m_last_entry_id_manufacturer[type_codes.first] = type_codes.second.front().manufacturer;
m_last_entry_id_model[type_codes.first] = type_codes.second.front().model;
}
}

#ifdef TELEMETRY_SUPPORT
size_t tv_count = codes.count(CTRLM_IRDB_DEV_TYPE_TV) ? codes.at(CTRLM_IRDB_DEV_TYPE_TV).size() : 0;
size_t avr_count = codes.count(CTRLM_IRDB_DEV_TYPE_AVR) ? codes.at(CTRLM_IRDB_DEV_TYPE_AVR).size() : 0;
Expand Down Expand Up @@ -636,30 +660,52 @@
bool ctrlm_irdb_interface_t::program_ir_codes(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_irdb_dev_type_t type, const std::string &id) {
std::unique_lock<std::mutex> guard(m_mutex);
bool ret = false;
std::string manufacturer;
std::string model;

XLOGD_INFO("Programming IR codes for (%u, %u) with database id <%s>", network_id, controller_id, id.c_str());

auto ids_itr = m_last_entry_ids.find(type);
if(ids_itr != m_last_entry_ids.end() && std::find(ids_itr->second.begin(), ids_itr->second.end(), id) != ids_itr->second.end()) {
Comment on lines +667 to +668
auto manufacturer_itr = m_last_entry_id_manufacturer.find(type);
auto model_itr = m_last_entry_id_model.find(type);
if(manufacturer_itr != m_last_entry_id_manufacturer.end()) {
manufacturer = manufacturer_itr->second;
}
if(model_itr != m_last_entry_id_model.end()) {
model = model_itr->second;
}
}
Comment on lines +667 to +677

XLOGD_INFO("Programming IR codes for (%u, %u) with database id <%s>, manufacturer <%s>, model <%s>",
network_id,
controller_id,
id.c_str(),
manufacturer.empty() ? "INVALID" : manufacturer.c_str(),
model.empty() ? "INVALID" : model.c_str());

ctrlm_irdb_ir_code_set_t code_set;
if (g_irdb.pluginGetCodeSet) {
if ( (*g_irdb.pluginGetCodeSet)(code_set, type, id) == false) {
XLOGD_ERROR("Failed getting IR code set");
} else {
guard.unlock();
ret = this->_program_ir_codes(network_id, controller_id, &code_set);
ret = this->_program_ir_codes(network_id, controller_id, &code_set, manufacturer, model);
}
}
return(ret);
}


bool ctrlm_irdb_interface_t::_program_ir_codes(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_irdb_ir_code_set_t *ir_codes) {
bool ctrlm_irdb_interface_t::_program_ir_codes(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_irdb_ir_code_set_t *ir_codes, const std::string &manufacturer, const std::string &model) {
bool ret = false;
vector<char> success_vec;

std::shared_ptr<ctrlm_main_queue_msg_program_ir_codes_t> msg = std::make_shared<ctrlm_main_queue_msg_program_ir_codes_t>();
msg->network_id = network_id;
msg->controller_id = controller_id;
msg->ir_codes = ir_codes;
msg->manufacturer = manufacturer;
msg->model = model;
msg->success = &success_vec;

if (false == get_vendor_info(msg->vendor_info)) {
Expand Down
7 changes: 6 additions & 1 deletion src/irdb/ctrlm_irdb_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ typedef struct {
ctrlm_network_id_t network_id;
ctrlm_controller_id_t controller_id;
ctrlm_irdb_ir_code_set_t * ir_codes;
std::string manufacturer;
std::string model;
std::vector<char> * success;
sem_t * semaphore;
ctrlm_irdb_vendor_info_t vendor_info;
Expand Down Expand Up @@ -91,14 +93,17 @@ class ctrlm_irdb_interface_t {
bool open_plugin();
bool close_plugin();

bool _program_ir_codes(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_irdb_ir_code_set_t *ir_codes);
bool _program_ir_codes(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id, ctrlm_irdb_ir_code_set_t *ir_codes, const std::string &manufacturer = "", const std::string &model = "");
bool _clear_ir_codes(ctrlm_network_id_t network_id, ctrlm_controller_id_t controller_id);

void *m_irdbPluginHandle;

ctrlm_irdb_mode_t mode;
bool m_platform_tv;
std::mutex m_mutex;
std::map<ctrlm_irdb_dev_type_t, std::string> m_last_entry_id_manufacturer;
std::map<ctrlm_irdb_dev_type_t, std::string> m_last_entry_id_model;
std::map<ctrlm_irdb_dev_type_t, ctrlm_irdb_entry_id_list_t> m_last_entry_ids;
};

#endif
Loading
Loading