Files
ECAP_Server/module/Local_Server/Data_Source/Data_Source_Handler.cpp
T

555 lines
22 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "Data_Source_Handler.h"
#include "Data_Source.h"
#include "Local_Server/server/Global.h"
using namespace Psc;
std::shared_ptr<Data_Source> ds(Data_Source_Handler* dsh) {
return dynamic_cast<Data_Source*>(dsh)->that();
}
std::shared_ptr<SSR::Msg> Data_Source_Handler::create_msg(
const std::string &packet) {
auto source = ds(this);
if (packet[0] != 0x1a)
{
std::cout << "first:" << mem2hex(packet) << std::endl;
return nullptr;
}
std::string error_len = source->key + " " + LOG_POS_SIMPLE + std::string(" ") + "mode_s_error_length";
if (packet.size() < 2) return nullptr;
auto mt = packet[1];
if (mt == SSR::Msg::AC)
{
if (packet.size() != SSR::Msg::AC_len)
{
SSR::mode_s_logger->c_debug(error_len, {},
std::to_string(mt) + " size:" + std::to_string(packet.size()) +
" hex:" + mem2hex(packet) + " should:" + std::to_string(SSR::Msg::AC_len));
mode_ac_statistic.add_length_error();
return nullptr;
}
mode_ac_statistic.add();
return std::make_shared<SSR::Mode_AC_Msg>(source, packet);
}
if (mt == SSR::Msg::S7)
{
if (packet.size() != SSR::Mode_S_Msg::S7_len)
{
SSR::mode_s_logger->c_debug(error_len, {},
std::to_string(mt) + " size:" + std::to_string(packet.size()) +
" hex:" + mem2hex(packet) + " should:" + std::to_string(SSR::Msg::S7_len));
mode_s_statistic.add_length_error("[length error] Msg::S7 handle_mode_s_source");
return nullptr;
}
return std::make_shared<SSR::Mode_S_Msg>(source, packet);
}
if (mt == SSR::Msg::S14)
{
if (packet.size() != SSR::Msg::S14_len)
{
SSR::mode_s_logger->c_debug(error_len, {},
std::to_string(mt) + " size:" + std::to_string(packet.size()) +
" hex:" + mem2hex(packet) + " should:" + std::to_string(SSR::Msg::S14_len));
mode_s_statistic.add_length_error("[length error] Msg::S14 handle_mode_s_source");
return nullptr;
}
return std::make_shared<SSR::Mode_S_Msg>(source, packet);
}
if (mt == SSR::Msg::Radarcape_status) {
return nullptr; // 不知道如何解析跳过
if (packet.size() != SSR::Msg::Radarcape_status_len)
{
SSR::mode_s_logger->c_debug(error_len, {},
std::to_string(mt) + " size:" + std::to_string(packet.size()) +
" hex:" + mem2hex(packet) + " should:" + std::to_string(SSR::Msg::Radarcape_status_len));
mode_s_statistic.add_length_error("[length error] Msg::Radarcape_status_len handle_mode_s_source");
return nullptr;
}
return std::make_shared<SSR::Msg>(source, packet);
}
if (mt == SSR::Msg::HULC_Status)
{
if (packet.size() != SSR::Msg::HULC_len)
{
// 找不到协议 size:23 hex:1A34195F0000001500B502FF06F423CE50000090000000 should:5
SSR::mode_s_logger->c_debug(error_len, {},
Psc::to_string(source->type) + " HULC size:" +
std::to_string(packet.size()) + " hex:" + mem2hex(packet));
return nullptr;
}
return std::make_shared<SSR::Msg>(source, packet);
}
// std::cout << "unknown_type:" << memory2hex(packet);
rotating_log("unknown_type", mem2hex(packet));
return nullptr;
}
void Data_Source_Handler::process_mode_acs_data(const std::string& origin_data) {
// 先读取原始数据 注意多复制了一遍
auto mode_data = origin_data;
origin_data_transform_mode_data(mode_data);
if (mode_data.empty()) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
auto source = ds(this);
auto size = mode_data.size();
read_speed.update(size);
value_statistics.update(size);
// 预处理数据
static bool mode_s_console = Global::instance()->console_config.mode_s_console;
static bool record_playback = Global::instance()->console_config.record_playback;
if (mode_data.empty()) return;
if (record_playback) {
pure_log(get_exe_dir() + "/playback/" + source->key + "_playback.dat", mem2hex(mode_data, true, " ") + "\n");
}
if (mode_s_console) {
std::cout << source->key + " read:[mode_s_serial]:" << mem2hex(mode_data) << std::endl;
}
SSR::Binary_Format_handle_buffer(source->buffer, mode_data, [this, source](std::string& packet) {
auto msg = create_msg(packet);
if (!msg) return;
source->push_to_feed(msg);
auto mt = msg->type;
bool mode_s = mt == SSR::Msg::S7 || mt == SSR::Msg::S14;
if (mt == SSR::Msg::HULC_Status) {
source->handle_HULC(packet);
}
else if (mt == SSR::Msg::Radarcape_status) {
auto radarcape_msg = SSR::create_Radarcape_STATUS_Message(packet);
std::cout << radarcape_msg.toJson().to_json_string() << std::endl;
SSR::mode_s_logger->debug("Radarcape_status/radarcape", {}, radarcape_msg.toJson().to_json_string());
}
else if (mode_s)
{
// 拓展点
handle_mode_s(std::dynamic_pointer_cast<SSR::Mode_S_Msg>(msg));
}
});
}
void Data_Source_Handler::handle_mode_s(std::shared_ptr<SSR::Mode_S_Msg> mode_s_msg) {
auto source = ds(this);
std::string t = mode_s_msg->mlat_timestamp.to_memory() + mode_s_msg->signal_level + Psc::hex2mem(mode_s_msg->msg_hex);
auto p = mode_s_msg->packet.substr(2);
if (t != p) {
std::cout << mem2hex(t, true, " ") << std::endl;
std::cout << mem2hex(mode_s_msg->packet, true, " ") << std::endl;
std::cout << VAR_STR_2(t, mode_s_msg->packet) << std::endl;
}
// TODO: 可能不需要push_to_feed
source->push_to_feed(mode_s_msg);
auto& cfg = Global::instance()->mode_acs;
SSR::parse_mode_s_bin(source.get(), mode_s_msg, source->base_station.get_pos(),cfg.max_speed_m_s, cfg.air_pos_timeout, cfg.surface_pos_timeout);
auto base = source->get_aircraft(mode_s_msg->icao);
if (base)
{
auto derived = std::dynamic_pointer_cast<Aircraft>(base);
derived->refresh_external_database_info();
}
if (Global::instance()->mlat.merge) {
auto& mh = Global::instance()->mlat_handler;
mh.push(mode_s_msg);
auto tt = mh.get_all();
if (!tt.empty()) {
pure_log("@/logs/mlat.log", "receive[" + std::to_string(tt.size()) + "]:\n");
for (Mlat_MSG& t : tt) {
std::ostringstream oss;
oss << std::fixed << std::setprecision(10);
oss << "===================================================\n";
int n = static_cast<int>(t.size());
auto icao = t.icao().value_or("null");
oss << "\tmlat_msg:" << n;
oss << "\ticao:" << icao;
oss << "\thex:" << t.msg_hex() << std::endl;
bool have_pos = false;
if (icao != "null") {
auto air = source->get_aircraft(icao);
if (air != nullptr) {
auto callsign = air->bds20_call_sign();
oss << "\tcall_sign" << callsign.value_or("null") << std::endl;
auto o_pos = air->pos();
auto o_alt = air->altitude_meter();
if (o_pos.has_value() && o_alt.has_value()) {
have_pos = true;
auto pos = o_pos.value();
source->alt = o_alt.value();
double x, y, z;
SSR::CPR::WGS84_LBH_to_XYZ(pos.lon, pos.lat, source->alt, x, y, z);
oss << "\tpos[" << pos.lon << "," << pos.lat << "," << source->alt << "]" << std::endl;
oss << "\tXYZ[" << x << "," << y << "," << z << "]" << std::endl;
}
}
}
for (int i = 0; i < t.size(); i++) {
auto& msg = t.list[i];
oss << "\t\tds:" << msg->source->get_key();
oss << "\ttime:" << msg->mlat_timestamp.to_string() << std::endl;
}
// if (have_pos) {
//std::cout << oss.str() << std::endl;
pure_log("@/logs/mlat.log", oss.str());
// }
// if (t.size() > 3 && have_pos && icao == "78139F") {
// size_t i = 1;
// auto range = hex_mlat_map.equal_range(t.msg_hex());
// // 遍历与key_to_find对应的所有元素
// for (auto it = range.first; it != range.second; ++it) {
// oss << "\t" << i++ << " " << it->second.msg << std::endl;
// }
// oss << "===================================================\n";
// std::cout << oss.str() << std::endl;
// pure_log("@/logs/icao/" + icao + "_mlat.log", oss.str(), true);
// }
}
}
}
}
void Data_Source_Handler::handle_HULC(const std::string& packet) {
std::uint8_t len = SSR::get_len(packet);
std::uint8_t id = SSR::get_id(packet);
auto msg = mem2hex(packet);
if (len != packet.size() - 4) {
SSR::mode_s_logger->debug("HULC/error_length", {},
"需要: " + std::to_string(len) + " 当前: " + std::to_string(packet.size()) + " hex: " +
mem2hex(packet));
return;
}
if (id == 1) {
// 状态消息
auto status_msg = SSR::create_HULC_Status_Message(packet);
bool gps_ok = status_msg.GPS_device_detected() && status_msg.GPS_valid() && status_msg.GPS_has_valid_fix();
if (gps_ok) {
}
auto g = Global::instance();
base_station.set_msg(status_msg);
Log_Type type({}, {{"msg", msg}});
SSR::mode_s_logger->debug("HULC/status", type, status_msg.toJson().to_json_string());
if (gps_ok) {
}
} else if (id == 24) {
SSR::mode_s_logger->debug("HULC/reply", {}, msg);
} else {
SSR::mode_s_logger->debug("HULC/unknown_id", {}, msg);
}
}
void Data_Source_Handler::refresh_data_feed_key_list() {
//std::cout << key << " refresh_data_feed_key_list" << std::endl;
std::vector<std::string> tmp;
for (auto& relation : Global::instance()->mode_acs.source_feed_relation_config.map.list()) {
if (!relation->enable) continue;
if (relation->type == "One_to_One_Relation") {
auto t = dynamic_cast<One_to_One_Relation*>(relation.get());
//std::cout << VAR_STR_2(t->source_key, this->key) << " refresh_data_feed_key_list" << std::endl;
if (t->source_key == this->key) {
tmp.push_back(t->feed_key);
}
} else if (relation->type == "First_Source_To_All_Feed_Relation") {
auto t = dynamic_cast<First_Source_To_All_Feed_Relation*>(relation.get());
std::shared_ptr<Data_Source> first = nullptr;
for (const auto& ds : Global::instance()->mode_acs.data_source_config.map.list()) {
if (ds->enable) {
first = ds;
break;
}
}
if (first->key == key) {
for (const auto& df : Global::instance()->mode_acs.data_feed_config.map.list()) {
if (df->enable) {
tmp.push_back(df->key);
}
}
}
}
std::sort(tmp.begin(), tmp.end());
// 去重
auto last = std::unique(tmp.begin(), tmp.end());
tmp.erase(last, tmp.end());
{
std::vector<Cached_Source_Info> tmp_info;
// 创建 tmp_info 向量,将 tmp 的内容转化为 Cached_Source_Info 对象
for (const auto& key : tmp) {
tmp_info.push_back({key});
}
{
// 进入临界区,锁住 mutex,确保线程安全
std::lock_guard<std::mutex> lock(cdf_mtx);
// 1. 删除 tmp 中没有的 cached_data_feed_key_list 元素
auto it = cached_data_feed_key_list.begin();
while (it != cached_data_feed_key_list.end()) {
if (std::find_if(tmp_info.begin(), tmp_info.end(),
[&](const Cached_Source_Info& info) {
return info.key == it->key;
}) == tmp_info.end()) {
// 如果当前元素在 tmp 中找不到,删除它
it = cached_data_feed_key_list.erase(it);
} else {
++it;
}
}
// 2. 创建 tmp 中有但 cached_data_feed_key_list 没有的元素
for (const auto& tmp_item : tmp_info) {
auto found = std::find_if(cached_data_feed_key_list.begin(), cached_data_feed_key_list.end(),
[&](const Cached_Source_Info& cached_item) {
return cached_item.key == tmp_item.key;
});
if (found == cached_data_feed_key_list.end()) {
// 如果 tmp_item 不在 cached_data_feed_key_list 中,添加它
cached_data_feed_key_list.push_back(tmp_item);
}
}
}
}
}
}
std::optional<std::string> convert_to_send_format(Data_Source_Handler* 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_Source_Handler::push_to_feed(const std::shared_ptr<SSR::Msg>& msg) {
if (need_refresh_data_feed_key_list) {
refresh_data_feed_key_list();
need_refresh_data_feed_key_list = false;
}
auto& other_size = Global::instance()->mode_acs.mode_other_max_num;
auto& s_size = Global::instance()->mode_acs.mode_other_max_num;
std::vector<std::string> list;
for (const auto& item : cached_data_feed_key_list) {
auto& key = item.key;
auto opt_feed = Global::instance()->mode_acs.data_feed_config.map.get(key);
if (!opt_feed.has_value()) {
std::cout << "wrong data feed: " << key << std::endl;
break;
}
std::shared_ptr<Data_Feed>& feed = opt_feed.value();
if (!feed->enable) continue;
if (msg->type == SSR::Mode_Msg::T::S7 || msg->type == SSR::Mode_Msg::T::S14) {
if (feed->msg_buffer.mode_s_msg_num > s_size) {
continue;
} else {
++feed->msg_buffer.mode_s_msg_num;
}
} else {
if (feed->msg_buffer.mode_other_msg_num > other_size) {
continue;
} else {
++feed->msg_buffer.mode_other_msg_num;
}
}
std::optional<std::string> binary = convert_to_send_format(this, feed, msg);
if (binary.has_value()) {
feed->msg_buffer.push(binary.value());
}
}
}
Psc::JSON Data_Source_Handler::get_all_connect_feed_status() {
Psc::JSON ret = Psc::JSON::object();
std::vector<Cached_Source_Info> list;
{
std::lock_guard g(cdf_mtx);
list = cached_data_feed_key_list;
}
for (auto& i : list) {
Psc::JSON cur = Psc::JSON::object();
auto odf = Global::instance()->mode_acs.data_feed_config.map.get(i.key);
if (odf.has_value()) {
const auto& df = odf.value();
i.mode_s_cache_num.update(df->msg_buffer.mode_s_msg_num);
i.mode_other_cache_num.update(df->msg_buffer.mode_other_msg_num);
cur.append({"mode_s_msg_num", i.mode_s_cache_num.to_json()});
cur.append({"mode_other_msg_num", i.mode_other_cache_num.to_json()});
}
ret.append({i.key, cur});
}
return ret;
}
Psc::JSON Data_Source_Handler::get_all_connect_feed() {
Psc::JSON ret = Psc::JSON::array();
std::vector<Cached_Source_Info> list;
{
std::lock_guard g(cdf_mtx);
list = cached_data_feed_key_list;
}
for (auto& i : list) {
Psc::JSON cur = Psc::JSON::object();
cur.append({"key", i.key});
ret.append(cur);
}
return ret;
}