Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion src/core/DataManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,20 @@ DataManager::MessageType DataManager::deltaEuroscopeToBackend(const std::array<t

void DataManager::setActiveAirports(const std::list<std::string> activeAirports) {
std::lock_guard guard(this->m_airportLock);
this->m_activeAirports = activeAirports;

std::list<std::string> supportedAirports = Server::instance().getSupportedAirports();
std::list<std::string> cdmActiveAirports;

for (const auto& activeAirport : activeAirports) {
for (const auto& supportedAirport : supportedAirports) {
if (supportedAirport == activeAirport) {
cdmActiveAirports.push_back(supportedAirport);
break;
}
}
}

this->m_activeAirports = cdmActiveAirports;
}

void DataManager::queueFlightplanUpdate(EuroScopePlugIn::CFlightPlan flightplan) {
Expand Down
167 changes: 97 additions & 70 deletions src/core/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,89 +134,116 @@ Server::ServerConfiguration Server::getServerConfig() {
return ServerConfiguration();
}

void Server::retrieveSupportedAirports() {
if (false == this->m_apiIsChecked || false == this->m_apiIsValid) { return; }

std::lock_guard guard(m_clientMutex);
if (m_client) {
std::string url = "/api/v1/airports";
auto result = m_client->Get(url);

if (result && result->status == 200) {
nlohmann::json root;

try {
root = nlohmann::json::parse(result->body);
std::list<std::string> airports;
for (const auto& airport : std::as_const(root)) {
airports.push_back(airport["icao"].get<std::string>());
}
m_supportedAirports = airports;
} catch (const std::exception& e) {
SpdLogger::log(SpdLogger::LogSender::Server, "Failed to parse response JSON: " + std::string(e.what()),
SpdLogger::LogLevel::Info);
}
}
}
}

std::list<std::string> Server::getSupportedAirports() { return m_supportedAirports; };



std::list<types::Pilot> Server::getPilots(const std::list<std::string> airports) {
std::lock_guard guard(m_clientMutex);
if (!m_client) {
return {};
}

std::string url = "/api/v1/pilots";
std::list<types::Pilot> pilots;
std::string baseUrl = "/api/v1/pilots?adep=";

// Add airport filter if specified
if (!airports.empty()) {
url += "?airports=";
url += std::accumulate(std::next(airports.begin()), airports.end(), *airports.begin(),
[](const std::string& a, const std::string& b) { return a + "," + b; });
}
for (const auto& airport : airports) {
std::string url = baseUrl + airport;

SpdLogger::log(SpdLogger::LogSender::Server, url, SpdLogger::LogLevel::Info);
SpdLogger::log(SpdLogger::LogSender::Server, url, SpdLogger::LogLevel::Info);

auto result = m_client->Get(url);
if (result && result->status == 200) {
nlohmann::json root;

try {
root = nlohmann::json::parse(result->body);
std::list<types::Pilot> pilots;

for (const auto& pilot : std::as_const(root)) {
pilots.push_back(types::Pilot());

pilots.back().callsign = pilot["callsign"].get<std::string>();
pilots.back().lastUpdate = utils::Date::isoStringToTimestamp(pilot["updatedAt"].get<std::string>());
pilots.back().inactive = pilot["inactive"].get<bool>();

// position data
pilots.back().latitude = pilot["position"]["lat"].get<double>();
pilots.back().longitude = pilot["position"]["lon"].get<double>();
pilots.back().taxizoneIsTaxiout = pilot["vacdm"]["taxizoneIsTaxiout"].get<bool>();

// flightplan & clearance data
pilots.back().origin = pilot["flightplan"]["departure"].get<std::string>();
pilots.back().destination = pilot["flightplan"]["arrival"].get<std::string>();
pilots.back().runway = pilot["clearance"]["dep_rwy"].get<std::string>();
pilots.back().sid = pilot["clearance"]["sid"].get<std::string>();

// ACDM procedure data
pilots.back().eobt = utils::Date::isoStringToTimestamp(pilot["vacdm"]["eobt"].get<std::string>());
pilots.back().tobt = utils::Date::isoStringToTimestamp(pilot["vacdm"]["tobt"].get<std::string>());
pilots.back().tobt_state = pilot["vacdm"]["tobt_state"].get<std::string>();
pilots.back().ctot = utils::Date::isoStringToTimestamp(pilot["vacdm"]["ctot"].get<std::string>());
pilots.back().ttot = utils::Date::isoStringToTimestamp(pilot["vacdm"]["ttot"].get<std::string>());
pilots.back().tsat = utils::Date::isoStringToTimestamp(pilot["vacdm"]["tsat"].get<std::string>());
pilots.back().exot =
std::chrono::utc_clock::time_point(std::chrono::minutes(pilot["vacdm"]["exot"].get<long int>()));
pilots.back().asat = utils::Date::isoStringToTimestamp(pilot["vacdm"]["asat"].get<std::string>());
pilots.back().aobt = utils::Date::isoStringToTimestamp(pilot["vacdm"]["aobt"].get<std::string>());
pilots.back().atot = utils::Date::isoStringToTimestamp(pilot["vacdm"]["atot"].get<std::string>());
pilots.back().asrt = utils::Date::isoStringToTimestamp(pilot["vacdm"]["asrt"].get<std::string>());
pilots.back().aort = utils::Date::isoStringToTimestamp(pilot["vacdm"]["aort"].get<std::string>());

// ECFMP measures
nlohmann::json measuresArray = pilot["measures"];
std::vector<types::EcfmpMeasure> parsedMeasures;
for (const auto& measureObject : std::as_const(measuresArray)) {
vacdm::types::EcfmpMeasure measure;

measure.ident = measureObject["ident"].get<std::string>();
measure.value = measureObject["value"].get<int>();

parsedMeasures.push_back(measure);
}
pilots.back().measures = parsedMeasures;
auto result = m_client->Get(url);
if (result && result->status == 200) {
nlohmann::json root;

// event booking data
pilots.back().hasBooking = pilot["hasBooking"].get<bool>();
try {
root = nlohmann::json::parse(result->body);

for (const auto& pilot : std::as_const(root)) {
pilots.push_back(types::Pilot());

pilots.back().callsign = pilot["callsign"].get<std::string>();
pilots.back().lastUpdate = utils::Date::isoStringToTimestamp(pilot["updatedAt"].get<std::string>());
pilots.back().inactive = pilot["inactive"].get<bool>();

// position data
pilots.back().latitude = pilot["position"]["lat"].get<double>();
pilots.back().longitude = pilot["position"]["lon"].get<double>();
pilots.back().taxizoneIsTaxiout = pilot["vacdm"]["taxizoneIsTaxiout"].get<bool>();

// flightplan & clearance data
pilots.back().origin = pilot["flightplan"]["departure"].get<std::string>();
pilots.back().destination = pilot["flightplan"]["arrival"].get<std::string>();
pilots.back().runway = pilot["clearance"]["dep_rwy"].get<std::string>();
pilots.back().sid = pilot["clearance"]["sid"].get<std::string>();

// ACDM procedure data
pilots.back().eobt = utils::Date::isoStringToTimestamp(pilot["vacdm"]["eobt"].get<std::string>());
pilots.back().tobt = utils::Date::isoStringToTimestamp(pilot["vacdm"]["tobt"].get<std::string>());
pilots.back().tobt_state = pilot["vacdm"]["tobt_state"].get<std::string>();
pilots.back().ctot = utils::Date::isoStringToTimestamp(pilot["vacdm"]["ctot"].get<std::string>());
pilots.back().ttot = utils::Date::isoStringToTimestamp(pilot["vacdm"]["ttot"].get<std::string>());
pilots.back().tsat = utils::Date::isoStringToTimestamp(pilot["vacdm"]["tsat"].get<std::string>());
pilots.back().exot =
std::chrono::utc_clock::time_point(std::chrono::minutes(pilot["vacdm"]["exot"].get<long int>()));
pilots.back().asat = utils::Date::isoStringToTimestamp(pilot["vacdm"]["asat"].get<std::string>());
pilots.back().aobt = utils::Date::isoStringToTimestamp(pilot["vacdm"]["aobt"].get<std::string>());
pilots.back().atot = utils::Date::isoStringToTimestamp(pilot["vacdm"]["atot"].get<std::string>());
pilots.back().asrt = utils::Date::isoStringToTimestamp(pilot["vacdm"]["asrt"].get<std::string>());
pilots.back().aort = utils::Date::isoStringToTimestamp(pilot["vacdm"]["aort"].get<std::string>());

// ECFMP measures
nlohmann::json measuresArray = pilot["measures"];
std::vector<types::EcfmpMeasure> parsedMeasures;
for (const auto& measureObject : std::as_const(measuresArray)) {
vacdm::types::EcfmpMeasure measure;

measure.ident = measureObject["ident"].get<std::string>();
measure.value = measureObject["value"].get<int>();

parsedMeasures.push_back(measure);
}
pilots.back().measures = parsedMeasures;

// event booking data
pilots.back().hasBooking = pilot["hasBooking"].get<bool>();
}
} catch (const std::exception& e) {
SpdLogger::log(SpdLogger::LogSender::Server, "Failed to parse response JSON: " + std::string(e.what()),
SpdLogger::LogLevel::Info);
}
SpdLogger::log(SpdLogger::LogSender::Server, "Pilots size: " + std::to_string(pilots.size()),
SpdLogger::LogLevel::Info);
return pilots;
} catch (const std::exception& e) {
SpdLogger::log(SpdLogger::LogSender::Server, "Failed to parse response JSON: " + std::string(e.what()),
SpdLogger::LogLevel::Info);
}
}
return {};

SpdLogger::log(SpdLogger::LogSender::Server, "Pilots size: " + std::to_string(pilots.size()),
SpdLogger::LogLevel::Info);
return pilots;
}

void Server::sendPostMessage(const std::string& endpointUrl, const nlohmann::json& root) {
Expand Down
5 changes: 5 additions & 0 deletions src/core/Server.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class Server {
std::string m_errorCode;
ServerConfiguration m_serverConfiguration;

std::list<std::string> m_supportedAirports;

public:
~Server();
Server(const Server&) = delete;
Expand Down Expand Up @@ -78,6 +80,9 @@ class Server {
void setMaster(bool master);
bool getMaster();

void retrieveSupportedAirports();
std::list<std::string> getSupportedAirports();

private:
// Helper method to initialize/reinitialize the HTTP client
void initClient();
Expand Down
4 changes: 2 additions & 2 deletions src/core/TagFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ void vACDM::OnFunctionCall(int functionId, const char *itemString, POINT pt, REC
break;
}
case AOBT_NOW_AND_STATE: {
// set ASRT if ASRT has not been set yet
if (pilot.asrt == types::defaultTime) {
// set AORT if AORT has not been set yet
if (pilot.aort == types::defaultTime) {
DataManager::instance().handleTagFunction(DataManager::MessageType::UpdateAORT, pilot.callsign,
std::chrono::utc_clock::now());
}
Expand Down
1 change: 1 addition & 0 deletions src/vACDM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ void vACDM::checkServerConfiguration() {
} else {
std::string serverName = Server::instance().getServerConfig().name;
DisplayMessage(("Connected to " + serverName), "Server");
Server::instance().retrieveSupportedAirports();
// set active airports and runways
this->OnAirportRunwayActivityChanged();
}
Expand Down
Loading