mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-06 18:25:37 +08:00
committed by
Mathew Sutcliffe
parent
34774bd005
commit
1f2a88e502
91
src/blackcore/blackcore.contextnetwork.xml
Normal file
91
src/blackcore/blackcore.contextnetwork.xml
Normal file
@@ -0,0 +1,91 @@
|
||||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||
<node>
|
||||
<interface name="blackcore.contextnetwork">
|
||||
<signal name="statusMessage">
|
||||
<arg name="message" type="(sii((iii)(iiii)i))" direction="out"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="BlackMisc::CStatusMessage"/>
|
||||
</signal>
|
||||
<signal name="changedAtcStationsOnline">
|
||||
</signal>
|
||||
<signal name="changedAtcStationsBooked">
|
||||
</signal>
|
||||
<signal name="changedAircraftsInRange">
|
||||
</signal>
|
||||
<signal name="connectionTerminated">
|
||||
</signal>
|
||||
<signal name="connectionStatusChanged">
|
||||
<arg name="from" type="u" direction="out"/>
|
||||
<arg name="to" type="u" direction="out"/>
|
||||
</signal>
|
||||
<signal name="textMessagesReceived">
|
||||
<arg name="textMessages" type="(a((s)(s)s(dd(s))))" direction="out"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="BlackMisc::Network::CTextMessageList"/>
|
||||
</signal>
|
||||
<method name="readAtcBookingsFromSource">
|
||||
</method>
|
||||
<method name="getAtcStationsOnline">
|
||||
<arg type="(a((s)(dd(s))(ssss)((dd(s))(dd(s))(dd(s)))(dd(s))(dd(s))b((iii)(iiii)i)((iii)(iiii)i)(si((iii)(iiii)i))(si((iii)(iiii)i))))" direction="out"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="BlackMisc::Aviation::CAtcStationList"/>
|
||||
</method>
|
||||
<method name="getAtcStationsBooked">
|
||||
<arg type="(a((s)(dd(s))(ssss)((dd(s))(dd(s))(dd(s)))(dd(s))(dd(s))b((iii)(iiii)i)((iii)(iiii)i)(si((iii)(iiii)i))(si((iii)(iiii)i))))" direction="out"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="BlackMisc::Aviation::CAtcStationList"/>
|
||||
</method>
|
||||
<method name="getAircraftsInRange">
|
||||
<arg type="(a((s)(ssss)(((dd(s))(dd(s))(dd(s)))(dd(s)i)(dd(s)i)(dd(s))(dd(s))(dd(s))((iii)(iiii)i))(s(dd(s))(dd(s))i)(s(dd(s))(dd(s))i)(sii)(sssss)(dd(s))))" direction="out"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="BlackMisc::Aviation::CAircraftList"/>
|
||||
</method>
|
||||
<method name="getOwnAircraft">
|
||||
<arg type="((s)(ssss)(((dd(s))(dd(s))(dd(s)))(dd(s)i)(dd(s)i)(dd(s))(dd(s))(dd(s))((iii)(iiii)i))(s(dd(s))(dd(s))i)(s(dd(s))(dd(s))i)(sii)(sssss)(dd(s)))" direction="out"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="BlackMisc::Aviation::CAircraft"/>
|
||||
</method>
|
||||
<method name="connectToNetwork">
|
||||
<arg type="(a(sii((iii)(iiii)i)))" direction="out"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="BlackMisc::CStatusMessages"/>
|
||||
</method>
|
||||
<method name="disconnectFromNetwork">
|
||||
<arg type="(a(sii((iii)(iiii)i)))" direction="out"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="BlackMisc::CStatusMessages"/>
|
||||
</method>
|
||||
<method name="isConnected">
|
||||
<arg type="b" direction="out"/>
|
||||
</method>
|
||||
<method name="setOwnAircraft">
|
||||
<arg type="(a(sii((iii)(iiii)i)))" direction="out"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="BlackMisc::CStatusMessages"/>
|
||||
<arg name="aircraft" type="((s)(ssss)(((dd(s))(dd(s))(dd(s)))(dd(s)i)(dd(s)i)(dd(s))(dd(s))(dd(s))((iii)(iiii)i))(s(dd(s))(dd(s))i)(s(dd(s))(dd(s))i)(sii)(sssss)(dd(s)))" direction="in"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="BlackMisc::Aviation::CAircraft"/>
|
||||
</method>
|
||||
<method name="updateOwnPosition">
|
||||
<arg name="position" type="((dd(s))(dd(s))(dd(s)))" direction="in"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="BlackMisc::Geo::CCoordinateGeodetic"/>
|
||||
<arg name="altitude" type="(dd(s)i)" direction="in"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="BlackMisc::Aviation::CAltitude"/>
|
||||
</method>
|
||||
<method name="updateOwnSituation">
|
||||
<arg name="situation" type="(((dd(s))(dd(s))(dd(s)))(dd(s)i)(dd(s)i)(dd(s))(dd(s))(dd(s))((iii)(iiii)i))" direction="in"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="BlackMisc::Aviation::CAircraftSituation"/>
|
||||
</method>
|
||||
<method name="updateOwnCockpit">
|
||||
<arg name="com1" type="(s(dd(s))(dd(s))i)" direction="in"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="BlackMisc::Aviation::CComSystem"/>
|
||||
<arg name="com2" type="(s(dd(s))(dd(s))i)" direction="in"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="BlackMisc::Aviation::CComSystem"/>
|
||||
<arg name="transponder" type="(sii)" direction="in"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.In2" value="BlackMisc::Aviation::CTransponder"/>
|
||||
</method>
|
||||
<method name="sendTextMessages">
|
||||
<arg name="textMessages" type="(a((s)(s)s(dd(s))))" direction="in"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="BlackMisc::Network::CTextMessageList"/>
|
||||
</method>
|
||||
<method name="getMetar">
|
||||
<arg type="(si((iii)(iiii)i))" direction="out"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="BlackMisc::Aviation::CInformationMessage"/>
|
||||
<arg name="airportIcaoCode" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="ping">
|
||||
<arg type="x" direction="out"/>
|
||||
<arg name="token" type="x" direction="in"/>
|
||||
</method>
|
||||
</interface>
|
||||
</node>
|
||||
19
src/blackcore/blackcore.contextsettings.xml
Normal file
19
src/blackcore/blackcore.contextsettings.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||
<node>
|
||||
<interface name="blackcore.contextsettings">
|
||||
<signal name="changedNetworkSettings">
|
||||
</signal>
|
||||
<method name="getNetworkSettings">
|
||||
<arg type="((sssi(ssss))(a(sssi(ssss))))" direction="out"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="BlackMisc::Settings::CSettingsNetwork"/>
|
||||
</method>
|
||||
<method name="value">
|
||||
<arg type="(a(sii))" direction="out"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="BlackMisc::CStatusMessages"/>
|
||||
<arg name="path" type="s" direction="in"/>
|
||||
<arg name="command" type="s" direction="in"/>
|
||||
<arg name="value" type="v" direction="in"/>
|
||||
<arg name="unifiedBlackMetaType" type="i" direction="in"/>
|
||||
</method>
|
||||
</interface>
|
||||
</node>
|
||||
@@ -1,7 +1,7 @@
|
||||
include (../../externals.pri)
|
||||
|
||||
# GUI is required for the matrix classes
|
||||
QT += network dbus
|
||||
QT += network dbus xml
|
||||
|
||||
TARGET = blackcore
|
||||
TEMPLATE = lib
|
||||
@@ -17,9 +17,24 @@ precompile_header:!isEmpty(PRECOMPILED_HEADER) {
|
||||
DEFINES += USING_PCH
|
||||
}
|
||||
|
||||
# Causes nmake to run qdbusxml2cpp to automatically generate the dbus adaptor and interface classes,
|
||||
# then automatically adds them to the sources to compile
|
||||
# !! Make sure the plugin is available as release build and known QT_PLUGIN_PATH
|
||||
# QDBUSXML2CPP_INTERFACE_HEADER_FLAGS = -i blackmisc/blackmiscfreefunctions.h -i blackmisc/blackmiscallvalueclasses.h
|
||||
QDBUSXML2CPP_ADAPTOR_HEADER_FLAGS = -i blackmisc/blackmiscfreefunctions.h -i blackmisc/blackmiscallvalueclasses.h
|
||||
DBUS_ADAPTORS += blackcore.contextnetwork.xml
|
||||
DBUS_ADAPTORS += blackcore.contextsettings.xml
|
||||
|
||||
# DBUS_INTERFACES += blackcore.contextnetwork.xml
|
||||
|
||||
DEFINES += LOG_IN_FILE
|
||||
|
||||
HEADERS += *.h
|
||||
SOURCES += *.cpp
|
||||
|
||||
win32:!win32-g++*: PRE_TARGETDEPS += ../../lib/blackmisc.lib
|
||||
else: PRE_TARGETDEPS += ../../lib/libblackmisc.a
|
||||
|
||||
DESTDIR = ../../lib
|
||||
|
||||
OTHER_FILES += readme.txt blackcore.contextnetwork.xml blackcore.contextsettings.xml
|
||||
|
||||
398
src/blackcore/context_network.cpp
Normal file
398
src/blackcore/context_network.cpp
Normal file
@@ -0,0 +1,398 @@
|
||||
/* Copyright (C) 2013 VATSIM Community / authors
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "context_network.h"
|
||||
#include "coreruntime.h"
|
||||
#include "blackmisc/avatcstationlist.h"
|
||||
#include <QtXml/QDomElement>
|
||||
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackMisc::PhysicalQuantities;
|
||||
using namespace BlackMisc::Aviation;
|
||||
using namespace BlackMisc::Network;
|
||||
using namespace BlackMisc::Geo;
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
|
||||
/*
|
||||
* Init this context
|
||||
*/
|
||||
CContextNetwork::CContextNetwork(CCoreRuntime *parent) :
|
||||
IContextNetwork(parent),
|
||||
m_atcStationsOnline(), m_atcStationsBooked(), m_aircraftsInRange(),
|
||||
m_network(nullptr), m_ownAircraft(),
|
||||
m_metarCache()
|
||||
{
|
||||
|
||||
// 1. Init by "network driver"
|
||||
this->m_network = new NetworkVatlib(this);
|
||||
|
||||
// 2. Init own aircraft
|
||||
this->initOwnAircraft();
|
||||
|
||||
// 3. Init network access driver for XML data (bookings)
|
||||
this->m_networkManager = new QNetworkAccessManager(this);
|
||||
this->connect(this->m_networkManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(psAtcBookingsRead(QNetworkReply *)));
|
||||
this->m_atcBookingTimer = new QTimer(this);
|
||||
this->connect(this->m_atcBookingTimer, SIGNAL(timeout()), this, SLOT(readAtcBookingsFromSource()));
|
||||
this->m_atcBookingTimer->start(15 * 1000);
|
||||
|
||||
// 4. connect signals and slots
|
||||
bool connect = this->connect(this->m_network, SIGNAL(connectionStatusChanged(Cvatlib_Network::connStatus, Cvatlib_Network::connStatus)),
|
||||
this, SLOT(psFsdConnectionStatusChanged(Cvatlib_Network::connStatus, Cvatlib_Network::connStatus)));
|
||||
Q_ASSERT_X(connect, "CContextNetwork", "Cannot connect connectionStatusChanged");
|
||||
|
||||
connect = this->connect(this->m_network, SIGNAL(terminate()),
|
||||
this, SLOT(psFsdConnectionTerminated()));
|
||||
Q_ASSERT_X(connect, "CContextNetwork", "Cannot connect terminate");
|
||||
|
||||
connect = this->connect(this->m_network, SIGNAL(atcPositionUpdate(BlackMisc::Aviation::CCallsign, BlackMisc::PhysicalQuantities::CFrequency, BlackMisc::Geo::CCoordinateGeodetic, BlackMisc::PhysicalQuantities::CLength)),
|
||||
this, SLOT(psFsdAtcPositionUpdate(BlackMisc::Aviation::CCallsign, BlackMisc::PhysicalQuantities::CFrequency, BlackMisc::Geo::CCoordinateGeodetic, BlackMisc::PhysicalQuantities::CLength)));
|
||||
Q_ASSERT_X(connect, "CContextNetwork", "Cannot connect atcPositionUpdate");
|
||||
|
||||
connect = this->connect(this->m_network, SIGNAL(atisQueryReplyReceived(BlackMisc::Aviation::CCallsign, QString)),
|
||||
this, SLOT(psFsdAtisQueryReceived(BlackMisc::Aviation::CCallsign, QString)));
|
||||
Q_ASSERT_X(connect, "CContextNetwork", "Cannot connect atis");
|
||||
|
||||
connect = this->connect(this->m_network, SIGNAL(metarReceived(QString)),
|
||||
this, SLOT(psFsdMetarReceived(QString)));
|
||||
Q_ASSERT_X(connect, "CContextNetwork", "Cannot connect metar");
|
||||
|
||||
connect = this->connect(this->m_network, SIGNAL(nameQueryReplyReceived(BlackMisc::Aviation::CCallsign, QString)),
|
||||
this, SLOT(psFsdNameQueryReplyReceived(BlackMisc::Aviation::CCallsign, QString)));
|
||||
Q_ASSERT_X(connect, "CContextNetwork", "Cannot connect name reply");
|
||||
|
||||
connect = this->connect(this->m_network, SIGNAL(exception(QString, bool)),
|
||||
this, SLOT(psVatlibExceptionMessage(QString, bool)));
|
||||
Q_ASSERT_X(connect, "CContextNetwork", "Cannot connect exception");
|
||||
|
||||
connect = this->connect(this->m_network, SIGNAL(aircraftInfoReceived(BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftIcao)),
|
||||
this, SLOT(psFsdAircraftInfoReceived(BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftIcao)));
|
||||
Q_ASSERT_X(connect, "CContextNetwork", "Cannot connect aircraft info");
|
||||
|
||||
connect = this->connect(this->m_network, SIGNAL(pilotDisconnected(BlackMisc::Aviation::CCallsign)),
|
||||
this, SLOT(psFsdPilotDisconnected(BlackMisc::Aviation::CCallsign)));
|
||||
Q_ASSERT_X(connect, "CContextNetwork", "Cannot connect pilot disconnected");
|
||||
|
||||
connect = this->connect(this->m_network, SIGNAL(aircraftPositionUpdate(BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftSituation, BlackMisc::Aviation::CTransponder)),
|
||||
this, SLOT(psFsdAircraftPositionUpdate(BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftSituation, BlackMisc::Aviation::CTransponder)));
|
||||
Q_ASSERT_X(connect, "CContextNetwork", "Cannot connect aircraft position update");
|
||||
|
||||
connect = this->connect(this->m_network, SIGNAL(frequencyQueryReplyReceived(BlackMisc::Aviation::CCallsign, BlackMisc::PhysicalQuantities::CFrequency)),
|
||||
this, SLOT(psFsdFrequencyReceived(BlackMisc::Aviation::CCallsign, BlackMisc::PhysicalQuantities::CFrequency)));
|
||||
Q_ASSERT_X(connect, "CContextNetwork", "Cannot connect frequency update");
|
||||
|
||||
connect = this->connect(this->m_network, SIGNAL(textMessagesReceived(BlackMisc::Network::CTextMessageList)),
|
||||
this, SLOT(psFsdTextMessageReceived(BlackMisc::Network::CTextMessageList)));
|
||||
Q_ASSERT_X(connect, "CContextNetwork", "Cannot connect text message");
|
||||
|
||||
|
||||
// relay status message
|
||||
connect = this->connect(this->m_network, SIGNAL(statusMessage(BlackMisc::CStatusMessage)),
|
||||
this, SIGNAL(statusMessage(BlackMisc::CStatusMessage)));
|
||||
Q_ASSERT_X(connect, "CContextNetwork", "Cannot connect status message");
|
||||
}
|
||||
|
||||
/*
|
||||
* Cleanup
|
||||
*/
|
||||
CContextNetwork::~CContextNetwork()
|
||||
{
|
||||
if (this->isConnected()) this->disconnectFromNetwork();
|
||||
this->disconnect(this);
|
||||
this->disconnect(this->m_network);
|
||||
}
|
||||
|
||||
/*
|
||||
* Init own aircraft
|
||||
*/
|
||||
void CContextNetwork::initOwnAircraft()
|
||||
{
|
||||
Q_ASSERT(this->getRuntime());
|
||||
Q_ASSERT(this->getRuntime()->getIContextSettings());
|
||||
this->m_ownAircraft.initComSystems();
|
||||
this->m_ownAircraft.initTransponder();
|
||||
CAircraftSituation situation(
|
||||
CCoordinateGeodetic(
|
||||
CLatitude::fromWgs84("N 049° 18' 17"),
|
||||
CLongitude::fromWgs84("E 008° 27' 05"),
|
||||
CLength(0, CLengthUnit::m())),
|
||||
CAltitude(312, CAltitude::MeanSeaLevel, CLengthUnit::ft())
|
||||
);
|
||||
this->m_ownAircraft.setSituation(situation);
|
||||
this->m_ownAircraft.setPilot(this->getRuntime()->getIContextSettings()->getNetworkSettings().getCurrentNetworkServer().getUser());
|
||||
|
||||
// TODO: This would need to come from somewhere (mappings)
|
||||
// Own callsign, plane ICAO status, model used
|
||||
this->m_ownAircraft.setCallsign(CCallsign("BLACK"));
|
||||
this->m_ownAircraft.setIcaoInfo(CAircraftIcao("C172", "L1P", "GA", "GA", "0000ff"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Connect to network
|
||||
*/
|
||||
CStatusMessages CContextNetwork::connectToNetwork()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
CStatusMessages msgs;
|
||||
CServer currentServer = this->getRuntime()->getIContextSettings()->getNetworkSettings().getCurrentNetworkServer();
|
||||
|
||||
if (!currentServer.getUser().isValid())
|
||||
{
|
||||
msgs.append(CStatusMessage(CStatusMessage::TypeTrafficNetwork, CStatusMessage::SeverityWarning, "Invalid user credentials"));
|
||||
}
|
||||
//else if (!this->m_network->isDisconnected())
|
||||
//{
|
||||
// msgs.append(CStatusMessage(CStatusMessage::TypeTrafficNetwork, CStatusMessage::SeverityWarning, "Already connected"));
|
||||
//}
|
||||
else
|
||||
{
|
||||
this->m_ownAircraft.setPilot(currentServer.getUser());
|
||||
this->m_network->setServer(currentServer);
|
||||
//this->m_network->setOwnAircraft(this->m_ownAircraft);
|
||||
this->m_network->initiateConnection();
|
||||
QString msg = "Connection pending ";
|
||||
msg.append(" ").append(currentServer.getAddress()).append(" ").append(QString::number(currentServer.getPort()));
|
||||
msgs.append(CStatusMessage(CStatusMessage::TypeTrafficNetwork, CStatusMessage::SeverityInfo, msg));
|
||||
}
|
||||
return msgs;
|
||||
}
|
||||
|
||||
/*
|
||||
* Disconnect from network
|
||||
*/
|
||||
CStatusMessages CContextNetwork::disconnectFromNetwork()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
CStatusMessages msgs;
|
||||
//if (this->m_network->isDisconnected())
|
||||
//{
|
||||
// msgs.append(CStatusMessage(CStatusMessage::TypeTrafficNetwork, CStatusMessage::SeverityWarning, "Already disconnected"));
|
||||
//}
|
||||
//else
|
||||
{
|
||||
this->m_network->terminateConnection();
|
||||
this->m_aircraftsInRange.clear();
|
||||
this->m_atcStationsBooked.clear();
|
||||
this->m_atcStationsOnline.clear();
|
||||
this->m_metarCache.clear();
|
||||
msgs.append(CStatusMessage(CStatusMessage::TypeTrafficNetwork, CStatusMessage::SeverityInfo, "Connection terminating"));
|
||||
}
|
||||
return msgs;
|
||||
}
|
||||
|
||||
/*
|
||||
* Connected
|
||||
*/
|
||||
bool CContextNetwork::isConnected() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Own's plane position update
|
||||
*/
|
||||
void CContextNetwork::sendOwnAircraftCheckedPositionUpdateToNetwork() const
|
||||
{
|
||||
// TODO: Would this logic go into network_vatlib?
|
||||
// 1. Check not sending to many updates
|
||||
// 2. Send as pull update to intermediate update
|
||||
// 3. Same position, no update?
|
||||
// ...
|
||||
|
||||
// this->log(Q_FUNC_INFO, this->m_ownAircraft.toQString());
|
||||
// this->m_network->sendAircraftUpdate(this->m_ownAircraft);
|
||||
}
|
||||
|
||||
/*
|
||||
* Own Aircraft
|
||||
*/
|
||||
CStatusMessages CContextNetwork::setOwnAircraft(const BlackMisc::Aviation::CAircraft &aircraft)
|
||||
{
|
||||
this->log(Q_FUNC_INFO, aircraft.toQString());
|
||||
CStatusMessages msgs;
|
||||
//if (this->m_network->isDisconnected())
|
||||
//{
|
||||
// this->m_ownAircraft = aircraft;
|
||||
//}
|
||||
//else
|
||||
{
|
||||
msgs.append(CStatusMessage(CStatusMessage::TypeTrafficNetwork, CStatusMessage::SeverityError, "Cannot set plane info, network already connected"));
|
||||
}
|
||||
return msgs;
|
||||
}
|
||||
|
||||
/*
|
||||
* Own Aircraft details
|
||||
*/
|
||||
CStatusMessages CContextNetwork::sendOwnAircraftDetails()
|
||||
{
|
||||
#if 0
|
||||
CStatusMessages msgs;
|
||||
if (this->m_network->isDisconnected() && false)
|
||||
{
|
||||
msgs.append(CStatusMessage(CStatusMessage::TypeTrafficNetwork, CStatusMessage::SeverityError, "Cannot send plane info, network not connected"));
|
||||
|
||||
}
|
||||
else if (!this->m_ownAircraft.isValidForLogin())
|
||||
{
|
||||
msgs.append(CStatusMessage(CStatusMessage::TypeTrafficNetwork, CStatusMessage::SeverityError, "Cannot send plane info, own aircraft is invalid"));
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: really sending plane info ??
|
||||
// NOPE: this->m_network->sendAircraftInfo(this->m_ownAircraft);
|
||||
this->sendOwnAircraftCheckedPositionUpdateToNetwork();
|
||||
QString m("Aircraft send ");
|
||||
m.append(this->m_ownAircraft.toQString(true));
|
||||
msgs.append(CStatusMessage(CStatusMessage::TypeTrafficNetwork, CStatusMessage::SeverityInfo, m));
|
||||
}
|
||||
return msgs;
|
||||
#endif // 0
|
||||
return CStatusMessages();
|
||||
}
|
||||
|
||||
/*
|
||||
* Own position
|
||||
*/
|
||||
void CContextNetwork::updateOwnPosition(const BlackMisc::Geo::CCoordinateGeodetic &position, const BlackMisc::Aviation::CAltitude &altitude)
|
||||
{
|
||||
if (position == this->m_ownAircraft.getPosition() && altitude == this->m_ownAircraft.getAltitude()) return;
|
||||
this->m_ownAircraft.setPosition(position);
|
||||
this->m_ownAircraft.setAltitude(altitude);
|
||||
this->sendOwnAircraftCheckedPositionUpdateToNetwork();
|
||||
}
|
||||
|
||||
/*
|
||||
* Update own situation
|
||||
*/
|
||||
void CContextNetwork::updateOwnSituation(const BlackMisc::Aviation::CAircraftSituation &situation)
|
||||
{
|
||||
if (situation == this->m_ownAircraft.getSituation()) return;
|
||||
this->m_ownAircraft.setSituation(situation);
|
||||
this->sendOwnAircraftCheckedPositionUpdateToNetwork();
|
||||
}
|
||||
|
||||
/*
|
||||
* Own cockpit data
|
||||
*/
|
||||
void CContextNetwork::updateOwnCockpit(const BlackMisc::Aviation::CComSystem &com1, const BlackMisc::Aviation::CComSystem &com2, const BlackMisc::Aviation::CTransponder &transponder)
|
||||
{
|
||||
bool changed = false;
|
||||
if (com1 != this->m_ownAircraft.getCom1System())
|
||||
{
|
||||
this->m_ownAircraft.setCom1System(com1);
|
||||
changed = true;
|
||||
}
|
||||
if (com2 != this->m_ownAircraft.getCom2System())
|
||||
{
|
||||
this->m_ownAircraft.setCom2System(com2);
|
||||
changed = true;
|
||||
}
|
||||
if (transponder != this->m_ownAircraft.getTransponder())
|
||||
{
|
||||
this->m_ownAircraft.setTransponder(transponder);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (!changed) return;
|
||||
//this->m_network->updateOwnCockpit(com1, com2, transponder);
|
||||
}
|
||||
|
||||
/*
|
||||
* Own aircraft
|
||||
*/
|
||||
CAircraft CContextNetwork::getOwnAircraft() const
|
||||
{
|
||||
this->log(Q_FUNC_INFO, this->m_ownAircraft.toQString());
|
||||
return this->m_ownAircraft;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send text messages
|
||||
*/
|
||||
void CContextNetwork::sendTextMessages(const CTextMessageList &textMessages)
|
||||
{
|
||||
this->log(Q_FUNC_INFO, textMessages.toQString());
|
||||
this->m_network->sendTextMessages(textMessages);
|
||||
}
|
||||
|
||||
/*
|
||||
* Connection terminated
|
||||
*/
|
||||
void CContextNetwork::psFsdConnectionTerminated()
|
||||
{
|
||||
emit this->statusMessage(CStatusMessage(CStatusMessage::TypeTrafficNetwork, CStatusMessage::SeverityInfo, "connection terminated"));
|
||||
emit this->connectionTerminated();
|
||||
}
|
||||
|
||||
/*
|
||||
* Connection status changed
|
||||
*/
|
||||
void CContextNetwork::psFsdConnectionStatusChanged(Cvatlib_Network::connStatus from, Cvatlib_Network::connStatus to)
|
||||
{
|
||||
ConnectionStatus fromCs = static_cast<ConnectionStatus>(from);
|
||||
ConnectionStatus toCs = static_cast<ConnectionStatus>(to);
|
||||
CStatusMessages msgs;
|
||||
|
||||
|
||||
// send 1st position
|
||||
if (toCs == CContextNetwork::ConnectionStatusConnected)
|
||||
{
|
||||
msgs = this->sendOwnAircraftDetails();
|
||||
}
|
||||
|
||||
// send as message
|
||||
QString m("connection status changed ");
|
||||
m.append(this->connectionStatusToString(fromCs)).
|
||||
append(" ").
|
||||
append(this->connectionStatusToString(toCs));
|
||||
qDebug() << m;
|
||||
msgs.append(CStatusMessage(CStatusMessage::TypeTrafficNetwork,
|
||||
toCs == ConnectionStatusError ? CStatusMessage::SeverityError : CStatusMessage::SeverityInfo, m));
|
||||
emit this->statusMessage(msgs.at(0));
|
||||
|
||||
// send as own signal
|
||||
emit this->connectionStatusChanged(fromCs, toCs);
|
||||
}
|
||||
|
||||
/*
|
||||
* Name query
|
||||
*/
|
||||
void CContextNetwork::psFsdNameQueryReplyReceived(const CCallsign &callsign, const QString &realname)
|
||||
{
|
||||
this->log(Q_FUNC_INFO, callsign.toQString(), realname);
|
||||
if (realname.isEmpty()) return;
|
||||
CValueMap vm(CAtcStation::IndexControllerRealname, realname);
|
||||
this->m_atcStationsOnline.applyIf(&CAtcStation::getCallsign, callsign, vm);
|
||||
this->m_atcStationsBooked.applyIf(&CAtcStation::getCallsign, callsign, vm);
|
||||
|
||||
vm = CValueMap(CAircraft::IndexPilotRealname, realname);
|
||||
this->m_aircraftsInRange.applyIf(&CAircraft::getCallsign, callsign, vm);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Ping, is DBus alive?
|
||||
*/
|
||||
qint64 CContextNetwork::ping(qint64 token) const
|
||||
{
|
||||
return token;
|
||||
}
|
||||
|
||||
/*
|
||||
* Exception to status message
|
||||
*/
|
||||
void CContextNetwork::psVatlibExceptionMessage(const QString &message, bool fatal)
|
||||
{
|
||||
CStatusMessage msg(CStatusMessage::TypeTrafficNetwork,
|
||||
fatal ? CStatusMessage::SeverityError : CStatusMessage::SeverityWarning, message);
|
||||
emit this->statusMessage(msg);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
354
src/blackcore/context_network.h
Normal file
354
src/blackcore/context_network.h
Normal file
@@ -0,0 +1,354 @@
|
||||
/* Copyright (C) 2013 VATSIM Community / authors
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef BLACKCORE_CONTEXTNETWORK_H
|
||||
#define BLACKCORE_CONTEXTNETWORK_H
|
||||
|
||||
#include "blackcore/dbus_server.h"
|
||||
#include "blackcore/network_vatlib.h"
|
||||
#include "blackcore/context_network_interface.h"
|
||||
#include "blackmisc/avallclasses.h"
|
||||
#include "blackmisc/statusmessage.h"
|
||||
#include "blackmisc/statusmessages.h"
|
||||
#include <QObject>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkReply>
|
||||
#include <QTimer>
|
||||
#include <QMap>
|
||||
|
||||
#define BLACKCORE_CONTEXTNETWORK_INTERFACENAME "blackcore.contextnetwork"
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
|
||||
class CCoreRuntime;
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Network context
|
||||
*/
|
||||
class CContextNetwork : public IContextNetwork
|
||||
{
|
||||
// Register by same name, make signals sender independent
|
||||
// http://dbus.freedesktop.org/doc/dbus-faq.html#idp48032144
|
||||
Q_CLASSINFO("D-Bus Interface", BLACKCORE_CONTEXTNETWORK_INTERFACENAME)
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief With link to server
|
||||
* \param server
|
||||
*/
|
||||
CContextNetwork(CCoreRuntime *parent);
|
||||
|
||||
/*!
|
||||
* \brief Destructor
|
||||
*/
|
||||
virtual ~CContextNetwork();
|
||||
|
||||
/*!
|
||||
* \brief Register myself in DBus
|
||||
* \param server
|
||||
*/
|
||||
void registerWithDBus(CDBusServer *server)
|
||||
{
|
||||
server->addObject(IContextNetwork::ServicePath(), this);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Runtime
|
||||
* \return
|
||||
*/
|
||||
const CCoreRuntime *getRuntime() const
|
||||
{
|
||||
return reinterpret_cast<CCoreRuntime *>(this->parent());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Using local objects?
|
||||
* \return
|
||||
*/
|
||||
virtual bool usingLocalObjects() const { return true; }
|
||||
|
||||
public slots:
|
||||
|
||||
/*!
|
||||
* \brief Read ATC bookings
|
||||
* \return
|
||||
*/
|
||||
virtual void readAtcBookingsFromSource() const;
|
||||
|
||||
/*!
|
||||
* \brief The "central" ATC list with online ATC controllers
|
||||
* \return
|
||||
*/
|
||||
// If I make this &getAtcStations XML is not generated correctly
|
||||
// needs to be crosschecked with the latest version of Qt
|
||||
virtual const BlackMisc::Aviation::CAtcStationList getAtcStationsOnline() const
|
||||
{
|
||||
this->log(Q_FUNC_INFO);
|
||||
return m_atcStationsOnline;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief ATC list, with booked controllers
|
||||
* \return
|
||||
*/
|
||||
// If I make this &getAtcStations XML is not generated correctly
|
||||
virtual const BlackMisc::Aviation::CAtcStationList getAtcStationsBooked() const
|
||||
{
|
||||
this->log(Q_FUNC_INFO);
|
||||
return m_atcStationsBooked;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Aircraft list
|
||||
* \return
|
||||
*/
|
||||
// If I make this &getAtcStations XML is not generated correctly
|
||||
virtual const BlackMisc::Aviation::CAircraftList getAircraftsInRange() const
|
||||
{
|
||||
this->log(Q_FUNC_INFO);
|
||||
return m_aircraftsInRange;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Connect to Network
|
||||
* \return
|
||||
*/
|
||||
virtual BlackMisc::CStatusMessages connectToNetwork();
|
||||
|
||||
/*!
|
||||
* \brief Disconnect from network
|
||||
* \return
|
||||
*/
|
||||
virtual BlackMisc::CStatusMessages disconnectFromNetwork();
|
||||
|
||||
/*!
|
||||
* \brief Network connected?
|
||||
* \return
|
||||
*/
|
||||
virtual bool isConnected() const;
|
||||
|
||||
/*!
|
||||
* \brief Set own aircraft
|
||||
* \param aircraft
|
||||
* \return
|
||||
*/
|
||||
virtual BlackMisc::CStatusMessages setOwnAircraft(const BlackMisc::Aviation::CAircraft &aircraft);
|
||||
|
||||
/*!
|
||||
* \brief Update own position
|
||||
* \param position
|
||||
* \param altitude
|
||||
*/
|
||||
virtual void updateOwnPosition(const BlackMisc::Geo::CCoordinateGeodetic &position, const BlackMisc::Aviation::CAltitude &altitude);
|
||||
|
||||
/*!
|
||||
* \brief Update own situation
|
||||
* \param situation
|
||||
*/
|
||||
virtual void updateOwnSituation(const BlackMisc::Aviation::CAircraftSituation &situation);
|
||||
|
||||
/*!
|
||||
* \brief Update own cockpit
|
||||
* \param com1
|
||||
* \param com2
|
||||
* \param transponder
|
||||
*/
|
||||
virtual void updateOwnCockpit(const BlackMisc::Aviation::CComSystem &com1, const BlackMisc::Aviation::CComSystem &com2, const BlackMisc::Aviation::CTransponder &transponder);
|
||||
|
||||
/*!
|
||||
* \brief Get own aircraft
|
||||
* \return
|
||||
*/
|
||||
virtual BlackMisc::Aviation::CAircraft getOwnAircraft() const;
|
||||
|
||||
/*!
|
||||
* \brief Text messages (also private chat messages)
|
||||
* \param textMessage
|
||||
*/
|
||||
virtual void sendTextMessages(const BlackMisc::Network::CTextMessageList &textMessages);
|
||||
|
||||
/*!
|
||||
* \brief Request METAR
|
||||
* \param airportIcaoCode
|
||||
*/
|
||||
virtual BlackMisc::Aviation::CInformationMessage getMetar(const QString &airportIcaoCode);
|
||||
|
||||
/*!
|
||||
* \brief Used to check if network is alive
|
||||
* \param token
|
||||
* \return
|
||||
*/
|
||||
virtual qint64 ping(qint64 token) const;
|
||||
|
||||
private:
|
||||
BlackMisc::Aviation::CAtcStationList m_atcStationsOnline;
|
||||
BlackMisc::Aviation::CAtcStationList m_atcStationsBooked;
|
||||
BlackMisc::Aviation::CAircraftList m_aircraftsInRange;
|
||||
BlackCore::INetwork *m_network;
|
||||
BlackMisc::Aviation::CAircraft m_ownAircraft;
|
||||
QMap<QString, BlackMisc::Aviation::CInformationMessage> m_metarCache;
|
||||
|
||||
// for reading XML
|
||||
QNetworkAccessManager *m_networkManager;
|
||||
QTimer *m_atcBookingTimer;
|
||||
QDateTime m_atcBookingsUpdateTimestamp;
|
||||
|
||||
/*!
|
||||
* \brief Replace value by new values, but keep object itself intact
|
||||
* \param newStations
|
||||
*/
|
||||
void setAtcStationsBooked(const BlackMisc::Aviation::CAtcStationList &newStations);
|
||||
|
||||
/*!
|
||||
* \brief Replace value by new values, but keep object itself intact
|
||||
* \param newStations
|
||||
*/
|
||||
void setAtcStationsOnline(const BlackMisc::Aviation::CAtcStationList &newStations);
|
||||
|
||||
/*!
|
||||
* \brief The "central" ATC list with online ATC controllers
|
||||
* \return
|
||||
*/
|
||||
BlackMisc::Aviation::CAtcStationList &atcStationsOnline()
|
||||
{
|
||||
return m_atcStationsOnline;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief ATC list, with booked controllers
|
||||
* \return
|
||||
*/
|
||||
BlackMisc::Aviation::CAtcStationList &atcStationsBooked()
|
||||
{
|
||||
return m_atcStationsBooked;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Check position update before sending to network
|
||||
*/
|
||||
void sendOwnAircraftCheckedPositionUpdateToNetwork() const;
|
||||
|
||||
/*!
|
||||
* \brief Own aircraft details
|
||||
* \param aircraft
|
||||
* \return
|
||||
*/
|
||||
BlackMisc::CStatusMessages sendOwnAircraftDetails();
|
||||
|
||||
/*!
|
||||
* \brief Init my very onw aircraft
|
||||
*/
|
||||
void initOwnAircraft();
|
||||
|
||||
private slots:
|
||||
/*!
|
||||
* \brief Terminated connection
|
||||
*/
|
||||
void psFsdConnectionTerminated();
|
||||
|
||||
/*!
|
||||
* \brief Connection status changed
|
||||
* \param from
|
||||
* \param to
|
||||
*/
|
||||
void psFsdConnectionStatusChanged(Cvatlib_Network::connStatus from, Cvatlib_Network::connStatus to);
|
||||
|
||||
/*!
|
||||
* \brief ATC position update
|
||||
* \param callsign
|
||||
* \param frequency
|
||||
* \param position
|
||||
* \param range
|
||||
*/
|
||||
void psFsdAtcPositionUpdate(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::PhysicalQuantities::CFrequency &frequency, const BlackMisc::Geo::CCoordinateGeodetic &position, const BlackMisc::PhysicalQuantities::CLength &range);
|
||||
|
||||
/*!
|
||||
* \brief Controller disconnected
|
||||
* \param callsign
|
||||
*/
|
||||
void psFsdAtcControllerDisconnected(const BlackMisc::Aviation::CCallsign &callsign);
|
||||
|
||||
/*!
|
||||
* \brief ATIS received
|
||||
* \param callsign
|
||||
* \param atisMessage
|
||||
*/
|
||||
void psFsdAtisQueryReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &atisMessage);
|
||||
|
||||
/*!
|
||||
* \brief METAR received
|
||||
* \param metarMessage
|
||||
*/
|
||||
void psFsdMetarReceived(const QString &metarMessage);
|
||||
|
||||
/*!
|
||||
* \brief Realnname recevied
|
||||
* \param callsign
|
||||
* \param realname
|
||||
*/
|
||||
void psFsdNameQueryReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &realname);
|
||||
|
||||
/*!
|
||||
* \brief Plane info received
|
||||
* \param callsign
|
||||
* \param icaoData
|
||||
*/
|
||||
void psFsdAircraftInfoReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftIcao &icaoData);
|
||||
|
||||
/*!
|
||||
* \brief Aircraft position update
|
||||
* \param callsign
|
||||
* \param situation
|
||||
* \param transponder
|
||||
*/
|
||||
void psFsdAircraftPositionUpdate(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &situation, const BlackMisc::Aviation::CTransponder &transponder);
|
||||
|
||||
/*!
|
||||
* \brief Pilot disconnected
|
||||
* \param callsign
|
||||
*/
|
||||
void psFsdPilotDisconnected(const BlackMisc::Aviation::CCallsign &callsign);
|
||||
|
||||
/*!
|
||||
* \brief Frequency received
|
||||
* \param callsign
|
||||
* \param frequency
|
||||
*/
|
||||
void psFsdFrequencyReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::PhysicalQuantities::CFrequency &frequency);
|
||||
|
||||
/*!
|
||||
* \brief Radio text message received
|
||||
* \param callsign
|
||||
* \param message
|
||||
* \param frequencies
|
||||
*/
|
||||
void psFsdTextMessageReceived(const BlackMisc::Network::CTextMessageList &messages);
|
||||
|
||||
/*!
|
||||
* \brief Bookings via XML read
|
||||
* \param nwReply
|
||||
* TODO: encapsulate reading from WWW in some class
|
||||
*/
|
||||
void psAtcBookingsRead(QNetworkReply *nwReply);
|
||||
|
||||
/*!
|
||||
* \brief Exception message
|
||||
* \param message
|
||||
* \param fatal
|
||||
*/
|
||||
void psVatlibExceptionMessage(const QString &message, bool fatal);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
// Declaring BlackCore::CContextNetwork * crashed when reading data
|
||||
Q_DECLARE_METATYPE(BlackCore::CContextNetwork::ConnectionStatus)
|
||||
|
||||
#endif // guard
|
||||
101
src/blackcore/context_network_aircraft.cpp
Normal file
101
src/blackcore/context_network_aircraft.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
/* Copyright (C) 2013 VATSIM Community / authors
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "context_network.h"
|
||||
#include "coreruntime.h"
|
||||
#include "blackmisc/predicates.h"
|
||||
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackMisc::PhysicalQuantities;
|
||||
using namespace BlackMisc::Aviation;
|
||||
using namespace BlackMisc::Network;
|
||||
using namespace BlackMisc::Geo;
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
|
||||
/*
|
||||
* Aircraft info received
|
||||
*/
|
||||
void CContextNetwork::psFsdAircraftInfoReceived(const CCallsign &callsign, const CAircraftIcao &icaoData)
|
||||
{
|
||||
this->log(Q_FUNC_INFO, callsign.toQString(), icaoData.toQString());
|
||||
CAircraftList aircraftsWithCallsign = this->m_aircraftsInRange.findByCallsign(callsign);
|
||||
if (aircraftsWithCallsign.isEmpty())
|
||||
{
|
||||
// new aircraft
|
||||
CAircraft aircraft;
|
||||
aircraft.setCallsign(callsign);
|
||||
aircraft.setIcaoInfo(icaoData);
|
||||
aircraft.calculcateDistanceToPlane(this->m_ownAircraft.getPosition());
|
||||
this->m_aircraftsInRange.insert(aircraft);
|
||||
emit this->m_network->sendFrequencyQuery(callsign);
|
||||
emit this->m_network->sendNameQuery(callsign);
|
||||
emit this->changedAircraftsInRange();
|
||||
}
|
||||
else
|
||||
{
|
||||
// update
|
||||
CValueMap vm(CAircraft::IndexIcao, icaoData.toQVariant());
|
||||
this->m_aircraftsInRange.applyIf(BlackMisc::Predicates::MemberEqual<CAircraft>(&CAircraft::getCallsign, callsign), vm);
|
||||
emit this->changedAircraftsInRange();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Aircraft update received
|
||||
*/
|
||||
void CContextNetwork::psFsdAircraftPositionUpdate(const CCallsign &callsign, const CAircraftSituation &situation, const CTransponder &transponder)
|
||||
{
|
||||
this->log(Q_FUNC_INFO, callsign.toQString(), situation.toQString(), transponder.toQString());
|
||||
CAircraftList list = this->m_aircraftsInRange.findByCallsign(callsign);
|
||||
if (list.isEmpty())
|
||||
{
|
||||
// new aircraft
|
||||
CAircraft aircraft;
|
||||
aircraft.setCallsign(callsign);
|
||||
aircraft.setSituation(situation);
|
||||
aircraft.setTransponder(transponder);
|
||||
aircraft.calculcateDistanceToPlane(this->m_ownAircraft.getPosition());
|
||||
this->m_aircraftsInRange.insert(aircraft);
|
||||
emit this->m_network->sendFrequencyQuery(callsign);
|
||||
emit this->m_network->sendNameQuery(callsign);
|
||||
emit this->m_network->requestAircraftInfo(callsign);
|
||||
emit this->changedAircraftsInRange();
|
||||
}
|
||||
else
|
||||
{
|
||||
// update
|
||||
CValueMap vm;
|
||||
vm.addValue(CAircraft::IndexTransponder, transponder);
|
||||
vm.addValue(CAircraft::IndexSituation, situation);
|
||||
this->m_aircraftsInRange.applyIf(BlackMisc::Predicates::MemberEqual<CAircraft>(&CAircraft::getCallsign, callsign), vm);
|
||||
emit this->changedAircraftsInRange();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Pilot disconnected
|
||||
*/
|
||||
void CContextNetwork::psFsdPilotDisconnected(const CCallsign &callsign)
|
||||
{
|
||||
this->log(Q_FUNC_INFO, callsign.toQString());
|
||||
this->m_aircraftsInRange.removeIf(&CAircraft::getCallsign, callsign);
|
||||
}
|
||||
|
||||
/*
|
||||
* Frequency received
|
||||
*/
|
||||
void CContextNetwork::psFsdFrequencyReceived(const CCallsign &callsign, const CFrequency &frequency)
|
||||
{
|
||||
this->log(Q_FUNC_INFO, callsign.toQString(), frequency.toQString());
|
||||
|
||||
// update
|
||||
CValueMap vm(CAircraft::IndexFrequencyCom1, frequency.toQVariant());
|
||||
this->m_aircraftsInRange.applyIf(BlackMisc::Predicates::MemberEqual<CAircraft>(&CAircraft::getCallsign, callsign), vm);
|
||||
emit this->changedAircraftsInRange();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
238
src/blackcore/context_network_atc.cpp
Normal file
238
src/blackcore/context_network_atc.cpp
Normal file
@@ -0,0 +1,238 @@
|
||||
/* Copyright (C) 2013 VATSIM Community / authors
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "context_network.h"
|
||||
#include "coreruntime.h"
|
||||
#include "blackmisc/avatcstationlist.h"
|
||||
#include "blackmisc/predicates.h"
|
||||
#include <QMetaEnum>
|
||||
#include <QUrl>
|
||||
#include <QNetworkRequest>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QtXml/QDomElement>
|
||||
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackMisc::PhysicalQuantities;
|
||||
using namespace BlackMisc::Aviation;
|
||||
using namespace BlackMisc::Network;
|
||||
using namespace BlackMisc::Geo;
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
|
||||
/*
|
||||
* Read bookings
|
||||
*/
|
||||
void CContextNetwork::readAtcBookingsFromSource() const
|
||||
{
|
||||
QUrl url("http://vatbook.euroutepro.com/xml2.php");
|
||||
QNetworkRequest request(url);
|
||||
this->m_networkManager->get(request);
|
||||
}
|
||||
|
||||
/*
|
||||
* Booked stations
|
||||
*/
|
||||
void CContextNetwork::setAtcStationsBooked(const BlackMisc::Aviation::CAtcStationList &newStations)
|
||||
{
|
||||
this->m_atcStationsBooked = newStations;
|
||||
}
|
||||
|
||||
/*
|
||||
* Online stations
|
||||
*/
|
||||
void CContextNetwork::setAtcStationsOnline(const BlackMisc::Aviation::CAtcStationList &newStations)
|
||||
{
|
||||
this->m_atcStationsOnline = newStations;
|
||||
}
|
||||
|
||||
/*
|
||||
* Request METAR
|
||||
*/
|
||||
BlackMisc::Aviation::CInformationMessage CContextNetwork::getMetar(const QString &airportIcaoCode)
|
||||
{
|
||||
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 (metar.isEmpty() || metar.timeDiffReceivedMs() > 10 * 1000)
|
||||
{
|
||||
// outdated, or not in cache at all
|
||||
this->m_network->requestMetar(airportIcaoCode.trimmed().toUpper());
|
||||
|
||||
// with this little trick we try to make an asynchronous signal / slot
|
||||
// based approach a synchronous return value
|
||||
QTime waitForMetar = QTime::currentTime().addMSecs(1000);
|
||||
while (QTime::currentTime() < waitForMetar)
|
||||
{
|
||||
// process some other events and hope network answer is received already
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
|
||||
if (m_metarCache.contains(icao))
|
||||
{
|
||||
metar = this->m_metarCache[icao];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return metar;
|
||||
}
|
||||
|
||||
/*
|
||||
* ATC Position update
|
||||
*/
|
||||
void CContextNetwork::psFsdAtcPositionUpdate(const CCallsign &callsign, const BlackMisc::PhysicalQuantities::CFrequency &frequency, const CCoordinateGeodetic &position, const BlackMisc::PhysicalQuantities::CLength &range)
|
||||
{
|
||||
this->log(Q_FUNC_INFO, callsign.toQString(), frequency.toQString(), position.toQString(), range.toQString());
|
||||
CAtcStationList stationsWithCallsign = this->m_atcStationsOnline.findByCallsign(callsign);
|
||||
if (stationsWithCallsign.isEmpty())
|
||||
{
|
||||
// new station
|
||||
CAtcStation station;
|
||||
station.setCallsign(callsign);
|
||||
station.setRange(range);
|
||||
station.setFrequency(frequency);
|
||||
station.setPosition(position);
|
||||
station.setOnline(true);
|
||||
station.calculcateDistanceToPlane(this->m_ownAircraft.getPosition());
|
||||
this->m_atcStationsOnline.insert(station);
|
||||
emit this->changedAtcStationsOnline();
|
||||
emit this->m_network->sendAtisQuery(callsign); // request ATIS
|
||||
emit this->m_network->sendNameQuery(callsign);
|
||||
}
|
||||
else
|
||||
{
|
||||
// update
|
||||
CValueMap values;
|
||||
values.addValue(CAtcStation::IndexFrequency, frequency);
|
||||
values.addValue(CAtcStation::IndexPosition, position);
|
||||
values.addValue(CAtcStation::IndexRange, range);
|
||||
this->m_atcStationsOnline.applyIf(BlackMisc::Predicates::MemberEqual<CAtcStation>(&CAtcStation::getCallsign, callsign), values);
|
||||
emit this->changedAtcStationsOnline();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ATC Controller disconnected
|
||||
*/
|
||||
void CContextNetwork::psFsdAtcControllerDisconnected(const CCallsign &callsign)
|
||||
{
|
||||
this->log(Q_FUNC_INFO, callsign.toQString());
|
||||
this->m_atcStationsOnline.removeIf(&CAtcStation::getCallsign, callsign);
|
||||
emit this->changedAtcStationsOnline();
|
||||
this->m_atcStationsBooked.applyIf(&CAtcStation::getCallsign, callsign, CValueMap(CAtcStation::IndexIsOnline, QVariant(false)));
|
||||
}
|
||||
|
||||
/*
|
||||
* ATIS received
|
||||
*/
|
||||
void CContextNetwork::psFsdAtisQueryReceived(const CCallsign &callsign, const QString &atisMessage)
|
||||
{
|
||||
this->log(Q_FUNC_INFO, callsign.toQString(), atisMessage);
|
||||
CValueMap vm(CAtcStation::IndexAtisMessage, atisMessage);
|
||||
this->m_atcStationsOnline.applyIf(&CAtcStation::getCallsign, callsign, vm);
|
||||
this->m_atcStationsBooked.applyIf(&CAtcStation::getCallsign, callsign, vm);
|
||||
}
|
||||
|
||||
/*
|
||||
* Metar received
|
||||
*/
|
||||
void CContextNetwork::psFsdMetarReceived(const QString &metarMessage)
|
||||
{
|
||||
this->log(Q_FUNC_INFO, 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
|
||||
CValueMap 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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Bookings read from XML
|
||||
* TODO: encapsulate reading from WWW in some class
|
||||
*/
|
||||
void CContextNetwork::psAtcBookingsRead(QNetworkReply *nwReply)
|
||||
{
|
||||
if (nwReply->error() == QNetworkReply::NoError)
|
||||
{
|
||||
QString xmlData = nwReply->readAll();
|
||||
QDomDocument doc;
|
||||
|
||||
if (doc.setContent(xmlData))
|
||||
{
|
||||
QDomNode atc = doc.elementsByTagName("atcs").at(0);
|
||||
QDomNodeList bookingNodes = atc.toElement().elementsByTagName("booking");
|
||||
int size = bookingNodes.size();
|
||||
CSequence<CAtcStation> stations;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
QDomNode bookingNode = bookingNodes.at(i);
|
||||
QDomNodeList bookingNodeValues = bookingNode.childNodes();
|
||||
CAtcStation bookedStation;
|
||||
CUser user;
|
||||
for (int v = 0; v < bookingNodeValues.size(); v++)
|
||||
{
|
||||
QDomNode bookingNodeValue = bookingNodeValues.at(v);
|
||||
QString name = bookingNodeValue.nodeName().toLower();
|
||||
QString value = bookingNodeValue.toElement().text();
|
||||
if (name == "id")
|
||||
{
|
||||
// could be used as unique key
|
||||
}
|
||||
else if (name == "callsign")
|
||||
{
|
||||
bookedStation.setCallsign(CCallsign(value));
|
||||
}
|
||||
else if (name == "name")
|
||||
{
|
||||
user.setRealname(value);
|
||||
}
|
||||
else if (name == "cid")
|
||||
{
|
||||
user.setId(value);
|
||||
}
|
||||
else if (name == "time_end")
|
||||
{
|
||||
QDateTime t = QDateTime::fromString(value, "yyyy-MM-dd HH:mm:ss");
|
||||
bookedStation.setBookedUntilUtc(t);
|
||||
}
|
||||
else if (name == "time_start")
|
||||
{
|
||||
QDateTime t = QDateTime::fromString(value, "yyyy-MM-dd HH:mm:ss");
|
||||
bookedStation.setBookedFromUtc(t);
|
||||
}
|
||||
}
|
||||
// time checks
|
||||
QDateTime now = QDateTime::currentDateTimeUtc();
|
||||
if (now.msecsTo(bookedStation.getBookedUntilUtc()) < (1000 * 60 * 15)) continue; // until n mins in past
|
||||
if (now.msecsTo(bookedStation.getBookedFromUtc()) > (1000 * 60 * 60 * 24)) continue; // to far in the future, n hours
|
||||
|
||||
// booking does not have position, so distance cannot be calculated
|
||||
// bookedStation.calculcateDistanceToPlane(this->m_ownAircraft.getPosition());
|
||||
|
||||
bookedStation.setController(user);
|
||||
|
||||
// consolidate and append
|
||||
this->m_atcStationsOnline.mergeWithBooking(bookedStation);
|
||||
stations.insert(bookedStation);
|
||||
}
|
||||
nwReply->close();
|
||||
nwReply->deleteLater();
|
||||
|
||||
// set the new values
|
||||
if (this->getAtcStationsBooked() != stations)
|
||||
{
|
||||
this->atcStationsBooked() = stations;
|
||||
emit this->changedAtcStationsBooked();
|
||||
}
|
||||
} // node
|
||||
} // content
|
||||
} // method
|
||||
} // namespace
|
||||
194
src/blackcore/context_network_interface.cpp
Normal file
194
src/blackcore/context_network_interface.cpp
Normal file
@@ -0,0 +1,194 @@
|
||||
/* Copyright (C) 2013 VATSIM Community / authors
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "blackcore/context_network_interface.h"
|
||||
#include <QObject>
|
||||
#include <QMetaEnum>
|
||||
#include <QDBusConnection>
|
||||
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
|
||||
/*
|
||||
* Constructor for DBus
|
||||
*/
|
||||
IContextNetwork::IContextNetwork(const QString &serviceName, QDBusConnection &connection, QObject *parent) : QObject(parent), m_dBusInterface(0)
|
||||
{
|
||||
this->m_dBusInterface = new BlackMisc::CGenericDBusInterface(
|
||||
serviceName , IContextNetwork::ServicePath(), IContextNetwork::InterfaceName(),
|
||||
connection, this);
|
||||
this->relaySignals(serviceName, connection);
|
||||
}
|
||||
|
||||
/*
|
||||
* Workaround for signals, not working without, but why?
|
||||
*/
|
||||
void IContextNetwork::relaySignals(const QString &serviceName, QDBusConnection &connection)
|
||||
{
|
||||
connection.connect(serviceName, IContextNetwork::ServicePath(), IContextNetwork::InterfaceName(),
|
||||
"connectionStatusChanged", this, SIGNAL(connectionStatusChanged(uint, uint)));
|
||||
connection.connect(serviceName, IContextNetwork::ServicePath(), IContextNetwork::InterfaceName(),
|
||||
"changedAtcStationsBooked", this, SIGNAL(changedAtcStationsBooked()));
|
||||
connection.connect(serviceName, IContextNetwork::ServicePath(), IContextNetwork::InterfaceName(),
|
||||
"changedAtcStationsOnline", this, SIGNAL(changedAtcStationsOnline()));
|
||||
connection.connect(serviceName, IContextNetwork::ServicePath(), IContextNetwork::InterfaceName(),
|
||||
"connectionTerminated", this, SIGNAL(connectionTerminated()));
|
||||
connection.connect(serviceName, IContextNetwork::ServicePath(), IContextNetwork::InterfaceName(),
|
||||
"statusMessage", this, SIGNAL(statusMessage(BlackMisc::CStatusMessage)));
|
||||
connection.connect(serviceName, IContextNetwork::ServicePath(), IContextNetwork::InterfaceName(),
|
||||
"textMessagesReceived", this, SIGNAL(textMessagesReceived(BlackMisc::Network::CTextMessageList)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear text of status
|
||||
*/
|
||||
QString IContextNetwork::connectionStatusToString(ConnectionStatus status) const
|
||||
{
|
||||
int index = metaObject()->indexOfEnumerator("ConnectionStatus");
|
||||
QMetaEnum metaEnum = metaObject()->enumerator(index);
|
||||
return metaEnum.valueToKey(status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Relay to DBus
|
||||
*/
|
||||
void IContextNetwork::readAtcBookingsFromSource() const
|
||||
{
|
||||
this->m_dBusInterface->callDBus(QLatin1Literal("readAtcBookingsFromSource"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Relay to DBus
|
||||
*/
|
||||
const BlackMisc::Aviation::CAtcStationList IContextNetwork::getAtcStationsOnline() const
|
||||
{
|
||||
return this->m_dBusInterface->callDBusRet<BlackMisc::Aviation::CAtcStationList>(QLatin1Literal("getAtcStationsOnline"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Relay to DBus
|
||||
*/
|
||||
const BlackMisc::Aviation::CAtcStationList IContextNetwork::getAtcStationsBooked() const
|
||||
{
|
||||
return this->m_dBusInterface->callDBusRet<BlackMisc::Aviation::CAtcStationList>(QLatin1Literal("getAtcStationsBooked"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Relay to DBus
|
||||
*/
|
||||
const BlackMisc::Aviation::CAircraftList IContextNetwork::getAircraftsInRange() const
|
||||
{
|
||||
return this->m_dBusInterface->callDBusRet<BlackMisc::Aviation::CAircraftList>(QLatin1Literal("getAircraftsInRange"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Relay to DBus
|
||||
*/
|
||||
BlackMisc::Aviation::CAircraft IContextNetwork::getOwnAircraft() const
|
||||
{
|
||||
return this->m_dBusInterface->callDBusRet<BlackMisc::Aviation::CAircraft>(QLatin1Literal("getOwnAircraft"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Relay to DBus
|
||||
*/
|
||||
BlackMisc::CStatusMessages IContextNetwork::connectToNetwork()
|
||||
{
|
||||
return this->m_dBusInterface->callDBusRet<BlackMisc::CStatusMessages>(QLatin1Literal("connectToNetwork"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Relay to DBus
|
||||
*/
|
||||
BlackMisc::CStatusMessages IContextNetwork::disconnectFromNetwork()
|
||||
{
|
||||
return this->m_dBusInterface->callDBusRet<BlackMisc::CStatusMessages>(QLatin1Literal("disconnectFromNetwork"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Relay to DBus
|
||||
*/
|
||||
bool IContextNetwork::isConnected() const
|
||||
{
|
||||
qint64 token = QDateTime::currentMSecsSinceEpoch();
|
||||
if (this->ping(token) != token) return false; // Core cannot be reached
|
||||
return this->m_dBusInterface->callDBusRet<bool>(QLatin1Literal("isConnected"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Relay to DBus
|
||||
*/
|
||||
BlackMisc::CStatusMessages IContextNetwork::setOwnAircraft(const BlackMisc::Aviation::CAircraft &aircraft)
|
||||
{
|
||||
return this->m_dBusInterface->callDBusRet<BlackMisc::CStatusMessages>(QLatin1Literal("setOwnAircraft"), aircraft);
|
||||
}
|
||||
|
||||
/*
|
||||
* Relay to DBus
|
||||
*/
|
||||
void IContextNetwork::updateOwnPosition(const BlackMisc::Geo::CCoordinateGeodetic &position, const BlackMisc::Aviation::CAltitude &altitude)
|
||||
{
|
||||
this->m_dBusInterface->callDBus(QLatin1Literal("updateOwnPosition"), position, altitude);
|
||||
}
|
||||
|
||||
/*
|
||||
* Relay to DBus
|
||||
*/
|
||||
void IContextNetwork::updateOwnSituation(const BlackMisc::Aviation::CAircraftSituation &situation)
|
||||
{
|
||||
this->m_dBusInterface->callDBus(QLatin1Literal("updateOwnSituation"), situation);
|
||||
}
|
||||
|
||||
/*
|
||||
* Relay to DBus
|
||||
*/
|
||||
void IContextNetwork::updateOwnCockpit(const BlackMisc::Aviation::CComSystem &com1, const BlackMisc::Aviation::CComSystem &com2, const BlackMisc::Aviation::CTransponder &transponder)
|
||||
{
|
||||
this->m_dBusInterface->callDBus(QLatin1Literal("updateOwnCockpit"), com1, com2, transponder);
|
||||
}
|
||||
|
||||
/*
|
||||
* Relay to DBus
|
||||
*/
|
||||
void IContextNetwork::sendTextMessages(const BlackMisc::Network::CTextMessageList &textMessages)
|
||||
{
|
||||
this->m_dBusInterface->callDBus(QLatin1Literal("sendTextMessages"), textMessages);
|
||||
}
|
||||
|
||||
/*
|
||||
* Relay to DBus
|
||||
*/
|
||||
BlackMisc::Aviation::CInformationMessage IContextNetwork::getMetar(const QString &airportIcaoCode)
|
||||
{
|
||||
return this->m_dBusInterface->callDBusRet<BlackMisc::Aviation::CInformationMessage>(QLatin1Literal("requestMetar"), airportIcaoCode);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ping, is DBus alive?
|
||||
*/
|
||||
qint64 IContextNetwork::ping(qint64 token) const
|
||||
{
|
||||
return this->m_dBusInterface->callDBusRet<qint64>(QLatin1Literal("ping"), token);
|
||||
}
|
||||
|
||||
/*
|
||||
* Logging
|
||||
*/
|
||||
void IContextNetwork::log(const QString &method, const QString &m1, const QString &m2, const QString &m3, const QString &m4) const
|
||||
{
|
||||
if (m1.isEmpty())
|
||||
qDebug() << " LOG: " << method;
|
||||
else if (m2.isEmpty())
|
||||
qDebug() << " LOG: " << method << m1;
|
||||
else if (m3.isEmpty())
|
||||
qDebug() << " LOG: " << method << m1 << m2;
|
||||
else if (m4.isEmpty())
|
||||
qDebug() << " LOG: " << method << m1 << m2 << m3;
|
||||
else
|
||||
qDebug() << " LOG: " << method << m1 << m2 << m3 << m4;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
267
src/blackcore/context_network_interface.h
Normal file
267
src/blackcore/context_network_interface.h
Normal file
@@ -0,0 +1,267 @@
|
||||
/* Copyright (C) 2013 VATSIM Community / authors
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef BLACKCORE_CONTEXTNETWORK_INTERFACE_H
|
||||
#define BLACKCORE_CONTEXTNETWORK_INTERFACE_H
|
||||
|
||||
#include "blackmisc/avallclasses.h"
|
||||
#include "blackmisc/statusmessage.h"
|
||||
#include "blackmisc/statusmessages.h"
|
||||
#include "blackmisc/nwtextmessagelist.h"
|
||||
#include "blackmisc/genericdbusinterface.h"
|
||||
#include "blackcore/network_vatlib.h"
|
||||
#include <QObject>
|
||||
#include <QDBusAbstractInterface>
|
||||
|
||||
#define BLACKCORE_CONTEXTNETWORK_INTERFACENAME "blackcore.contextnetwork"
|
||||
#define BLACKCORE_CONTEXTNETWORK_SERVICEPATH "/network"
|
||||
|
||||
// SERVICENAME must contain at least one ".", otherwise generation fails
|
||||
// as this is interpreted in the way comain.somename
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
|
||||
/*!
|
||||
* \brief The IContextNetwork class
|
||||
*/
|
||||
class IContextNetwork : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_ENUMS(ConnectionStatus)
|
||||
Q_CLASSINFO("D-Bus Interface", BLACKCORE_CONTEXTNETWORK_INTERFACENAME)
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Service name
|
||||
* \return
|
||||
*/
|
||||
static const QString &InterfaceName()
|
||||
{
|
||||
static QString s(BLACKCORE_CONTEXTNETWORK_INTERFACENAME);
|
||||
return s;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Service path
|
||||
* \return
|
||||
*/
|
||||
static const QString &ServicePath()
|
||||
{
|
||||
static QString s(BLACKCORE_CONTEXTNETWORK_SERVICEPATH);
|
||||
return s;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Qt compliant status
|
||||
*/
|
||||
enum ConnectionStatus
|
||||
{
|
||||
ConnectionStatusIdle = static_cast<uint>(Cvatlib_Network::connStatus_Idle),
|
||||
ConnectionStatusConnected = static_cast<uint>(Cvatlib_Network::connStatus_Connected),
|
||||
ConnectionStatusConnecting = static_cast<uint>(Cvatlib_Network::connStatus_Connecting),
|
||||
ConnectionStatusDisconnected = static_cast<uint>(Cvatlib_Network::connStatus_Disconnected),
|
||||
ConnectionStatusError = static_cast<uint>(Cvatlib_Network::connStatus_Error)
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief DBus version constructor
|
||||
* \param serviceName
|
||||
* \param connection
|
||||
* \param parent
|
||||
*/
|
||||
IContextNetwork(const QString &serviceName, QDBusConnection &connection, QObject *parent = 0);
|
||||
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
~IContextNetwork() {}
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Using local objects?
|
||||
* \return
|
||||
*/
|
||||
virtual bool usingLocalObjects() const { return false; }
|
||||
|
||||
private:
|
||||
BlackMisc::CGenericDBusInterface *m_dBusInterface;
|
||||
|
||||
/*!
|
||||
* Relay connection signals to local signals
|
||||
* No idea why this has to be wired and is not done automatically
|
||||
* \param connection
|
||||
*/
|
||||
void relaySignals(const QString &serviceName, QDBusConnection &connection);
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* \brief IContextNetwork
|
||||
* \param parent
|
||||
*/
|
||||
IContextNetwork(QObject *parent = 0) : QObject(parent), m_dBusInterface(0) {}
|
||||
|
||||
/*!
|
||||
* Connection status as cleartext
|
||||
*/
|
||||
QString connectionStatusToString(ConnectionStatus status) const;
|
||||
|
||||
/*!
|
||||
* \brief Helper for logging, likely to be removed / changed
|
||||
* \param method
|
||||
* \param m1
|
||||
* \param m2
|
||||
* \param m3
|
||||
* \param m4
|
||||
*/
|
||||
void log(const QString &method, const QString &m1 = "", const QString &m2 = "", const QString &m3 = "", const QString &m4 = "") const;
|
||||
|
||||
signals:
|
||||
|
||||
/*!
|
||||
* \brief ATC station list has been changed
|
||||
* \param message
|
||||
*/
|
||||
void statusMessage(const BlackMisc::CStatusMessage &message);
|
||||
|
||||
/*!
|
||||
* \brief List has been changed
|
||||
*/
|
||||
void changedAtcStationsOnline();
|
||||
|
||||
/*!
|
||||
* \brief ATC station list has been changed
|
||||
*/
|
||||
void changedAtcStationsBooked();
|
||||
|
||||
/*!
|
||||
* \brief Aircraft list has been changed
|
||||
*/
|
||||
void changedAircraftsInRange();
|
||||
|
||||
/*!
|
||||
* \brief Terminated connection
|
||||
*/
|
||||
void connectionTerminated();
|
||||
|
||||
/*!
|
||||
* \brief Connection status changed
|
||||
* \param from
|
||||
* \param to
|
||||
*/
|
||||
// If I use the enum, adaptor / interface are not created correctly
|
||||
void connectionStatusChanged(uint from, uint to);
|
||||
|
||||
/*!
|
||||
* \brief Text messages (also private chat messages)
|
||||
* \param textMessage
|
||||
*/
|
||||
void textMessagesReceived(const BlackMisc::Network::CTextMessageList &textMessages);
|
||||
|
||||
public slots:
|
||||
|
||||
/*!
|
||||
* \brief Read ATC bookings
|
||||
* \return
|
||||
*/
|
||||
virtual void readAtcBookingsFromSource() const;
|
||||
|
||||
/*!
|
||||
* \brief The "central" ATC list with online ATC controllers
|
||||
* \return
|
||||
*/
|
||||
// If I make this &getAtcStations XML is not generated correctly
|
||||
virtual const BlackMisc::Aviation::CAtcStationList getAtcStationsOnline() const;
|
||||
|
||||
/*!
|
||||
* \brief ATC list, with booked controllers
|
||||
* \return
|
||||
*/
|
||||
virtual const BlackMisc::Aviation::CAtcStationList getAtcStationsBooked() const;
|
||||
|
||||
/*!
|
||||
* \brief Aircraft list
|
||||
* \return
|
||||
*/
|
||||
virtual const BlackMisc::Aviation::CAircraftList getAircraftsInRange() const;
|
||||
|
||||
/*!
|
||||
* \brief Get own aircraft
|
||||
* \return
|
||||
*/
|
||||
virtual BlackMisc::Aviation::CAircraft getOwnAircraft() const;
|
||||
|
||||
/*!
|
||||
* \brief Connect to Network
|
||||
* \return
|
||||
*/
|
||||
virtual BlackMisc::CStatusMessages connectToNetwork();
|
||||
|
||||
/*!
|
||||
* \brief Disconnect from network
|
||||
* \return
|
||||
*/
|
||||
virtual BlackMisc::CStatusMessages disconnectFromNetwork();
|
||||
|
||||
/*!
|
||||
* \brief Network connected?
|
||||
* \return
|
||||
*/
|
||||
virtual bool isConnected() const;
|
||||
|
||||
/*!
|
||||
* Set own aircraft
|
||||
* \param aircraft
|
||||
* \return
|
||||
*/
|
||||
virtual BlackMisc::CStatusMessages setOwnAircraft(const BlackMisc::Aviation::CAircraft &aircraft);
|
||||
|
||||
/*!
|
||||
* \brief Own position, be aware height is terrain height
|
||||
* \param Position
|
||||
* \param altitude
|
||||
* \return
|
||||
*/
|
||||
virtual void updateOwnPosition(const BlackMisc::Geo::CCoordinateGeodetic &position, const BlackMisc::Aviation::CAltitude &altitude);
|
||||
|
||||
/*!
|
||||
* \brief Complete situation update
|
||||
* \param Situation
|
||||
* \return
|
||||
*/
|
||||
virtual void updateOwnSituation(const BlackMisc::Aviation::CAircraftSituation &situation);
|
||||
|
||||
/*!
|
||||
* \brief Update own cockpit
|
||||
* \param com1
|
||||
* \param com2
|
||||
* \param transponder
|
||||
*/
|
||||
virtual void updateOwnCockpit(const BlackMisc::Aviation::CComSystem &com1, const BlackMisc::Aviation::CComSystem &com2, const BlackMisc::Aviation::CTransponder &transponder);
|
||||
|
||||
/*!
|
||||
* \brief Text messages (radio and private chat messages)
|
||||
* \param textMessage
|
||||
*/
|
||||
virtual void sendTextMessages(const BlackMisc::Network::CTextMessageList &textMessages);
|
||||
|
||||
/*!
|
||||
* \brief Get METAR, if not available request it
|
||||
* \param airportIcaoCode
|
||||
* \return
|
||||
*/
|
||||
virtual BlackMisc::Aviation::CInformationMessage getMetar(const QString &airportIcaoCode);
|
||||
|
||||
/*!
|
||||
* \brief Ping
|
||||
* \param token
|
||||
* \return
|
||||
*/
|
||||
virtual qint64 ping(qint64 token) const;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif // guard
|
||||
27
src/blackcore/context_network_textmessages.cpp
Normal file
27
src/blackcore/context_network_textmessages.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
/* Copyright (C) 2013 VATSIM Community / authors
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "context_network.h"
|
||||
#include "coreruntime.h"
|
||||
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackMisc::PhysicalQuantities;
|
||||
using namespace BlackMisc::Aviation;
|
||||
using namespace BlackMisc::Network;
|
||||
using namespace BlackMisc::Geo;
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
/*
|
||||
* Radio text message received
|
||||
*/
|
||||
void CContextNetwork::psFsdTextMessageReceived(const CTextMessageList &messages)
|
||||
{
|
||||
if (messages.isEmpty()) return;
|
||||
this->log(Q_FUNC_INFO, messages.toQString());
|
||||
this->textMessagesReceived(messages); // relay
|
||||
}
|
||||
|
||||
} // namespace
|
||||
61
src/blackcore/context_settings.cpp
Normal file
61
src/blackcore/context_settings.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
/* Copyright (C) 2013 VATSIM Community / authors
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "context_settings.h"
|
||||
#include "coreruntime.h"
|
||||
#include "blackmisc/settingutilities.h"
|
||||
|
||||
using namespace BlackMisc::Settings;
|
||||
using namespace BlackMisc::Network;
|
||||
using namespace BlackMisc;
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
|
||||
/*
|
||||
* Init this context
|
||||
*/
|
||||
CContextSettings::CContextSettings(CCoreRuntime *parent) : IContextSettings(parent), m_settingsNetwork()
|
||||
{
|
||||
// create some dummy settings
|
||||
// this would actually be reading the settings from disk ..
|
||||
|
||||
this->m_settingsNetwork.setCurrentNetworkServer(
|
||||
CServer("Testserver", "Client project testserver", "vatsim-germany.org", 6809,
|
||||
CUser("guest", "Guest Client project", "", "guest")));
|
||||
this->m_settingsNetwork.addTrafficNetworkServer(this->m_settingsNetwork.getCurrentNetworkServer());
|
||||
this->m_settingsNetwork.addTrafficNetworkServer(
|
||||
CServer("Europe C2", "Real VATSIM Server", "88.198.19.202", 6809,
|
||||
CUser("vatsimid", "Black Client", "", "vatsimpw"))
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Network settings
|
||||
*/
|
||||
BlackMisc::Settings::CSettingsNetwork CContextSettings::getNetworkSettings() const
|
||||
{
|
||||
return this->m_settingsNetwork;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pass value
|
||||
*/
|
||||
BlackMisc::CStatusMessages CContextSettings::value(const QString &path, const QString &command, const QVariant &value)
|
||||
{
|
||||
Q_ASSERT(path.length() > 3);
|
||||
Q_ASSERT(path.indexOf('/') >= 0);
|
||||
QString nextLevelPath = CSettingUtilities::removeLeadingPath(path);
|
||||
BlackMisc::CStatusMessages msgs = CSettingUtilities::wrongPathMessages(path);
|
||||
bool changed = false;
|
||||
if (path.startsWith(IContextSettings::PathNetworkSettings()))
|
||||
{
|
||||
msgs = this->m_settingsNetwork.value(nextLevelPath, command, value, changed);
|
||||
if (changed) emit this->changedNetworkSettings();
|
||||
}
|
||||
return msgs;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
83
src/blackcore/context_settings.h
Normal file
83
src/blackcore/context_settings.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/* Copyright (C) 2013 VATSIM Community / authors
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef BLACKCORE_CONTEXTSETTINGS_H
|
||||
#define BLACKCORE_CONTEXTSETTINGS_H
|
||||
|
||||
#include "blackcore/dbus_server.h"
|
||||
#include "blackcore/context_settings_interface.h"
|
||||
#include "blackmisc/statusmessage.h"
|
||||
#include "blackmisc/statusmessages.h"
|
||||
#include <QObject>
|
||||
|
||||
#define BLACKCORE_CONTEXTSETTINGS_INTERFACENAME "blackcore.contextsettings"
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
class CCoreRuntime;
|
||||
|
||||
/*!
|
||||
* \brief Network context
|
||||
*/
|
||||
class CContextSettings : public IContextSettings
|
||||
{
|
||||
// Register by same name, make signals sender independent
|
||||
// http://dbus.freedesktop.org/doc/dbus-faq.html#idp48032144
|
||||
Q_CLASSINFO("D-Bus Interface", BLACKCORE_CONTEXTSETTINGS_INTERFACENAME)
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
* Context
|
||||
* \param parent
|
||||
*/
|
||||
CContextSettings(CCoreRuntime *parent);
|
||||
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~CContextSettings() {}
|
||||
|
||||
/*!
|
||||
* \brief Register myself in DBus
|
||||
* \param server
|
||||
*/
|
||||
void registerWithDBus(CDBusServer *server)
|
||||
{
|
||||
server->addObject(IContextSettings::ServicePath(), this);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Runtime
|
||||
* \return
|
||||
*/
|
||||
const CCoreRuntime *getRuntime() const
|
||||
{
|
||||
return reinterpret_cast<CCoreRuntime *>(this->parent());
|
||||
}
|
||||
|
||||
public slots:
|
||||
/*!
|
||||
* \brief Network settings
|
||||
* \return
|
||||
*/
|
||||
virtual BlackMisc::Settings::CSettingsNetwork getNetworkSettings() const;
|
||||
|
||||
/*!
|
||||
* \brief Validate
|
||||
* \param path
|
||||
* \param value
|
||||
* \return
|
||||
*/
|
||||
virtual BlackMisc::CStatusMessages value(const QString &path, const QString &command, const QVariant &value);
|
||||
|
||||
private:
|
||||
BlackMisc::Settings::CSettingsNetwork m_settingsNetwork;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif // guard
|
||||
70
src/blackcore/context_settings_interface.cpp
Normal file
70
src/blackcore/context_settings_interface.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
/* Copyright (C) 2013 VATSIM Community / authors
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "blackcore/context_settings_interface.h"
|
||||
#include "blackmisc/blackmiscfreefunctions.h"
|
||||
#include <QObject>
|
||||
#include <QMetaEnum>
|
||||
#include <QDBusConnection>
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
|
||||
/*
|
||||
* Constructor for DBus
|
||||
*/
|
||||
IContextSettings::IContextSettings(const QString &serviceName, QDBusConnection &connection, QObject *parent) : QObject(parent), m_dBusInterface(0)
|
||||
{
|
||||
this->m_dBusInterface = new BlackMisc::CGenericDBusInterface(
|
||||
serviceName , IContextSettings::ServicePath(), IContextSettings::InterfaceName(),
|
||||
connection, this);
|
||||
this->relaySignals(serviceName, connection);
|
||||
}
|
||||
|
||||
/*
|
||||
* Workaround for unreliable signals
|
||||
*/
|
||||
void IContextSettings::relaySignals(const QString &serviceName, QDBusConnection &connection)
|
||||
{
|
||||
connection.connect(serviceName, IContextSettings::ServicePath(), IContextSettings::InterfaceName(),
|
||||
"changedNetworkSettings", this, SIGNAL(changedNetworkSettings()));
|
||||
}
|
||||
|
||||
/*
|
||||
* Relay to DBus
|
||||
*/
|
||||
BlackMisc::Settings::CSettingsNetwork IContextSettings::getNetworkSettings() const
|
||||
{
|
||||
return this->m_dBusInterface->callDBusRet<BlackMisc::Settings::CSettingsNetwork>(QLatin1Literal("getNetworkSettings"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Relay to DBus
|
||||
*/
|
||||
BlackMisc::CStatusMessages IContextSettings::value(const QString &path, const QString &command, const QVariant &value)
|
||||
{
|
||||
int type = value.userType() - BlackMisc::firstBlackMetaType();
|
||||
return this->m_dBusInterface->callDBusRet<BlackMisc::CStatusMessages>(QLatin1Literal("value"), path, command, QDBusVariant(value), type);
|
||||
}
|
||||
|
||||
/*
|
||||
* DBus version of value
|
||||
*/
|
||||
BlackMisc::CStatusMessages IContextSettings::value(const QString &path, const QString &command, QDBusVariant value, int unifiedBlackMetaType)
|
||||
{
|
||||
QVariant qv = value.variant();
|
||||
if (qv.canConvert<QDBusArgument>())
|
||||
{
|
||||
// convert from QDBusArgument
|
||||
int type = BlackMisc::firstBlackMetaType() + unifiedBlackMetaType; // unify
|
||||
qv = BlackMisc::fixQVariantFromDbusArgument(qv, type);
|
||||
}
|
||||
// when called locally, this will call the virtual method
|
||||
// of the concrete implementation in context_settings
|
||||
return this->value(path, command, qv);
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
136
src/blackcore/context_settings_interface.h
Normal file
136
src/blackcore/context_settings_interface.h
Normal file
@@ -0,0 +1,136 @@
|
||||
/* Copyright (C) 2013 VATSIM Community / authors
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef BLACKCORE_CONTEXTSETTINGS_INTERFACE_H
|
||||
#define BLACKCORE_CONTEXTSETTINGS_INTERFACE_H
|
||||
|
||||
#include "blackmisc/statusmessages.h"
|
||||
#include "blackmisc/genericdbusinterface.h"
|
||||
#include "blackmisc/settingutilities.h"
|
||||
#include "blackmisc/setnetwork.h"
|
||||
#include <QObject>
|
||||
#include <QVariant>
|
||||
#include <QDBusAbstractInterface>
|
||||
|
||||
#define BLACKCORE_CONTEXTSETTINGS_INTERFACENAME "blackcore.contextsettings"
|
||||
#define BLACKCORE_CONTEXTSETTINGS_SERVICEPATH "/settings"
|
||||
|
||||
// SERVICENAME must contain at least one ".", otherwise generation fails
|
||||
// as this is interpreted in the way comain.somename
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
|
||||
/*!
|
||||
* \brief The IContextSettings class
|
||||
*/
|
||||
class IContextSettings : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", BLACKCORE_CONTEXTSETTINGS_INTERFACENAME)
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
* \brief Service name
|
||||
* \return
|
||||
*/
|
||||
static const QString &InterfaceName()
|
||||
{
|
||||
static QString s(BLACKCORE_CONTEXTSETTINGS_INTERFACENAME);
|
||||
return s;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Service path
|
||||
* \return
|
||||
*/
|
||||
static const QString &ServicePath()
|
||||
{
|
||||
static QString s(BLACKCORE_CONTEXTSETTINGS_SERVICEPATH);
|
||||
return s;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Path
|
||||
* \return
|
||||
*/
|
||||
static const QString &PathNetworkSettings()
|
||||
{
|
||||
static QString s("network");
|
||||
return s;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief DBus version constructor
|
||||
* \param serviceName
|
||||
* \param connection
|
||||
* \param parent
|
||||
*/
|
||||
IContextSettings(const QString &serviceName, QDBusConnection &connection, QObject *parent = 0);
|
||||
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
~IContextSettings() {}
|
||||
|
||||
private:
|
||||
BlackMisc::CGenericDBusInterface *m_dBusInterface;
|
||||
|
||||
/*!
|
||||
* \brief Relay connection signals to local signals
|
||||
* No idea why this has to be wired and is not done automatically
|
||||
* \param connection
|
||||
*/
|
||||
void relaySignals(const QString &serviceName, QDBusConnection &connection);
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* \brief IContextSettings
|
||||
* \param parent
|
||||
*/
|
||||
IContextSettings(QObject *parent = 0) : QObject(parent), m_dBusInterface(0) {}
|
||||
|
||||
signals:
|
||||
|
||||
/*!
|
||||
* \brief Settings have been changed
|
||||
*/
|
||||
void changedNetworkSettings();
|
||||
|
||||
public slots:
|
||||
|
||||
/*!
|
||||
* \brief Network settings
|
||||
* \return
|
||||
*/
|
||||
virtual BlackMisc::Settings::CSettingsNetwork getNetworkSettings() const;
|
||||
|
||||
/*!
|
||||
* \brief Handle value
|
||||
* \param path
|
||||
* \param command
|
||||
* \param value
|
||||
* \return
|
||||
*/
|
||||
virtual BlackMisc::CStatusMessages value(const QString &path, const QString &command, const QVariant &value);
|
||||
|
||||
/*!
|
||||
* Basically an unwanted signature as this is different from the "local" signature and
|
||||
* contains explicit DBus types (a: QDbusArgument, b: type for conversion).
|
||||
* If this can be removed, fine.
|
||||
*
|
||||
* \brief value
|
||||
* \param path
|
||||
* \param command
|
||||
* \param value
|
||||
* \param unifiedBlackMetaType
|
||||
* \return
|
||||
*/
|
||||
virtual BlackMisc::CStatusMessages value(const QString &path, const QString &command, QDBusVariant value, int unifiedBlackMetaType);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // guard
|
||||
42
src/blackcore/coreruntime.cpp
Normal file
42
src/blackcore/coreruntime.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "blackcore/coreruntime.h"
|
||||
#include "blackmisc/blackmiscfreefunctions.h"
|
||||
#include "blackmisc/nwserver.h"
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
CCoreRuntime::CCoreRuntime(bool withDbus, QObject *parent) :
|
||||
QObject(parent), m_init(false), m_dbusServer(nullptr), m_contextNetwork(nullptr), m_settings(nullptr)
|
||||
{
|
||||
this->init(withDbus);
|
||||
}
|
||||
|
||||
/*
|
||||
* Init runtime
|
||||
*/
|
||||
void CCoreRuntime::init(bool withDbus)
|
||||
{
|
||||
if (m_init) return;
|
||||
BlackMisc::registerMetadata();
|
||||
BlackMisc::initResources();
|
||||
|
||||
// TODO: read settings
|
||||
if (withDbus)
|
||||
{
|
||||
QString dBusAddress = "session";
|
||||
this->m_dbusServer = new CDBusServer(dBusAddress, this);
|
||||
}
|
||||
|
||||
// contexts
|
||||
this->m_settings = new CContextSettings(this);
|
||||
if (withDbus) this->m_settings->registerWithDBus(this->m_dbusServer);
|
||||
|
||||
this->m_contextNetwork = new CContextNetwork(this);
|
||||
if (withDbus) this->m_contextNetwork->registerWithDBus(this->m_dbusServer); // complete object after init
|
||||
|
||||
// flag
|
||||
m_init = true;
|
||||
}
|
||||
}
|
||||
90
src/blackcore/coreruntime.h
Normal file
90
src/blackcore/coreruntime.h
Normal file
@@ -0,0 +1,90 @@
|
||||
#ifndef BLACKCORE_CORERUNTIME_H
|
||||
#define BLACKCORE_CORERUNTIME_H
|
||||
|
||||
#include <QObject>
|
||||
#include "dbus_server.h"
|
||||
#include "context_network.h"
|
||||
#include "context_settings.h"
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
/*!
|
||||
* \brief The CCoreRuntime class
|
||||
*/
|
||||
class CCoreRuntime : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
bool m_init; /*!< flag */
|
||||
CDBusServer *m_dbusServer;
|
||||
CContextNetwork *m_contextNetwork;
|
||||
CContextSettings *m_settings;
|
||||
|
||||
/*!
|
||||
* \brief Init
|
||||
* \param withDbus
|
||||
*/
|
||||
void init(bool withDbus);
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Constructor
|
||||
* \param withDbus
|
||||
* \param parent
|
||||
*/
|
||||
CCoreRuntime(bool withDbus = true, QObject *parent = nullptr);
|
||||
|
||||
/*!
|
||||
* \brief Destructor
|
||||
*/
|
||||
virtual ~CCoreRuntime() {}
|
||||
|
||||
/*!
|
||||
* \brief DBus server
|
||||
* \return
|
||||
*/
|
||||
const CDBusServer *getDBusServer() const
|
||||
{
|
||||
return this->m_dbusServer;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Context for network
|
||||
* \return
|
||||
*/
|
||||
IContextNetwork *getIContextNetwork()
|
||||
{
|
||||
return this->m_contextNetwork;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Context for network
|
||||
* \return
|
||||
*/
|
||||
const IContextNetwork *getIContextNetwork() const
|
||||
{
|
||||
return this->m_contextNetwork;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Settings
|
||||
* \return
|
||||
*/
|
||||
IContextSettings *getIContextSettings()
|
||||
{
|
||||
return this->m_settings;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Settings
|
||||
* \return
|
||||
*/
|
||||
const IContextSettings *getIContextSettings() const
|
||||
{
|
||||
return this->m_settings;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
#endif // guard
|
||||
@@ -4,53 +4,155 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <QDebug>
|
||||
#include <QMetaClassInfo>
|
||||
|
||||
#include "dbus_server.h"
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
|
||||
const QString CDBusServer::ServiceName = QString(BLACKCORE_DBUSERVER_SERVICENAME);
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
* Remark, without the default "unix:tmpdir=/tmp" any refereal to address crashes
|
||||
* see http://download.froglogic.com/public/qt5-squishcoco-report/QtBase/source_241_preprocessed.html
|
||||
*/
|
||||
CDBusServer::CDBusServer(const QString &address, QObject *parent) :
|
||||
QObject(parent), m_busServer(address, parent)
|
||||
QObject(parent), m_busServer(CDBusServer::isP2P(address) ? address : "unix:tmpdir=/tmp" , parent), m_serverMode(CDBusServer::SERVERMODE_P2P)
|
||||
{
|
||||
if (!m_busServer.isConnected())
|
||||
if (address.isEmpty() || address.toLower() == "session")
|
||||
{
|
||||
qWarning() << m_busServer.lastError().message();
|
||||
// we use a session bus connection instead of a real P2P connection
|
||||
this->m_serverMode = CDBusServer::SERVERMODE_SESSIONBUS;
|
||||
QDBusConnection con = QDBusConnection::sessionBus();
|
||||
|
||||
if (!con.registerService(CDBusServer::ServiceName))
|
||||
{
|
||||
qFatal("Cannot register DBus service");
|
||||
}
|
||||
this->newConnection(con);
|
||||
}
|
||||
else if (address.toLower() == "system")
|
||||
{
|
||||
// we use a system bus connection instead of a real P2P connection
|
||||
this->m_serverMode = CDBusServer::SERVERMODE_SYSTEMBUS;
|
||||
QDBusConnection con = QDBusConnection::systemBus();
|
||||
if (!con.registerService(CDBusServer::ServiceName))
|
||||
{
|
||||
qFatal("Cannot register DBus service");
|
||||
}
|
||||
this->newConnection(con);
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "Server listening on address: " << m_busServer.address();
|
||||
this->m_serverMode = CDBusServer::SERVERMODE_P2P;
|
||||
// Note: P2P has no service name
|
||||
if (!m_busServer.isConnected())
|
||||
{
|
||||
qWarning() << m_busServer.lastError().message();
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "Server listening on address: " << m_busServer.address();
|
||||
}
|
||||
connect(&m_busServer, &QDBusServer::newConnection, this, &CDBusServer::newConnection);
|
||||
}
|
||||
|
||||
connect(&m_busServer, &QDBusServer::newConnection, this, &CDBusServer::newConnection);
|
||||
}
|
||||
|
||||
void CDBusServer::newConnection(const QDBusConnection & connection)
|
||||
/*
|
||||
* Check for P2P address
|
||||
*/
|
||||
bool CDBusServer::isP2P(const QString &address)
|
||||
{
|
||||
QMap<QString, QObject*>::ConstIterator i = m_objects.begin();
|
||||
return !(address.isEmpty() || address.toLower() == "session" || address.toLower() == "system");
|
||||
}
|
||||
|
||||
/*
|
||||
* Class info
|
||||
*/
|
||||
const QString CDBusServer::getClassInfo(QObject *object)
|
||||
{
|
||||
if (!object) return "";
|
||||
const QMetaObject *mo = object->metaObject();
|
||||
if (mo->classInfoCount() < 1) return "";
|
||||
for (int i = 0; i < mo->classInfoCount(); i++)
|
||||
{
|
||||
QMetaClassInfo ci = mo->classInfo(i);
|
||||
QString name(ci.name());
|
||||
if (name == "D-Bus Interface") return QString(ci.value());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/*
|
||||
* Connection established
|
||||
*/
|
||||
bool CDBusServer::newConnection(const QDBusConnection &connection)
|
||||
{
|
||||
QMap<QString, QObject *>::ConstIterator i = m_objects.begin();
|
||||
QDBusConnection newConnection(connection);
|
||||
|
||||
m_DBusConnections.insert(newConnection.name(), newConnection);
|
||||
|
||||
bool success = true;
|
||||
qDebug() << "New Connection from: " << newConnection.name();
|
||||
|
||||
while (i != m_objects.end())
|
||||
{
|
||||
qDebug() << "Adding " << i.key() << "to the new connection.";
|
||||
newConnection.registerObject(i.key(), i.value());
|
||||
qDebug() << "Adding " << i.key() << CDBusServer::getClassInfo(i.value()) << "to the new connection.";
|
||||
bool ok = newConnection.registerObject(i.key(), i.value(), CDBusServer::RegisterOptions());
|
||||
Q_ASSERT_X(ok, "CDBusServer::newConnection", "Registration failed");
|
||||
if (!ok) success = false;
|
||||
++i;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void CDBusServer::addObject(const QString &name, QObject *object)
|
||||
/*
|
||||
* Add the objects
|
||||
*/
|
||||
void CDBusServer::addObject(const QString &path, QObject *object)
|
||||
{
|
||||
m_objects.insert(name, object);
|
||||
if (!object) return;
|
||||
m_objects.insert(path, object); // this will be added when connection is established
|
||||
|
||||
if (this->m_serverMode == CDBusServer::SERVERMODE_P2P) return;
|
||||
|
||||
bool success = false;
|
||||
if (this->m_serverMode == CDBusServer::SERVERMODE_SESSIONBUS)
|
||||
{
|
||||
success = QDBusConnection::sessionBus().registerObject(path, object, CDBusServer::RegisterOptions());
|
||||
qDebug() << "Adding " << path << CDBusServer::getClassInfo(object) << "to the session bus.";
|
||||
if (!success) qDebug() << "Error, no success with registration" << this->lastError().message();
|
||||
}
|
||||
else if (this->m_serverMode == CDBusServer::SERVERMODE_SYSTEMBUS)
|
||||
{
|
||||
success = QDBusConnection::systemBus().registerObject(path, object, CDBusServer::RegisterOptions());
|
||||
qDebug() << "Adding " << path << CDBusServer::getClassInfo(object) << "to the system bus.";
|
||||
if (!success) qDebug() << "Error, no success with registration" << this->lastError().message();
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_ASSERT_X(false, "CDBusServer::addObject", "Wrong server mode");
|
||||
}
|
||||
// Q_ASSERT_X(success, "CDBusServer::addObject", "Registration failed");
|
||||
}
|
||||
|
||||
void CDBusServer::printError()
|
||||
/*
|
||||
* Print last error message
|
||||
*/
|
||||
void CDBusServer::printError() const
|
||||
{
|
||||
qWarning() << m_busServer.lastError().name();
|
||||
}
|
||||
|
||||
/*
|
||||
* Last error
|
||||
*/
|
||||
QDBusError CDBusServer::lastError() const
|
||||
{
|
||||
return this->m_busServer.lastError();
|
||||
}
|
||||
|
||||
} // namespace BlackCore
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#ifndef BLACKCORE_DBUSSERVER_H
|
||||
#define BLACKCORE_DBUSSERVER_H
|
||||
|
||||
#include "blackmisc/valueobject.h" // for qHash overload, include before Qt stuff due GCC issue
|
||||
#include <QObject>
|
||||
#include <QtDBus/QDBusServer>
|
||||
#include <QtDBus/QDBusError>
|
||||
@@ -13,52 +14,147 @@
|
||||
#include <QStringList>
|
||||
#include <QMap>
|
||||
|
||||
namespace BlackCore {
|
||||
#define BLACKCORE_DBUSERVER_SERVICENAME "org.vatsim.pilotClient"
|
||||
|
||||
/*!
|
||||
* \brief Custom DBusServer
|
||||
* \details This class implements a custom DBusServer for DBus peer connections
|
||||
*/
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
|
||||
/*!
|
||||
* \brief Custom DBusServer
|
||||
* \details This class implements a custom DBusServer for DBus peer connections
|
||||
*/
|
||||
class CDBusServer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "org.vatsim.pilotClient")
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", BLACKCORE_DBUSERVER_SERVICENAME)
|
||||
|
||||
private:
|
||||
QDBusServer m_busServer; //!< QDBusServer implementation
|
||||
public:
|
||||
static const QString ServiceName;
|
||||
|
||||
QMap<QString, QObject*> m_objects; //!< Mapping of all exposed objects
|
||||
/*!
|
||||
* \brief Server mode, normally P2P, but can be changed for debugging / testing
|
||||
*/
|
||||
enum ServerMode
|
||||
{
|
||||
SERVERMODE_P2P,
|
||||
SERVERMODE_SESSIONBUS,
|
||||
SERVERMODE_SYSTEMBUS
|
||||
};
|
||||
|
||||
QMap<QString, QDBusConnection> m_DBusConnections; //!< Mapping of all DBusConnection objects
|
||||
private:
|
||||
QDBusServer m_busServer; //!< QDBusServer implementation
|
||||
ServerMode m_serverMode;
|
||||
QMap<QString, QObject *> m_objects; //!< Mapping of all exposed objects
|
||||
QMap<QString, QDBusConnection> m_DBusConnections; //!< Mapping of all DBusConnection objects
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Check if address means a real server with P2P connection
|
||||
* \param address
|
||||
* \return
|
||||
*/
|
||||
static bool isP2P(const QString &address);
|
||||
|
||||
/*!
|
||||
* \brief Constructor
|
||||
* \param parent
|
||||
*/
|
||||
/*!
|
||||
* \brief Get the class info
|
||||
* \param object
|
||||
* \return
|
||||
*/
|
||||
static const QString getClassInfo(QObject *object);
|
||||
|
||||
/*!
|
||||
* \brief Register options with connection
|
||||
* \return
|
||||
*/
|
||||
static const QDBusConnection::RegisterOptions &RegisterOptions()
|
||||
{
|
||||
static QDBusConnection::RegisterOptions opt = QDBusConnection::ExportAdaptors | QDBusConnection::ExportAllSignals | QDBusConnection::ExportAllSlots;
|
||||
return opt;
|
||||
}
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Constructor
|
||||
* \param parent
|
||||
*/
|
||||
CDBusServer(const QString &address, QObject *parent = 0);
|
||||
|
||||
/*!
|
||||
* \brief Adds a QObject to be exposed to DBus
|
||||
* \param name
|
||||
* \param object
|
||||
*/
|
||||
void addObject(const QString &name, QObject *object);
|
||||
/*!
|
||||
* \brief Adds a QObject to be exposed to DBus
|
||||
* \param name
|
||||
* \param object
|
||||
*/
|
||||
void addObject(const QString &name, QObject *object);
|
||||
|
||||
void printError();
|
||||
/*!
|
||||
* \brief printError
|
||||
*/
|
||||
void printError() const;
|
||||
|
||||
public slots:
|
||||
/*!
|
||||
* \brief Last error
|
||||
* \return
|
||||
*/
|
||||
QDBusError lastError() const;
|
||||
|
||||
/*!
|
||||
* \brief Called when a new DBus client has connected
|
||||
* \param connection
|
||||
*/
|
||||
void newConnection(const QDBusConnection & connection);
|
||||
signals:
|
||||
};
|
||||
/*!
|
||||
* \brief Connected?
|
||||
* \return
|
||||
*/
|
||||
bool isConnected() const
|
||||
{
|
||||
return this->m_busServer.isConnected();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief address
|
||||
* \return
|
||||
*/
|
||||
QString address() const
|
||||
{
|
||||
|
||||
return this->m_busServer.address();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Connection by name
|
||||
* \param connectionName
|
||||
* \return
|
||||
*/
|
||||
const QDBusConnection getDbusConnection(const QString &connectionName) const
|
||||
{
|
||||
return this->m_DBusConnections.value(connectionName, CDBusServer::defaultConnection());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Get DBbus connections
|
||||
* \return
|
||||
*/
|
||||
const QList<QDBusConnection> getDbusConnections() const
|
||||
{
|
||||
// http://stackoverflow.com/questions/1124340/any-ideas-why-qhash-and-qmap-return-const-t-instead-of-const-t
|
||||
return this->m_DBusConnections.values();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Default connection
|
||||
* \return
|
||||
*/
|
||||
static const QDBusConnection &defaultConnection()
|
||||
{
|
||||
static QDBusConnection defaultConnection("default");
|
||||
return defaultConnection;
|
||||
}
|
||||
|
||||
private slots:
|
||||
|
||||
/*!
|
||||
* \brief Called when a new DBus client has connected
|
||||
* \param connection
|
||||
* \return
|
||||
*/
|
||||
bool newConnection(const QDBusConnection &connection);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DBUSSERVER_H
|
||||
#endif // guard
|
||||
|
||||
27
src/blackcore/readme.txt
Normal file
27
src/blackcore/readme.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
Starting: dbus-daemon.exe --session
|
||||
- blocks CMD (sometimes daemon continues to run when pressing CTRL/C)
|
||||
- does not start without directory session.d, i.e. ..\Qt\Qt5.1.0DBus\qtbase\etc\dbus-1\session.d
|
||||
|
||||
!!! The includes are set in the qmake file, there are the header files
|
||||
!!! which are used in the interface
|
||||
/// qdbuscpp2xml context_network.h -x blackmisc_cpp2xml.dll -o blackcore.contextnetwork.xml
|
||||
qdbuscpp2xml context_network_interface.h -x blackmisc_cpp2xml.dll -o blackcore.contextnetwork.xml
|
||||
qdbuscpp2xml context_settings_interface.h -x blackmisc_cpp2xml.dll -o blackcore.contextsettings.xml
|
||||
|
||||
Set search path for plugins: env.var. QT_PLUGIN_PATH
|
||||
|
||||
Done automatically (qmake), but if required manually
|
||||
Interface:
|
||||
qdbusxml2cpp -i blackmisc/blackmiscfreefunctions.h -i blackmisc/blackmiscallvalueclasses.h -p contextnetwork_interface.h: H:\Projects\Qt\VatsimClient\client\src\blackcore\blackcore.contextnetwork.xml
|
||||
qdbusxml2cpp -i contextnetwork_interface.h -p :contextnetwork_interface.cpp H:\Projects\Qt\VatsimClient\client\src\blackcore\blackcore.contextnetwork.xml
|
||||
|
||||
The : indicates generation of cpp file
|
||||
|
||||
Adaptor:
|
||||
qdbusxml2cpp -i blackmisc/blackmiscfreefunctions.h -i blackmisc/blackmiscallvalueclasses.h -a contextnetwork_adaptor.h blackcore.contextnetwork.xml
|
||||
qdbusxml2cpp -i context_adaptor.h -a :contextnetwork_adaptor.cpp blackcore.contextnetwork.xml
|
||||
|
||||
|
||||
Manually:
|
||||
<signal name="statusMessage">
|
||||
<signal name="textMessagesReceived">
|
||||
Reference in New Issue
Block a user