Skip to content
Merged
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
3 changes: 3 additions & 0 deletions Changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@
* FPLN - temporarily added scratch pad info which callsign used the sync command
* CONF - collapsing SID or TRANS base when consecutive characters are the same as new Navigraph data collapses those names which are then present in the sector file (#358)
* FPLN - add squawk queue with a grace period to fetch assignements that were too fast. Squawk assignement works now also in auto-mode and with our own included TopSky assign function (fast click sequence). Note: CCAMS only supported in auto-mode as there currently is no additional function implemented (currently not planned) (#388)
* When using our internal TopSky auto-assign function the selected flight plan will be moved to the front of the queue

:gear: **Changed Features / Behaviour**
* GEN - changed topsky and ccams lookup check to lower case
* FPLN - added checks to _CTL_ and _AUTO_ scratch pad entries to not trigger sync queue processing
* FPLN - moved clearance flag sync release to flight plan data update
* FPLN - removed syncing of unset clearance flag - only if the clearance flag is set it will be synced
* ATC - changed frequency matching to consider ICAO (e.g. EDGG, EDDF) and facility (e.g. DEL, GND) and only matches the frequency if ICAO and facility also match in case close but different stations share the same frequency
* flight information stations are determined by "Information" in the name of the station

:lady_beetle: **Fixes**
* CONF - fixed a crash when SID health check was triggered for different SID numbers due to an accidentally wrong type assignment
Expand Down
2 changes: 2 additions & 0 deletions constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,5 +116,7 @@ const std::string ERROR_CONF_DISPLAY = "E052";
const std::string ERROR_CMD_ATCICAO = "E060";

const std::string ERROR_ATC_ICAOSPLIT = "E070";
const std::string ERROR_ATC_ICAOSPLIT_FREQ_OTH = "E070-1";
const std::string ERROR_ATC_ICAOSPLIT_FREQ_MY = "E070-2";

const std::string ERROR_REQ_RWYSPLIT = "E080";
26 changes: 26 additions & 0 deletions eseparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,35 @@ void vsid::EseParser::line(Section s, std::string_view l)

try
{
int facility = 0;

if (atcVec.at(1).find("Information") != std::string::npos) facility = 1;
else
{
std::optional<std::string> callsignFac = std::nullopt;

if(std::vector<std::string> callsignSplit = vsid::utils::split(atcVec.at(0), '_'); callsignSplit.size() > 2)
callsignFac = callsignSplit.at(2);
else if(callsignSplit.size() > 1)
callsignFac = callsignSplit.at(1);


if (callsignFac)
{
const std::string& fac = *callsignFac;

if (fac == "DEL") facility = 2;
else if (fac == "GND") facility = 3;
else if (fac == "TWR") facility = 4;
else if (fac == "APP" || fac == "DEP") facility = 5;
else if (fac == "CTR") facility = 6;
}
}

this->sectionAtc_.emplace(
atcVec.at(0), // callsign
atcVec.at(3), // si
facility,
std::stod(atcVec.at(2)), // freq
visPoints // additional vis points
);
Expand Down
5 changes: 3 additions & 2 deletions eseparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,12 @@ namespace vsid
{
std::string callsign;
std::string si;
int facility;
double freq;
std::vector<EuroScopePlugIn::CPosition> visPoints;

explicit SectionAtc(std::string callsign, std::string si, double freq, std::vector<EuroScopePlugIn::CPosition> visPoints) :
callsign(std::move(callsign)), si(std::move(si)), freq(freq), visPoints(std::move(visPoints)) {}
explicit SectionAtc(std::string callsign, std::string si, int facility, double freq, std::vector<EuroScopePlugIn::CPosition> visPoints) :
callsign(std::move(callsign)), si(std::move(si)), facility(facility), freq(freq), visPoints(std::move(visPoints)) {}

bool operator<(const vsid::SectionAtc& other) const noexcept
{
Expand Down
77 changes: 66 additions & 11 deletions vSIDPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1604,7 +1604,7 @@ bool vsid::VSIDPlugin::outOfVis(EuroScopePlugIn::CFlightPlan& FlightPlan)
{
for (auto& atc : this->sectionAtc)
{
if (myCallsign == atc.callsign || myFreq == atc.freq)
if (myCallsign == atc.callsign || atcFreqMatch(ControllerMyself(), atc))
{
if (atc.visPoints.empty()) return true;

Expand Down Expand Up @@ -1811,6 +1811,66 @@ void vsid::VSIDPlugin::addOrSetSquawk(const std::string& callsign, bool forceTS)
}
}
}

bool vsid::VSIDPlugin::atcFreqMatch(const EuroScopePlugIn::CController& other, const vsid::SectionAtc& local)
{
if (other.GetPrimaryFrequency() != local.freq)
{
messageHandler->writeMessage("DEBUG", "[FREQ Match] other: " + std::to_string(other.GetPrimaryFrequency()) +
" is NOT local: " + std::to_string(local.freq), vsid::MessageHandler::DebugArea::Dev);
return false;
}

const std::string atcCallsign = other.GetCallsign();
const std::string myCallsign = local.callsign;
std::optional<std::string> atcIcao = std::nullopt;
std::optional<std::string> myIcao = std::nullopt;

try
{
atcIcao = vsid::utils::split(atcCallsign, '_').at(0);
messageHandler->removeGenError(ERROR_ATC_ICAOSPLIT_FREQ_OTH + "_" + atcCallsign);
}
catch (std::out_of_range)
{
if (!messageHandler->genErrorsContains(ERROR_ATC_ICAOSPLIT_FREQ_OTH + "_" + atcCallsign))
{
messageHandler->writeMessage("ERROR", "Failed to get ICAO part of other controller callsign \"" + atcCallsign +
"\" in Freq match check. Code: " + ERROR_ATC_ICAOSPLIT_FREQ_OTH);
messageHandler->addGenError(ERROR_ATC_ICAOSPLIT_FREQ_OTH + "_" + atcCallsign);
}
}

try
{
myIcao = vsid::utils::split(myCallsign, '_').at(0);
messageHandler->removeGenError(ERROR_ATC_ICAOSPLIT_FREQ_MY + "_" + myCallsign);
}
catch (std::out_of_range)
{
if (!messageHandler->genErrorsContains(ERROR_ATC_ICAOSPLIT_FREQ_MY + "_" + myCallsign))
{
messageHandler->writeMessage("ERROR", "Failed to get ICAO part of my controller callsign \"" + myCallsign +
"\" in Freq match check. Code: " + ERROR_ATC_ICAOSPLIT_FREQ_MY);
messageHandler->addGenError(ERROR_ATC_ICAOSPLIT_FREQ_MY + "_" + myCallsign);
}
}

if (atcIcao && myIcao && *atcIcao == *myIcao && other.GetFacility() == local.facility)
{
messageHandler->writeMessage("DEBUG", "[FREQ Match] other: " + atcCallsign + "(" + std::to_string(other.GetPrimaryFrequency()) +
") IS local: " + myCallsign + "(" + std::to_string(local.freq) + ")", vsid::MessageHandler::DebugArea::Dev);
return true;
}
else if (other.GetFacility() != local.facility) // #dev - debugging purpose
{
messageHandler->writeMessage("DEBUG", "[FREQ Match] other fac: " + atcCallsign + "(" + std::to_string(other.GetFacility()) +
") is NOT local fac: " + myCallsign + "(" + std::to_string(local.facility) + ")", vsid::MessageHandler::DebugArea::Dev);
return false;

}
else return false;
}
/*
* END OWN FUNCTIONS
*/
Expand Down Expand Up @@ -4720,15 +4780,15 @@ void vsid::VSIDPlugin::OnRadarTargetPositionUpdate(EuroScopePlugIn::CRadarTarget

void vsid::VSIDPlugin::OnControllerPositionUpdate(EuroScopePlugIn::CController Controller)
{
std::string atcCallsign = Controller.GetCallsign();
const std::string atcCallsign = Controller.GetCallsign();
std::string atcSI = Controller.GetPositionId();
int atcFac = Controller.GetFacility();
double atcFreq = Controller.GetPrimaryFrequency();
const int atcFac = Controller.GetFacility();
const double atcFreq = Controller.GetPrimaryFrequency();
std::string atcIcao;

try
{
atcIcao = vsid::utils::split(Controller.GetCallsign(), '_').at(0);
atcIcao = vsid::utils::split(atcCallsign, '_').at(0);
messageHandler->removeGenError(ERROR_ATC_ICAOSPLIT + "_" + atcCallsign);
}
catch (std::out_of_range)
Expand All @@ -4750,7 +4810,7 @@ void vsid::VSIDPlugin::OnControllerPositionUpdate(EuroScopePlugIn::CController C
{
for (const vsid::SectionAtc &sAtc : this->sectionAtc)
{
if (atcCallsign == sAtc.callsign || atcFreq == sAtc.freq)
if (atcCallsign == sAtc.callsign || atcFreqMatch(Controller, sAtc))
{
atcSI = sAtc.si;

Expand Down Expand Up @@ -4855,11 +4915,6 @@ void vsid::VSIDPlugin::OnControllerPositionUpdate(EuroScopePlugIn::CController C
}
}

if (std::none_of(atcIcaos.begin(), atcIcaos.end(), [&](auto atcIcao)
{
return this->activeAirports.contains(atcIcao);
})) return;

for (const std::string& atcIcao : atcIcaos)
{
if (!this->activeAirports.contains(atcIcao)) continue;
Expand Down
12 changes: 12 additions & 0 deletions vSIDPlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -550,5 +550,17 @@ namespace vsid
// Parameter: bool forceTS - if TopSky should be forced for squawk assignment
//************************************
void addOrSetSquawk(const std::string& callsign, bool forceTS = false);

//************************************
// Description: Checks for frequency match and considers ICAO and facility parts matching
// Method: atcFreqMatch
// FullName: vsid::VSIDPlugin::atcFreqMatch
// Access: private
// Returns: bool
// Qualifier:
// Parameter: const EuroScopePlugIn::CController & other
// Parameter: const vsid::SectionAtc & local
//************************************
bool atcFreqMatch(const EuroScopePlugIn::CController& other, const vsid::SectionAtc& local);
};
}