diff --git a/src/blackcore/network.h b/src/blackcore/network.h new file mode 100644 index 000000000..6e5c65954 --- /dev/null +++ b/src/blackcore/network.h @@ -0,0 +1,79 @@ +/* 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/. */ + +/*! + \file +*/ + +#ifndef BLACKCORE_NETWORK_H +#define BLACKCORE_NETWORK_H + +#include "../blackmisc/pqfrequency.h" +#include "../blackmisc/coordinategeodetic.h" +#include "../blackmisc/pqlength.h" +#include "../blackmisc/pqtime.h" +#include +#include +#include +#include + +namespace BlackCore +{ + + class INetwork : public QObject + { + Q_OBJECT; + + public slots: + virtual void setServerDetails(const QString& hostname, quint16 port) = 0; + virtual void setUserCredentials(const QString& username, const QString& password) = 0; + virtual void initiateConnection() = 0; + virtual void terminateConnection() = 0; + virtual void sendPrivateTextMessage(const QString& callsign, const QString& msg) = 0; + virtual void sendRadioTextMessage(const QVector& freqs, const QString& msg) = 0; + //TODO virtual void sendInfoQuery(...) = 0; + //TODO virtual void replyToInfoQuery(...) = 0; + virtual void requestPlaneInfo(const QString& callsign) = 0; + //TODO virtual void setPlanePosition(...) = 0; + //TODO virtual void sendFlightPlan(...) = 0; + virtual void sendPlaneInfo(const QString& callsign, const QString& acTypeICAO, const QString& airlineICAO, const QString& livery) = 0; + virtual void ping(const QString& callsign) = 0; + virtual void requestMetar(const QString& airportICAO) = 0; + virtual void requestWeatherData(const QString& airportICAO) = 0; + + signals: + void atcPositionUpdate(const QString& callsign, const BlackMisc::PhysicalQuantities::CFrequency& freq, + const BlackMisc::Geo::CCoordinateGeodetic& pos, const BlackMisc::PhysicalQuantities::CLength& range); + void atcDisconnected(const QString& callsign); + void atisReplyReceived(const QString& callsign, const QString& data); + //TODO void cloudDataReceived(...); + void connectionStatusIdle(); + void connectionStatusConnecting(); + void connectionStatusConnected(); + void connectionStatusDisconnected(); + void connectionStatusError(); + //TODO void atisQueryReplyReceived(...); + //TODO void nameQueryReplyReceived(const QString& callsign, const QString& name); + //TODO void capabilitiesQueryReplyReceived(...); + void ipQueryReplyReceived(const QString& ip); + void fpQueryRequestReceived(const QString& callsign); + void freqQueryRequestReceived(const QString& callsign); + //TODO void interimPilotPositionUpdate(...); + void kicked(const QString& msg); + void metarReceived(const QString& data); + void pilotDisconnected(const QString& callsign); + void planeInfoReceived(const QString& callsign, const QString& acTypeICAO, const QString& airlineICAO, const QString& livery); + void planeInfoRequestReceived(const QString& callsign); + //TODO void pilotPositionUpdate(...); + void pong(const QString& callsign, const BlackMisc::PhysicalQuantities::CTime& elapsedTime); + void radioTextMessageReceived(const QString& callsign, const QString& msg, const QVector& freqs); + void privateTextMessageReceived(const QString& fromCallsign, const QString& toCallsign, const QString& msg); + //TODO void temperatureDataReceived(...); + //TODO void windDataReceived(...); + }; + +} //namespace BlackCore + +#endif //BLACKCORE_NETWORK_H diff --git a/src/blackcore/network_vatlib.cpp b/src/blackcore/network_vatlib.cpp new file mode 100644 index 000000000..24df8ba24 --- /dev/null +++ b/src/blackcore/network_vatlib.cpp @@ -0,0 +1,422 @@ +/* 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 "network_vatlib.h" +#include +#include +#include + +/* +Macro to convert a QString to a C string (const char*). +The C string will cease to be valid at the end of the current statement, so it can't be saved for later without making a copy. +Something like this is valid: + myPrint(C_STR(myQString)); +But this is not: + const char *s = C_STR(myQString); myPrint(s); +*/ +#define C_STR(s) ((s).toUtf8().constData()) //TODO ask Gary UTF-8 or ASCII for text that will be sent over FSD? + +namespace BlackCore +{ + + using namespace BlackMisc::PhysicalQuantities; + using namespace BlackMisc::Geo; + + NetworkVatlib::NetworkVatlib() + : m_net(Create_Cvatlib_Network()) + { + try + { + m_net->InstallOnConnectionStatusChangedEvent(onConnectionStatusChanged, this); + m_net->InstallOnTextMessageReceivedEvent(onTextMessageReceived, this); + m_net->InstallOnRadioMessageReceivedEvent(onRadioMessageReceived, this); + m_net->InstallOnPilotDisconnectedEvent(onPilotDisconnected, this); + m_net->InstallOnControllerDisconnectedEvent(onControllerDisconnected, this); + m_net->InstallOnPilotPositionUpdateEvent(onPilotPositionUpdate, this); + m_net->InstallOnInterimPilotPositionUpdateEvent(onInterimPilotPositionUpdate, this); + m_net->InstallOnAtcPositionUpdateEvent(onAtcPositionUpdate, this); + m_net->InstallOnKickedEvent(onKicked, this); + m_net->InstallOnPongEvent(onPong, this); + m_net->InstallOnMetarReceivedEvent(onMetarReceived, this); + m_net->InstallOnInfoQueryRequestReceivedEvent(onInfoQueryRequestReceived, this); + m_net->InstallOnInfoQueryReplyReceivedEvent(onInfoQueryReplyReceived, this); + m_net->InstallOnCapabilitiesReplyReceivedEvent(onCapabilitiesReplyReceived, this); + m_net->InstallOnAtisReplyReceivedEvent(onAtisReplyReceived, this); + m_net->InstallOnTemperatureDataReceivedEvent(onTemperatureDataReceived, this); + m_net->InstallOnErrorReceivedEvent(onErrorReceived, this); + m_net->InstallOnWindDataReceivedEvent(onWindDataReceived, this); + m_net->InstallOnCloudDataReceivedEvent(onCloudDataReceived, this); + m_net->InstallOnPilotInfoRequestReceivedEvent(onPilotInfoRequestReceived, this); + m_net->InstallOnPilotInfoReceivedEvent(onPilotInfoReceived, this); + + QString capabilities; + capabilities += m_net->capability_AtcInfo; + capabilities += "=1:"; + capabilities += m_net->capability_InterimPos; + capabilities += "=1:"; + capabilities += m_net->capability_ModelDesc; + capabilities += "=1"; + + m_net->CreateNetworkSession(CLIENT_NAME_VERSION, CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, + CLIENT_SIMULATOR_NAME, CLIENT_PUBLIC_ID, CLIENT_PRIVATE_KEY, C_STR(capabilities)); + + m_timer.start(c_updateIntervalMillisecs, this); + } + catch (...) { exceptionDispatcher(); } + } + + NetworkVatlib::~NetworkVatlib() + { + try + { + m_timer.stop(); + + if (m_net->IsNetworkConnected()) + { + m_net->LogoffAndDisconnect(0); + } + + m_net->DestroyNetworkSession(); + } + catch (...) { exceptionDispatcher(); } + } + + void NetworkVatlib::timerEvent(QTimerEvent*) + { + try + { + if (m_net->IsValid() && m_net->IsSessionExists()) + { + m_net->DoProcessing(); + } + } + catch (...) { exceptionDispatcher(); } + } + + void NetworkVatlib::exceptionDispatcher() + { + try + { + throw; + } + //catch (InvalidObjectException& e) //TODO ask Gary to confirm that trying to use an invalid Cvatlib_Network is always the result of a programmer error + //catch (ObjectNotSetupException& e) //TODO ask Gary what is "the setup function" mentioned in the ObjectNotSetupException documentation? + catch (NetworkNotConnectedException& e) + { + qDebug() << "NetworkNotConnectedException: " << e.what(); + } + catch (VatlibException& e) + { + Q_ASSERT_X(false, "NetworkVatlib", e.what()); + assert(false); + qDebug() << "VatlibException: " << e.what(); + } + catch (std::exception& e) + { + Q_ASSERT_X(false, "NetworkVatlib", e.what()); + assert(false); + qDebug() << "NetworkVatlib: std::exception: " << e.what(); + } + catch (...) + { + Q_ASSERT_X(false, "NetworkVatlib", "Unknown exception"); + assert(false); + qDebug() << "NetworkVatlib: unknown exception"; + } + } + + /********************************** * * * * * * * * * * * * * * * * * * * ************************************/ + /********************************** INetwork slots ************************************/ + /********************************** * * * * * * * * * * * * * * * * * * * ************************************/ + + void NetworkVatlib::setServerDetails(const QString& host, quint16 port) + { + m_serverHost = host; + m_serverPort = port; + } + + void NetworkVatlib::setUserCredentials(const QString& username, const QString& password) + { + m_username = username; + m_password = password; + } + + void NetworkVatlib::initiateConnection() + { + try + { + m_net->ConnectAndLogon(); + } + catch (...) { exceptionDispatcher(); } + } + + void NetworkVatlib::terminateConnection() + { + try + { + m_net->LogoffAndDisconnect(c_logoffTimeoutSeconds); //TODO ask Gary will this block? + } + catch (...) { exceptionDispatcher(); } + } + + void NetworkVatlib::sendPrivateTextMessage(const QString& callsign, const QString& msg) + { + try + { + m_net->SendPrivateTextMessage(C_STR(callsign), C_STR(msg)); + } + catch (...) { exceptionDispatcher(); } + } + + void NetworkVatlib::sendRadioTextMessage(const QVector& freqs, const QString& msg) + { + try + { + std::vector freqsVec; + for (int i = 0; i < freqs.size(); ++i) + { + freqsVec.push_back(freqs[i].value(CFrequencyUnit::kHz())); + } + m_net->SendRadioTextMessage(freqsVec.size(), freqsVec.data(), C_STR(msg)); + } + catch (...) { exceptionDispatcher(); } + } + + void NetworkVatlib::requestPlaneInfo(const QString& callsign) + { + try + { + m_net->RequestPlaneInfo(C_STR(callsign)); + } + catch (...) { exceptionDispatcher(); } + } + + void NetworkVatlib::sendPlaneInfo(const QString& callsign, const QString& acTypeICAO, const QString& airlineICAO, const QString& livery) + { + try + { + const QByteArray acTypeICAObytes = acTypeICAO.toUtf8(); //TODO ask Gary UTF-8 or ASCII? + const QByteArray airlineICAObytes = airlineICAO.toUtf8(); //TODO ask Gary UTF-8 or ASCII? + const QByteArray liverybytes = livery.toUtf8(); //TODO ask Gary UTF-8 or ASCII? + std::vector keysValues; + if (! acTypeICAO.isEmpty()) + { + keysValues.push_back(m_net->acinfo_Equipment); + keysValues.push_back(acTypeICAObytes.data()); + } + if (! airlineICAO.isEmpty()) + { + keysValues.push_back(m_net->acinfo_Airline); + keysValues.push_back(airlineICAObytes.data()); + } + if (! livery.isEmpty()) + { + keysValues.push_back(m_net->acinfo_Livery); + keysValues.push_back(liverybytes.data()); + } + keysValues.push_back(0); + m_net->SendPlaneInfo(C_STR(callsign), keysValues.data()); + } + catch (...) { exceptionDispatcher(); } + } + + void NetworkVatlib::ping(const QString& callsign) + { + try + { + m_net->PingUser(C_STR(callsign)); + } + catch (...) { exceptionDispatcher(); } + } + + void NetworkVatlib::requestMetar(const QString& airportICAO) + { + try + { + m_net->RequestMetar(C_STR(airportICAO)); + } + catch (...) { exceptionDispatcher(); } + } + + void NetworkVatlib::requestWeatherData(const QString& airportICAO) + { + try + { + m_net->RequestWeatherData(C_STR(airportICAO)); + } + catch (...) { exceptionDispatcher(); } + } + + /********************************** * * * * * * * * * * * * * * * * * * * ************************************/ + /********************************** shimlib callbacks ************************************/ + /********************************** * * * * * * * * * * * * * * * * * * * ************************************/ + + NetworkVatlib* cbvar_cast(void* cbvar) + { + return static_cast(cbvar); + } + + void NetworkVatlib::onConnectionStatusChanged(Cvatlib_Network*, Cvatlib_Network::connStatus, Cvatlib_Network::connStatus newStatus, void* cbvar) + { + switch (newStatus) + { + case Cvatlib_Network::connStatus_Idle: emit cbvar_cast(cbvar)->connectionStatusIdle(); break; + case Cvatlib_Network::connStatus_Connecting: emit cbvar_cast(cbvar)->connectionStatusConnecting(); break; + case Cvatlib_Network::connStatus_Connected: emit cbvar_cast(cbvar)->connectionStatusConnected(); break; + case Cvatlib_Network::connStatus_Disconnected: emit cbvar_cast(cbvar)->connectionStatusDisconnected(); break; + case Cvatlib_Network::connStatus_Error: emit cbvar_cast(cbvar)->connectionStatusError(); break; + } + } + + void NetworkVatlib::onTextMessageReceived(Cvatlib_Network*, const char* from, const char* to, const char* msg, void* cbvar) + { + emit cbvar_cast(cbvar)->privateTextMessageReceived(from, to, msg); + } + + void NetworkVatlib::onRadioMessageReceived(Cvatlib_Network*, const char* from, INT numFreq, INT* freqList, const char* msg, void* cbvar) + { + QVector freqs; + for (int i = 0; i < numFreq; ++i) + { + freqs.push_back(CFrequency(freqList[i], CFrequencyUnit::kHz())); + } + emit cbvar_cast(cbvar)->radioTextMessageReceived(from, msg, freqs); + } + + void NetworkVatlib::onPilotDisconnected(Cvatlib_Network*, const char* callsign, void* cbvar) + { + emit cbvar_cast(cbvar)->pilotDisconnected(callsign); + } + + void NetworkVatlib::onControllerDisconnected(Cvatlib_Network*, const char* callsign, void* cbvar) + { + emit cbvar_cast(cbvar)->atcDisconnected(callsign); + } + + void NetworkVatlib::onPilotPositionUpdate(Cvatlib_Network*, const char* callsign, Cvatlib_Network::PilotPosUpdate pos, void* cbvar) + { + //TODO + } + + void NetworkVatlib::onInterimPilotPositionUpdate(Cvatlib_Network*, const char* callsign, Cvatlib_Network::PilotPosUpdate pos, void* cbvar) + { + //TODO + } + + void NetworkVatlib::onAtcPositionUpdate(Cvatlib_Network*, const char* callsign, Cvatlib_Network::ATCPosUpdate pos, void* cbvar) + { + emit cbvar_cast(cbvar)->atcPositionUpdate(callsign, CFrequency(pos.frequency, CFrequencyUnit::kHz()), + CCoordinateGeodetic(pos.lat, pos.lon, 0), CLength(pos.visibleRange, CLengthUnit::NM())); + } + + void NetworkVatlib::onKicked(Cvatlib_Network*, const char* reason, void* cbvar) + { + emit cbvar_cast(cbvar)->kicked(reason); + } + + void NetworkVatlib::onPong(Cvatlib_Network*, const char* callsign, INT elapsedTime, void* cbvar) + { + emit cbvar_cast(cbvar)->pong(callsign, CTime(elapsedTime, CTimeUnit::ms())); //TODO ask Gary to confirm time unit + } + + void NetworkVatlib::onMetarReceived(Cvatlib_Network*, const char* data, void* cbvar) + { + emit cbvar_cast(cbvar)->metarReceived(data); + } + + void NetworkVatlib::onInfoQueryRequestReceived(Cvatlib_Network*, const char* callsign, Cvatlib_Network::infoQuery type, const char* data, void* cbvar) + { + switch (type) + { + case Cvatlib_Network::infoQuery_FP: emit cbvar_cast(cbvar)->fpQueryRequestReceived(callsign); break; + case Cvatlib_Network::infoQuery_Freq: emit cbvar_cast(cbvar)->freqQueryRequestReceived(callsign); break; + //TODO ask Gary whether we need to reply to UserInfo, Server, Name, Capabilities, or IP queries + } + } + + void NetworkVatlib::onInfoQueryReplyReceived(Cvatlib_Network*, const char* callsign, Cvatlib_Network::infoQuery type, const char* data, const char* data2, void* cbvar) + { + switch (type) + { + case Cvatlib_Network::infoQuery_ATIS: break; //TODO ask Gary do we handle this here or in onAtisReplyReceived or both? + case Cvatlib_Network::infoQuery_Name: break; //TODO ask Gary what are the meanings of data and data2 in this context? + case Cvatlib_Network::infoQuery_Capabilities: break; //TODO ask Gary do we handle this here or in onCapabilitiesReplyReceived or both? + case Cvatlib_Network::infoQuery_IP: emit cbvar_cast(cbvar)->ipQueryReplyReceived(data); break; + } + } + + void NetworkVatlib::onCapabilitiesReplyReceived(Cvatlib_Network*, const char* callsign, const char** keysValues, void* cbvar) + { + //TODO + } + + void NetworkVatlib::onAtisReplyReceived(Cvatlib_Network*, const char* callsign, Cvatlib_Network::atisLineType type, const char* data, void* cbvar) + { + emit cbvar_cast(cbvar)->atisReplyReceived(callsign, data); + } + + void NetworkVatlib::onTemperatureDataReceived(Cvatlib_Network*, Cvatlib_Network::TempLayer layers[4], INT pressure, void* cbvar) + { + //TODO + } + + void NetworkVatlib::onErrorReceived(Cvatlib_Network*, Cvatlib_Network::error type, const char* msg, const char* data, void* cbvar) + { + switch (type) + { + case Cvatlib_Network::error_Ok: return; + case Cvatlib_Network::error_CallsignTaken: qCritical() << "The requested callsign is already taken"; break; + case Cvatlib_Network::error_CallsignInvalid: qCritical() << "The requested callsign is not valid"; break; + case Cvatlib_Network::error_Registered: break; //TODO ask Gary to explain meaning + case Cvatlib_Network::error_Syntax: assert(false); qWarning() << "VATSIM shim library: Syntax error: " << data; break; + case Cvatlib_Network::error_SourceInvalid: break; //TODO ask Gary to explain meaning + case Cvatlib_Network::error_CIDPasswdInvalid: qCritical() << "Wrong user ID or password"; break; + case Cvatlib_Network::error_CallsignNotExists: qDebug() << "Shim lib: " << msg << " (" << data << ")"; break; + case Cvatlib_Network::error_NoFP: break; //TODO ask Gary under what circumstance this can happen + case Cvatlib_Network::error_NoWeather: break; //TODO ask Gary to explain meaning + case Cvatlib_Network::error_ProtoVersion: qCritical() << "This server uses an unsupported protocol version"; break; + case Cvatlib_Network::error_LevelTooHigh: qCritical() << "You are not authorized to use the requested pilot rating"; break; //TODO ask Gary to confirm meaning + case Cvatlib_Network::error_ServerFull: qCritical() << "The server is full"; break; + case Cvatlib_Network::error_CIDSuspended: qCritical() << "Your user account is suspended"; break; + case Cvatlib_Network::error_InvalidControl: break; //TODO ask Gary to explain meaning + case Cvatlib_Network::error_InvalidPosition: qCritical() << "You are not authorized to use the requested pilot rating"; break; + case Cvatlib_Network::error_SoftwareNotAuthorized: qCritical() << "This client software has not been authorized for use on this network"; break; + default: assert(false); qWarning() << "VATSIM shim library: " << msg << "(error " << type << ")"; break; + } + } + + void NetworkVatlib::onWindDataReceived(Cvatlib_Network*, Cvatlib_Network::WindLayer layers[4], void* cbvar) + { + //TODO + } + + void NetworkVatlib::onCloudDataReceived(Cvatlib_Network*, Cvatlib_Network::CloudLayer layers[2], Cvatlib_Network::StormLayer storm, float vis, void* cbvar) + { + //TODO + } + + void NetworkVatlib::onPilotInfoRequestReceived(Cvatlib_Network*, const char* callsign, void* cbvar) + { + emit cbvar_cast(cbvar)->planeInfoRequestReceived(callsign); + } + + void NetworkVatlib::onPilotInfoReceived(Cvatlib_Network* net, const char* callsign, const char** keysValues, void* cbvar) + { + QString acTypeICAO; + QString airlineICAO; + QString livery; + while (*keysValues) + { + QString key (*keysValues); + keysValues++; + if (key == net->acinfo_Equipment) { acTypeICAO = *keysValues; } + else if (key == net->acinfo_Airline) { airlineICAO = *keysValues; } + else if (key == net->acinfo_Livery) { livery = *keysValues; } + keysValues++; + } + emit cbvar_cast(cbvar)->planeInfoReceived(callsign, acTypeICAO, airlineICAO, livery); + } + +} //namespace BlackCore diff --git a/src/blackcore/network_vatlib.h b/src/blackcore/network_vatlib.h new file mode 100644 index 000000000..4a106e9ad --- /dev/null +++ b/src/blackcore/network_vatlib.h @@ -0,0 +1,86 @@ +/* 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/. */ + +/*! + \file +*/ + +#ifndef BLACKCORE_NETWORK_VATLIB_H +#define BLACKCORE_NETWORK_VATLIB_H + +#include "network.h" +#include "../../vatlib/vatlib.h" +#include +#include + +namespace BlackCore +{ + + class NetworkVatlib : public INetwork + { + Q_OBJECT; + + public: + NetworkVatlib(); + virtual ~NetworkVatlib(); + + protected: //QObject overrides + virtual void timerEvent(QTimerEvent*); + + public: //INetwork slots overrides + virtual void setServerDetails(const QString& hostname, quint16 port); + virtual void setUserCredentials(const QString& username, const QString& password); + virtual void initiateConnection(); + virtual void terminateConnection(); + virtual void sendPrivateTextMessage(const QString& callsign, const QString& msg); + virtual void sendRadioTextMessage(const QVector& freqs, const QString& msg); + virtual void requestPlaneInfo(const QString& callsign); + virtual void sendPlaneInfo(const QString& callsign, const QString& acTypeICAO, const QString& airlineICAO, const QString& livery); + virtual void ping(const QString& callsign); + virtual void requestMetar(const QString& airportICAO); + virtual void requestWeatherData(const QString& airportICAO); + + private: //shimlib callbacks + static void onConnectionStatusChanged(Cvatlib_Network*, Cvatlib_Network::connStatus oldStatus, Cvatlib_Network::connStatus newStatus, void* cbvar); + static void onTextMessageReceived(Cvatlib_Network*, const char* from, const char* to, const char* msg, void* cbvar); + static void onRadioMessageReceived(Cvatlib_Network*, const char* from, INT numFreq, INT* freqList, const char* msg, void* cbvar); + static void onPilotDisconnected(Cvatlib_Network*, const char* callsign, void* cbvar); + static void onControllerDisconnected(Cvatlib_Network*, const char* callsign, void* cbvar); + static void onPilotPositionUpdate(Cvatlib_Network*, const char* callsign, Cvatlib_Network::PilotPosUpdate pos, void* cbvar); + static void onInterimPilotPositionUpdate(Cvatlib_Network*, const char* callsign, Cvatlib_Network::PilotPosUpdate pos, void* cbvar); + static void onAtcPositionUpdate(Cvatlib_Network*, const char* callsign, Cvatlib_Network::ATCPosUpdate pos, void* cbvar); + static void onKicked(Cvatlib_Network*, const char* reason, void* cbvar); + static void onPong(Cvatlib_Network*, const char* callsign, INT elapsedTime, void* cbvar); + static void onMetarReceived(Cvatlib_Network*, const char* data, void* cbvar); + static void onInfoQueryRequestReceived(Cvatlib_Network*, const char* callsign, Cvatlib_Network::infoQuery type, const char* data, void* cbvar); + static void onInfoQueryReplyReceived(Cvatlib_Network*, const char* callsign, Cvatlib_Network::infoQuery type, const char* data, const char* data2, void* cbvar); + static void onCapabilitiesReplyReceived(Cvatlib_Network*, const char* callsign, const char** keysValues, void* cbvar); + static void onAtisReplyReceived(Cvatlib_Network*, const char* callsign, Cvatlib_Network::atisLineType type, const char* data, void* cbvar); + static void onTemperatureDataReceived(Cvatlib_Network*, Cvatlib_Network::TempLayer layers[4], INT pressure, void* cbvar); + static void onErrorReceived(Cvatlib_Network*, Cvatlib_Network::error type, const char* msg, const char* data, void* cbvar); + static void onWindDataReceived(Cvatlib_Network*, Cvatlib_Network::WindLayer layers[4], void* cbvar); + static void onCloudDataReceived(Cvatlib_Network*, Cvatlib_Network::CloudLayer layers[2], Cvatlib_Network::StormLayer storm, float vis, void* cbvar); + static void onPilotInfoRequestReceived(Cvatlib_Network*, const char* callsign, void* cbvar); + static void onPilotInfoReceived(Cvatlib_Network*, const char* callsign, const char** keysValues, void* cbvar); + + private: + void exceptionDispatcher(); + + private: + QScopedPointer m_net; + + QBasicTimer m_timer; + static int const c_updateIntervalMillisecs = 100; + static int const c_logoffTimeoutSeconds = 5; + + QString m_serverHost; + quint16 m_serverPort; + QString m_username; + QString m_password; + }; + +} //namespace BlackCore + +#endif //BLACKCORE_NETWORK_VATLIB_H