diff --git a/src/blackcore/network.h b/src/blackcore/network.h index 2f5100041..36364df0a 100644 --- a/src/blackcore/network.h +++ b/src/blackcore/network.h @@ -198,6 +198,12 @@ namespace BlackCore */ virtual void sendTextMessages(const BlackMisc::Network::CTextMessageList &messages) = 0; + /*! + * Send a custom packet. + * \pre Network must be connected when calling this function. + */ + virtual void sendCustomPacket(const BlackMisc::Aviation::CCallsign &callsign, const QString &packetId, const QStringList &data) = 0; + //! @} //////////////////////////////////////////////////////////////// //! \name ATC slots @@ -339,6 +345,11 @@ namespace BlackCore */ void atisLogoffTimeReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &zuluTime); + /*! + * We received a custom packet. It is the slot's responsibility to decode the data. + */ + void customPacketReceived(const BlackMisc::Aviation::CCallsign &callsign, const QString &packetId, const QStringList &data); + //! @} //////////////////////////////////////////////////////////////// //! \name Aircraft signals diff --git a/src/blackcore/network_vatlib.cpp b/src/blackcore/network_vatlib.cpp index a6f0bf93a..3634a011b 100644 --- a/src/blackcore/network_vatlib.cpp +++ b/src/blackcore/network_vatlib.cpp @@ -90,6 +90,7 @@ namespace BlackCore m_net->InstallOnCloudDataReceivedEvent(onCloudDataReceived, this); m_net->InstallOnPilotInfoRequestReceivedEvent(onPilotInfoRequestReceived, this); m_net->InstallOnPilotInfoReceivedEvent(onPilotInfoReceived, this); + m_net->InstallOnCustomPilotPacketReceivedEvent(onCustomPacketReceived, this); } catch (...) { exceptionDispatcher(Q_FUNC_INFO); } } @@ -250,11 +251,47 @@ namespace BlackCore return toFSD(callsign.getStringAsSet()); } + std::function CNetworkVatlib::toFSD(QStringList qstrList) const + { + struct Closure + { + QVector m_bytesVec; + QVector m_cstrVec; + Closure(QStringList qsl, const CNetworkVatlib *creator) + { + for (auto i = qsl.begin(); i != qsl.end(); ++i) + { + m_bytesVec.push_back(creator->toFSD(*i)); + } + } + const char **operator ()() + { + Q_ASSERT(m_cstrVec.isEmpty()); + for (auto i = m_bytesVec.begin(); i != m_bytesVec.end(); ++i) + { + m_cstrVec.push_back(i->constData()); + } + return const_cast(m_cstrVec.constData()); + } + }; + return Closure(qstrList, this); + } + QString CNetworkVatlib::fromFSD(const char *cstr) const { return m_fsdTextCodec->toUnicode(cstr); } + QStringList CNetworkVatlib::fromFSD(const char **cstrArray, int size) const + { + QStringList qstrList; + for (int i = 0; i < size; ++i) + { + qstrList.push_back(fromFSD(cstrArray[i])); + } + return qstrList; + } + void exceptionDispatcher(const char *caller) { try @@ -441,6 +478,17 @@ namespace BlackCore catch (...) { exceptionDispatcher(Q_FUNC_INFO); } } + void CNetworkVatlib::sendCustomPacket(const BlackMisc::Aviation::CCallsign &callsign, const QString &packetId, const QStringList &data) + { + Q_ASSERT_X(isConnected(), "CNetworkVatlib", "Can't send to server when disconnected"); + + try + { + m_net->SendCustomPilotPacket(toFSD(callsign), toFSD(packetId), toFSD(data)(), data.size()); + } + catch (...) { exceptionDispatcher(Q_FUNC_INFO); } + } + void CNetworkVatlib::sendIpQuery() { Q_ASSERT_X(isConnected(), "CNetworkVatlib", "Can't send to server when disconnected"); @@ -763,6 +811,11 @@ namespace BlackCore emit cbvar_cast(cbvar)->pongReceived(cbvar_cast(cbvar)->fromFSD(callsign), CTime(elapsedTime, CTimeUnit::s())); } + void CNetworkVatlib::onCustomPacketReceived(Cvatlib_Network *, const char *callsign, const char *packetId, const char **data, INT dataSize, void *cbvar) + { + emit cbvar_cast(cbvar)->customPacketReceived(cbvar_cast(cbvar)->fromFSD(callsign), cbvar_cast(cbvar)->fromFSD(packetId), cbvar_cast(cbvar)->fromFSD(data, dataSize)); + } + void CNetworkVatlib::onMetarReceived(Cvatlib_Network *, const char *data, void *cbvar) { emit cbvar_cast(cbvar)->metarReplyReceived(cbvar_cast(cbvar)->fromFSD(data)); diff --git a/src/blackcore/network_vatlib.h b/src/blackcore/network_vatlib.h index 9ee0f7a02..1fd45a365 100644 --- a/src/blackcore/network_vatlib.h +++ b/src/blackcore/network_vatlib.h @@ -49,6 +49,7 @@ namespace BlackCore virtual void sendRealNameQuery(const BlackMisc::Aviation::CCallsign &callsign) override; virtual void sendIpQuery() override; virtual void sendServerQuery(const BlackMisc::Aviation::CCallsign &callsign) override; + virtual void sendCustomPacket(const BlackMisc::Aviation::CCallsign &callsign, const QString &packetId, const QStringList &data) override; // Text message slots virtual void sendTextMessages(const BlackMisc::Network::CTextMessageList &messages) override; @@ -100,11 +101,15 @@ namespace BlackCore static void onPilotInfoRequestReceived(Cvatlib_Network *, const char *callsign, void *cbvar); static void onPilotInfoReceived(Cvatlib_Network *, const char *callsign, const char **keysValues, void *cbvar); static void onPilotPositionUpdate(Cvatlib_Network *, const char *callsign, Cvatlib_Network::PilotPosUpdate pos, void *cbvar); + static void onCustomPacketReceived(Cvatlib_Network *, const char *callsign, const char *packetId, const char **data, INT dataSize, void *cbvar); private: QByteArray toFSD(QString qstr) const; QByteArray toFSD(const BlackMisc::Aviation::CCallsign &callsign) const; + std::function toFSD(QStringList qstrList) const; QString fromFSD(const char *cstr) const; + QStringList fromFSD(const char **cstrArray, int size) const; + void initializeSession(); void changeConnectionStatus(Cvatlib_Network::connStatus newStatus, QString errorMessage = ""); bool isDisconnected() const { return m_status != Cvatlib_Network::connStatus_Connecting && m_status != Cvatlib_Network::connStatus_Connected; }