From 085edc82cb4d1243f46f7340f675bbe5d631fe7b Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Sat, 25 Apr 2015 01:36:24 +0200 Subject: [PATCH] refs #395, post merge and rebase adjustments plus further testing fixes: * adjusted iterim position updates * removed deadlocks (thread safe values in airspace monitor) * resolved some merge issues * some smaller fixes in airspace monitor (style, finders) --- src/blackcore/airspace_monitor.cpp | 164 ++++++++++++++--------------- src/blackcore/airspace_monitor.h | 10 +- src/blackcore/network.h | 2 +- src/blackcore/network_vatlib.cpp | 58 +++++----- src/blackcore/network_vatlib.h | 2 +- 5 files changed, 115 insertions(+), 121 deletions(-) diff --git a/src/blackcore/airspace_monitor.cpp b/src/blackcore/airspace_monitor.cpp index a0e77d96a..9aba8935a 100644 --- a/src/blackcore/airspace_monitor.cpp +++ b/src/blackcore/airspace_monitor.cpp @@ -32,6 +32,9 @@ namespace BlackCore m_network(network), m_vatsimBookingReader(bookings), m_vatsimDataFileReader(dataFile), m_analyzer(new CAirspaceAnalyzer(ownAircraftProvider, this, network, this)) { + this->setObjectName("CAirspaceMonitor"); + m_interimPositionUpdateTimer.setObjectName(this->objectName().append(":m_interimPositionUpdateTimer")); + this->connect(this->m_network, &INetwork::atcPositionUpdate, this, &CAirspaceMonitor::ps_atcPositionUpdate); this->connect(this->m_network, &INetwork::atisReplyReceived, this, &CAirspaceMonitor::ps_atisReceived); this->connect(this->m_network, &INetwork::atisVoiceRoomReplyReceived, this, &CAirspaceMonitor::ps_atisVoiceRoomReceived); @@ -49,8 +52,8 @@ namespace BlackCore this->connect(this->m_network, &INetwork::customFSinnPacketReceived, this, &CAirspaceMonitor::ps_customFSinnPacketReceived); this->connect(this->m_network, &INetwork::serverReplyReceived, this, &CAirspaceMonitor::ps_serverReplyReceived); this->connect(this->m_network, &INetwork::aircraftConfigPacketReceived, this, &CAirspaceMonitor::ps_aircraftConfigReceived); - this->connect(&m_interimPositionUpdateTimer, &QTimer::timeout, this, &CAirspaceMonitor::ps_sendInterimPosition); - + this->connect(&m_interimPositionUpdateTimer, &QTimer::timeout, this, &CAirspaceMonitor::ps_sendInterimPositions); + // AutoConnection: this should also avoid race conditions by updating the bookings this->connect(this->m_vatsimBookingReader, &CVatsimBookingReader::dataRead, this, &CAirspaceMonitor::ps_receivedBookings); this->connect(this->m_vatsimDataFileReader, &CVatsimDataFileReader::dataRead, this, &CAirspaceMonitor::ps_receivedDataFile); @@ -228,10 +231,11 @@ namespace BlackCore CCallsignSet searchList(callsigns); // myself, which is not in the lists below - if (!ownAircraft().getCallsign().isEmpty() && searchList.contains(ownAircraft().getCallsign())) + CSimulatedAircraft myAircraft(ownAircraft()); + if (!myAircraft.getCallsign().isEmpty() && searchList.contains(myAircraft.getCallsign())) { - searchList.remove(ownAircraft().getCallsign()); - users.push_back(ownAircraft().getPilot()); + searchList.remove(myAircraft.getCallsign()); + users.push_back(myAircraft.getPilot()); } // do aircraft first, this will handle most callsigns @@ -247,7 +251,7 @@ namespace BlackCore } } - foreach(CAtcStation station, this->m_atcStationsOnline) + for (const CAtcStation &station : this->m_atcStationsOnline) { if (searchList.isEmpty()) break; CCallsign callsign = station.getCallsign(); @@ -260,8 +264,8 @@ namespace BlackCore } // we might have unresolved callsigns - // these are the ones not in range - foreach(CCallsign callsign, searchList) + // those are the ones not in range + for (const CCallsign &callsign : searchList) { CUserList usersByCallsign = this->m_vatsimDataFileReader->getUsersForCallsign(callsign); if (usersByCallsign.isEmpty()) @@ -281,11 +285,8 @@ namespace BlackCore CClientList CAirspaceMonitor::getOtherClientsForCallsigns(const CCallsignSet &callsigns) const { CClientList clients; - if (callsigns.isEmpty()) return clients; - for (const CCallsign &callsign : callsigns) - { - clients.push_back(this->m_otherClients.findBy(&CClient::getCallsign, callsign)); - } + if (callsigns.isEmpty()) { return clients; } + clients.push_back(this->m_otherClients.findByCallsigns(callsigns)); return clients; } @@ -325,18 +326,14 @@ namespace BlackCore { CAtcStation station; CAtcStationList stations = this->m_atcStationsOnline.findIfComUnitTunedIn25KHz(comSystem); - if (!stations.isEmpty()) - { - stations.sortBy(&CAtcStation::getDistanceToOwnAircraft); - station = stations.front(); - } - return station; + if (stations.isEmpty()) { return station; } + stations.sortByDistanceToOwnAircraft(); + return stations.front(); } void CAirspaceMonitor::requestDataUpdates() { - if (!this->m_network->isConnected()) return; - + if (!this->m_network->isConnected()) { return; } for (const CAircraft &aircraft : this->getAircraftInRange()) { const CCallsign cs(aircraft.getCallsign()); @@ -428,7 +425,7 @@ namespace BlackCore // Client vm = CPropertyIndexVariantMap({CClient::IndexUser, CUser::IndexRealName}, realname); vm.addValue({ CClient::IndexVoiceCapabilities }, caps); - if (!this->m_otherClients.contains(&CClient::getCallsign, callsign)) { this->m_otherClients.push_back(CClient(callsign)); } + if (!this->m_otherClients.containsCallsign(callsign)) { this->m_otherClients.push_back(CClient(callsign)); } this->m_otherClients.applyIf(&CClient::getCallsign, callsign, vm); } @@ -444,7 +441,7 @@ namespace BlackCore CPropertyIndexVariantMap vm(CClient::IndexCapabilities, capabilities.toCVariant()); CVoiceCapabilities caps = m_vatsimDataFileReader->getVoiceCapabilityForCallsign(callsign); vm.addValue({CClient::IndexVoiceCapabilities}, caps); - if (!this->m_otherClients.contains(&CClient::getCallsign, callsign)) { this->m_otherClients.push_back(CClient(callsign)); } + if (!this->m_otherClients.containsCallsign(callsign)) { this->m_otherClients.push_back(CClient(callsign)); } this->m_otherClients.applyIf(&CClient::getCallsign, callsign, vm); // apply same to client in aircraft @@ -464,7 +461,7 @@ namespace BlackCore // Request of other client, I can get the other's model from that CPropertyIndexVariantMap vm({ CClient::IndexModel, CAircraftModel::IndexModelString }, model); vm.addValue({ CClient::IndexModel, CAircraftModel::IndexModelType }, static_cast(CAircraftModel::TypeQueriedFromNetwork)); - if (!this->m_otherClients.contains(&CClient::getCallsign, callsign)) + if (!this->m_otherClients.containsCallsign(callsign)) { // with custom packets it can happen, // the packet is received before any other packet @@ -482,7 +479,6 @@ namespace BlackCore // if update was successful we know we have that callsign, otherwise explicit check aircraftContainsCallsign = (u > 0) || this->m_aircraftInRange.containsCallsign(callsign); } - this->sendFsipiCustomPacket(callsign); // response // ICAO response from custom data if (!aircraftDesignator.isEmpty()) @@ -504,7 +500,7 @@ namespace BlackCore void CAirspaceMonitor::ps_serverReplyReceived(const CCallsign &callsign, const QString &server) { if (!this->m_connected || callsign.isEmpty() || server.isEmpty()) { return; } - if (!this->m_otherClients.contains(&CClient::getCallsign, callsign)) { this->m_otherClients.push_back(CClient(callsign)); } + if (!this->m_otherClients.containsCallsign(callsign)) { this->m_otherClients.push_back(CClient(callsign)); } CPropertyIndexVariantMap vm(CClient::IndexServer, server); this->m_otherClients.applyIf(&CClient::getCallsign, callsign, vm); } @@ -522,8 +518,8 @@ namespace BlackCore this->m_atcStationsOnline.applyIf(&CAtcStation::getCallsign, callsignTower, vm); this->m_atcStationsBooked.applyIf(&CAtcStation::getCallsign, callsignTower, vm); this->m_metarCache.insert(icaoCode, metar); - if (this->m_atcStationsOnline.contains(&CAtcStation::getCallsign, callsignTower)) { emit this->changedAtcStationsOnline(); } - if (this->m_atcStationsBooked.contains(&CAtcStation::getCallsign, callsignTower)) { emit this->changedAtcStationsBooked(); } + if (this->m_atcStationsOnline.containsCallsign(callsignTower)) { emit this->changedAtcStationsOnline(); } + if (this->m_atcStationsBooked.containsCallsign(callsignTower)) { emit this->changedAtcStationsBooked(); } } void CAirspaceMonitor::ps_flightPlanReceived(const CCallsign &callsign, const CFlightPlan &flightPlan) @@ -540,16 +536,14 @@ namespace BlackCore void CAirspaceMonitor::removeAllAircraft() { - QWriteLocker l1(&m_lockParts); - QWriteLocker l2(&m_lockSituations); - QWriteLocker l3(&m_lockAircraft); - - for (const CAircraft &aircraft : m_aircraftInRange) + for (const CAircraft &aircraft : getAircraftInRange()) { const CCallsign cs(aircraft.getCallsign()); emit removedAircraft(cs); } + QWriteLocker l1(&m_lockParts); + QWriteLocker l2(&m_lockSituations); m_situationsByCallsign.clear(); m_partsByCallsign.clear(); m_aircraftSupportingParts.clear(); @@ -601,21 +595,18 @@ namespace BlackCore void CAirspaceMonitor::ps_receivedDataFile() { Q_ASSERT(BlackCore::isCurrentThreadCreatingThread(this)); - for (auto i = this->m_otherClients.begin(); i != this->m_otherClients.end(); ++i) + for (auto client = this->m_otherClients.begin(); client != this->m_otherClients.end(); ++client) { - CClient client = (*i); - if (client.hasSpecifiedVoiceCapabilities()) continue; - CVoiceCapabilities vc = this->m_vatsimDataFileReader->getVoiceCapabilityForCallsign(client.getCallsign()); - if (vc.isUnknown()) continue; - client.setVoiceCapabilities(vc); - (*i) = client; + if (client->hasSpecifiedVoiceCapabilities()) { continue; } // we already have voice caps + CVoiceCapabilities vc = this->m_vatsimDataFileReader->getVoiceCapabilityForCallsign(client->getCallsign()); + if (vc.isUnknown()) { continue; } + client->setVoiceCapabilities(vc); } } void CAirspaceMonitor::ps_sendReadyForModelMatching(const CCallsign &callsign, int trial) { // some checks for special conditions, e.g. logout -> empty list, but still signals pending - // lock block CSimulatedAircraft remoteAircraft; { QReadLocker l(&m_lockAircraft); @@ -704,7 +695,7 @@ namespace BlackCore Q_ASSERT(BlackCore::isCurrentThreadCreatingThread(this)); this->m_otherClients.removeByCallsign(callsign); - if (this->m_atcStationsOnline.contains(&CAtcStation::getCallsign, callsign)) + if (this->m_atcStationsOnline.containsCallsign(callsign)) { CAtcStation removedStation = this->m_atcStationsOnline.findFirstByCallsign(callsign); this->m_atcStationsOnline.removeByCallsign(callsign); @@ -799,6 +790,7 @@ namespace BlackCore } // ICAO code received when aircraft is already removed or not yet ready // We add it to cache and use it when aircraft is created + int c; { QWriteLocker l(&m_lockAircraft); if (!this->m_aircraftInRange.containsCallsign(callsign)) @@ -808,18 +800,18 @@ namespace BlackCore } // update - int c = this->m_aircraftInRange.applyIfCallsign(callsign, vm); - if (c > 0) { ps_sendReadyForModelMatching(callsign, 1); } + c = this->m_aircraftInRange.applyIfCallsign(callsign, vm); } + if (c > 0) { ps_sendReadyForModelMatching(callsign, 1); } } void CAirspaceMonitor::ps_aircraftUpdateReceived(const CAircraftSituation &situation, const CTransponder &transponder) { - Q_ASSERT_X(BlackCore::isCurrentThreadCreatingThread(this), "ps_aircraftUpdateReceived", "Called in different thread"); + Q_ASSERT_X(BlackCore::isCurrentThreadCreatingThread(this), Q_FUNC_INFO, "Called in different thread"); if (!this->m_connected) { return; } CCallsign callsign(situation.getCallsign()); - Q_ASSERT_X(!callsign.isEmpty(), "ps_aircraftUpdateReceived", "Empty callsign"); + Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "Empty callsign"); // store situation history this->storeAircraftSituation(situation); @@ -852,7 +844,7 @@ namespace BlackCore this->m_aircraftInRange.push_back(aircraft); // new client, there is a chance it has been already created by custom packet - if (!this->m_otherClients.contains(&CClient::getCallsign, callsign)) + if (!this->m_otherClients.containsCallsign(callsign)) { CClient c(callsign); this->m_otherClients.push_back(c); // initial, will be filled by data later @@ -905,38 +897,41 @@ namespace BlackCore void CAirspaceMonitor::ps_aircraftInterimUpdateReceived(const CAircraftSituation &situation) { - Q_ASSERT_X(BlackCore::isCurrentThreadCreatingThread(this), "ps_aircraftInterimUpdateReceived", "Called in different thread"); + Q_ASSERT_X(BlackCore::isCurrentThreadCreatingThread(this), Q_FUNC_INFO, "Called in different thread"); if (!this->m_connected) { return; } CCallsign callsign(situation.getCallsign()); - Q_ASSERT_X(!callsign.isEmpty(), "ps_aircraftInterimUpdateReceived", "Empty callsign"); + Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "Empty callsign"); // todo: Check if the timestamp is copied here as well. - CAircraftSituation sitationCopy(situation); // Interim packets do not have groundspeed, hence set the last known value. // If there is no full position available yet, throw this interim position away. - auto history = this->m_aircraftSituations.findByCallsign(callsign); - if (history.empty()) return; - sitationCopy.setGroundspeed(history.latestValue().getGroundSpeed()); + CAircraftSituation iterimSituation(situation); + { + QReadLocker l(&m_lockSituations); + auto history = this->m_situationsByCallsign[callsign]; + if (history.empty()) { return; } // we need one full situation + iterimSituation.setCurrentUtcTime(); + iterimSituation.setGroundspeed(history.latestValue().getGroundSpeed()); + } // store situation history - this->m_aircraftSituations.push_front(situation); - this->m_aircraftSituations.removeOlderThanNowMinusOffset(AircraftSituationsRemovedOffsetMs); - emit this->addedRemoteAircraftSituation(situation); + this->storeAircraftSituation(iterimSituation); + emit this->addedAircraftSituation(iterimSituation); - // update - CLength distance = ownAircraft().calculateGreatCircleDistance(situation.getPosition()); - distance.switchUnit(CLengthUnit::NM()); + // update aircraft + //! \todo skip aircraft updates for interim positions as for performance reasons + CLength distance = ownAircraft().calculateGreatCircleDistance(iterimSituation.getPosition()); + distance.switchUnit(CLengthUnit::NM()); // lloks nicer CPropertyIndexVariantMap vm; - vm.addValue(CAircraft::IndexSituation, situation); + vm.addValue(CAircraft::IndexSituation, iterimSituation); vm.addValue(CAircraft::IndexDistanceToOwnAircraft, distance); // here I expect always a changed value - this->m_aircraftInRange.applyIfCallsign(callsign, vm); - this->m_aircraftWatchdog.resetCallsign(callsign); - emit this->changedAircraftInRange(); + QWriteLocker l(&m_lockAircraft); + this->m_aircraftInRange.applyIfCallsign(callsign, vm); } void CAirspaceMonitor::ps_pilotDisconnected(const CCallsign &callsign) @@ -956,13 +951,14 @@ namespace BlackCore m_aircraftSupportingParts.remove(callsign); } - QWriteLocker l(&m_lockAircraft); - bool contains = this->m_aircraftInRange.containsCallsign(callsign); - if (contains) + bool containsCallsign; { - this->m_aircraftInRange.removeByCallsign(callsign); - emit this->removedAircraft(callsign); + QWriteLocker l(&m_lockAircraft); + containsCallsign = this->m_aircraftInRange.containsCallsign(callsign); + if (containsCallsign) { this->m_aircraftInRange.removeByCallsign(callsign); } } + + if (containsCallsign) { emit this->removedAircraft(callsign); } } void CAirspaceMonitor::ps_frequencyReceived(const CCallsign &callsign, const CFrequency &frequency) @@ -970,23 +966,23 @@ namespace BlackCore Q_ASSERT(BlackCore::isCurrentThreadCreatingThread(this)); // update + int changed; CPropertyIndexVariantMap vm({CAircraft::IndexCom1System, CComSystem::IndexActiveFrequency}, frequency.toCVariant()); - QWriteLocker l(&m_lockAircraft); - int changed = this->m_aircraftInRange.applyIf(&CAircraft::getCallsign, callsign, vm, true); + { + QWriteLocker l(&m_lockAircraft); + changed = this->m_aircraftInRange.applyIf(&CAircraft::getCallsign, callsign, vm, true); + } if (changed > 0) { emit this->changedAircraftInRange(); } } - void CAirspaceMonitor::ps_aircraftConfigReceived(const BlackMisc::Aviation::CCallsign &callsign, const QJsonObject &jsonObject, bool isFull) + void CAirspaceMonitor::ps_aircraftConfigReceived(const BlackMisc::Aviation::CCallsign &callsign, const QJsonObject &jsonObject, bool isFull) { Q_ASSERT(BlackCore::isCurrentThreadCreatingThread(this)); - QWriteLocker l(&m_lockAircraft); - CSimulatedAircraftList list = this->m_aircraftInRange.findByCallsign(callsign); - // Skip unknown callsigns - if (list.isEmpty()) { return; } + CSimulatedAircraft simAircraft(getAircraftForCallsign(callsign)); - CSimulatedAircraft simAircraft = list.front(); // If we are not yet synchronized, we throw away any incremental packet + if (!simAircraft.hasValidCallsign()) { return; } if (!simAircraft.isPartsSynchronized() && !isFull) { return; } CAircraftParts parts; @@ -1011,39 +1007,41 @@ namespace BlackCore emit this->addedAircraftParts(parts); // here I expect always a changed value + QWriteLocker l(&m_lockAircraft); this->m_aircraftInRange.setAircraftParts(callsign, parts); } - void CAirspaceMonitor::ps_sendInterimPosition() + void CAirspaceMonitor::ps_sendInterimPositions() { Q_ASSERT(BlackCore::isCurrentThreadCreatingThread(this)); if (!this->m_connected || !m_sendInterimPositions) { return; } CSimulatedAircraftList aircrafts = m_aircraftInRange.findBy(&CSimulatedAircraft::fastPositionUpdates, true); - m_network->sendInterimPosition(aircrafts.getCallsigns()); + m_network->sendInterimPositions(aircrafts.getCallsigns()); + } - void CAirspaceMonitor::storeAircraftSituation(const CAircraftSituation &situation) + void CAirspaceMonitor::storeAircraftSituation(const CAircraftSituation &situation) { - QWriteLocker lock(&m_lockSituations); const CCallsign callsign(situation.getCallsign()); - Q_ASSERT_X(!callsign.isEmpty(), "storeAircraftSituation", "empty callsign"); + Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "empty callsign"); if (callsign.isEmpty()) { return; } // list from new to old + QWriteLocker lock(&m_lockSituations); CAircraftSituationList &l = this->m_situationsByCallsign[callsign]; l.push_frontMaxElements(situation, MaxSituationsPerCallsign); // check sort order - Q_ASSERT_X(l.size() < 2 || l[0].getMSecsSinceEpoch() >= l[1].getMSecsSinceEpoch(), "storeAircraftSituation", "wrong sort order"); + Q_ASSERT_X(l.size() < 2 || l[0].getMSecsSinceEpoch() >= l[1].getMSecsSinceEpoch(), Q_FUNC_INFO, "wrong sort order"); } void CAirspaceMonitor::storeAircraftParts(const CAircraftParts &parts) { - QWriteLocker lock(&m_lockParts); const CCallsign callsign(parts.getCallsign()); Q_ASSERT_X(!callsign.isEmpty(), "storeAircraftParts", "empty callsign"); if (callsign.isEmpty()) { return; } // list sorted from new to old + QWriteLocker lock(&m_lockParts); CAircraftPartsList &l = this->m_partsByCallsign[callsign]; l.push_frontMaxElements(parts, MaxPartsPerCallsign); diff --git a/src/blackcore/airspace_monitor.h b/src/blackcore/airspace_monitor.h index fcb4805ce..6602abe89 100644 --- a/src/blackcore/airspace_monitor.h +++ b/src/blackcore/airspace_monitor.h @@ -159,9 +159,6 @@ namespace BlackCore static const qint64 AircraftPartsRemoveOffsetMs = 30 * 1000; //!< parts older than now - offset will be removed signals: - - //--- DBus / local signals - //! Online ATC stations were changed void changedAtcStationsOnline(); @@ -218,11 +215,6 @@ namespace BlackCore mutable QReadWriteLock m_lockParts; //!< lock for parts mutable QReadWriteLock m_lockAircraft; //!< lock aircraft - // TODO FIXME (MS) should be in INetwork - void sendFsipiCustomPacket(const BlackMisc::Aviation::CCallsign &recipientCallsign) const; - void sendFsipirCustomPacket(const BlackMisc::Aviation::CCallsign &recipientCallsign) const; - QStringList createFsipiCustomPacketData() const; - //! Remove ATC online stations void removeAllOnlineAtcStations(); @@ -274,7 +266,7 @@ namespace BlackCore void ps_receivedDataFile(); void ps_aircraftConfigReceived(const BlackMisc::Aviation::CCallsign &callsign, const QJsonObject &jsonObject, bool isFull); void ps_aircraftInterimUpdateReceived(const BlackMisc::Aviation::CAircraftSituation &situation); - void ps_sendInterimPosition(); + void ps_sendInterimPositions(); }; } // namespace diff --git a/src/blackcore/network.h b/src/blackcore/network.h index 638d814cd..246452d91 100644 --- a/src/blackcore/network.h +++ b/src/blackcore/network.h @@ -346,7 +346,7 @@ namespace BlackCore * Send interim position directly to a set of receivers. * \pre Network must be connected when calling this function. */ - virtual void sendInterimPosition(const BlackMisc::Aviation::CCallsignSet &receiver) = 0; + virtual void sendInterimPositions(const BlackMisc::Aviation::CCallsignSet &receiver) = 0; //! @} //////////////////////////////////////////////////////////////// diff --git a/src/blackcore/network_vatlib.cpp b/src/blackcore/network_vatlib.cpp index 8ccb4594d..e48f087cc 100644 --- a/src/blackcore/network_vatlib.cpp +++ b/src/blackcore/network_vatlib.cpp @@ -119,14 +119,15 @@ namespace BlackCore if (isConnected()) { + CSimulatedAircraft myAircraft(ownAircraft()); if (this->m_loginMode == LoginAsObserver) { // Observer VatAtcPosition pos; pos.facility = vatFacilityTypeUnknown; pos.visibleRange = 10; // NM - pos.latitude = ownAircraft().latitude().value(CAngleUnit::deg()); - pos.longitude = ownAircraft().longitude().value(CAngleUnit::deg()); + pos.latitude = myAircraft.latitude().value(CAngleUnit::deg()); + pos.longitude = myAircraft.longitude().value(CAngleUnit::deg()); pos.elevation = 0; pos.rating = vatAtcRatingObserver; pos.frequency = 199998; @@ -137,18 +138,18 @@ namespace BlackCore // Normal / Stealth mode VatPilotPosition pos; // TODO: we need to distinguish true and pressure altitude - pos.altitudePressure = ownAircraft().getAltitude().value(CLengthUnit::ft()); - pos.altitudeTrue = ownAircraft().getAltitude().value(CLengthUnit::ft()); - pos.heading = ownAircraft().getHeading().value(CAngleUnit::deg()); - pos.pitch = ownAircraft().getPitch().value(CAngleUnit::deg()); - pos.bank = ownAircraft().getBank().value(CAngleUnit::deg()); - pos.latitude = ownAircraft().latitude().value(CAngleUnit::deg()); - pos.longitude = ownAircraft().longitude().value(CAngleUnit::deg()); - pos.groundSpeed = ownAircraft().getGroundSpeed().value(CSpeedUnit::kts()); + pos.altitudePressure = myAircraft.getAltitude().value(CLengthUnit::ft()); + pos.altitudeTrue = myAircraft.getAltitude().value(CLengthUnit::ft()); + pos.heading = myAircraft.getHeading().value(CAngleUnit::deg()); + pos.pitch = myAircraft.getPitch().value(CAngleUnit::deg()); + pos.bank = myAircraft.getBank().value(CAngleUnit::deg()); + pos.latitude = myAircraft.latitude().value(CAngleUnit::deg()); + pos.longitude = myAircraft.longitude().value(CAngleUnit::deg()); + pos.groundSpeed = myAircraft.getGroundSpeed().value(CSpeedUnit::kts()); pos.rating = vatPilotRatingUnknown; - pos.transponderCode = static_cast(ownAircraft().getTransponderCode()); + pos.transponderCode = static_cast(myAircraft.getTransponderCode()); pos.transponderMode = vatTransponderModeStandby; - switch (ownAircraft().getTransponderMode()) + switch (myAircraft.getTransponderMode()) { case CTransponder::ModeC: pos.transponderMode = vatTransponderModeCharlie; break; case CTransponder::StateIdent: pos.transponderMode = vatTransponderModeIdent; break; @@ -422,20 +423,21 @@ namespace BlackCore Vat_SendClientQuery(m_net.data(), vatClientQueryInfo, toFSD(callsign)); } - void CNetworkVatlib::sendInterimPosition(const CCallsignSet &receivers) + void CNetworkVatlib::sendInterimPositions(const CCallsignSet &receivers) { Q_ASSERT_X(isConnected(), "CNetworkVatlib", "Can't send to server when disconnected"); - + if (receivers.isEmpty()) { return; } + CSimulatedAircraft myAircraft(ownAircraft()); if (this->m_loginMode == LoginNormal) { VatInterimPilotPosition pos; // TODO: we need to distinguish true and pressure altitude - pos.altitudeTrue = ownAircraft().getAltitude().value(CLengthUnit::ft()); - pos.heading = ownAircraft().getHeading().value(CAngleUnit::deg()); - pos.pitch = ownAircraft().getPitch().value(CAngleUnit::deg()); - pos.bank = ownAircraft().getBank().value(CAngleUnit::deg()); - pos.latitude = ownAircraft().latitude().value(CAngleUnit::deg()); - pos.longitude = ownAircraft().longitude().value(CAngleUnit::deg()); + pos.altitudeTrue = myAircraft.getAltitude().value(CLengthUnit::ft()); + pos.heading = myAircraft.getHeading().value(CAngleUnit::deg()); + pos.pitch = myAircraft.getPitch().value(CAngleUnit::deg()); + pos.bank = myAircraft.getBank().value(CAngleUnit::deg()); + pos.latitude = myAircraft.latitude().value(CAngleUnit::deg()); + pos.longitude = myAircraft.longitude().value(CAngleUnit::deg()); for (const auto &receiver : receivers) { @@ -615,7 +617,8 @@ namespace BlackCore if (modelString.isEmpty()) { modelString = defaultModelString(); } QStringList data { { "0" }, icao.getAirlineDesignator(), icao.getAircraftDesignator(), - { "" }, { "" }, { "" }, { "" }, icao.getAircraftCombinedType(), modelString }; + { "" }, { "" }, { "" }, { "" }, icao.getAircraftCombinedType(), modelString + }; sendCustomPacket(callsign, "FSIPIR", data); } @@ -627,7 +630,8 @@ namespace BlackCore if (modelString.isEmpty()) { modelString = defaultModelString(); } QStringList data { { "0" }, icao.getAirlineDesignator(), icao.getAircraftDesignator(), - { "" }, { "" }, { "" }, { "" }, icao.getAircraftCombinedType(), modelString }; + { "" }, { "" }, { "" }, { "" }, icao.getAircraftCombinedType(), modelString + }; sendCustomPacket(callsign, "FSIPI", data); } @@ -877,11 +881,11 @@ namespace BlackCore { switch (type) { - case vatInfoQueryTypeFreq: emit cbvar_cast(cbvar)->frequencyReplyReceived(cbvar_cast(cbvar)->fromFSD(callsign), CFrequency(cbvar_cast(cbvar)->fromFSD(data).toFloat(), CFrequencyUnit::MHz())); break; - case vatInfoQueryTypeServer: emit cbvar_cast(cbvar)->serverReplyReceived(cbvar_cast(cbvar)->fromFSD(callsign), cbvar_cast(cbvar)->fromFSD(data)); break; - case vatInfoQueryTypeAtc: emit cbvar_cast(cbvar)->atcReplyReceived(CCallsign(cbvar_cast(cbvar)->fromFSD(data2), CCallsign::Atc), *data == 'Y'); break; - case vatInfoQueryTypeName: emit cbvar_cast(cbvar)->realNameReplyReceived(cbvar_cast(cbvar)->fromFSD(callsign), cbvar_cast(cbvar)->fromFSD(data)); break; - case vatInfoQueryTypeIP: emit cbvar_cast(cbvar)->ipReplyReceived(cbvar_cast(cbvar)->fromFSD(data)); break; + case vatClientQueryFreq: emit cbvar_cast(cbvar)->frequencyReplyReceived(cbvar_cast(cbvar)->fromFSD(callsign), CFrequency(cbvar_cast(cbvar)->fromFSD(data).toFloat(), CFrequencyUnit::MHz())); break; + case vatClientQueryServer: emit cbvar_cast(cbvar)->serverReplyReceived(cbvar_cast(cbvar)->fromFSD(callsign), cbvar_cast(cbvar)->fromFSD(data)); break; + case vatClientQueryAtc: emit cbvar_cast(cbvar)->atcReplyReceived(CCallsign(cbvar_cast(cbvar)->fromFSD(data2), CCallsign::Atc), *data == 'Y'); break; + case vatClientQueryName: emit cbvar_cast(cbvar)->realNameReplyReceived(cbvar_cast(cbvar)->fromFSD(callsign), cbvar_cast(cbvar)->fromFSD(data)); break; + case vatClientQueryIP: emit cbvar_cast(cbvar)->ipReplyReceived(cbvar_cast(cbvar)->fromFSD(data)); break; default: break; } } diff --git a/src/blackcore/network_vatlib.h b/src/blackcore/network_vatlib.h index d948a4b2d..e633163a1 100644 --- a/src/blackcore/network_vatlib.h +++ b/src/blackcore/network_vatlib.h @@ -81,7 +81,7 @@ namespace BlackCore virtual void sendIcaoCodesQuery(const BlackMisc::Aviation::CCallsign &callsign) override; virtual void sendFrequencyQuery(const BlackMisc::Aviation::CCallsign &callsign) override; virtual void sendUserInfoQuery(const BlackMisc::Aviation::CCallsign &callsign) override; - virtual void sendInterimPosition(const BlackMisc::Aviation::CCallsignSet &receiver) override; + virtual void sendInterimPositions(const BlackMisc::Aviation::CCallsignSet &receiver) override; //! @} //! \name Weather slots