231 lines
9.9 KiB
C++
231 lines
9.9 KiB
C++
#include "../server/Global.h"
|
|
#include "../server/Mode_Msg_Buffer.h"
|
|
#include <future>
|
|
#include <iostream>
|
|
long long get_current_milliseconds() {
|
|
auto now = std::chrono::system_clock::now();
|
|
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
|
|
return duration.count();
|
|
}
|
|
Frequency_Limit too_many_msg_limit;
|
|
Frequency_Limit flush_limit;
|
|
|
|
|
|
std::optional<std::string> convert_to_send_format(Data_Source* ds, const std::shared_ptr<Data_Feed>& feed, const std::shared_ptr<SSR::Msg>& msg)
|
|
{
|
|
auto& type = msg->type;
|
|
auto fs = dynamic_cast<File_Data_Source*>(msg->source.get());
|
|
if (fs) {
|
|
if (fs->play_mode == Play_Mode::analysis) {
|
|
//std::cout << fs->key << " analysis i ==" << i << std::endl;
|
|
}
|
|
}
|
|
// 出口输出的条件
|
|
auto& output_format = feed->output_format.type;
|
|
auto& use_mode_ac = feed->output_format.use_mode_ac;
|
|
auto& use_status = feed->output_format.use_status;
|
|
auto& mode_s_output_type = feed->output_format.mode_s_output_type;
|
|
// 计算出是否输出消息
|
|
std::optional<std::string> send_msg = std::nullopt;
|
|
if (type == SSR::Msg::HULC_Status) {
|
|
if (!use_status) return std::nullopt;
|
|
auto data = static_cast<SSR::Msg*>(msg.get());
|
|
if (output_format == Output_Data_Format::BIN || output_format == Output_Data_Format::BIN_ID) {
|
|
send_msg = SSR::packet_to_escape_format(data->packet);
|
|
}
|
|
} else if (type == SSR::Msg::Radarcape_status) {
|
|
auto data = static_cast<SSR::Msg*>(msg.get());
|
|
if (output_format == Output_Data_Format::BIN || output_format == Output_Data_Format::BIN_ID) {
|
|
send_msg = SSR::packet_to_escape_format(data->packet);
|
|
}
|
|
} else if (type == SSR::Msg::AC) {
|
|
if (!use_mode_ac) return std::nullopt;
|
|
auto data = static_cast<SSR::Mode_AC_Msg*>(msg.get());
|
|
std::string& msg_hex = data->msg_hex;
|
|
char signal_level = data->signal_level;
|
|
SSR::MLAT_timestamp& mlat_timestamp = data->mlat_timestamp;
|
|
if (output_format == Output_Data_Format::BIN) {
|
|
//send_msg = create_Binary_Format_memory(msg_hex, signal_level, &mlat_timestamp);
|
|
send_msg = SSR::packet_to_escape_format(msg->packet);
|
|
} else if (output_format == Output_Data_Format::BIN_ID) {
|
|
// std::uint32_t id;
|
|
// {
|
|
// id = Global::instance()->mlat_server.id;
|
|
// }
|
|
// auto bin_id_packet = mode_s_msg_packet_to_server_packet(id, data->packet);
|
|
// send_msg = packet_to_escape_format(bin_id_packet);
|
|
} else if (output_format == Output_Data_Format::AVR) {
|
|
send_msg = SSR::create_AVR_format(msg_hex);
|
|
} else if (output_format == Output_Data_Format::AVR_MLAT) {
|
|
send_msg = create_MLAT_AVR_format(msg_hex, &mlat_timestamp);
|
|
}
|
|
} else if (type == SSR::Msg::S7 || type == SSR::Msg::S14) {
|
|
auto s_msg = static_cast<SSR::Mode_S_Msg*>(msg.get());
|
|
std::string& icao = s_msg->icao;
|
|
SSR::Downlink_Format& df = s_msg->df;
|
|
std::string& msg_hex = s_msg->msg_hex;
|
|
auto& signal_level = s_msg->signal_level;
|
|
SSR::MLAT_timestamp& mlat_timestamp = s_msg->mlat_timestamp;
|
|
auto aircraft = ds->get_aircraft(s_msg->icao);
|
|
|
|
if (output_format == Output_Data_Format::SBS) {
|
|
bool sbs_out_put = false;
|
|
if (feed->output_format.sbs_only_pos) {
|
|
auto s = ds->get_aircraft(s_msg->icao);
|
|
if (s) {
|
|
auto pos = s->pos();
|
|
if (pos.has_value()) {
|
|
if (feed->sbs_flm.test(s_msg->icao)) {
|
|
sbs_out_put = true;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (feed->sbs_flm.test(s_msg->icao)) {
|
|
sbs_out_put = true;
|
|
}
|
|
}
|
|
if (!sbs_out_put) return std::nullopt;
|
|
|
|
send_msg = "";
|
|
SSR::SBS_MSG msg_base;
|
|
if (!aircraft) return std::nullopt;
|
|
msg_base.set(aircraft.get());
|
|
for (int msg_t = 1; msg_t <= 8; ++msg_t) {
|
|
send_msg->append(msg_base.to_msg(msg_t) + "\n");
|
|
}
|
|
send_msg->append(msg_base.to_ID() + "\n");
|
|
send_msg->append(msg_base.to_AIR() + "\n");
|
|
send_msg->append(msg_base.to_CLK() + "\n");
|
|
send_msg->append(msg_base.to_SEL() + "\n");
|
|
send_msg->append(msg_base.to_STA() + "\n");
|
|
return send_msg;
|
|
}
|
|
|
|
bool DF_11_17_18 = df == SSR::Downlink_Format::All_Call_Reply_11 || df == SSR::Downlink_Format::Extended_Squitter_17 || df ==
|
|
SSR::Downlink_Format::Extended_Squitter_Non_Transponder_18;
|
|
if (mode_s_output_type == Mode_S_Output_Type::DF_11_17_18 && !DF_11_17_18) return std::nullopt;
|
|
if (mode_s_output_type == Mode_S_Output_Type::NO_POS_Mode_S) {
|
|
if (aircraft && aircraft->pos().has_value()) {
|
|
return std::nullopt;
|
|
}
|
|
}
|
|
|
|
if (output_format == Output_Data_Format::BIN) {
|
|
send_msg = SSR::packet_to_escape_format(s_msg->packet);
|
|
//send_msg = create_Binary_Format_memory(msg_hex, signal_level, &mlat_timestamp);
|
|
} else if (output_format == Output_Data_Format::BIN_ID) {
|
|
// std::uint32_t id;
|
|
// {
|
|
// id = Global::instance()->mlat_server.id;
|
|
// }
|
|
// auto bin_id_packet = mode_s_msg_packet_to_server_packet(id, data->packet);
|
|
// send_msg = packet_to_escape_format(bin_id_packet);
|
|
} else if (output_format == Output_Data_Format::AVR) {
|
|
send_msg = SSR::create_AVR_format(msg_hex);
|
|
} else if (output_format == Output_Data_Format::AVR_MLAT) {
|
|
send_msg = create_MLAT_AVR_format(msg_hex, &mlat_timestamp);
|
|
} else {
|
|
std::cerr << "Unknown output format " << VAR_STR_1(output_format) << std::endl;
|
|
return std::nullopt;
|
|
}
|
|
}
|
|
return send_msg;
|
|
}
|
|
|
|
void data_feed_thread(std::atomic<bool>& running) {
|
|
auto g = Global::instance();
|
|
for (auto& t : g->mode_acs.data_feed_config.map.list()) {
|
|
if (t->enable) {
|
|
auto ret = t->check_and_open();
|
|
if (!ret) {
|
|
std::cout << "[Data_feed_Config] [" << t->key << "] 第一次打开失败! 程序退出! " << std::endl;
|
|
}
|
|
}
|
|
}
|
|
auto& mode_acs = Global::instance()->mode_acs;
|
|
auto& cfg = mode_acs.data_feed_config;
|
|
auto& pool = cfg.pool_;
|
|
auto t = cfg.empty_wait_milliseconds.load();
|
|
auto& report_data_feed_msg_mum = mode_acs.report_data_feed_msg_mum;
|
|
std::vector<std::shared_ptr<Data_Feed>> enable_feeds; // all_feed 保证声明周期仍然存在
|
|
auto monitor_msg_live = mode_acs.monitor_msg_live.load();
|
|
bool all_empty = true;
|
|
while (running.load(std::memory_order_acquire) == true) {
|
|
// 这两个每次循环都要重新计算 保证实时性
|
|
// if (flush_limit.test()) {
|
|
auto all_feed = cfg.map.list();
|
|
enable_feeds.clear();
|
|
for (auto& feed : all_feed) {
|
|
if (!feed->enable) continue;
|
|
enable_feeds.push_back(feed);
|
|
// 执行特定的刷新逻辑 比如 tcp_server 检查自身的连接
|
|
feed->handle_in_loop();
|
|
}
|
|
|
|
|
|
int m = static_cast<int>(enable_feeds.size());
|
|
for (int j = 0; j < m; j++) {
|
|
auto& feed = enable_feeds[j];
|
|
auto s_num = feed->msg_buffer.mode_s_msg_num.load();
|
|
auto other_num = feed->msg_buffer.mode_other_msg_num.load();
|
|
//const std::vector<std::shared_ptr<Msg>>& all = feed->msg_buffer.get_all();
|
|
const std::vector<std::string*>& all = feed->msg_buffer.get_all();
|
|
// 释放内存池
|
|
|
|
|
|
Pool_Guard pg(&pool, all);
|
|
|
|
auto num = report_data_feed_msg_mum.load();
|
|
if (monitor_msg_live) {
|
|
if (num != 0 && all.size() > num) {
|
|
if (too_many_msg_limit.test()) {
|
|
std::ostringstream oss;
|
|
oss << "feed_key:" << feed->key << " ";
|
|
oss << "recv_s:" << s_num << " ";
|
|
oss << "recv_other:" << other_num << " ";
|
|
std::cout << oss.str() << std::endl;
|
|
}
|
|
}
|
|
}
|
|
if (all.empty()) continue;
|
|
all_empty = false;
|
|
auto n = all.size();
|
|
|
|
|
|
|
|
for (auto i = 0; i < n; i++) {
|
|
const auto& str = all[i];
|
|
if (str->empty()) {
|
|
std::cout << "警告:未知原因:" << feed->key << "内有空的消息体" << std::endl;
|
|
continue;
|
|
}
|
|
if (feed->type == "Data_Feed_TCP_Server") {
|
|
auto it = dynamic_cast<Data_Feed_TCP_Server*>(feed.get());
|
|
ucoro::sync_await(it->svr.write_to_all_clients_coro(*str));
|
|
}
|
|
else if (feed->type == "Data_Feed_UDP_Server") {
|
|
auto it = dynamic_cast<Data_Feed_UDP_Server*>(feed.get());
|
|
ucoro::sync_await(it->svr.write_to_all_clients_coro(*str));
|
|
}
|
|
else if (feed->type == "Data_Feed_TCP_Client") {
|
|
auto it = dynamic_cast<Data_Feed_TCP_Client*>(feed.get());
|
|
ucoro::sync_await(it->cli.send_coro(*str));
|
|
}
|
|
else if (feed->type == "Data_Feed_UDP_Client") {
|
|
auto it = dynamic_cast<Data_Feed_UDP_Client*>(feed.get());
|
|
ucoro::sync_await(it->cli.send_coro(*str));
|
|
}
|
|
}
|
|
}
|
|
if (t != 0) {
|
|
if (all_empty) {
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(t * 2));
|
|
} else {
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(t));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|