Skip to content
Draft
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
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Build DLL

on:
pull_request:
branches: [main,master,dev,develop]
branches: [master,main,dev,develop]
release:
types: [published]

Expand Down
72 changes: 65 additions & 7 deletions vSMR/SMRPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ struct AcarsMessage {

vector<string> AircraftDemandingClearance;
vector<string> AircraftMessageSent;
vector<string> AircraftClearedByDatalink;
map<string, clock_t> AircraftClearedTimestamps;
vector<string> AircraftMessage;
vector<string> AircraftWilco;
vector<string> AircraftStandby;
Expand All @@ -54,6 +56,7 @@ string ttype;
int messageId = 0;

clock_t timer;
int pollInterval = 45 + rand() % 31; // Random interval between 45-75 seconds

string myfrequency;

Expand Down Expand Up @@ -188,20 +191,41 @@ void pollMessages(void * arg) {
AFX_MANAGE_STATE(AfxGetStaticModuleState());
PlaySound(MAKEINTRESOURCE(IDR_WAVE1), AfxGetInstanceHandle(), SND_RESOURCE | SND_ASYNC);
}
AircraftDemandingClearance.push_back(message.from);
string timeS, dateS;
formatNowTimeDate(timeS, dateS);
// Send ack
// Send ack synchronously before adding to clearance queue
string reqAck = "DEPART MESSAGE REQUEST RECEIVED ";
reqAck += timeS + " " + dateS;
reqAck += " REQUEST BEING PROCESSED";
createPlainCpdlcMessage(reqAck.c_str(), "NE");
tdest = message.from;
_beginthread(sendDatalinkMessage, 0, NULL);

string raw;
string url = baseUrlDatalink;
url += "?logon=";
url += logonCode;
url += "&from=";
url += logonCallsign;
url += "&to=";
url += message.from;
url += "&type=CPDLC&packet=/data2/";
url += std::to_string(++messageId);
url += "//NE/";
url += reqAck;

size_t start_pos = 0;
while ((start_pos = url.find(" ", start_pos)) != std::string::npos) {
url.replace(start_pos, string(" ").length(), "%20");
start_pos += string("%20").length();
}

raw.assign(httpHelper->downloadStringFromURL(url));

// Only add to clearance queue after ack is sent
AircraftDemandingClearance.push_back(message.from);
}
}
else if (message.message.find("WILCO") != std::string::npos || message.message.find("ROGER") != std::string::npos || message.message.find("RGR") != std::string::npos || message.message.find("ACCEPT") != std::string::npos) {
if (std::find(AircraftMessageSent.begin(), AircraftMessageSent.end(), message.from) != AircraftMessageSent.end()) {
// Only send confirmation if this aircraft actually received a clearance (not just a voice message)
if (std::find(AircraftClearedByDatalink.begin(), AircraftClearedByDatalink.end(), message.from) != AircraftClearedByDatalink.end()) {
AircraftWilco.push_back(message.from);
string timeS, dateS;
formatNowTimeDate(timeS, dateS);
Expand All @@ -211,6 +235,10 @@ void pollMessages(void * arg) {
clearanceAck += " CLEARANCE CONFIRMED";
createPlainCpdlcMessage(clearanceAck.c_str(), "NE");
_beginthread(sendDatalinkMessage, 0, NULL);

// Remove from cleared list - clearance workflow is complete
AircraftClearedByDatalink.erase(std::remove(AircraftClearedByDatalink.begin(), AircraftClearedByDatalink.end(), message.from), AircraftClearedByDatalink.end());
AircraftClearedTimestamps.erase(message.from);
}
}
else if (message.message.length() != 0 ){
Expand Down Expand Up @@ -293,6 +321,8 @@ if (DatalinkToSend.sid == "CHK" && DatalinkToSend.rwy == "09R") // CPT 09R
if (PendingMessages.find(DatalinkToSend.callsign) != PendingMessages.end())
PendingMessages.erase(DatalinkToSend.callsign);
AircraftMessageSent.push_back(DatalinkToSend.callsign.c_str());
AircraftClearedByDatalink.push_back(DatalinkToSend.callsign.c_str());
AircraftClearedTimestamps[DatalinkToSend.callsign] = clock();
}
};

Expand Down Expand Up @@ -490,6 +520,10 @@ void CSMRPlugin::OnFunctionCall(int FunctionId, const char * sItemString, POINT
if (std::find(AircraftMessageSent.begin(), AircraftMessageSent.end(), FlightPlan.GetCallsign()) != AircraftMessageSent.end()) {
AircraftMessageSent.erase(std::remove(AircraftMessageSent.begin(), AircraftMessageSent.end(), FlightPlan.GetCallsign()), AircraftMessageSent.end());
}
if (std::find(AircraftClearedByDatalink.begin(), AircraftClearedByDatalink.end(), FlightPlan.GetCallsign()) != AircraftClearedByDatalink.end()) {
AircraftClearedByDatalink.erase(std::remove(AircraftClearedByDatalink.begin(), AircraftClearedByDatalink.end(), FlightPlan.GetCallsign()), AircraftClearedByDatalink.end());
AircraftClearedTimestamps.erase(FlightPlan.GetCallsign());
}
if (std::find(AircraftWilco.begin(), AircraftWilco.end(), FlightPlan.GetCallsign()) != AircraftWilco.end()) {
AircraftWilco.erase(std::remove(AircraftWilco.begin(), AircraftWilco.end(), FlightPlan.GetCallsign()), AircraftWilco.end());
}
Expand Down Expand Up @@ -641,6 +675,17 @@ void CSMRPlugin::OnFlightPlanDisconnect(CFlightPlan FlightPlan)

if (std::find(ManuallyCorrelated.begin(), ManuallyCorrelated.end(), rt.GetSystemID()) != ManuallyCorrelated.end())
ManuallyCorrelated.erase(std::find(ManuallyCorrelated.begin(), ManuallyCorrelated.end(), rt.GetSystemID()));

// Clean up all datalink tracking lists
string callsign = FlightPlan.GetCallsign();
AircraftDemandingClearance.erase(std::remove(AircraftDemandingClearance.begin(), AircraftDemandingClearance.end(), callsign), AircraftDemandingClearance.end());
AircraftMessageSent.erase(std::remove(AircraftMessageSent.begin(), AircraftMessageSent.end(), callsign), AircraftMessageSent.end());
AircraftClearedByDatalink.erase(std::remove(AircraftClearedByDatalink.begin(), AircraftClearedByDatalink.end(), callsign), AircraftClearedByDatalink.end());
AircraftClearedTimestamps.erase(callsign);
AircraftMessage.erase(std::remove(AircraftMessage.begin(), AircraftMessage.end(), callsign), AircraftMessage.end());
AircraftWilco.erase(std::remove(AircraftWilco.begin(), AircraftWilco.end(), callsign), AircraftWilco.end());
AircraftStandby.erase(std::remove(AircraftStandby.begin(), AircraftStandby.end(), callsign), AircraftStandby.end());
PendingMessages.erase(callsign);
}

void CSMRPlugin::OnTimer(int Counter)
Expand All @@ -663,9 +708,22 @@ void CSMRPlugin::OnTimer(int Counter)
HoppieConnected = false;
}

if (((clock() - timer) / CLOCKS_PER_SEC) > 10 && HoppieConnected) {
if (((clock() - timer) / CLOCKS_PER_SEC) > pollInterval && HoppieConnected) {
_beginthread(pollMessages, 0, NULL);
timer = clock();
pollInterval = 45 + rand() % 31; // Next random interval between 45-75 seconds
}

// Remove cleared aircraft after 5 minutes (300 seconds)
clock_t currentTime = clock();
for (auto it = AircraftClearedTimestamps.begin(); it != AircraftClearedTimestamps.end(); ) {
if (((currentTime - it->second) / CLOCKS_PER_SEC) > 300) {
string callsign = it->first;
AircraftClearedByDatalink.erase(std::remove(AircraftClearedByDatalink.begin(), AircraftClearedByDatalink.end(), callsign), AircraftClearedByDatalink.end());
it = AircraftClearedTimestamps.erase(it);
} else {
++it;
}
}

for (auto &ac : AircraftWilco)
Expand Down