diff --git a/src/blackcore/context_network.h b/src/blackcore/context_network.h index e04b020a8..a7c3da356 100644 --- a/src/blackcore/context_network.h +++ b/src/blackcore/context_network.h @@ -132,12 +132,15 @@ namespace BlackCore //! Send flight plan virtual void sendFlightPlan(const BlackMisc::Aviation::CFlightPlan &flightPlan) = 0; + //! Load flight plan (from network) + virtual BlackMisc::Aviation::CFlightPlan loadFlightPlanFromNetwork(const BlackMisc::Aviation::CCallsign &callsign) const = 0; + /*! * \brief Get METAR, if not available request it * \param airportIcaoCode such as EDDF, KLAX * \return */ - virtual BlackMisc::Aviation::CInformationMessage getMetar(const QString &airportIcaoCode) = 0; + virtual BlackMisc::Aviation::CInformationMessage getMetar(const BlackMisc::Aviation::CAirportIcao &airportIcaoCode) = 0; //! Use the selected COM1/2 frequencies, and get the corresponding voice room for it virtual BlackMisc::Audio::CVoiceRoomList getSelectedVoiceRooms() const = 0; diff --git a/src/blackcore/context_network_atc.cpp b/src/blackcore/context_network_atc.cpp index 1d4ec657f..ebecaf26b 100644 --- a/src/blackcore/context_network_atc.cpp +++ b/src/blackcore/context_network_atc.cpp @@ -9,7 +9,9 @@ #include "context_runtime.h" #include "blackmisc/avatcstationlist.h" +#include "blackmisc/statusmessage.h" #include "blackmisc/predicates.h" +#include "blackcore/context_application.h" #include #include @@ -41,7 +43,7 @@ namespace BlackCore /* * Update bookings */ - void CContextNetwork::psReceivedBookings(CAtcStationList bookedStations) + void CContextNetwork::psReceivedBookings(const CAtcStationList &bookedStations) { const int interval = 60 * 1000; if (this->m_vatsimBookingReader->interval() < interval) this->m_vatsimBookingReader->setInterval(interval); @@ -55,6 +57,8 @@ namespace BlackCore // into list this->m_atcStationsBooked.push_back(bookedStation); } + + this->getIContextApplication()->sendStatusMessage(CStatusMessage::getInfoMessage("Read bookings from network", CStatusMessage::TypeTrafficNetwork)); } /* @@ -106,16 +110,16 @@ namespace BlackCore /* * Request METAR */ - BlackMisc::Aviation::CInformationMessage CContextNetwork::getMetar(const QString &airportIcaoCode) + BlackMisc::Aviation::CInformationMessage CContextNetwork::getMetar(const BlackMisc::Aviation::CAirportIcao &airportIcaoCode) { + if (this->getRuntime()->isSlotLogForNetworkEnabled()) this->getRuntime()->logSlot(Q_FUNC_INFO, airportIcaoCode.toQString()); CInformationMessage metar; - QString icao = airportIcaoCode.trimmed().toUpper(); - if (icao.length() != 4) return metar; - if (this->m_metarCache.contains(icao)) metar = this->m_metarCache[icao]; + if (airportIcaoCode.isEmpty()) return metar; + if (this->m_metarCache.contains(airportIcaoCode)) metar = this->m_metarCache[airportIcaoCode]; if (metar.isEmpty() || metar.timeDiffReceivedMs() > 10 * 1000) { // outdated, or not in cache at all - this->m_network->sendMetarQuery(airportIcaoCode.trimmed().toUpper()); + this->m_network->sendMetarQuery(airportIcaoCode); // with this little trick we try to make an asynchronous signal / slot // based approach a synchronous return value @@ -124,9 +128,9 @@ namespace BlackCore { // process some other events and hope network answer is received already QCoreApplication::processEvents(QEventLoop::AllEvents, 100); - if (m_metarCache.contains(icao)) + if (m_metarCache.contains(airportIcaoCode)) { - metar = this->m_metarCache[icao]; + metar = this->m_metarCache[airportIcaoCode]; break; } } @@ -139,20 +143,27 @@ namespace BlackCore */ CAtcStationList CContextNetwork::getSelectedAtcStations() const { + CAtcStation com1Station; + CAtcStation com2Station; + CAtcStationList stationsCom1 = this->m_atcStationsOnline.findIfComUnitTunedIn25KHz(this->ownAircraft().getCom1System()); CAtcStationList stationsCom2 = this->m_atcStationsOnline.findIfComUnitTunedIn25KHz(this->ownAircraft().getCom2System()); - stationsCom1.sortBy(&CAtcStation::getDistanceToPlane); - stationsCom2.sortBy(&CAtcStation::getDistanceToPlane); + if (!stationsCom1.isEmpty()) + { + stationsCom1.sortBy(&CAtcStation::getDistanceToPlane); + com1Station = stationsCom1.front(); + } - CAtcStation s; - CAtcStationList stations; - CAtcStation com1 = stationsCom1.isEmpty() ? s : stationsCom1[0]; - CAtcStation com2 = stationsCom2.isEmpty() ? s : stationsCom2[0]; + if (!stationsCom2.isEmpty()) + { + stationsCom2.sortBy(&CAtcStation::getDistanceToPlane); + com2Station = stationsCom2.front(); + } - stations.push_back(com1); - stations.push_back(com2); - - return stations; + CAtcStationList selectedStations; + selectedStations.push_back(com1Station); + selectedStations.push_back(com2Station); + return selectedStations; } /* @@ -165,6 +176,14 @@ namespace BlackCore CVoiceRoomList rooms; rooms.push_back(stations[0].getVoiceRoom()); rooms.push_back(stations[1].getVoiceRoom()); + + CAtcStation s1 = stations[0]; + CAtcStation s2 = stations[1]; + + // KB_REMOVE + qDebug() << this->ownAircraft().getCom1System().getFrequencyActive() << s1.getCallsign() << s1.getFrequency() << s1.getVoiceRoom().getVoiceRoomUrl(); + qDebug() << this->ownAircraft().getCom2System().getFrequencyActive() << s2.getCallsign() << s2.getFrequency() << s2.getVoiceRoom().getVoiceRoomUrl(); + return rooms; } @@ -280,25 +299,4 @@ namespace BlackCore if (this->m_atcStationsBooked.contains(&CAtcStation::getCallsign, callsign)) emit this->changedAtcStationsBooked(); } } - - /* - * Metar received - */ - void CContextNetwork::psFsdMetarReceived(const QString &metarMessage) - { - if (metarMessage.length() < 10) return; // invalid - const QString icaoCode = metarMessage.left(4).toUpper(); - const QString icaoCodeTower = icaoCode + "_TWR"; - CCallsign callsignTower(icaoCodeTower); - CInformationMessage metar(CInformationMessage::METAR, metarMessage); - - // add METAR to existing stations - CIndexVariantMap vm(CAtcStation::IndexMetar, metar.toQVariant()); - 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->changedAtcStationsBooked(); - if (this->m_atcStationsBooked.contains(&CAtcStation::getCallsign, callsignTower)) emit this->changedAtcStationsBooked(); - } - } // namespace diff --git a/src/blackcore/context_network_impl.cpp b/src/blackcore/context_network_impl.cpp index d5a823140..fdb5c8dcb 100644 --- a/src/blackcore/context_network_impl.cpp +++ b/src/blackcore/context_network_impl.cpp @@ -67,6 +67,7 @@ namespace BlackCore this->connect(this->m_network, &INetwork::atisVoiceRoomReplyReceived, this, &CContextNetwork::psFsdAtisVoiceRoomQueryReceived); this->connect(this->m_network, &INetwork::atisLogoffTimeReplyReceived, this, &CContextNetwork::psFsdAtisLogoffTimeQueryReceived); this->connect(this->m_network, &INetwork::metarReplyReceived, this, &CContextNetwork::psFsdMetarReceived); + this->connect(this->m_network, &INetwork::flightPlanReplyReceived, this, &CContextNetwork::psFsdFlightplanReceived); this->connect(this->m_network, &INetwork::realNameReplyReceived, this, &CContextNetwork::psFsdRealNameReplyReceived); this->connect(this->m_network, &INetwork::icaoCodesReplyReceived, this, &CContextNetwork::psFsdIcaoCodesReceived); this->connect(this->m_network, &INetwork::pilotDisconnected, this, &CContextNetwork::psFsdPilotDisconnected); @@ -259,15 +260,6 @@ namespace BlackCore this->m_network->setOwnAircraftAvionics(com1, com2, transponder); } - /* - * Own aircraft - */ - CAircraft CContextNetwork::getOwnAircraft() const - { - if (this->getRuntime()->isSlotLogForNetworkEnabled()) this->getRuntime()->logSlot(Q_FUNC_INFO, this->ownAircraft().toQString()); - return this->ownAircraft(); - } - /* * Send text messages */ @@ -284,6 +276,36 @@ namespace BlackCore { if (this->getRuntime()->isSlotLogForNetworkEnabled()) this->getRuntime()->logSlot(Q_FUNC_INFO, flightPlan.toQString()); this->m_network->sendFlightPlan(flightPlan); + this->m_network->sendFlightPlanQuery(this->ownAircraft().getCallsign()); + } + + CFlightPlan CContextNetwork::loadFlightPlanFromNetwork(const BlackMisc::Aviation::CCallsign &callsign) const + { + if (this->getRuntime()->isSlotLogForNetworkEnabled()) this->getRuntime()->logSlot(Q_FUNC_INFO); + CFlightPlan plan; + + // use cache, but not for own callsign (always reload) + if (this->m_flightPlanCache.contains(callsign)) plan = this->m_flightPlanCache[callsign]; + if (!plan.wasSentOrLoaded() || plan.timeDiffSentOrLoadedMs() > 30 * 1000) + { + // outdated, or not in cache at all + this->m_network->sendFlightPlanQuery(callsign); + + // with this little trick we try to make an asynchronous signal / slot + // based approach a synchronous return value + QTime waitForFlightPlan = QTime::currentTime().addMSecs(1000); + while (QTime::currentTime() < waitForFlightPlan) + { + // process some other events and hope network answer is received already + QCoreApplication::processEvents(QEventLoop::AllEvents, 100); + if (m_flightPlanCache.contains(callsign)) + { + plan = this->m_flightPlanCache[callsign]; + break; + } + } + } + return plan; } /* @@ -315,7 +337,7 @@ namespace BlackCore CCallsignList searchList(callsigns); // myself, which is not in the lists below - CAircraft ownAircraft = this->getOwnAircraft(); + CAircraft ownAircraft = this->ownAircraft(); if (!ownAircraft.getCallsign().isEmpty() && searchList.contains(ownAircraft.getCallsign())) { searchList.remove(ownAircraft.getCallsign()); @@ -513,6 +535,37 @@ namespace BlackCore this->m_otherClients.applyIf(&CClient::getCallsign, callsign, vm); } + /* + * Metar received + */ + void CContextNetwork::psFsdMetarReceived(const QString &metarMessage) + { + if (metarMessage.length() < 10) return; // invalid + const QString icaoCode = metarMessage.left(4).toUpper(); + const QString icaoCodeTower = icaoCode + "_TWR"; + CCallsign callsignTower(icaoCodeTower); + CInformationMessage metar(CInformationMessage::METAR, metarMessage); + + // add METAR to existing stations + CIndexVariantMap vm(CAtcStation::IndexMetar, metar.toQVariant()); + 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->changedAtcStationsBooked(); + if (this->m_atcStationsBooked.contains(&CAtcStation::getCallsign, callsignTower)) emit this->changedAtcStationsBooked(); + } + + /* + * Flight plan received + */ + void CContextNetwork::psFsdFlightplanReceived(const CCallsign &callsign, const CFlightPlan &flightPlan) + { + CFlightPlan plan(flightPlan); + plan.setWhenLastSentOrLoaded(QDateTime::currentDateTimeUtc()); + this->m_flightPlanCache.insert(callsign, plan); + } + + void CContextNetwork::sendFsipiCustomPackage(const CCallsign &recipientCallsign) const { QStringList data = this->createFsipiCustomPackageData(); @@ -527,7 +580,7 @@ namespace BlackCore QStringList CContextNetwork::createFsipiCustomPackageData() const { - CAircraft me = this->getOwnAircraft(); + CAircraft me = this->ownAircraft(); CAircraftIcao icao = me.getIcaoInfo(); QString modelString; if (this->getIContextSimulator()) diff --git a/src/blackcore/context_network_impl.h b/src/blackcore/context_network_impl.h index ac29d2210..87ef7bb32 100644 --- a/src/blackcore/context_network_impl.h +++ b/src/blackcore/context_network_impl.h @@ -51,9 +51,6 @@ namespace BlackCore //! Update own cockpit void updateOwnCockpit(const BlackMisc::Aviation::CComSystem &com1, const BlackMisc::Aviation::CComSystem &com2, const BlackMisc::Aviation::CTransponder &transponder); - //! Get own aircraft - BlackMisc::Aviation::CAircraft getOwnAircraft() const; - public slots: // IContextNetwork overrides //! \copydoc IContextNetwork::readAtcBookingsFromSource() @@ -95,8 +92,11 @@ namespace BlackCore //! \copydoc IContextNetwork::sendFlightPlan() virtual void sendFlightPlan(const BlackMisc::Aviation::CFlightPlan &flightPlan) override; - //! \copydoc IContextNetwork::getMetar() - virtual BlackMisc::Aviation::CInformationMessage getMetar(const QString &airportIcaoCode) override; + //! \copydoc IContextNetwork::loadFlightPlanFromNetwork() + virtual BlackMisc::Aviation::CFlightPlan loadFlightPlanFromNetwork(const BlackMisc::Aviation::CCallsign &callsign) const override; + + //! \copydoc IContextNetwork::getMetar + virtual BlackMisc::Aviation::CInformationMessage getMetar(const BlackMisc::Aviation::CAirportIcao &airportIcaoCode) override; //! \copydoc IContextNetwork::getSelectedVoiceRooms() virtual BlackMisc::Audio::CVoiceRoomList getSelectedVoiceRooms() const override; @@ -143,7 +143,8 @@ namespace BlackCore BlackMisc::Aviation::CAircraftList m_aircraftsInRange; BlackMisc::Network::CClientList m_otherClients; BlackCore::INetwork *m_network; - QMap m_metarCache /*!< Keep METARs for a while */; + QMap m_metarCache /*!< Keep METARs for a while */; + QMap m_flightPlanCache /*!< Keep flight plans for a while */; // for reading XML and VATSIM data files CVatsimBookingReader *m_vatsimBookingReader; @@ -190,7 +191,7 @@ namespace BlackCore private slots: //! ATC bookings received - void psReceivedBookings(BlackMisc::Aviation::CAtcStationList bookedStations); + void psReceivedBookings(const BlackMisc::Aviation::CAtcStationList &bookedStations); //! Data file has been read void psDataFileRead(); @@ -231,6 +232,9 @@ namespace BlackCore //! METAR received void psFsdMetarReceived(const QString &metarMessage); + //! Flight plan received + void psFsdFlightplanReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CFlightPlan &flightplan); + //! Realname recevied void psFsdRealNameReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &realname); diff --git a/src/blackcore/context_network_proxy.cpp b/src/blackcore/context_network_proxy.cpp index 674e2d96a..6c7394dbf 100644 --- a/src/blackcore/context_network_proxy.cpp +++ b/src/blackcore/context_network_proxy.cpp @@ -38,7 +38,7 @@ namespace BlackCore "changedAtcStationsOnline", this, SIGNAL(changedAtcStationsOnline())); Q_ASSERT(s); s = connection.connect(serviceName, IContextNetwork::ObjectPath(), IContextNetwork::InterfaceName(), - "changedAtcStationOnlineConnectionStatus", this, SIGNAL(changedAtcStationOnlineConnectionStatus(BlackMisc::Aviation::CAtcStation,bool))); + "changedAtcStationOnlineConnectionStatus", this, SIGNAL(changedAtcStationOnlineConnectionStatus(BlackMisc::Aviation::CAtcStation, bool))); Q_ASSERT(s); s = connection.connect(serviceName, IContextNetwork::ObjectPath(), IContextNetwork::InterfaceName(), "connectionTerminated", this, SIGNAL(connectionTerminated())); @@ -139,7 +139,12 @@ namespace BlackCore this->m_dBusInterface->callDBus(QLatin1Literal("sendFlightPlan"), flightPlan); } - BlackMisc::Aviation::CInformationMessage CContextNetworkProxy::getMetar(const QString &airportIcaoCode) + BlackMisc::Aviation::CFlightPlan CContextNetworkProxy::loadFlightPlanFromNetwork(const BlackMisc::Aviation::CCallsign &callsign) const + { + return this->m_dBusInterface->callDBusRet(QLatin1Literal("loadFlightPlanFromNetwork"), callsign); + } + + BlackMisc::Aviation::CInformationMessage CContextNetworkProxy::getMetar(const BlackMisc::Aviation::CAirportIcao &airportIcaoCode) { return this->m_dBusInterface->callDBusRet(QLatin1Literal("getMetar"), airportIcaoCode); } diff --git a/src/blackcore/context_network_proxy.h b/src/blackcore/context_network_proxy.h index 7b934854d..5e60e2268 100644 --- a/src/blackcore/context_network_proxy.h +++ b/src/blackcore/context_network_proxy.h @@ -73,8 +73,11 @@ namespace BlackCore //! \copydoc IContextNetwork::sendFlightPlan() virtual void sendFlightPlan(const BlackMisc::Aviation::CFlightPlan &flightPlan) override; - //! \copydoc IContextNetwork::getMetar() - virtual BlackMisc::Aviation::CInformationMessage getMetar(const QString &airportIcaoCode) override; + //! \copydoc IContextNetwork::loadFlightPlanFromNetwork() + virtual BlackMisc::Aviation::CFlightPlan loadFlightPlanFromNetwork(const BlackMisc::Aviation::CCallsign &callsign) const override; + + //! \copydoc IContextNetwork::getMetar + virtual BlackMisc::Aviation::CInformationMessage getMetar(const BlackMisc::Aviation::CAirportIcao &airportIcaoCode) override; //! \copydoc IContextNetwork::getSelectedVoiceRooms() virtual BlackMisc::Audio::CVoiceRoomList getSelectedVoiceRooms() const override;