From 9c29878bb90561c6b32e0226f730f80af6779bb5 Mon Sep 17 00:00:00 2001 From: wyc <1104749580@qq.com> Date: Tue, 14 Jul 2026 18:10:23 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B8=B8=E8=A7=84=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- module/Local_Server/Aircraft/Aircraft.h | 121 +- .../Local_Server/Data_Source/Data_Source.cpp | 1024 ++++++++--------- module/Local_Server/Data_Source/Data_Source.h | 702 +++++------ module/Local_Server/global_include.h | 609 +++++----- module/Local_Server/server/Global.cpp | 4 +- 5 files changed, 1212 insertions(+), 1248 deletions(-) diff --git a/module/Local_Server/Aircraft/Aircraft.h b/module/Local_Server/Aircraft/Aircraft.h index f22e07c..f44a45d 100644 --- a/module/Local_Server/Aircraft/Aircraft.h +++ b/module/Local_Server/Aircraft/Aircraft.h @@ -1,82 +1,73 @@ #pragma once #include - #include "../External_Database/export.h" - #include #include #include #include - #include "SSR/Aircraft_Info.h" - class Aircraft : public SSR::Aircraft_Info { public: - explicit Aircraft(std::string_view icao); - - // 静态信息按 ICAO24 加载一次;航线信息仅在 callsign 变化时重新加载。 - // map 的键是外部数据源名称。 - std::map> - external_database_info; - std::map> - callsign_external_database_info; - bool external_database_info_loaded{}; - std::optional last_external_database_callsign; - - [[nodiscard]] std::shared_ptr - external_database_row(std::string_view resource_name) const { - auto key = std::string(resource_name); - const auto callsign_iter = + explicit Aircraft(std::string_view icao); + // 静态信息按 ICAO24 加载一次;航线信息仅在 callsign 变化时重新加载。 + // map 的键是外部数据源名称。 + std::map> + external_database_info; + std::map> + callsign_external_database_info; + bool external_database_info_loaded{}; + std::optional last_external_database_callsign; + [[nodiscard]] std::shared_ptr + external_database_row(std::string_view resource_name) const { + auto key = std::string(resource_name); + const auto callsign_iter = callsign_external_database_info.find(key); - if (callsign_iter != callsign_external_database_info.end()) { - return callsign_iter->second; + if (callsign_iter != callsign_external_database_info.end()) { + return callsign_iter->second; + } + const auto iter = external_database_info.find(key); + return iter == external_database_info.end() ? nullptr : iter->second; } - const auto iter = external_database_info.find(key); - return iter == external_database_info.end() ? nullptr : iter->second; - } - - void refresh_external_database_info(); - - Psc::JSON toJson() { - refresh_external_database_info(); - Psc::JSON ret = Psc::JSON::object(); - Ret_J(icao) ret.append({"每秒位置数", get_pest()}); - ret.append({"飞机位置轨迹点数", air_pos_track_list.size()}); - ret.append({"地面位置轨迹点数", surface_pos_track_list.size()}); - ret.append({"信号强度", signal_level}); - auto opt_pos = air_pos_track_list.last(); - ret.append({"当前位置消息", opt_pos.has_value() ? opt_pos->to_json() : ""}); - - auto cpr_state_opt = BDS05_airborne_position.value; - ret.append( - {"cpr解码器状态", cpr_state_opt.has_value() - ? cpr_state_opt.value().current_state_json() - : ""}); - ret.append({"时间", Psc::utc_2_local_time(timestamp)}); - ret.append({"多点定位数据源", mlat}); - - auto external_info = Psc::JSON::object(); - for (const auto &[resource_key, row] : external_database_info) { - external_info.append({resource_key, row->to_json()}); + void refresh_external_database_info(); + Psc::JSON toJson() { + refresh_external_database_info(); + Psc::JSON ret = Psc::JSON::object(); + Ret_J(icao) + ret.append({"每秒位置数", get_pest()}); + ret.append({"飞机位置轨迹点数", air_pos_track_list.size()}); + ret.append({"地面位置轨迹点数", surface_pos_track_list.size()}); + ret.append({"信号强度", signal_level}); + auto opt_pos = air_pos_track_list.last(); + ret.append({"当前位置消息", opt_pos.has_value() ? opt_pos->to_json() : ""}); + auto cpr_state_opt = BDS05_airborne_position.value; + ret.append( + { + "cpr解码器状态", cpr_state_opt.has_value() + ? cpr_state_opt.value().current_state_json() + : "" + }); + ret.append({"时间", Psc::utc_2_local_time(timestamp)}); + ret.append({"多点定位数据源", mlat}); + auto external_info = Psc::JSON::object(); + for (const auto& [resource_key, row] : external_database_info) { + external_info.append({resource_key, row->to_json()}); + } + for (const auto& [resource_key, row] : callsign_external_database_info) { + external_info.append({resource_key, row->to_json()}); + } + ret.append({"external_database_info", external_info}); + push_all_bds_info(ret); + return ret; } - for (const auto &[resource_key, row] : callsign_external_database_info) { - external_info.append({resource_key, row->to_json()}); - } - ret.append({"external_database_info", external_info}); - - push_all_bds_info(ret); - return ret; - } - #ifdef Cache_Some_Mode_S - std::list> cache; - size_t total_num = 0; - void add_msg_limit(const std::shared_ptr &msg) { - if (cache.size() > Cache_Some_Mode_S_Num) { - cache.pop_front(); + std::list> cache; + size_t total_num = 0; + void add_msg_limit(const std::shared_ptr& msg) { + if (cache.size() > Cache_Some_Mode_S_Num) { + cache.pop_front(); + } + cache.emplace_back(msg); + total_num++; } - cache.emplace_back(msg); - total_num++; - } #endif }; diff --git a/module/Local_Server/Data_Source/Data_Source.cpp b/module/Local_Server/Data_Source/Data_Source.cpp index da847d7..a3bda50 100644 --- a/module/Local_Server/Data_Source/Data_Source.cpp +++ b/module/Local_Server/Data_Source/Data_Source.cpp @@ -3,567 +3,559 @@ #include "../server/Global.h" #include "Database.h" #include - -Psc::serial::Serial *create_serial(std::string_view serial_name, +Psc::serial::Serial* create_serial(std::string_view serial_name, Baud_Rate_Type baud_rate) { - auto serial = new Psc::serial::Serial; - serial->set_serial_name(serial_name); - serial->set_baud_rate(baud_rate); - serial->set_parity(Psc::serial::Parity::NoParity); - serial->set_data_bits(Psc::serial::DataBits::Data8); - serial->set_stop_bits(Psc::serial::StopBits::OneStop); - serial->set_flow_control(Psc::serial::FlowControl::HardwareControl); - serial->set_buffer_byte_size(10 * 1024); - if (!serial->open()) { - std::cerr << "createSerial " + std::string(serial_name) + ":" + - std::to_string(baud_rate) + " 打开串口失败!\n"; - Psc::fail_fast(); - return nullptr; - } else { - // std::cerr << "createSerial " + serial_name + ":" + - // std::to_string(baud_rate) + " 打开串口成功!\n"; - } - return serial; + auto serial = new Psc::serial::Serial; + serial->set_serial_name(serial_name); + serial->set_baud_rate(baud_rate); + serial->set_parity(Psc::serial::Parity::NoParity); + serial->set_data_bits(Psc::serial::DataBits::Data8); + serial->set_stop_bits(Psc::serial::StopBits::OneStop); + serial->set_flow_control(Psc::serial::FlowControl::HardwareControl); + serial->set_buffer_byte_size(10 * 1024); + if (!serial->open()) { + std::cerr << "createSerial " + std::string(serial_name) + ":" + + std::to_string(baud_rate) + " 打开串口失败!\n"; + Psc::fail_fast(); + return nullptr; + } + else { + // std::cerr << "createSerial " + serial_name + ":" + + // std::to_string(baud_rate) + " 打开串口成功!\n"; + } + return serial; } - -std::shared_ptr create_from_json(const JSON *that_json) { - std::string type = that_json->get_string("type"); - std::shared_ptr ret = create_data_source_from_type(type); - ret->from_json(that_json); - // if (ret->enable) - // { - // ret->open(); - // } - return ret; +std::shared_ptr create_from_json(const JSON* that_json) { + std::string type = that_json->get_string("type"); + std::shared_ptr ret = create_data_source_from_type(type); + ret->from_json(that_json); + // if (ret->enable) + // { + // ret->open(); + // } + return ret; } - std::shared_ptr Data_Source::that() { - return shared_from_this(); + return shared_from_this(); } - bool Data_Source::registered() const { - auto all_source = Global::instance()->mode_acs.data_source_config.map.list(); - for (auto &item: all_source) { - if (item.get() == this) { - return true; - } - } - return false; + auto all_source = Global::instance()->mode_acs.data_source_config.map.list(); + for (auto& item : all_source) { + if (item.get() == this) { + return true; + } + } + return false; } - Psc::JSON Data_Source::get_state() { - Psc::JSON ret = Psc::JSON::object(); - ret.append_list(get_custom_state_json().children); - ret.append({"ds: read_speed(byte)", read_speed}); - ret.append({"ds: value_statistics(byte)", value_statistics}); - return ret; + Psc::JSON ret = Psc::JSON::object(); + ret.append({"state", Psc::to_string(state)}); + ret.append_list(get_custom_state_json().children); + ret.append({"ds: read_speed(byte)", read_speed}); + ret.append({"ds: value_statistics(byte)", value_statistics}); + return ret; } - Data_Source::Data_Source() { - // parse_format = std::make_shared(); - // 写入到配置文件是懒加载 其他保存时他跟着保存 - base_station.handle_when_updated = [this](SSR::HULC_Status_Message msg) { - if (this->update_form_gps) { - lat = msg.get_latitude(); - lon = msg.get_longitude(); - alt = msg.Alt; - } - }; + // parse_format = std::make_shared(); + // 写入到配置文件是懒加载 其他保存时他跟着保存 + base_station.handle_when_updated = [this](SSR::HULC_Status_Message msg) { + if (this->update_form_gps) { + lat = msg.get_latitude(); + lon = msg.get_longitude(); + alt = msg.Alt; + } + }; } - std::string Data_Source::thread_key() const { - // return "Data_Source_Handle_Thread:[" + key + "]"; - return key + "_DS_HT"; + // return "Data_Source_Handle_Thread:[" + key + "]"; + return key + "_DS_HT"; } - -void File_Data_Source::before_handle_msg(std::shared_ptr &msg) { - auto cur = std::dynamic_pointer_cast(msg); - if (cur != nullptr) { - auto &pre = last_prase_msg; - if (!pre) { - pre = cur; - return; - } - cur->day_num = pre->day_num; - if (cur->time() < pre->time()) { - ++cur->day_num; - } - } +void File_Data_Source::before_handle_msg(std::shared_ptr& msg) { + auto cur = std::dynamic_pointer_cast(msg); + if (cur != nullptr) { + auto& pre = last_prase_msg; + if (!pre) { + pre = cur; + return; + } + cur->day_num = pre->day_num; + if (cur->time() < pre->time()) { + ++cur->day_num; + } + } } - std::vector readLines(std::string_view path) { - std::vector lines; - auto path_string = std::string(path); - std::filesystem::path p = - std::filesystem::path((const char8_t *) path_string.c_str()); - // std::filesystem::path p = std::filesystem::u8path(path); - std::ifstream istream(p); - if (!istream) { - std::cerr << "读取模拟数据源 readLines 无法打开文件:" << path_string << std::endl; - Psc::fail_fast(); - } - // 将整个文件读入一个字符串 - std::stringstream stream; - stream << istream.rdbuf(); - // 使用 stringstream 按行分割内容 - std::string line; - char ch; - while (stream.get(ch)) { - if (ch == ' ') { - continue; - } - if (ch == '\r' || ch == '\n') { - if (!line.empty()) { - lines.push_back(line); - line.clear(); - } - // if (ch == '\r') { - // stream.get(); // 吃掉 \n - // } - // if (ch == '\n') { - // stream.get(); // 吃掉 \n - // } - // 处理 \r\n 组合:如果当前是 \r,下一个是 \n,跳过它 - // if (ch == '\r' && stream.peek() == '\n') { - // stream.get(); // 吃掉 \n - // } - } else { - line += ch; - } - if (line.size() == 1000) { - lines.push_back(line); - line.clear(); - } - } - // 最后一行如果没有换行符也处理一下 - if (!line.empty()) { - lines.push_back(line); - } - std::ostringstream oss; - oss << path_string + " 总行数:" + std::to_string(lines.size()) + " 有效行数:" + - std::to_string(lines.size()) + "\n" - << std::flush; - std::cout << oss.str() << std::flush; - return lines; + std::vector lines; + auto path_string = std::string(path); + std::filesystem::path p = + std::filesystem::path((const char8_t*)path_string.c_str()); + // std::filesystem::path p = std::filesystem::u8path(path); + std::ifstream istream(p); + if (!istream) { + std::cerr << "读取模拟数据源 readLines 无法打开文件:" << path_string << std::endl; + Psc::fail_fast(); + } + // 将整个文件读入一个字符串 + std::stringstream stream; + stream << istream.rdbuf(); + // 使用 stringstream 按行分割内容 + std::string line; + char ch; + while (stream.get(ch)) { + if (ch == ' ') { + continue; + } + if (ch == '\r' || ch == '\n') { + if (!line.empty()) { + lines.push_back(line); + line.clear(); + } + // if (ch == '\r') { + // stream.get(); // 吃掉 \n + // } + // if (ch == '\n') { + // stream.get(); // 吃掉 \n + // } + // 处理 \r\n 组合:如果当前是 \r,下一个是 \n,跳过它 + // if (ch == '\r' && stream.peek() == '\n') { + // stream.get(); // 吃掉 \n + // } + } + else { + line += ch; + } + if (line.size() == 1000) { + lines.push_back(line); + line.clear(); + } + } + // 最后一行如果没有换行符也处理一下 + if (!line.empty()) { + lines.push_back(line); + } + std::ostringstream oss; + oss << path_string + " 总行数:" + std::to_string(lines.size()) + " 有效行数:" + + std::to_string(lines.size()) + "\n" + << std::flush; + std::cout << oss.str() << std::flush; + return lines; } - std::string extractID(std::string_view logLine) { - size_t lastSpacePos = logLine.rfind(" "); // 查找最后一个空格 - if (lastSpacePos != std::string::npos) { - return std::string(logLine.substr(lastSpacePos + 1)); // 从最后一个空格之后提取字符串 - } - return std::string(logLine); + size_t lastSpacePos = logLine.rfind(" "); // 查找最后一个空格 + if (lastSpacePos != std::string::npos) { + return std::string(logLine.substr(lastSpacePos + 1)); // 从最后一个空格之后提取字符串 + } + return std::string(logLine); } - time_t convert_to_timestamp(std::string_view str) { - // 创建一个结构体 tm 来存储解析后的时间 - std::tm timeStruct = {}; - std::istringstream ss{std::string(str)}; - ss >> std::get_time(&timeStruct, "%Y-%m-%d %H:%M:%S"); - if (ss.fail()) { - std::cerr << "Failed to parse time" << std::endl; - return -1; // 如果解析失败,返回 -1 - } - // 将 tm 转换为 time_t(时间戳) - time_t timestamp = std::mktime(&timeStruct); - if (timestamp == -1) { - std::cerr << "Failed to convert to time_t" << std::endl; - return -1; // 如果转换失败,返回 -1 - } - return timestamp; + // 创建一个结构体 tm 来存储解析后的时间 + std::tm timeStruct = {}; + std::istringstream ss{std::string(str)}; + ss >> std::get_time(&timeStruct, "%Y-%m-%d %H:%M:%S"); + if (ss.fail()) { + std::cerr << "Failed to parse time" << std::endl; + return -1; // 如果解析失败,返回 -1 + } + // 将 tm 转换为 time_t(时间戳) + time_t timestamp = std::mktime(&timeStruct); + if (timestamp == -1) { + std::cerr << "Failed to convert to time_t" << std::endl; + return -1; // 如果转换失败,返回 -1 + } + return timestamp; } - std::tuple extractID2(std::string_view logLine) { - size_t lastSpacePos = logLine.rfind(" "); // 查找最后一个空格 - time_t t = convert_to_timestamp(logLine.substr(0, 19)); - if (lastSpacePos != std::string::npos) { - return { - std::string(logLine.substr(lastSpacePos + 1)), - t - }; // 从最后一个空格之后提取字符串 - } - return {std::string(logLine), t}; + size_t lastSpacePos = logLine.rfind(" "); // 查找最后一个空格 + time_t t = convert_to_timestamp(logLine.substr(0, 19)); + if (lastSpacePos != std::string::npos) { + return { + std::string(logLine.substr(lastSpacePos + 1)), + t + }; // 从最后一个空格之后提取字符串 + } + return {std::string(logLine), t}; } - std::string bin_format(std::string_view hex, time_t t) { - std::tm *currentTime = std::localtime(&t); - auto sec = currentTime->tm_hour * 3600 + currentTime->tm_min * 60 + - currentTime->tm_sec; - SSR::MLAT_timestamp a(sec, 0); - return create_Binary_Format_memory(hex, 0, &a); + std::tm* currentTime = std::localtime(&t); + auto sec = currentTime->tm_hour * 3600 + currentTime->tm_min * 60 + + currentTime->tm_sec; + SSR::MLAT_timestamp a(sec, 0); + return create_Binary_Format_memory(hex, 0, &a); } - -std::optional File_Data_Source::get_raw_line(int &ret_index) { - if (index == 0 && part_infos.empty()) { - ret_index = -1; - return std::nullopt; - } - std::optional log_info = std::nullopt; - if (index == part_infos.size()) { - if (play_mode == Play_Mode::loop) { - index = 0; - } else { - if (!have_report_play_back_all_success) { - std::ostringstream oss; - oss << SSR::get_current_date() << " " << SSR::get_current_time() - << " [进程:" << std::this_thread::get_id() << "] " - << file_path + " 全部加载成功!\n" - << std::flush; - std::cout << oss.str() << std::flush; - have_report_play_back_all_success = true; - } - ret_index = -1; - return std::nullopt; - } - } - ret_index = index + 1; - return part_infos[index++]; +std::optional File_Data_Source::get_raw_line(int& ret_index) { + if (index == 0 && part_infos.empty()) { + ret_index = -1; + return std::nullopt; + } + std::optional log_info = std::nullopt; + if (index == part_infos.size()) { + if (play_mode == Play_Mode::loop) { + index = 0; + } + else { + if (!have_report_play_back_all_success) { + std::ostringstream oss; + oss << SSR::get_current_date() << " " << SSR::get_current_time() + << " [进程:" << std::this_thread::get_id() << "] " + << file_path + " 全部加载成功!\n" + << std::flush; + std::cout << oss.str() << std::flush; + have_report_play_back_all_success = true; + } + ret_index = -1; + return std::nullopt; + } + } + ret_index = index + 1; + return part_infos[index++]; } - // 1A 33 1A 1A F1 FB 87 73 7E 7F a8001d81a87543b0a80000 -std::string get_true_from_raw_line(Data_Source *ds, File_Data_Type data_type, +std::string get_true_from_raw_line(Data_Source* ds, File_Data_Type data_type, int index, std::string_view log_info) { - std::string ret; - // 2025-01-06 07:20:17 [info] dc2541e65001401a3119b2dd1c7af67132201 - if (data_type == File_Data_Type::BIN) { - return std::string(log_info); - } else if (data_type == File_Data_Type::BIN_Text) { - auto info = extractID(log_info); - ret = hex2mem(info); - } else if (data_type == File_Data_Type::AVR) { - auto [info, time] = extractID2(log_info); - ret = bin_format(info, time); - } - // 1A 33 10 01 A5 31 FB 9A 5D 8D 78 0E 47 99 08 8E 32 B0 08 BE E9 8A E6 1A 32 - // 10 01 AA 14 61 7E 5E 02 E6 0F 38 7D 87 08 1A 32 10 01 AD B5 64 F7 63 5D 78 - // 0F 9D BA 93 BA - else if (data_type == File_Data_Type::BIN_Blank_Text) { - std::string info(log_info); - std::string result = ds->last_char; - ds->last_char = ""; - for (char c: info) { - if (std::isxdigit(c)) { - // 会判断字符 c 是否是十六进制数字字符 - result += c; - } else if (std::isspace(c)) { - // - } else { - std::ostringstream oss; - oss << "存在非法字符[" << c << "]: value:" << (int) c << " in:" - << log_info << LOG_POS; - server_logger->c_debug("非法字符:", {}, oss.str()); - return ""; - } - } - auto size = result.size(); - if (size % 2 != 0) { - // 保存最后一个字符 - ds->last_char = result.empty() ? "" : std::string(1, result.back()); - result.pop_back(); - } - ret = hex2mem(result); - } else if (data_type == File_Data_Type::BIN_Blank_One_Line_With_Escape) { - auto size = log_info.size(); - if (size % 2 != 0) { - return hex2mem(std::string(log_info.substr(0, size - 1))); - } - return hex2mem(std::string(log_info)); - } else if (data_type == File_Data_Type::BIN_Blank_One_Line_No_Escape) { - auto size = log_info.size(); - std::string data; - if (size % 2 != 0) { - data = std::string(log_info.substr(0, size - 1)); - } else { - data = std::string(log_info); - } - return SSR::packet_to_escape_format(hex2mem(data)); - } else if (data_type == File_Data_Type::SIMPLE_BIN_Blank) { - std::string info(log_info); - std::string result; - for (char c: info) { - if (c != ' ') { - result += c; - } - } - // 1 + 1 + 6 + 1 + 2/7/14 - // 1a + type time_stamp signal_level data - int size = result.size(); - if (size != 2 * 2 && size != 7 * 2 && size != 14 * 2) { - std::cout << "line_offset:[" << index << "] " << "大小" << size - << " 不为偶数,或不为2,7,14 不能转换成二进制格式:" << result - << std::endl; - return ""; - } - std::string head("\x1a"); - std::string type; - std::string time_stamp = "\x11\x22\x33\x44\x55\x66"; - std::string signal_level("\xFF"); - if (size == 2 * 2) { - type = R"(1)"; - } else if (size == 7 * 2) { - type = R"(2)"; - } else if (size == 14 * 2) { - type = R"(3)"; - } - ret = SSR::packet_to_escape_format(head + type + time_stamp + signal_level + - hex2mem(result)); - // std::cout << ret.size() << std::endl; - } else { - std::cout << "未知的回放类型 " << static_cast(data_type) << std::endl; - Psc::fail_fast(); - } - return ret; + std::string ret; + // 2025-01-06 07:20:17 [info] dc2541e65001401a3119b2dd1c7af67132201 + if (data_type == File_Data_Type::BIN) { + return std::string(log_info); + } + else if (data_type == File_Data_Type::BIN_Text) { + auto info = extractID(log_info); + ret = hex2mem(info); + } + else if (data_type == File_Data_Type::AVR) { + auto [info, time] = extractID2(log_info); + ret = bin_format(info, time); + } + // 1A 33 10 01 A5 31 FB 9A 5D 8D 78 0E 47 99 08 8E 32 B0 08 BE E9 8A E6 1A 32 + // 10 01 AA 14 61 7E 5E 02 E6 0F 38 7D 87 08 1A 32 10 01 AD B5 64 F7 63 5D 78 + // 0F 9D BA 93 BA + else if (data_type == File_Data_Type::BIN_Blank_Text) { + std::string info(log_info); + std::string result = ds->last_char; + ds->last_char = ""; + for (char c : info) { + if (std::isxdigit(c)) { + // 会判断字符 c 是否是十六进制数字字符 + result += c; + } + else if (std::isspace(c)) { + // + } + else { + std::ostringstream oss; + oss << "存在非法字符[" << c << "]: value:" << (int)c << " in:" + << log_info << LOG_POS; + server_logger->c_debug("非法字符:", {}, oss.str()); + return ""; + } + } + auto size = result.size(); + if (size % 2 != 0) { + // 保存最后一个字符 + ds->last_char = result.empty() ? "" : std::string(1, result.back()); + result.pop_back(); + } + ret = hex2mem(result); + } + else if (data_type == File_Data_Type::BIN_Blank_One_Line_With_Escape) { + auto size = log_info.size(); + if (size % 2 != 0) { + return hex2mem(std::string(log_info.substr(0, size - 1))); + } + return hex2mem(std::string(log_info)); + } + else if (data_type == File_Data_Type::BIN_Blank_One_Line_No_Escape) { + auto size = log_info.size(); + std::string data; + if (size % 2 != 0) { + data = std::string(log_info.substr(0, size - 1)); + } + else { + data = std::string(log_info); + } + return SSR::packet_to_escape_format(hex2mem(data)); + } + else if (data_type == File_Data_Type::SIMPLE_BIN_Blank) { + std::string info(log_info); + std::string result; + for (char c : info) { + if (c != ' ') { + result += c; + } + } + // 1 + 1 + 6 + 1 + 2/7/14 + // 1a + type time_stamp signal_level data + int size = result.size(); + if (size != 2 * 2 && size != 7 * 2 && size != 14 * 2) { + std::cout << "line_offset:[" << index << "] " << "大小" << size + << " 不为偶数,或不为2,7,14 不能转换成二进制格式:" << result + << std::endl; + return ""; + } + std::string head("\x1a"); + std::string type; + std::string time_stamp = "\x11\x22\x33\x44\x55\x66"; + std::string signal_level("\xFF"); + if (size == 2 * 2) { + type = R"(1)"; + } + else if (size == 7 * 2) { + type = R"(2)"; + } + else if (size == 14 * 2) { + type = R"(3)"; + } + ret = SSR::packet_to_escape_format(head + type + time_stamp + signal_level + + hex2mem(result)); + // std::cout << ret.size() << std::endl; + } + else { + std::cout << "未知的回放类型 " << static_cast(data_type) << std::endl; + Psc::fail_fast(); + } + return ret; } - asio::awaitable File_Data_Source::_close() { - std::lock_guard g(mtx); - index = 0; - part_infos.clear(); - co_return; + std::lock_guard g(mtx); + index = 0; + part_infos.clear(); + co_return; } - asio::awaitable File_Data_Source::_open() { - std::lock_guard g(mtx); - auto path = get_true_file_path(); - namespace fs = std::filesystem; - if (!fs::exists(path)) { - state = "文件不存在"; - co_return; - } - if (data_type == File_Data_Type::BIN) { - part_infos = readBinaryFileAsString(path, 1000); - } else { - part_infos = readLines(path); - } - state = "已加载" + to_string(part_infos.size()) + "长度数据!"; - co_return; + std::lock_guard g(mtx); + auto path = get_true_file_path(); + namespace fs = std::filesystem; + if (!fs::exists(path)) { + state = "文件不存在"; + co_return; + } + if (data_type == File_Data_Type::BIN) { + part_infos = readBinaryFileAsString(path, 1000); + } + else { + part_infos = readLines(path); + } + state = "已加载" + to_string(part_infos.size()) + "长度数据!"; + co_return; } - std::vector File_Data_Source::readBinaryFileAsString(std::string_view filepath, size_t part_size) { - // 打开文件(以二进制模式) - std::ifstream file(filepath.data(), std::ios::binary); - if (!file) { - std::cerr << "无法打开文件: " << filepath << std::endl; - return {}; // 文件打开失败,返回空vector - } - // 获取文件大小 - file.seekg(0, std::ios::end); - size_t fileSize = file.tellg(); - file.seekg(0, std::ios::beg); - // 存储读取的部分 - std::vector parts; - // 读取文件的每一部分 - size_t bytesRead = 0; - while (bytesRead < fileSize) { - // 计算每个部分的长度(最后一部分可能小于part_size) - size_t remaining = fileSize - bytesRead; - size_t currentPartSize = (remaining < part_size) ? remaining : part_size; - // 创建buffer来存储当前部分 - std::string buffer(currentPartSize, '\0'); - // 读取当前部分 - file.read(&buffer[0], currentPartSize); - // 将读取的部分添加到vector - parts.push_back(std::move(buffer)); - // 更新已读取字节数 - bytesRead += currentPartSize; - } - // 关闭文件 - file.close(); - return parts; + // 打开文件(以二进制模式) + std::ifstream file(filepath.data(), std::ios::binary); + if (!file) { + std::cerr << "无法打开文件: " << filepath << std::endl; + return {}; // 文件打开失败,返回空vector + } + // 获取文件大小 + file.seekg(0, std::ios::end); + size_t fileSize = file.tellg(); + file.seekg(0, std::ios::beg); + // 存储读取的部分 + std::vector parts; + // 读取文件的每一部分 + size_t bytesRead = 0; + while (bytesRead < fileSize) { + // 计算每个部分的长度(最后一部分可能小于part_size) + size_t remaining = fileSize - bytesRead; + size_t currentPartSize = (remaining < part_size) ? remaining : part_size; + // 创建buffer来存储当前部分 + std::string buffer(currentPartSize, '\0'); + // 读取当前部分 + file.read(&buffer[0], currentPartSize); + // 将读取的部分添加到vector + parts.push_back(std::move(buffer)); + // 更新已读取字节数 + bytesRead += currentPartSize; + } + // 关闭文件 + file.close(); + return parts; } - -void File_Data_Source::origin_data_transform_mode_data(std::string &mode_data) { - std::lock_guard g(mtx); - assert(mode_data.size() == 0); - int ret_index = 0; - if (play_mode != Play_Mode::analysis) { - std::optional log_info = get_raw_line(ret_index); - mode_data = log_info.has_value() - ? get_true_from_raw_line(this, data_type, ret_index, - log_info.value()) - : ""; - } else { - int num = 0; - std::string ret; - std::optional log_info = get_raw_line(ret_index); - while (log_info.has_value()) { - num++; - auto data = log_info.value(); - auto cur = get_true_from_raw_line(this, data_type, ret_index, data); - ret += cur; - // 一定要在这个位置,否则会导致遗漏报文 - if (num == 1000) { - break; - } - log_info = get_raw_line(ret_index); - } - // std::cout << "size == " << t.size() << std::endl; - mode_data = ret; - } +void File_Data_Source::origin_data_transform_mode_data(std::string& mode_data) { + std::lock_guard g(mtx); + assert(mode_data.size() == 0); + int ret_index = 0; + if (play_mode != Play_Mode::analysis) { + std::optional log_info = get_raw_line(ret_index); + mode_data = log_info.has_value() + ? get_true_from_raw_line(this, data_type, ret_index, + log_info.value()) + : ""; + } + else { + int num = 0; + std::string ret; + std::optional log_info = get_raw_line(ret_index); + while (log_info.has_value()) { + num++; + auto data = log_info.value(); + auto cur = get_true_from_raw_line(this, data_type, ret_index, data); + ret += cur; + // 一定要在这个位置,否则会导致遗漏报文 + if (num == 1000) { + break; + } + log_info = get_raw_line(ret_index); + } + // std::cout << "size == " << t.size() << std::endl; + mode_data = ret; + } } - void File_Data_Source::handle_mode_s(std::shared_ptr msg) { - if (!msg) return; - cache_list.push_back(std::make_shared(std::move(msg))); - if (cache_list.empty()) return; - if (pre_cache == nullptr) { - pre_cache = cache_list.front(); - cache_list.pop_front(); - SSR::Play_Back_Time_Point &start = player_clock.start_time; - start.day_num = pre_cache->day_num; - start.day_sec = pre_cache->msg->mlat_timestamp.daysec; - } - auto sys_time = player_clock.get_cur_time_point(); - while (true) { - if (cache_list.empty()) break; - auto pre = pre_cache; - auto cur = cache_list.front(); - cur->day_num = pre->day_num; - if (cur->time() < pre->time()) { - cur->day_num++; - } - cache_list.pop_front(); - pre_cache = cur; - Data_Source::handle_mode_s(cur->msg); - if (cur->time() > sys_time) { - break; - } - } + if (!msg) return; + cache_list.push_back(std::make_shared(std::move(msg))); + if (cache_list.empty()) return; + if (pre_cache == nullptr) { + pre_cache = cache_list.front(); + cache_list.pop_front(); + SSR::Play_Back_Time_Point& start = player_clock.start_time; + start.day_num = pre_cache->day_num; + start.day_sec = pre_cache->msg->mlat_timestamp.daysec; + } + auto sys_time = player_clock.get_cur_time_point(); + while (true) { + if (cache_list.empty()) break; + auto pre = pre_cache; + auto cur = cache_list.front(); + cur->day_num = pre->day_num; + if (cur->time() < pre->time()) { + cur->day_num++; + } + cache_list.pop_front(); + pre_cache = cur; + Data_Source::handle_mode_s(cur->msg); + if (cur->time() > sys_time) { + break; + } + } } - -void Dll_Data_Source::origin_data_transform_mode_data(std::string &mode_data) { - auto start = std::chrono::steady_clock::now(); - if (read_func_ptr == nullptr) return; - auto buf = reinterpret_cast(buffer.data()); - auto len = read_func_ptr(buf, buffer_size); - vs.update(len); - std::string data(buf, len); - if (data.empty()) { - auto end = std::chrono::steady_clock::now(); - auto cost = - std::chrono::duration_cast(end - start) - .count(); - // std::cout << "Dll_Data_Source::read cost: " << cost << " us\n"; - return; - } - auto ret = get_true_from_raw_line(this, data_type, -1, data); - auto end = std::chrono::steady_clock::now(); - auto cost = std::chrono::duration_cast(end - start) - .count(); - // std::cout << "Dll_Data_Source::read cost: " << cost << " us\n"; - mode_data = ret; +void Dll_Data_Source::origin_data_transform_mode_data(std::string& mode_data) { + auto start = std::chrono::steady_clock::now(); + if (read_func_ptr == nullptr) return; + auto buf = reinterpret_cast(buffer.data()); + auto len = read_func_ptr(buf, buffer_size); + vs.update(len); + std::string data(buf, len); + if (data.empty()) { + auto end = std::chrono::steady_clock::now(); + auto cost = + std::chrono::duration_cast(end - start) + .count(); + // std::cout << "Dll_Data_Source::read cost: " << cost << " us\n"; + return; + } + auto ret = get_true_from_raw_line(this, data_type, -1, data); + auto end = std::chrono::steady_clock::now(); + auto cost = std::chrono::duration_cast(end - start) + .count(); + // std::cout << "Dll_Data_Source::read cost: " << cost << " us\n"; + mode_data = ret; } - asio::awaitable Shared_Memory_Data_Source::_open() { - sm = std::make_unique(); - sm->init(shared_memory_name, shared_memory_size); - co_return; + sm = std::make_unique(); + sm->init(shared_memory_name, shared_memory_size); + co_return; } - asio::awaitable Shared_Memory_Data_Source::_close() { - sm.reset(); - co_return; + sm.reset(); + co_return; } - void Shared_Memory_Data_Source::origin_data_transform_mode_data( - std::string &mode_data) { - auto size = sm->shm.size(); - size_t length = size; - std::string data; - data.resize(size); - bool ok = sm->read((uint8_t *) data.data(), length); - if (!ok) { - mode_data = ""; - } - if (length != size) { - data.resize(length); - } - if (Global::instance()->console_config.mode_s_console) { - std::cout << "read:" << data << std::endl; - } - auto ret = get_true_from_raw_line(this, data_type, -1, data); - mode_data = ret; + std::string& mode_data) { + auto size = sm->shm.size(); + size_t length = size; + std::string data; + data.resize(size); + bool ok = sm->read((uint8_t*)data.data(), length); + if (!ok) { + mode_data = ""; + } + if (length != size) { + data.resize(length); + } + if (Global::instance()->console_config.mode_s_console) { + std::cout << "read:" << data << std::endl; + } + auto ret = get_true_from_raw_line(this, data_type, -1, data); + mode_data = ret; } - -void Data_Source_Config::server(Global *g) { - auto &svr = g->svr; - auto &api = g->api; - std::string name = "data_source"; - // 返回所有 JSON 数据的 API - svr.Post(api + "get_data_source_connect", [this](HTTP_Param) { - CHECK_JSON_PARAM - HTTP_REQUIRE_VALUE(key, params.try_get_string("key")) - auto t = map.get(key); - JSON ret{nullptr}; - if (t.has_value()) { - ret = t.value()->get_all_connect_feed(); - } - res->setBody(warp(ret).to_json_string()); - }); - svr.Post(api + "get_data_source_state", [this](HTTP_Param) { - CHECK_JSON_PARAM - HTTP_REQUIRE_VALUE(key, params.try_get_string("key")) - auto t = map.get(key); - JSON ret{nullptr}; - if (t.has_value()) { - ret = t.value()->get_state(); - } - res->setBody(warp(ret).to_json_string()); - }); - svr.Post(api + "get_mode_s_data_source_config", [this](HTTP_Param) { - res->setBody(warp(to_json()).to_json_string()); - }); - svr.Post(api + svr.update + name, [this, g](HTTP_Param) { - CHECK_JSON_PARAM - HTTP_REQUIRE_VALUE(key, params.try_get_string("key")) - HTTP_REQUIRE_VALUE(ds, map.get(key)) - ds->from_json(¶ms); - g->save(); - g->mode_acs.source_feed_relation_config.set_need_refresh(); - }); - svr.Post(api + svr.insert + name, [g, this](HTTP_Param) { - CHECK_JSON_PARAM - HTTP_REQUIRE_VALUE(index, params.try_get_number("index")) - HTTP_REQUIRE_PTR(data, params.get("data")) - HTTP_REQUIRE_VALUE(t, data->try_get_string("type")) - std::cout << params.to_json_string() << std::endl; - std::shared_ptr ds = create_data_source_from_type(t); - ds->from_json(data); - HTTP_REQUIRE_VALUE(enable, data->try_get_bool("enable")) - (void) enable; - HTTP_REQUIRE_TRUE(map.insert(index, ds), "index") - // std::cout << params.to_json_string() << std::endl; - g->mode_acs.source_feed_relation_config.set_need_refresh(); - Config::save(); - res->setBody(warp(to_json()).to_json_string()); - }); - svr.Post(api + svr.remove + name, [g, this](HTTP_Param) { - CHECK_JSON_PARAM - HTTP_REQUIRE_VALUE(index, params.try_get_number("index")) - HTTP_REQUIRE_VALUE(ds, map.try_get(index)) - ds->async_stop(); - HTTP_REQUIRE_TRUE(map.remove(index), "index") - g->save(); - res->setBody(warp(to_json()).to_json_string()); - g->mode_acs.source_feed_relation_config.set_need_refresh(); - }); - svr.Post(api + svr.rise + name, [g, this](HTTP_Param) { - CHECK_JSON_PARAM - HTTP_REQUIRE_VALUE(index, params.try_get_number("index")) - HTTP_REQUIRE_TRUE(map.swap(index, index - 1), "index") - g->save(); - res->setBody(warp(to_json()).to_json_string()); - g->mode_acs.source_feed_relation_config.set_need_refresh(); - }); - svr.Post(api + svr.fall + name, [g, this](HTTP_Param) { - CHECK_JSON_PARAM - HTTP_REQUIRE_VALUE(index, params.try_get_number("index")) - HTTP_REQUIRE_TRUE(map.swap(index, index + 1), "index") - g->save(); - res->setBody(warp(to_json()).to_json_string()); - g->mode_acs.source_feed_relation_config.set_need_refresh(); - }); +void Data_Source_Config::server(Global* g) { + auto& svr = g->svr; + auto& api = g->api; + std::string name = "data_source"; + // 返回所有 JSON 数据的 API + svr.Post(api + "get_data_source_connect", [this](HTTP_Param) { + CHECK_JSON_PARAM + HTTP_REQUIRE_VALUE(key, params.try_get_string("key")) + auto t = map.get(key); + JSON ret{nullptr}; + if (t.has_value()) { + ret = t.value()->get_all_connect_feed(); + } + res->setBody(warp(ret).to_json_string()); + }); + svr.Post(api + "get_data_source_state", [this](HTTP_Param) { + CHECK_JSON_PARAM + HTTP_REQUIRE_VALUE(key, params.try_get_string("key")) + auto t = map.get(key); + JSON ret{nullptr}; + if (t.has_value()) { + ret = t.value()->get_state(); + } + res->setBody(warp(ret).to_json_string()); + }); + svr.Post(api + "get_mode_s_data_source_config", [this](HTTP_Param) { + res->setBody(warp(to_json()).to_json_string()); + }); + svr.Post(api + svr.update + name, [this, g](HTTP_Param) { + CHECK_JSON_PARAM + HTTP_REQUIRE_VALUE(key, params.try_get_string("key")) + HTTP_REQUIRE_VALUE(ds, map.get(key)) + ds->from_json(¶ms); + g->save(); + g->mode_acs.source_feed_relation_config.set_need_refresh(); + }); + svr.Post(api + svr.insert + name, [g, this](HTTP_Param) { + CHECK_JSON_PARAM + HTTP_REQUIRE_VALUE(index, params.try_get_number("index")) + HTTP_REQUIRE_PTR(data, params.get("data")) + HTTP_REQUIRE_VALUE(t, data->try_get_string("type")) + std::cout << params.to_json_string() << std::endl; + std::shared_ptr ds = create_data_source_from_type(t); + ds->from_json(data); + HTTP_REQUIRE_VALUE(enable, data->try_get_bool("enable")) + (void)enable; + HTTP_REQUIRE_TRUE(map.insert(index, ds), "index") + // std::cout << params.to_json_string() << std::endl; + g->mode_acs.source_feed_relation_config.set_need_refresh(); + Config::save(); + res->setBody(warp(to_json()).to_json_string()); + }); + svr.Post(api + svr.remove + name, [g, this](HTTP_Param) { + CHECK_JSON_PARAM + HTTP_REQUIRE_VALUE(index, params.try_get_number("index")) + HTTP_REQUIRE_VALUE(ds, map.try_get(index)) + ds->async_stop(); + HTTP_REQUIRE_TRUE(map.remove(index), "index") + g->save(); + res->setBody(warp(to_json()).to_json_string()); + g->mode_acs.source_feed_relation_config.set_need_refresh(); + }); + svr.Post(api + svr.rise + name, [g, this](HTTP_Param) { + CHECK_JSON_PARAM + HTTP_REQUIRE_VALUE(index, params.try_get_number("index")) + HTTP_REQUIRE_TRUE(map.swap(index, index - 1), "index") + g->save(); + res->setBody(warp(to_json()).to_json_string()); + g->mode_acs.source_feed_relation_config.set_need_refresh(); + }); + svr.Post(api + svr.fall + name, [g, this](HTTP_Param) { + CHECK_JSON_PARAM + HTTP_REQUIRE_VALUE(index, params.try_get_number("index")) + HTTP_REQUIRE_TRUE(map.swap(index, index + 1), "index") + g->save(); + res->setBody(warp(to_json()).to_json_string()); + g->mode_acs.source_feed_relation_config.set_need_refresh(); + }); } diff --git a/module/Local_Server/Data_Source/Data_Source.h b/module/Local_Server/Data_Source/Data_Source.h index fc50228..af6f81d 100644 --- a/module/Local_Server/Data_Source/Data_Source.h +++ b/module/Local_Server/Data_Source/Data_Source.h @@ -5,404 +5,404 @@ namespace Psc { class SM_RingBuffer; } class Data_Source; -std::shared_ptr create_from_json(const Psc::JSON *that_json); +std::shared_ptr create_from_json(const Psc::JSON* that_json); class Input_Format { public: - Input_Format() { - test_v.resize(static_cast(SSR::Downlink_Format::Unknown)); - } - Psc::JSON to_json() { - std::lock_guard g(mtx); - Psc::JSON ret = Psc::JSON::object(); - for (auto e : magic_enum::enum_values()) { - std::string_view value_view = magic_enum::enum_name(e); - std::string value(value_view.begin(), value_view.end()); - if (value == Psc::to_string(SSR::Downlink_Format::Unknown)) continue; - auto ev = static_cast(e); - bool it = test_v[ev]; - ret.append({value, it}); - } - return ret; - } - void from_json(const Psc::JSON *json) { - std::lock_guard g(mtx); - for (auto e : magic_enum::enum_values()) { - std::string_view value_view = magic_enum::enum_name(e); - std::string value(value_view.begin(), value_view.end()); - if (value == Psc::to_string(SSR::Downlink_Format::Unknown)) continue; - auto use = json->get_bool(value); - auto ev = static_cast(e); - test_v[ev] = use; - } - } - bool test(SSR::Downlink_Format df) { - std::lock_guard g(mtx); - auto dfv = static_cast(df); - if (dfv >= static_cast(SSR::Downlink_Format::Unknown)) return false; - return test_v[dfv]; - } - bool test(std::uint8_t dfv) { - std::lock_guard g(mtx); - if (dfv >= static_cast(SSR::Downlink_Format::Unknown)) return false; - return test_v[dfv]; - } + Input_Format() { + test_v.resize(static_cast(SSR::Downlink_Format::Unknown)); + } + Psc::JSON to_json() { + std::lock_guard g(mtx); + Psc::JSON ret = Psc::JSON::object(); + for (auto e : magic_enum::enum_values()) { + std::string_view value_view = magic_enum::enum_name(e); + std::string value(value_view.begin(), value_view.end()); + if (value == Psc::to_string(SSR::Downlink_Format::Unknown)) continue; + auto ev = static_cast(e); + bool it = test_v[ev]; + ret.append({value, it}); + } + return ret; + } + void from_json(const Psc::JSON* json) { + std::lock_guard g(mtx); + for (auto e : magic_enum::enum_values()) { + std::string_view value_view = magic_enum::enum_name(e); + std::string value(value_view.begin(), value_view.end()); + if (value == Psc::to_string(SSR::Downlink_Format::Unknown)) continue; + auto use = json->get_bool(value); + auto ev = static_cast(e); + test_v[ev] = use; + } + } + bool test(SSR::Downlink_Format df) { + std::lock_guard g(mtx); + auto dfv = static_cast(df); + if (dfv >= static_cast(SSR::Downlink_Format::Unknown)) return false; + return test_v[dfv]; + } + bool test(std::uint8_t dfv) { + std::lock_guard g(mtx); + if (dfv >= static_cast(SSR::Downlink_Format::Unknown)) return false; + return test_v[dfv]; + } protected: - std::mutex mtx; - std::vector test_v; + std::mutex mtx; + std::vector test_v; }; class Data_Source_Data { public: - Psc::Copyable_Atomic base_station_show{}; - Psc::Copyable_Atomic aircraft_show{}; - std::string color = "#1677ff"; - int aircraft_pixel_size{}; - double lat{}; - double lon{}; - double alt{}; - Psc::Copyable_Atomic update_form_gps{}; - Psc::Copyable_Atomic show_icao = true; - Psc::Copyable_Atomic show_call_sign = false; - Psc::Copyable_Atomic show_fly_status = false; - Psc::Copyable_Atomic keep_mode = true; - PSC_USE_JSON + Psc::Copyable_Atomic base_station_show{}; + Psc::Copyable_Atomic aircraft_show{}; + std::string color = "#1677ff"; + int aircraft_pixel_size{}; + double lat{}; + double lon{}; + double alt{}; + Psc::Copyable_Atomic update_form_gps{}; + Psc::Copyable_Atomic show_icao = true; + Psc::Copyable_Atomic show_call_sign = false; + Psc::Copyable_Atomic show_fly_status = false; + Psc::Copyable_Atomic keep_mode = true; + PSC_USE_JSON }; class Data_Source : public std::enable_shared_from_this, public Data_Source_Handler, public Data_Source_Data { public: - std::shared_ptr that(); - virtual asio::awaitable read_coro() { - co_return ""; - } - bool registered() const; - virtual Psc::JSON get_custom_state_json() = 0; - Psc::JSON get_state(); - std::string last_char; // 用于处理奇数字节 - Data_Source(); - asio::awaitable loop_coro() final; - std::shared_ptr last_prase_msg = nullptr; - virtual asio::awaitable handle_in_loop_coro() { - co_return; - } - Frequency_Limit statistic_fl; - std::string thread_key() const; - Psc::JSON statistic_json() { - Psc::JSON ret = With_Loop_Coro::to_base_json(); - ret.append({"aircraft_total", get_aircraft_num()}); - ret.append({"aircraft_with_position", have_pos_aircraft_num}); - ret.append({"mode_ac_statistic", mode_ac_statistic.to_json()}); - ret.append({"mode_s_statistic", mode_s_statistic.to_json()}); - ret.append({"all_connect_feed", get_all_connect_feed_status()}); - return ret; - } - virtual Psc::JSON to_json() { - return With_Loop_Coro::to_base_json() += Data_Source_Data::to_base_json(); - } - virtual void from_json(const Psc::JSON *that_json) { - With_Loop_Coro::from_base_json(that_json); - Data_Source_Data::from_base_json(that_json); - } - std::string buffer; - std::atomic_bool ask_sleep = false; + std::shared_ptr that(); + virtual asio::awaitable read_coro() { + co_return ""; + } + bool registered() const; + virtual Psc::JSON get_custom_state_json() = 0; + Psc::JSON get_state(); + std::string last_char; // 用于处理奇数字节 + Data_Source(); + asio::awaitable loop_coro() final; + std::shared_ptr last_prase_msg = nullptr; + virtual asio::awaitable handle_in_loop_coro() { + co_return; + } + Frequency_Limit statistic_fl; + std::string thread_key() const; + Psc::JSON statistic_json() { + Psc::JSON ret = With_Loop_Coro::to_base_json(); + ret.append({"aircraft_total", get_aircraft_num()}); + ret.append({"aircraft_with_position", have_pos_aircraft_num}); + ret.append({"mode_ac_statistic", mode_ac_statistic.to_json()}); + ret.append({"mode_s_statistic", mode_s_statistic.to_json()}); + ret.append({"all_connect_feed", get_all_connect_feed_status()}); + return ret; + } + virtual Psc::JSON to_json() { + return With_Loop_Coro::to_base_json() += Data_Source_Data::to_base_json(); + } + virtual void from_json(const Psc::JSON* that_json) { + With_Loop_Coro::from_base_json(that_json); + Data_Source_Data::from_base_json(that_json); + } + std::string buffer; + std::atomic_bool ask_sleep = false; }; class TCP_Client_Data_Source_Data { public: - std::string ip; - std::uint16_t port{}; - PSC_USE_JSON + std::string ip; + std::uint16_t port{}; + PSC_USE_JSON }; class TCP_Client_Data_Source : public Data_Source, public TCP_Client_Data_Source_Data { public: - asio::awaitable handle_in_loop_coro() override { - co_await cli.tick_coro(); - co_return; - } - Psc::JSON get_custom_state_json() override { - auto& state = cli.state; - return VAR_JSON_1(state); - } - Psc::asio_socket::TCP_Client_Coro cli; - ~TCP_Client_Data_Source() override = default; - TCP_Client_Data_Source() { - type = "TCP_Client_Data_Source"; - } - asio::awaitable _open() override { - Psc::asio_socket::Sockaddr_In addr; - addr.ip = ip; - addr.port = port; - cli.set_dest_address(addr); - cli.create(); - co_await cli.connect_coro(); - co_return; - } - asio::awaitable _close() override { - co_await cli.close_coro(); - co_return; - } - Psc::JSON to_json() override { - return Data_Source::to_json() += TCP_Client_Data_Source_Data::to_base_json(); - } - void from_json(const Psc::JSON *that_json) override { - Data_Source::from_json(that_json); - TCP_Client_Data_Source_Data::from_base_json(that_json); - } - asio::awaitable read_coro() override { - co_return co_await cli.read_coro(); - } + asio::awaitable handle_in_loop_coro() override { + co_await cli.tick_coro(); + co_return; + } + Psc::JSON get_custom_state_json() override { + auto& state = cli.state; + return VAR_JSON_1(state); + } + Psc::asio_socket::TCP_Client_Coro cli; + ~TCP_Client_Data_Source() override = default; + TCP_Client_Data_Source() { + type = "TCP_Client_Data_Source"; + } + asio::awaitable _open() override { + Psc::asio_socket::Sockaddr_In addr; + addr.ip = ip; + addr.port = port; + cli.set_dest_address(addr); + cli.create(); + co_await cli.connect_coro(); + co_return; + } + asio::awaitable _close() override { + co_await cli.close_coro(); + co_return; + } + Psc::JSON to_json() override { + return Data_Source::to_json() += TCP_Client_Data_Source_Data::to_base_json(); + } + void from_json(const Psc::JSON* that_json) override { + Data_Source::from_json(that_json); + TCP_Client_Data_Source_Data::from_base_json(that_json); + } + asio::awaitable read_coro() override { + co_return co_await cli.read_coro(); + } }; class Serial_Data_Source_Data { public: - std::string port_name; - Baud_Rate_Type baud_rate{}; - PSC_USE_JSON + std::string port_name; + Baud_Rate_Type baud_rate{}; + PSC_USE_JSON }; class Serial_Data_Source : public Data_Source, public Serial_Data_Source_Data { public: - Psc::JSON get_custom_state_json() override { - return Psc::JSON::object(); - } - Serial_Data_Source() { - this->type = "Serial_Data_Source"; - } - asio::awaitable _open() override { - serial = std::make_unique(); - serial->set_serial_name(port_name); - serial->set_baud_rate(baud_rate); - serial->set_parity(Psc::serial::Parity::NoParity); - serial->set_data_bits(Psc::serial::DataBits::Data8); - serial->set_stop_bits(Psc::serial::StopBits::OneStop); - serial->set_flow_control(Psc::serial::FlowControl::HardwareControl); - serial->set_buffer_byte_size(10 * 1024); - bool ok = serial->open(); - if (!ok) { - std::cerr << "createSerial " + port_name + ":" + - std::to_string(baud_rate) + " 打开串口失败!\n"; - } - else { - // std::cerr << "createSerial " + serial_name + ":" + - // std::to_string(baud_rate) + " 打开串口成功!\n"; - } - co_return; - } - asio::awaitable _close() override { - if (serial) serial->close(); - co_return; - } - asio::awaitable handle_in_loop_coro() override { - if (serial) { - co_await serial->tick_coro(); - } - co_return; - } - asio::awaitable read_coro() override { - if (!serial) { - co_return ""; - } - co_return co_await serial->read_coro(); - } - Psc::JSON to_json() override { - return Data_Source::to_json() += Serial_Data_Source_Data::to_base_json(); - } - void from_json(const Psc::JSON *that_json) override { - Data_Source::from_json(that_json); - Serial_Data_Source_Data::from_base_json(that_json); - } - std::unique_ptr serial{}; - ~Serial_Data_Source() override { - if (serial) { - serial->close(); - } - } + Psc::JSON get_custom_state_json() override { + return Psc::JSON::object(); + } + Serial_Data_Source() { + this->type = "Serial_Data_Source"; + } + asio::awaitable _open() override { + serial = std::make_unique(); + serial->set_serial_name(port_name); + serial->set_baud_rate(baud_rate); + serial->set_parity(Psc::serial::Parity::NoParity); + serial->set_data_bits(Psc::serial::DataBits::Data8); + serial->set_stop_bits(Psc::serial::StopBits::OneStop); + serial->set_flow_control(Psc::serial::FlowControl::HardwareControl); + serial->set_buffer_byte_size(10 * 1024); + bool ok = serial->open(); + if (!ok) { + std::cerr << "createSerial " + port_name + ":" + + std::to_string(baud_rate) + " 打开串口失败!\n"; + } + else { + // std::cerr << "createSerial " + serial_name + ":" + + // std::to_string(baud_rate) + " 打开串口成功!\n"; + } + co_return; + } + asio::awaitable _close() override { + if (serial) serial->close(); + co_return; + } + asio::awaitable handle_in_loop_coro() override { + if (serial) { + co_await serial->tick_coro(); + } + co_return; + } + asio::awaitable read_coro() override { + if (!serial) { + co_return ""; + } + co_return co_await serial->read_coro(); + } + Psc::JSON to_json() override { + return Data_Source::to_json() += Serial_Data_Source_Data::to_base_json(); + } + void from_json(const Psc::JSON* that_json) override { + Data_Source::from_json(that_json); + Serial_Data_Source_Data::from_base_json(that_json); + } + std::unique_ptr serial{}; + ~Serial_Data_Source() override { + if (serial) { + serial->close(); + } + } }; enum class File_Data_Type { - SIMPLE_BIN_Blank, // 没有1a转义�? - BIN_Blank_Text, - AVR, - BIN_Text, - BIN_Blank_One_Line_With_Escape, - BIN_Blank_One_Line_No_Escape, - BIN, - Unknown - // 纯粹的二进制 + SIMPLE_BIN_Blank, // 没有1a转义�? + BIN_Blank_Text, + AVR, + BIN_Text, + BIN_Blank_One_Line_With_Escape, + BIN_Blank_One_Line_No_Escape, + BIN, + Unknown + // 纯粹的二进制 }; enum Play_Mode { one, loop, analysis, time_batch }; class File_Data_Source_Data { public: - std::string file_path; - File_Data_Type data_type = File_Data_Type::BIN_Blank_Text; - Play_Mode play_mode = Play_Mode::one; - PSC_USE_JSON + std::string file_path; + File_Data_Type data_type = File_Data_Type::BIN_Blank_Text; + Play_Mode play_mode = Play_Mode::one; + PSC_USE_JSON }; class File_Data_Source : public Data_Source, public File_Data_Source_Data { public: - bool have_report_play_back_all_success = false; - std::string state = "null"; - Psc::JSON get_custom_state_json() override { - auto cur_virtual_time = player_clock.get_cur_time_point(); - auto playback_speed_rate = player_clock.playback_speed_rate; - return VAR_JSON_5(cur_virtual_time, playback_speed_rate, state, index, - part_infos.size()); - } - File_Data_Source() { - this->type = "File_Data_Source"; - } - ~File_Data_Source() override = default; - void before_handle_msg(std::shared_ptr& msg) override; - struct Cache_Msg { - explicit Cache_Msg(std::shared_ptr msg) : msg(std::move(msg)) {} - SSR::Play_Back_Time_Point time() const { - return SSR::Play_Back_Time_Point{day_num, msg->mlat_timestamp.daysec}; - } - std::uint64_t day_num = 0; - std::shared_ptr msg; - }; - Player_Clock player_clock; - std::shared_ptr pre_cache = nullptr; - std::deque> cache_list; - std::string get_true_file_path() const { - return Psc::get_abs_path(file_path); - } - asio::awaitable _close() override; - asio::awaitable _open() override; - std::vector readBinaryFileAsString(std::string_view filepath, - size_t part_size); - void from_json(const Psc::JSON *that_json) override { - Data_Source::from_json(that_json); - File_Data_Source_Data::from_base_json(that_json); - } - Psc::JSON to_json() override { - return Data_Source::to_json() += File_Data_Source_Data::to_base_json(); - } - void origin_data_transform_mode_data(std::string& data) override; - void handle_mode_s(std::shared_ptr msg) override; + bool have_report_play_back_all_success = false; + std::string state = "null"; + Psc::JSON get_custom_state_json() override { + auto cur_virtual_time = player_clock.get_cur_time_point(); + auto playback_speed_rate = player_clock.playback_speed_rate; + return VAR_JSON_5(cur_virtual_time, playback_speed_rate, state, index, + part_infos.size()); + } + File_Data_Source() { + this->type = "File_Data_Source"; + } + ~File_Data_Source() override = default; + void before_handle_msg(std::shared_ptr& msg) override; + struct Cache_Msg { + explicit Cache_Msg(std::shared_ptr msg) : msg(std::move(msg)) {} + SSR::Play_Back_Time_Point time() const { + return SSR::Play_Back_Time_Point{day_num, msg->mlat_timestamp.daysec}; + } + std::uint64_t day_num = 0; + std::shared_ptr msg; + }; + Player_Clock player_clock; + std::shared_ptr pre_cache = nullptr; + std::deque> cache_list; + std::string get_true_file_path() const { + return Psc::get_abs_path(file_path); + } + asio::awaitable _close() override; + asio::awaitable _open() override; + std::vector readBinaryFileAsString(std::string_view filepath, + size_t part_size); + void from_json(const Psc::JSON* that_json) override { + Data_Source::from_json(that_json); + File_Data_Source_Data::from_base_json(that_json); + } + Psc::JSON to_json() override { + return Data_Source::to_json() += File_Data_Source_Data::to_base_json(); + } + void origin_data_transform_mode_data(std::string& data) override; + void handle_mode_s(std::shared_ptr msg) override; protected: - std::optional get_raw_line(int& ret_index); - long long index = 0; - std::vector part_infos; - std::mutex mtx; + std::optional get_raw_line(int& ret_index); + long long index = 0; + std::vector part_infos; + std::mutex mtx; }; class Dll_Data_Source_Data { public: - std::string library_path; - std::string function_name; - File_Data_Type data_type = File_Data_Type::BIN_Blank_Text; - std::size_t buffer_size{}; - PSC_USE_JSON + std::string library_path; + std::string function_name; + File_Data_Type data_type = File_Data_Type::BIN_Blank_Text; + std::size_t buffer_size{}; + PSC_USE_JSON }; class Dll_Data_Source : public Data_Source, public Dll_Data_Source_Data { public: - Psc::JSON get_custom_state_json() override { - auto ret = VAR_JSON_1(state); - ret.append({"read_vaild_len", vs.to_string()}); - return ret; - } - Psc::Value_Statistics vs; - Dll_Data_Source() { - this->type = "Dll_Data_Source"; - } - ~Dll_Data_Source() override = default; - std::vector buffer; - void from_json(const Psc::JSON *that_json) override { - Data_Source::from_json(that_json); - Dll_Data_Source_Data::from_base_json(that_json); - buffer.resize(buffer_size); - } - Psc::JSON to_json() override { - return Data_Source::to_json() += Dll_Data_Source_Data::to_base_json(); - } - void *lib{}; - using Func_Type = size_t (*)(char *buf, std::size_t max_len); - // using Func_Type = std::uint16_t (*)(char *buf, std::uint16_t max_len); - Func_Type read_func_ptr{}; - using Call_Back = void (*)(char *buf, std::size_t len); - using set_Call_back = void (*)(Call_Back); - std::string state; - asio::awaitable _close() override { - Psc::free_library(lib); - co_return; - } - asio::awaitable _open() override { - { - auto r = Psc::try_load_library(Psc::get_abs_path(library_path)); - if (!r) { - state = r.error().message(); - co_return; - } - lib = r.value(); - } - { - auto r = Psc::try_load_function(lib, function_name); - if (!r) { - state = r.error().message(); - std::cout << LOG_POS << " [" << function_name << "] 函数指针加载失败!" - << std::endl; - co_return; - } - read_func_ptr = (Func_Type)r.value(); - } - state = "加载成功"; - co_return; - } - void origin_data_transform_mode_data(std::string& data) override; + Psc::JSON get_custom_state_json() override { + auto ret = VAR_JSON_1(state); + ret.append({"read_vaild_len", vs.to_string()}); + return ret; + } + Psc::Value_Statistics vs; + Dll_Data_Source() { + this->type = "Dll_Data_Source"; + } + ~Dll_Data_Source() override = default; + std::vector buffer; + void from_json(const Psc::JSON* that_json) override { + Data_Source::from_json(that_json); + Dll_Data_Source_Data::from_base_json(that_json); + buffer.resize(buffer_size); + } + Psc::JSON to_json() override { + return Data_Source::to_json() += Dll_Data_Source_Data::to_base_json(); + } + void* lib{}; + using Func_Type = size_t (*)(char* buf, std::size_t max_len); + // using Func_Type = std::uint16_t (*)(char *buf, std::uint16_t max_len); + Func_Type read_func_ptr{}; + using Call_Back = void (*)(char* buf, std::size_t len); + using set_Call_back = void (*)(Call_Back); + std::string state; + asio::awaitable _close() override { + Psc::free_library(lib); + co_return; + } + asio::awaitable _open() override { + { + auto r = Psc::try_load_library(Psc::get_abs_path(library_path)); + if (!r) { + state = r.error().message(); + co_return; + } + lib = r.value(); + } + { + auto r = Psc::try_load_function(lib, function_name); + if (!r) { + state = r.error().message(); + std::cout << LOG_POS << " [" << function_name << "] 函数指针加载失败!" + << std::endl; + co_return; + } + read_func_ptr = (Func_Type)r.value(); + } + state = "加载成功"; + co_return; + } + void origin_data_transform_mode_data(std::string& data) override; }; class Shared_Memory_Data_Source_Data { public: - std::string shared_memory_name; - std::uint64_t shared_memory_size{}; - File_Data_Type data_type = File_Data_Type::BIN_Blank_Text; - PSC_USE_JSON + std::string shared_memory_name; + std::uint64_t shared_memory_size{}; + File_Data_Type data_type = File_Data_Type::BIN_Blank_Text; + PSC_USE_JSON }; class Shared_Memory_Data_Source : public Data_Source, public Shared_Memory_Data_Source_Data { public: - Psc::JSON get_custom_state_json() override { - return Psc::JSON::object(); - } - void from_json(const Psc::JSON *that_json) override { - Data_Source::from_json(that_json); - Shared_Memory_Data_Source_Data::from_base_json(that_json); - } - Psc::JSON to_json() override { - return Data_Source::to_json() += Shared_Memory_Data_Source_Data::to_base_json(); - } - asio::awaitable _open() override; - asio::awaitable _close() override; - void origin_data_transform_mode_data(std::string& data) override; + Psc::JSON get_custom_state_json() override { + return Psc::JSON::object(); + } + void from_json(const Psc::JSON* that_json) override { + Data_Source::from_json(that_json); + Shared_Memory_Data_Source_Data::from_base_json(that_json); + } + Psc::JSON to_json() override { + return Data_Source::to_json() += Shared_Memory_Data_Source_Data::to_base_json(); + } + asio::awaitable _open() override; + asio::awaitable _close() override; + void origin_data_transform_mode_data(std::string& data) override; protected: - std::unique_ptr sm; + std::unique_ptr sm; }; inline std::shared_ptr create_data_source_from_type(std::string_view t) { - std::shared_ptr ret{}; - if (t == "Serial_Data_Source") ret = std::make_shared(); - else if (t == "TCP_Client_Data_Source") ret = std::make_shared(); - else if (t == "File_Data_Source") ret = std::make_shared(); - else if (t == "Dll_Data_Source") ret = std::make_shared(); - else if (t == "Shared_Memory_Data_Source") ret = std::make_shared(); - else { - std::cout << "未知�?Data_Source type类型!" << std::endl; - throw std::invalid_argument("unknown Data_Source type: " + std::string(t)); - } - return ret; + std::shared_ptr ret{}; + if (t == "Serial_Data_Source") ret = std::make_shared(); + else if (t == "TCP_Client_Data_Source") ret = std::make_shared(); + else if (t == "File_Data_Source") ret = std::make_shared(); + else if (t == "Dll_Data_Source") ret = std::make_shared(); + else if (t == "Shared_Memory_Data_Source") ret = std::make_shared(); + else { + std::cout << "未知�?Data_Source type类型!" << std::endl; + throw std::invalid_argument("unknown Data_Source type: " + std::string(t)); + } + return ret; } struct Data_Source_Config { - Ordered_Map> map; - Data_Source_Config() = default; - void init(const Psc::JSON *that_json) { - auto list = that_json->get("list"); - for (auto& it : list->children) { - auto ds = create_from_json(&it); - map.push_back(ds); - } - } - Psc::JSON list() { - auto connect_json = Psc::JSON::array(); - for (auto& it : map.list()) { - connect_json.children.emplace_back(it->to_json()); - } - return connect_json; - } - Psc::JSON to_json() { - Psc::JSON ret = Psc::JSON::object(); - ret.append({"list", list()}); - return ret; - } - void server(Global *g); + Ordered_Map> map; + Data_Source_Config() = default; + void init(const Psc::JSON* that_json) { + auto list = that_json->get("list"); + for (auto& it : list->children) { + auto ds = create_from_json(&it); + map.push_back(ds); + } + } + Psc::JSON list() { + auto connect_json = Psc::JSON::array(); + for (auto& it : map.list()) { + connect_json.children.emplace_back(it->to_json()); + } + return connect_json; + } + Psc::JSON to_json() { + Psc::JSON ret = Psc::JSON::object(); + ret.append({"list", list()}); + return ret; + } + void server(Global* g); }; diff --git a/module/Local_Server/global_include.h b/module/Local_Server/global_include.h index 54cf959..b5fe3c0 100644 --- a/module/Local_Server/global_include.h +++ b/module/Local_Server/global_include.h @@ -15,18 +15,14 @@ #include #include #include - class Global; - class Invalid_Http_Param final : public std::runtime_error { public: - using std::runtime_error::runtime_error; + using std::runtime_error::runtime_error; }; - -[[noreturn]] inline void throw_invalid_http_param(const char *detail) { - throw Invalid_Http_Param(detail); +[[noreturn]] inline void throw_invalid_http_param(const char* detail) { + throw Invalid_Http_Param(detail); } - #define CHECK_JSON_PARAM \ auto o_params = Psc::try_parse_json(req->body().data()); \ if (!o_params.has_value()) { \ @@ -34,356 +30,343 @@ public: } \ auto ¶ms = o_params.value(); \ auto that_json = ¶ms; - #define HTTP_REQUIRE_VALUE(NAME, EXPRESSION) \ auto o_http_##NAME = (EXPRESSION); \ if (!o_http_##NAME.has_value()) { \ throw_invalid_http_param(#NAME); \ } \ auto NAME = std::move(o_http_##NAME).value(); - #define HTTP_REQUIRE_PTR(NAME, EXPRESSION) \ auto NAME = (EXPRESSION); \ if ((NAME) == nullptr) { \ throw_invalid_http_param(#NAME); \ } - #define HTTP_REQUIRE_TRUE(EXPRESSION, DETAIL) \ if (!(EXPRESSION)) { \ throw_invalid_http_param(DETAIL); \ } - -template class Ordered_List { +template +class Ordered_List { public: - void swap(size_t i, size_t j) { - std::lock_guard g(mtx); - if (i >= _list.size() || j >= _list.size()) - return; - - std::swap(_list[i], _list[j]); - } - - void push_back(Value_Type value) { - std::lock_guard g(mtx); - _list.push_back(value); // 添加默认值 - } - - void insert(int i, Value_Type value) { - std::lock_guard g(mtx); - _list.insert(_list.begin() + i, value); - } - - Value_Type get(size_t i) { return _list[i]; } - - void remove(size_t i) { - std::lock_guard g(mtx); - if (i >= _list.size()) - return; - _list.erase(_list.begin() + i); - } - std::vector list() { - std::lock_guard g(mtx); - return this->_list; - } - - void clear() { list().clear(); } - -protected: - std::mutex mtx; - std::vector _list; -}; - -template class Ordered_Map { -public: - std::optional get(Key_Type key) { - std::lock_guard g(mtx); - auto it = _map.find(key); - if (it != _map.end()) { - return it->second; + void swap(size_t i, size_t j) { + std::lock_guard g(mtx); + if (i >= _list.size() || j >= _list.size()) + return; + std::swap(_list[i], _list[j]); + } + void push_back(Value_Type value) { + std::lock_guard g(mtx); + _list.push_back(value); // 添加默认值 + } + void insert(int i, Value_Type value) { + std::lock_guard g(mtx); + _list.insert(_list.begin() + i, value); + } + Value_Type get(size_t i) { + return _list[i]; + } + void remove(size_t i) { + std::lock_guard g(mtx); + if (i >= _list.size()) + return; + _list.erase(_list.begin() + i); + } + std::vector list() { + std::lock_guard g(mtx); + return this->_list; + } + void clear() { + list().clear(); } - return std::nullopt; - } - bool swap(size_t i, size_t j) { - std::lock_guard g(mtx); - if (i >= _list.size() || j >= _list.size()) - return false; - - std::swap(_list[i], _list[j]); - - // 更新 map 中的 value,假设你可以从 Value 中获取 key - Key_Type key_i = _list[i]->key; - Key_Type key_j = _list[j]->key; - - _map[key_i] = _list[i]; - _map[key_j] = _list[j]; - return true; - } - - void push_back(Value_Type value) { - std::lock_guard g(mtx); - _list.push_back(value); // 添加默认值 - _map[value->key] = value; // 插入到 map - } - - bool insert(int i, Value_Type value) { - std::lock_guard g(mtx); - if (i < 0 || static_cast(i) > _list.size()) - return false; - _list.insert(_list.begin() + i, value); - _map[value->key] = value; - return true; - } - - Value_Type get(size_t i) { return _list[i]; } - - std::optional try_get(size_t i) { - std::lock_guard g(mtx); - if (i >= _list.size()) - return std::nullopt; - return _list[i]; - } - - bool remove(size_t i) { - std::lock_guard g(mtx); - if (i >= _list.size()) - return false; - Key_Type &key = _list[i]->key; - _map.erase(key); - _list.erase(_list.begin() + i); - return true; - } - std::vector list() { - std::lock_guard g(mtx); - return this->_list; - } - // std::map map(){ - // std::lock_guard g(mtx); - // return this->_map; - // } - void clear() { - list().clear(); - _map.clear(); - } - protected: - std::mutex mtx; - std::vector _list; - std::map _map; + std::mutex mtx; + std::vector _list; +}; +template +class Ordered_Map { +public: + std::optional get(Key_Type key) { + std::lock_guard g(mtx); + auto it = _map.find(key); + if (it != _map.end()) { + return it->second; + } + return std::nullopt; + } + bool swap(size_t i, size_t j) { + std::lock_guard g(mtx); + if (i >= _list.size() || j >= _list.size()) + return false; + std::swap(_list[i], _list[j]); + // 更新 map 中的 value,假设你可以从 Value 中获取 key + Key_Type key_i = _list[i]->key; + Key_Type key_j = _list[j]->key; + _map[key_i] = _list[i]; + _map[key_j] = _list[j]; + return true; + } + void push_back(Value_Type value) { + std::lock_guard g(mtx); + _list.push_back(value); // 添加默认值 + _map[value->key] = value; // 插入到 map + } + bool insert(int i, Value_Type value) { + std::lock_guard g(mtx); + if (i < 0 || static_cast(i) > _list.size()) + return false; + _list.insert(_list.begin() + i, value); + _map[value->key] = value; + return true; + } + Value_Type get(size_t i) { + return _list[i]; + } + std::optional try_get(size_t i) { + std::lock_guard g(mtx); + if (i >= _list.size()) + return std::nullopt; + return _list[i]; + } + bool remove(size_t i) { + std::lock_guard g(mtx); + if (i >= _list.size()) + return false; + Key_Type& key = _list[i]->key; + _map.erase(key); + _list.erase(_list.begin() + i); + return true; + } + std::vector list() { + std::lock_guard g(mtx); + return this->_list; + } + // std::map map(){ + // std::lock_guard g(mtx); + // return this->_map; + // } + void clear() { + list().clear(); + _map.clear(); + } +protected: + std::mutex mtx; + std::vector _list; + std::map _map; }; - class Mode_AC_Statistic_Data { public: - Psc::JSON to_json() { - std::lock_guard g(mtx); - Psc::JSON ret = Psc::JSON::object(); - Ret_J(pre_second_num); - Ret_J(total_num); - Ret_J(length_error_num); - // Ret_J(speed); - return ret; - } - void add() { - std::lock_guard g(mtx); - add_inter(); - // speed.update(1); - } - void add_length_error() { - std::lock_guard g(mtx); - add_inter(); - length_error_num++; - } - -protected: - std::atomic length_error_num{}; - void add_inter() { - total_num++; - auto cur_time = std::time(nullptr); - if (cur_time != utc) { - utc = cur_time; - pre_second_num = 0; + Psc::JSON to_json() { + std::lock_guard g(mtx); + Psc::JSON ret = Psc::JSON::object(); + Ret_J(pre_second_num); + Ret_J(total_num); + Ret_J(length_error_num); + // Ret_J(speed); + return ret; } - pre_second_num++; - } - std::mutex mtx; - size_t pre_second_num{}; - size_t total_num{}; - time_t utc{}; - // Psc::Speed_Statistics speed; + void add() { + std::lock_guard g(mtx); + add_inter(); + // speed.update(1); + } + void add_length_error() { + std::lock_guard g(mtx); + add_inter(); + length_error_num++; + } +protected: + std::atomic length_error_num{}; + void add_inter() { + total_num++; + auto cur_time = std::time(nullptr); + if (cur_time != utc) { + utc = cur_time; + pre_second_num = 0; + } + pre_second_num++; + } + std::mutex mtx; + size_t pre_second_num{}; + size_t total_num{}; + time_t utc{}; + // Psc::Speed_Statistics speed; }; - class Statistic_Data { public: - time_t utc{}; - size_t pre_second_num{}; - size_t total_num{}; - [[nodiscard]] Psc::JSON to_json() const { - Psc::JSON ret = Psc::JSON::object(); - Ret_J(pre_second_num); - Ret_J(total_num); - return ret; - } - Statistic_Data() = default; + time_t utc{}; + size_t pre_second_num{}; + size_t total_num{}; + [[nodiscard]] Psc::JSON to_json() const { + Psc::JSON ret = Psc::JSON::object(); + Ret_J(pre_second_num); + Ret_J(total_num); + return ret; + } + Statistic_Data() = default; }; - class DF_Statistic_Data { public: - time_t utc{}; - size_t pre_second_num{}; - size_t total_num{}; - size_t crc_error_num{}; - Psc::JSON to_json() { - Psc::JSON ret = Psc::JSON::object(); - Ret_J(pre_second_num); - Ret_J(total_num); - Ret_J(crc_error_num); - // Ret_J(speed); - - std::string t = "null"; - if (total_num != 0) { - t = std::to_string(static_cast(crc_error_num) / - static_cast(total_num)) + - "%"; + time_t utc{}; + size_t pre_second_num{}; + size_t total_num{}; + size_t crc_error_num{}; + Psc::JSON to_json() { + Psc::JSON ret = Psc::JSON::object(); + Ret_J(pre_second_num); + Ret_J(total_num); + Ret_J(crc_error_num); + // Ret_J(speed); + std::string t = "null"; + if (total_num != 0) { + t = std::to_string(static_cast(crc_error_num) / + static_cast(total_num)) + + "%"; + } + ret.append({"crc误码率", t}); + for (auto& cur : statistic_map) { + ret.append({cur.first, cur.second.to_json()}); + } + return ret; } - ret.append({"crc误码率", t}); - for (auto &cur : statistic_map) { - ret.append({cur.first, cur.second.to_json()}); + void add() { + add_inter(); } - return ret; - } - void add() { add_inter(); } - void add_crc_error() { crc_error_num++; } - void add_sub_part(std::string_view key) { add_sub_part_inter(key); } - - // Psc::Speed_Statistics speed; + void add_crc_error() { + crc_error_num++; + } + void add_sub_part(std::string_view key) { + add_sub_part_inter(key); + } + // Psc::Speed_Statistics speed; protected: - void add_inter() { - total_num++; - auto cur_time = std::time(nullptr); - if (cur_time != utc) { - utc = cur_time; - pre_second_num = 0; + void add_inter() { + total_num++; + auto cur_time = std::time(nullptr); + if (cur_time != utc) { + utc = cur_time; + pre_second_num = 0; + } + pre_second_num++; + // speed.update(1); } - pre_second_num++; - // speed.update(1); - } - - void add_sub_part_inter(std::string_view key) { - auto t = get_create_statistic_data(key); - t->total_num++; - auto cur_time = std::time(nullptr); - if (cur_time != t->utc) { - t->utc = cur_time; - t->pre_second_num = 0; + void add_sub_part_inter(std::string_view key) { + auto t = get_create_statistic_data(key); + t->total_num++; + auto cur_time = std::time(nullptr); + if (cur_time != t->utc) { + t->utc = cur_time; + t->pre_second_num = 0; + } + t->pre_second_num++; } - t->pre_second_num++; - } - Statistic_Data *get_create_statistic_data(std::string_view key) { - Statistic_Data *t; - auto key_string = std::string(key); - auto iter = statistic_map.find(key_string); - if (iter == statistic_map.end()) { - Statistic_Data cur{}; - statistic_map.insert(std::make_pair(key_string, cur)); + Statistic_Data* get_create_statistic_data(std::string_view key) { + Statistic_Data* t; + auto key_string = std::string(key); + auto iter = statistic_map.find(key_string); + if (iter == statistic_map.end()) { + Statistic_Data cur{}; + statistic_map.insert(std::make_pair(key_string, cur)); + } + t = &statistic_map[key_string]; + return t; } - t = &statistic_map[key_string]; - return t; - } - - std::map statistic_map; + std::map statistic_map; }; - class Mode_S_Statistic_Data { public: - // Psc::Speed_Statistics speed; - - // Psc::Speed_Statistics total_speed() const { - // Psc::Speed_Statistics total_speed{}; - // for (auto& cur : DF_Statistic_Data_map) { - // total_speed += cur.second.speed; - // } - // return total_speed; - // } - Psc::JSON to_json() { - size_t total_num = get_total_num(); - size_t crc_error_num = get_crc_error_num(); - Psc::JSON ret = Psc::JSON::object(); - - ret.append({"每秒数量", get_total_pre_second_num()}); - - Ret_J(length_error_num); - Ret_J(total_num); - - std::string t = "null"; - if (total_num != 0) { - t = std::to_string(static_cast(crc_error_num) / - static_cast(total_num)) + - "%"; + // Psc::Speed_Statistics speed; + // Psc::Speed_Statistics total_speed() const { + // Psc::Speed_Statistics total_speed{}; + // for (auto& cur : DF_Statistic_Data_map) { + // total_speed += cur.second.speed; + // } + // return total_speed; + // } + Psc::JSON to_json() { + size_t total_num = get_total_num(); + size_t crc_error_num = get_crc_error_num(); + Psc::JSON ret = Psc::JSON::object(); + ret.append({"每秒数量", get_total_pre_second_num()}); + Ret_J(length_error_num); + Ret_J(total_num); + std::string t = "null"; + if (total_num != 0) { + t = std::to_string(static_cast(crc_error_num) / + static_cast(total_num)) + + "%"; + } + Ret_J(crc_error_num); + ret.append({"crc_error_rate", t}); + Psc::JSON df_sub_type = Psc::JSON::object(); + for (auto& cur : DF_Statistic_Data_map) { + df_sub_type.append({ + Psc::to_string(cur.first) + " [" + + std::to_string(static_cast(cur.first)) + "]", + cur.second.to_json() + }); + } + Psc::JSON cpr_error_o = Psc::JSON::object(); + for (auto& cur : cpr_error) { + auto num = cur.second; + std::string rate_str = std::format("{:.2f}%", static_cast(num) / base * 100.0); + auto& type = cur.first; + auto key = Psc::to_string(type); + auto val = Psc::to_string(static_cast(cur.second)) + " " + rate_str; + cpr_error_o.append({key, val}); + } + ret.append({"DF子类型", df_sub_type}); + ret.append({"CPR统计信息", cpr_error_o}); + return ret; } - Ret_J(crc_error_num); - ret.append({"crc_error_rate", t}); - - Psc::JSON df_sub_type = Psc::JSON::object(); - for (auto &cur : DF_Statistic_Data_map) { - df_sub_type.append({Psc::to_string(cur.first) + " [" + - std::to_string(static_cast(cur.first)) + "]", - cur.second.to_json()}); + void add_length_error(std::string_view key) { + length_error_num++; } - Psc::JSON cpr_error_o = Psc::JSON::object(); - for (auto &cur : cpr_error) { - cpr_error_o.append({Psc::to_string(cur.first) + " [" + - std::to_string(static_cast(cur.first)) + "]", - Psc::to_string(cur.second)}); + void add_cpr_error(SSR::CPR_Error_Type cet) { + if (cet == SSR::CPR_Error_Type::Normal) { + base++; + } + else { + ++cpr_error[cet]; + } } - ret.append({"DF子类型", df_sub_type}); - ret.append({"CPR统计信息", cpr_error_o}); - return ret; - } - - void add_length_error(std::string_view key) { length_error_num++; } - - void add_cpr_error(SSR::CPR_Error_Type cet) { ++cpr_error[cet]; } - - DF_Statistic_Data * - get_create_df_statistic_data(const SSR::Downlink_Format &key) { - DF_Statistic_Data *t; - auto iter = DF_Statistic_Data_map.find(key); - if (iter == DF_Statistic_Data_map.end()) { - DF_Statistic_Data cur{}; - DF_Statistic_Data_map.insert(std::make_pair(key, cur)); + DF_Statistic_Data* + get_create_df_statistic_data(const SSR::Downlink_Format& key) { + DF_Statistic_Data* t; + auto iter = DF_Statistic_Data_map.find(key); + if (iter == DF_Statistic_Data_map.end()) { + DF_Statistic_Data cur{}; + DF_Statistic_Data_map.insert(std::make_pair(key, cur)); + } + t = &DF_Statistic_Data_map[key]; + return t; } - t = &DF_Statistic_Data_map[key]; - return t; - } - - size_t get_total_pre_second_num() { - size_t ret = 0; - for (auto &cur : DF_Statistic_Data_map) { - ret += cur.second.pre_second_num; + size_t get_total_pre_second_num() { + size_t ret = 0; + for (auto& cur : DF_Statistic_Data_map) { + ret += cur.second.pre_second_num; + } + return ret; } - return ret; - } - - size_t get_total_num() { - size_t ret = 0; - for (auto &cur : DF_Statistic_Data_map) { - ret += cur.second.total_num; + size_t get_total_num() { + size_t ret = 0; + for (auto& cur : DF_Statistic_Data_map) { + ret += cur.second.total_num; + } + return ret; } - return ret; - } - size_t get_crc_error_num() { - size_t ret = 0; - for (auto &cur : DF_Statistic_Data_map) { - ret += cur.second.crc_error_num; + size_t get_crc_error_num() { + size_t ret = 0; + for (auto& cur : DF_Statistic_Data_map) { + ret += cur.second.crc_error_num; + } + return ret; } - return ret; - } - protected: - std::atomic length_error_num{}; - std::map DF_Statistic_Data_map; - std::map cpr_error; + std::atomic length_error_num{}; + std::map DF_Statistic_Data_map; + std::map cpr_error; + double base = 0; }; - -template class Immutable : public T {}; - +template +class Immutable : public T {}; #endif diff --git a/module/Local_Server/server/Global.cpp b/module/Local_Server/server/Global.cpp index 4c7d839..b9964cf 100644 --- a/module/Local_Server/server/Global.cpp +++ b/module/Local_Server/server/Global.cpp @@ -102,9 +102,7 @@ Global::Global() { SSR::P_S msg) { auto src = std::dynamic_pointer_cast(msg->source); Mode_S_Statistic_Data* ss = &src->mode_s_statistic; - if (t != SSR::CPR_Error_Type::Normal) { - ss->add_cpr_error(t); - } + ss->add_cpr_error(t); SSR::mode_s_logger->debug("CPR/" + to_string(t), {}, log); }; // 处理错误