mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-05 09:15:34 +08:00
Ref T730, style and log messages
This commit is contained in:
committed by
Mat Sutcliffe
parent
e30b690191
commit
401c89aa63
@@ -7,8 +7,11 @@
|
||||
*/
|
||||
|
||||
#include "clientconnection.h"
|
||||
#include "blackmisc/logmessage.h"
|
||||
|
||||
#include <QNetworkDatagram>
|
||||
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackCore::Afv::Crypto;
|
||||
|
||||
namespace BlackCore
|
||||
@@ -23,75 +26,64 @@ namespace BlackCore
|
||||
m_voiceServerTimer(new QTimer(this)),
|
||||
m_apiServerConnection(new CApiServerConnection(apiServer, this))
|
||||
{
|
||||
qDebug() << "ClientConnection instantiated";
|
||||
CLogMessage(this).debug(u"ClientConnection instantiated");
|
||||
|
||||
// connect(&m_apiServerConnection, &ApiServerConnection::authenticationFinished, this, &ClientConnection::apiConnectionFinished);
|
||||
// connect(&m_apiServerConnection, &ApiServerConnection::addCallsignFinished, this, &ClientConnection::addCallsignFinished);
|
||||
// connect(&m_apiServerConnection, &ApiServerConnection::removeCallsignFinished, this, &ClientConnection::removeCallsignFinished);
|
||||
|
||||
connect(m_voiceServerTimer, &QTimer::timeout, this, &CClientConnection::voiceServerHeartbeat);
|
||||
|
||||
connect(m_udpSocket, &QUdpSocket::readyRead, this, &CClientConnection::readPendingDatagrams);
|
||||
connect(m_udpSocket, &QUdpSocket::readyRead, this, &CClientConnection::readPendingDatagrams);
|
||||
connect(m_udpSocket, qOverload<QAbstractSocket::SocketError>(&QUdpSocket::error), this, &CClientConnection::handleSocketError);
|
||||
}
|
||||
|
||||
void CClientConnection::connectTo(const QString &userName, const QString &password, const QString &callsign)
|
||||
{
|
||||
if (m_connection.m_connected)
|
||||
if (m_connection.isConnected())
|
||||
{
|
||||
qDebug() << "Client already connected";
|
||||
CLogMessage(this).debug(u"Client already connected");
|
||||
return;
|
||||
}
|
||||
|
||||
m_connection.m_userName = userName;
|
||||
m_connection.m_callsign = callsign;
|
||||
m_connection.setUserName(userName);
|
||||
m_connection.setCallsign(callsign);
|
||||
bool result = m_apiServerConnection->connectTo(userName, password, m_networkVersion);
|
||||
if (!result) { return; }
|
||||
m_connection.m_tokens = m_apiServerConnection->addCallsign(m_connection.m_callsign);
|
||||
m_connection.m_authenticatedDateTimeUtc = QDateTime::currentDateTimeUtc();
|
||||
m_connection.setTokens(m_apiServerConnection->addCallsign(m_connection.getCallsign()));
|
||||
m_connection.setTsAuthenticatedToNow();
|
||||
m_connection.createCryptoChannels();
|
||||
|
||||
connectToVoiceServer();
|
||||
|
||||
// taskServerConnectionCheck.Start();
|
||||
|
||||
m_connection.m_connected = true;
|
||||
qDebug() << "Connected:" << callsign;
|
||||
m_connection.setConnected(true);
|
||||
CLogMessage(this).debug(u"Connected: '%1'") << callsign;
|
||||
}
|
||||
|
||||
void CClientConnection::disconnectFrom(const QString &reason)
|
||||
{
|
||||
if (! m_connection.m_connected)
|
||||
if (!m_connection.isConnected())
|
||||
{
|
||||
qDebug() << "Client not connected";
|
||||
CLogMessage(this).debug(u"Client not connected");
|
||||
return;
|
||||
}
|
||||
|
||||
m_connection.m_connected = false;
|
||||
m_connection.setConnected(false);
|
||||
// TODO emit disconnected(reason)
|
||||
qDebug() << "Disconnected:" << reason;
|
||||
CLogMessage(this).debug(u"Disconnected client: %1") << reason;
|
||||
|
||||
if (! m_connection.m_callsign.isEmpty())
|
||||
if (! m_connection.getCallsign().isEmpty())
|
||||
{
|
||||
m_apiServerConnection->removeCallsign(m_connection.m_callsign);
|
||||
m_apiServerConnection->removeCallsign(m_connection.getCallsign());
|
||||
}
|
||||
|
||||
// TODO connectionCheckCancelTokenSource.Cancel(); //Stops connection check loop
|
||||
disconnectFromVoiceServer();
|
||||
m_apiServerConnection->forceDisconnect();
|
||||
m_connection.m_tokens = {};
|
||||
m_connection.setTokens({});
|
||||
|
||||
qDebug() << "Disconnection complete";
|
||||
}
|
||||
|
||||
bool CClientConnection::receiveAudioDto() const
|
||||
{
|
||||
return m_receiveAudioDto;
|
||||
}
|
||||
|
||||
void CClientConnection::setReceiveAudioDto(bool receiveAudioDto)
|
||||
{
|
||||
m_receiveAudioDto = receiveAudioDto;
|
||||
CLogMessage(this).debug(u"Disconnection complete");
|
||||
}
|
||||
|
||||
void CClientConnection::updateTransceivers(const QString &callsign, const QVector<TransceiverDto> &transceivers)
|
||||
@@ -110,62 +102,62 @@ namespace BlackCore
|
||||
m_udpSocket->bind(localAddress);
|
||||
m_voiceServerTimer->start(3000);
|
||||
|
||||
qDebug() << "Connected to voice server (" + m_connection.m_tokens.VoiceServer.addressIpV4 << ")";
|
||||
CLogMessage(this).info(u"Connected to voice server '%1'") << m_connection.getTokens().VoiceServer.addressIpV4;
|
||||
}
|
||||
|
||||
void CClientConnection::disconnectFromVoiceServer()
|
||||
{
|
||||
m_voiceServerTimer->stop();
|
||||
m_udpSocket->disconnectFromHost();
|
||||
qDebug() << "All TaskVoiceServer tasks stopped";
|
||||
CLogMessage(this).info(u"All TaskVoiceServer tasks stopped");
|
||||
}
|
||||
|
||||
void CClientConnection::readPendingDatagrams()
|
||||
{
|
||||
while (m_udpSocket->hasPendingDatagrams())
|
||||
{
|
||||
QNetworkDatagram datagram = m_udpSocket->receiveDatagram();
|
||||
processMessage(datagram.data());
|
||||
const QNetworkDatagram datagram = m_udpSocket->receiveDatagram();
|
||||
this->processMessage(datagram.data());
|
||||
}
|
||||
}
|
||||
|
||||
void CClientConnection::processMessage(const QByteArray &messageDdata, bool loopback)
|
||||
{
|
||||
CryptoDtoSerializer::Deserializer deserializer = CryptoDtoSerializer::deserialize(*m_connection.voiceCryptoChannel, messageDdata, loopback);
|
||||
CryptoDtoSerializer::Deserializer deserializer = CryptoDtoSerializer::deserialize(*m_connection.m_voiceCryptoChannel, messageDdata, loopback);
|
||||
|
||||
if (deserializer.dtoNameBuffer == AudioRxOnTransceiversDto::getShortDtoName())
|
||||
{
|
||||
// qDebug() << "Received audio data";
|
||||
AudioRxOnTransceiversDto audioOnTransceiverDto = deserializer.getDto<AudioRxOnTransceiversDto>();
|
||||
if (m_connection.m_receiveAudio && m_connection.m_connected)
|
||||
const AudioRxOnTransceiversDto audioOnTransceiverDto = deserializer.getDto<AudioRxOnTransceiversDto>();
|
||||
if (m_connection.isReceivingAudio() && m_connection.isConnected())
|
||||
{
|
||||
emit audioReceived(audioOnTransceiverDto);
|
||||
}
|
||||
}
|
||||
else if (deserializer.dtoNameBuffer == HeartbeatAckDto::getShortDtoName())
|
||||
{
|
||||
m_connection.m_lastVoiceServerHeartbeatAckUtc = QDateTime::currentDateTimeUtc();
|
||||
qDebug() << "Received voice server heartbeat";
|
||||
m_connection.setTsHeartbeatToNow();
|
||||
CLogMessage(this).debug(u"Received voice server heartbeat");
|
||||
}
|
||||
else
|
||||
{
|
||||
qWarning() << "Received unknown data:" << deserializer.dtoNameBuffer << deserializer.dataLength;
|
||||
CLogMessage(this).warning(u"Received unknown data: %1 %2") << QString(deserializer.dtoNameBuffer) << deserializer.dataLength;
|
||||
}
|
||||
}
|
||||
|
||||
void CClientConnection::handleSocketError(QAbstractSocket::SocketError error)
|
||||
{
|
||||
Q_UNUSED(error)
|
||||
qDebug() << "UDP socket error" << m_udpSocket->errorString();
|
||||
CLogMessage(this).debug(u"UDP socket error: '%1'") << m_udpSocket->errorString();
|
||||
}
|
||||
|
||||
void CClientConnection::voiceServerHeartbeat()
|
||||
{
|
||||
const QUrl voiceServerUrl("udp://" + m_connection.m_tokens.VoiceServer.addressIpV4);
|
||||
qDebug() << "Sending voice server heartbeat to" << voiceServerUrl.host();
|
||||
const QUrl voiceServerUrl("udp://" + m_connection.getTokens().VoiceServer.addressIpV4);
|
||||
CLogMessage(this).debug(u"Sending voice server heartbeat to '%1'") << voiceServerUrl.host();
|
||||
HeartbeatDto keepAlive;
|
||||
keepAlive.callsign = m_connection.m_callsign.toStdString();
|
||||
const QByteArray dataBytes = CryptoDtoSerializer::serialize(*m_connection.voiceCryptoChannel, CryptoDtoMode::AEAD_ChaCha20Poly1305, keepAlive);
|
||||
keepAlive.callsign = m_connection.getCallsign().toStdString();
|
||||
const QByteArray dataBytes = CryptoDtoSerializer::serialize(*m_connection.m_voiceCryptoChannel, CryptoDtoMode::AEAD_ChaCha20Poly1305, keepAlive);
|
||||
m_udpSocket->writeDatagram(dataBytes, QHostAddress(voiceServerUrl.host()), static_cast<quint16>(voiceServerUrl.port()));
|
||||
}
|
||||
} // ns
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace BlackCore
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
//! Com status
|
||||
//! Connection status
|
||||
enum ConnectionStatus
|
||||
{
|
||||
Disconnected, //!< Not connected
|
||||
@@ -41,32 +41,42 @@ namespace BlackCore
|
||||
};
|
||||
Q_ENUM(ConnectionStatus)
|
||||
|
||||
//! Ctor
|
||||
CClientConnection(const QString &apiServer, QObject *parent = nullptr);
|
||||
|
||||
//! Connect/disconnect @{
|
||||
void connectTo(const QString &userName, const QString &password, const QString &callsign);
|
||||
void disconnectFrom(const QString &reason = {});
|
||||
bool isConnected() const { return m_connection.isConnected(); }
|
||||
//! @}
|
||||
|
||||
bool isConnected() const { return m_connection.m_connected; }
|
||||
|
||||
void setReceiveAudio(bool value) { m_connection.m_receiveAudio = value; }
|
||||
bool receiveAudio() const { return m_connection.m_receiveAudio; }
|
||||
|
||||
template<typename T>
|
||||
void sendToVoiceServer(T dto)
|
||||
//! Receiving audio? @{
|
||||
void setReceiveAudio(bool value) { m_connection.setReceiveAudio(value); }
|
||||
bool receiveAudio() const { return m_connection.isReceivingAudio(); }
|
||||
bool receiveAudioDto() const { return m_receiveAudioDto; }
|
||||
void setReceiveAudioDto(bool receiveAudioDto)
|
||||
{
|
||||
QUrl voiceServerUrl("udp://" + m_connection.m_tokens.VoiceServer.addressIpV4);
|
||||
QByteArray dataBytes = Crypto::CryptoDtoSerializer::serialize(*m_connection.voiceCryptoChannel, CryptoDtoMode::AEAD_ChaCha20Poly1305, dto);
|
||||
m_receiveAudioDto = receiveAudioDto;
|
||||
}
|
||||
//! @}
|
||||
|
||||
//! Send voiceDTO to server
|
||||
template<typename T>
|
||||
void sendToVoiceServer(const T &dto)
|
||||
{
|
||||
const QUrl voiceServerUrl("udp://" + m_connection.getTokens().VoiceServer.addressIpV4);
|
||||
const QByteArray dataBytes = Crypto::CryptoDtoSerializer::serialize(*m_connection.m_voiceCryptoChannel, Crypto::CryptoDtoMode::AEAD_ChaCha20Poly1305, dto);
|
||||
m_udpSocket->writeDatagram(dataBytes, QHostAddress(voiceServerUrl.host()), static_cast<quint16>(voiceServerUrl.port()));
|
||||
}
|
||||
|
||||
bool receiveAudioDto() const;
|
||||
void setReceiveAudioDto(bool receiveAudioDto);
|
||||
|
||||
//! Update transceivers
|
||||
void updateTransceivers(const QString &callsign, const QVector<TransceiverDto> &transceivers);
|
||||
|
||||
//! All aliased stations
|
||||
QVector<StationDto> getAllAliasedStations();
|
||||
|
||||
signals:
|
||||
//! Audio has been received
|
||||
void audioReceived(const AudioRxOnTransceiversDto &dto);
|
||||
|
||||
private:
|
||||
@@ -85,8 +95,8 @@ namespace BlackCore
|
||||
CClientConnectionData m_connection;
|
||||
|
||||
// Voice server
|
||||
QUdpSocket *m_udpSocket = nullptr;
|
||||
QTimer *m_voiceServerTimer = nullptr;
|
||||
QUdpSocket *m_udpSocket = nullptr;
|
||||
QTimer *m_voiceServerTimer = nullptr;
|
||||
|
||||
// API server
|
||||
CApiServerConnection *m_apiServerConnection = nullptr;
|
||||
|
||||
@@ -7,8 +7,10 @@
|
||||
*/
|
||||
|
||||
#include "clientconnectiondata.h"
|
||||
#include "blackmisc/logmessage.h"
|
||||
#include <QDebug>
|
||||
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackCore::Afv::Crypto;
|
||||
|
||||
namespace BlackCore
|
||||
@@ -17,6 +19,12 @@ namespace BlackCore
|
||||
{
|
||||
namespace Connection
|
||||
{
|
||||
const CLogCategoryList &CClientConnectionData::getLogCategories()
|
||||
{
|
||||
static const CLogCategoryList cats { CLogCategory::audio(), CLogCategory::vatsimSpecific() };
|
||||
return cats;
|
||||
}
|
||||
|
||||
qint64 CClientConnectionData::secondsSinceAuthentication() const
|
||||
{
|
||||
return m_authenticatedDateTimeUtc.secsTo(QDateTime::currentDateTimeUtc());
|
||||
@@ -29,17 +37,28 @@ namespace BlackCore
|
||||
|
||||
void CClientConnectionData::createCryptoChannels()
|
||||
{
|
||||
if (! m_tokens.isValid)
|
||||
if (!m_tokens.isValid)
|
||||
{
|
||||
qWarning() << "Tokens not set";
|
||||
CLogMessage(this).warning(u"Tokens not set");
|
||||
return;
|
||||
}
|
||||
voiceCryptoChannel.reset(new CCryptoDtoChannel(m_tokens.VoiceServer.channelConfig));
|
||||
m_voiceCryptoChannel.reset(new CCryptoDtoChannel(m_tokens.VoiceServer.channelConfig));
|
||||
// dataCryptoChannel.reset(new CryptoDtoChannel(m_tokens.DataServer.channelConfig));
|
||||
}
|
||||
|
||||
void CClientConnectionData::setTsAuthenticatedToNow()
|
||||
{
|
||||
m_authenticatedDateTimeUtc = QDateTime::currentDateTimeUtc();
|
||||
}
|
||||
|
||||
void CClientConnectionData::setTsHeartbeatToNow()
|
||||
{
|
||||
m_lastVoiceServerHeartbeatAckUtc = QDateTime::currentDateTimeUtc();
|
||||
}
|
||||
|
||||
bool CClientConnectionData::voiceServerAlive() const
|
||||
{
|
||||
return timeSinceAuthentication() < ServerTimeoutSecs ||
|
||||
return timeSinceAuthenticationSecs() < ServerTimeoutSecs ||
|
||||
m_lastVoiceServerHeartbeatAckUtc.secsTo(QDateTime::currentDateTimeUtc()) < ServerTimeoutSecs;
|
||||
}
|
||||
} // ns
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "blackcore/afv/dto.h"
|
||||
#include "apiserverconnection.h"
|
||||
#include "blackmisc/logcategorylist.h"
|
||||
#include "blackcore/afv/crypto/cryptodtochannel.h"
|
||||
|
||||
#include <QDateTime>
|
||||
@@ -27,8 +28,12 @@ namespace BlackCore
|
||||
namespace Connection
|
||||
{
|
||||
//! Client connection data
|
||||
struct CClientConnectionData
|
||||
class CClientConnectionData
|
||||
{
|
||||
public:
|
||||
//! Categories
|
||||
static const BlackMisc::CLogCategoryList &getLogCategories();
|
||||
|
||||
//! Ctor
|
||||
CClientConnectionData() = default;
|
||||
|
||||
@@ -40,6 +45,39 @@ namespace BlackCore
|
||||
bool isDataServerAlive() const;
|
||||
//! @}
|
||||
|
||||
//! Is connected? @{
|
||||
bool isConnected() const { return m_connected; }
|
||||
void setConnected(bool connected) { m_connected = connected; }
|
||||
//! @}
|
||||
|
||||
//! Receiving audio? @{
|
||||
bool isReceivingAudio() const { return m_receiveAudio; }
|
||||
void setReceiveAudio(bool receive) { m_receiveAudio = receive; }
|
||||
//! @}
|
||||
|
||||
//! Crypto channels for voice and data
|
||||
void createCryptoChannels();
|
||||
|
||||
//! Tokens @{
|
||||
const PostCallsignResponseDto &getTokens() const { return m_tokens; }
|
||||
void setTokens(const PostCallsignResponseDto &dto) { m_tokens = dto; }
|
||||
//! @}
|
||||
|
||||
//! Callsign @{
|
||||
const QString &getCallsign() const { return m_callsign; }
|
||||
void setCallsign(const QString &callsign) { m_callsign = callsign; }
|
||||
//! @}
|
||||
|
||||
//! Uername @{
|
||||
const QString &getUserName() const { return m_userName; }
|
||||
void setUserName(const QString &un) { m_userName = un; }
|
||||
//! @}
|
||||
|
||||
//! Timestamps @{
|
||||
void setTsAuthenticatedToNow();
|
||||
void setTsHeartbeatToNow();
|
||||
//! @}
|
||||
|
||||
/* TODO
|
||||
public long VoiceServerBytesSent { get; set; }
|
||||
public long VoiceServerBytesReceived { get; set; }
|
||||
@@ -47,17 +85,19 @@ namespace BlackCore
|
||||
public long DataServerBytesReceived { get; set; }
|
||||
*/
|
||||
|
||||
//! Crypto channels for voice and data
|
||||
void createCryptoChannels();
|
||||
QScopedPointer<Crypto::CCryptoDtoChannel> m_voiceCryptoChannel; //!< used crypto channel
|
||||
|
||||
qint64 timeSinceAuthentication() const { return m_authenticatedDateTimeUtc.secsTo(QDateTime::currentDateTimeUtc()); }
|
||||
private:
|
||||
//! Time since authentication
|
||||
qint64 timeSinceAuthenticationSecs() const { return m_authenticatedDateTimeUtc.secsTo(QDateTime::currentDateTimeUtc()); }
|
||||
|
||||
//! Is the voice server alive?
|
||||
bool voiceServerAlive() const;
|
||||
|
||||
QString m_userName; //!< user name
|
||||
QString m_callsign; //!< callsign
|
||||
|
||||
PostCallsignResponseDto m_tokens; //!< tokens
|
||||
QScopedPointer<Crypto::CCryptoDtoChannel> voiceCryptoChannel; //!< used crypto channel
|
||||
|
||||
QDateTime m_authenticatedDateTimeUtc;
|
||||
QDateTime m_lastVoiceServerHeartbeatAckUtc;
|
||||
|
||||
@@ -25,9 +25,9 @@ namespace BlackCore
|
||||
//! DTO header
|
||||
struct CryptoDtoHeaderDto
|
||||
{
|
||||
std::string ChannelTag;
|
||||
uint64_t Sequence;
|
||||
CryptoDtoMode Mode;
|
||||
std::string ChannelTag; //!< channel
|
||||
uint64_t Sequence; //!< sequence
|
||||
CryptoDtoMode Mode; //!< mode
|
||||
MSGPACK_DEFINE(ChannelTag, Sequence, Mode)
|
||||
};
|
||||
} // ns
|
||||
|
||||
@@ -13,14 +13,24 @@
|
||||
|
||||
#include "msgpack.hpp"
|
||||
|
||||
//! DTO mode
|
||||
enum class CryptoDtoMode
|
||||
namespace BlackCore
|
||||
{
|
||||
Undefined = 0,
|
||||
None = 1,
|
||||
AEAD_ChaCha20Poly1305 = 2
|
||||
};
|
||||
namespace Afv
|
||||
{
|
||||
namespace Crypto
|
||||
{
|
||||
//! DTO mode
|
||||
enum class CryptoDtoMode
|
||||
{
|
||||
Undefined = 0, //!< undefined
|
||||
None = 1, //!< none
|
||||
AEAD_ChaCha20Poly1305 = 2 //!< AEAD
|
||||
};
|
||||
|
||||
MSGPACK_ADD_ENUM(CryptoDtoMode);
|
||||
} // ns
|
||||
} // ns
|
||||
} // ns
|
||||
|
||||
MSGPACK_ADD_ENUM(BlackCore::Afv::Crypto::CryptoDtoMode);
|
||||
|
||||
#endif // guard
|
||||
|
||||
Reference in New Issue
Block a user