Ref T730, style and log messages

This commit is contained in:
Klaus Basan
2019-10-06 00:07:23 +02:00
committed by Mat Sutcliffe
parent e30b690191
commit 401c89aa63
10 changed files with 161 additions and 87 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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