yituo_video/src/mqtt_config.cpp
2025-09-08 10:59:08 +08:00

122 lines
3.4 KiB
C++

#include "mqtt_config.hpp"
MQTTConfig g_mqtt_config;
MQTTConfig MQTTConfig::load_from_file(const std::string &filepath)
{
MQTTConfig cfg;
std::ifstream ifs(filepath);
if (!ifs)
{
LOG_ERROR("[Config] Failed to open config file: " + filepath);
throw std::runtime_error("Failed to open config file: " + filepath);
}
nlohmann::json j;
ifs >> j;
cfg.device_id = j["device_id"];
cfg.vin = j["vin"];
cfg.server_ip = j["server_ip"];
cfg.server_port = j["server_port"];
cfg.client_id = j["client_id"];
cfg.username = j["username"];
cfg.password = j["password"];
cfg.qos = j["qos"];
cfg.keep_alive = j["keep_alive"];
cfg.clean_session = j["clean_session"];
const std::string &id = cfg.device_id;
cfg.topics.uplink_1 = j["topics"]["uplink_1"].get<std::string>() + id;
cfg.topics.uplink_2 = j["topics"]["uplink_2"].get<std::string>() + id;
cfg.topics.downlink = j["topics"]["downlink"].get<std::string>() + id;
cfg.ports.config_port = j["ports"]["config_port"];
cfg.ports.uplink_1_port = j["ports"]["uplink_1_port"];
cfg.ports.uplink_2_port = j["ports"]["uplink_2_port"];
cfg.ports.downlink_port = j["ports"]["downlink_port"];
LOG_INFO("[Config] Loaded config from " + filepath);
LOG_INFO(" - MQTT Server: " + cfg.server_ip + ":" + std::to_string(cfg.server_port));
LOG_INFO(" - Client ID: " + cfg.client_id);
LOG_INFO(" - Topics: " + cfg.topics.uplink_1 + ", " + cfg.topics.uplink_2 + ", " + cfg.topics.downlink);
return cfg;
}
bool MQTTConfig::update_mqtt_config(const ordered_json &new_values,
const std::string &filepath)
{
std::ifstream ifs(filepath);
if (!ifs.is_open())
{
LOG_ERROR("[ConfigEdit] Failed to open config file: " + filepath);
return false;
}
ordered_json j;
try
{
ifs >> j;
ifs.close();
}
catch (const std::exception &e)
{
LOG_ERROR(std::string("[ConfigEdit] JSON parse error: ") + e.what());
return false;
}
for (auto it = new_values.begin(); it != new_values.end(); ++it)
{
const std::string &key = it.key();
const auto &val = it.value();
if (j.contains(key))
{
LOG_INFO("[ConfigEdit] Updating key: " + key + " -> " + val.dump());
j[key] = val;
}
else
{
LOG_WARN("[ConfigEdit] Warning: key '" + key + "' not found in config, ignored.");
}
}
std::ofstream ofs(filepath);
if (!ofs.is_open())
{
LOG_ERROR("[ConfigEdit] Failed to write updated config file: " + filepath);
return false;
}
ofs << j.dump(4);
ofs.close();
return true;
}
std::string get_executable_dir()
{
char result[PATH_MAX] = {0};
ssize_t count = readlink("/proc/self/exe", result, PATH_MAX);
if (count == -1)
{
throw std::runtime_error("Failed to read /proc/self/exe");
}
std::string full_path(result, count);
auto pos = full_path.find_last_of('/');
if (pos == std::string::npos)
{
throw std::runtime_error("Failed to find executable directory");
}
return full_path.substr(0, pos);
}
std::string get_executable_dir_file_path(const std::string &filename)
{
std::string dir = get_executable_dir();
if (dir.back() != '/')
dir += '/';
return dir + filename;
}