Skip to content

Commit

Permalink
Convert AirLinkManager & UTMSPManager to Singletons
Browse files Browse the repository at this point in the history
  • Loading branch information
HTRamsey committed Oct 16, 2024
1 parent 13031c3 commit 3228bf9
Show file tree
Hide file tree
Showing 14 changed files with 210 additions and 247 deletions.
99 changes: 49 additions & 50 deletions src/AirLink/AirLinkManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,39 @@
****************************************************************************/

#include "AirLinkManager.h"
#include "QGCApplication.h"
#include "QGCToolbox.h"
#include "SettingsManager.h"
#include "QGCLoggingCategory.h"

#include <QtCore/qapplicationstatic.h>
#include <QtCore/QJsonArray>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkAccessManager>
#include <QtCore/QJsonObject>
#include <QtCore/QJsonArray>

QGC_LOGGING_CATEGORY(AirLinkManagerLog, "qgc.airlink.airlinkmanager");

const QString AirLinkManager::airlinkHost = "air-link.space";

AirLinkManager::AirLinkManager(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox)
{
}
Q_APPLICATION_STATIC(AirLinkManager, _airLinkManager);

AirLinkManager::~AirLinkManager()
AirLinkManager::AirLinkManager(QObject *parent)
: QObject(parent)
, _mngr(new QNetworkAccessManager(this))
{
// qCDebug(AirLinkManagerLog) << Q_FUNC_INFO << this;
}

void AirLinkManager::setToolbox(QGCToolbox* toolbox)
{
QGCTool::setToolbox(toolbox);
}

QStringList AirLinkManager::droneList() const
AirLinkManager::~AirLinkManager()
{
return _vehiclesFromServer.keys();
// qCDebug(AirLinkManagerLog) << Q_FUNC_INFO << this;
}

void AirLinkManager::updateDroneList(const QString &login, const QString &pass)
AirLinkManager *AirLinkManager::instance()
{
connectToAirLinkServer(login, pass);
return _airLinkManager();
}

bool AirLinkManager::isOnline(const QString &drone)
Expand All @@ -52,10 +52,14 @@ bool AirLinkManager::isOnline(const QString &drone)
}
}

void AirLinkManager::connectToAirLinkServer(const QString &login, const QString &pass)
void AirLinkManager::updateCredentials(const QString &login, const QString &pass)
{
QNetworkAccessManager *mngr = new QNetworkAccessManager(this);
qgcApp()->toolbox()->settingsManager()->appSettings()->loginAirLink()->setRawValue(login);
qgcApp()->toolbox()->settingsManager()->appSettings()->passAirLink()->setRawValue(pass);
}

void AirLinkManager::_connectToAirLinkServer(const QString &login, const QString &pass)
{
const QUrl url("https://air-link.space/api/gs/getModems");
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
Expand All @@ -64,48 +68,43 @@ void AirLinkManager::connectToAirLinkServer(const QString &login, const QString
obj["login"] = login;
obj["password"] = pass;
QJsonDocument doc(obj);
QByteArray data = doc.toJson();

_reply = mngr->post(request, data);

QObject::connect(_reply, &QNetworkReply::finished, [this](){
_processReplyAirlinkServer(*_reply);
_reply->deleteLater();
});
const QByteArray data = doc.toJson();

mngr = nullptr;
delete mngr;
QNetworkReply *const reply = _mngr->post(request, data);
(void) QObject::connect(reply, &QNetworkReply::finished, this, &AirLinkManager::_processReplyAirlinkServer);
}

void AirLinkManager::updateCredentials(const QString &login, const QString &pass)
void AirLinkManager::_processReplyAirlinkServer()
{
_toolbox->settingsManager()->appSettings()->loginAirLink()->setRawValue(login);
_toolbox->settingsManager()->appSettings()->passAirLink()->setRawValue(pass);
QNetworkReply* const reply = qobject_cast<QNetworkReply*>(sender());
if (!reply) {
return;
}
reply->deleteLater();

if (reply->error() != QNetworkReply::NoError) {
qCDebug(AirLinkManagerLog) << "Airlink auth - network error";
return;
}

const QByteArray ba = reply->readAll();

if (!QJsonDocument::fromJson(ba)["modems"].toArray().isEmpty()) {
_parseAnswer(ba);
} else {
qCDebug(AirLinkManagerLog) << "No airlink modems in answer";
}
}

void AirLinkManager::_parseAnswer(const QByteArray &ba)
{
_vehiclesFromServer.clear();

for (const auto &arr : QJsonDocument::fromJson(ba)["modems"].toArray()) {
QString droneModem = arr.toObject()["name"].toString();
bool isOnline = arr.toObject()["isOnline"].toBool();
const QString droneModem = arr.toObject()["name"].toString();
const bool isOnline = arr.toObject()["isOnline"].toBool();
_vehiclesFromServer[droneModem] = isOnline;
}
emit droneListChanged();
}

void AirLinkManager::_processReplyAirlinkServer(QNetworkReply &reply)
{
QByteArray ba = reply.readAll();

if (reply.error() == QNetworkReply::NoError) {
if (!QJsonDocument::fromJson(ba)["modems"].toArray().isEmpty()) {
_parseAnswer(ba);
} else {
qDebug() << "No airlink modems in answer";
}
} else {
qDebug() << "Airlink auth - network error";
}
emit droneListChanged();
}

45 changes: 24 additions & 21 deletions src/AirLink/AirLinkManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,44 +9,47 @@

#pragma once

#include "QGCToolbox.h"

#include <QtCore/QLoggingCategory>
#include <QtCore/QMap>
#include <QtCore/QObject>

class QNetworkAccessManager;

class AppSettings;
class QGCApplication;
class LinkInterface;
class QNetworkReply;
Q_DECLARE_LOGGING_CATEGORY(AirLinkManagerLog)

//-----------------------------------------------------------------------------
class AirLinkManager : public QGCTool
class AirLinkManager : public QObject
{
Q_OBJECT

public:
Q_PROPERTY(QStringList droneList READ droneList NOTIFY droneListChanged)
Q_INVOKABLE void updateDroneList(const QString &login, const QString &pass);

public:
explicit AirLinkManager(QObject *parent = nullptr);
~AirLinkManager();

/// Gets the singleton instance of AirLinkManager.
/// @return The singleton instance.
static AirLinkManager *instance();

Q_INVOKABLE void updateDroneList(const QString &login, const QString &pass) { _connectToAirLinkServer(login, pass); }
Q_INVOKABLE bool isOnline(const QString &drone);
Q_INVOKABLE void connectToAirLinkServer(const QString &login, const QString &pass);
Q_INVOKABLE void updateCredentials(const QString &login, const QString &pass);

explicit AirLinkManager(QGCApplication* app, QGCToolbox* toolbox);
~AirLinkManager() override;

void setToolbox (QGCToolbox* toolbox) override;
QStringList droneList() const;
QStringList droneList() const { return _vehiclesFromServer.keys(); }

static const QString airlinkHost;
static constexpr int airlinkPort = 10000;

signals:
void droneListChanged();
void droneListChanged();

private:
void _parseAnswer (const QByteArray &ba);
void _processReplyAirlinkServer (QNetworkReply &reply);
private slots:
void _processReplyAirlinkServer();

private:
void _connectToAirLinkServer(const QString &login, const QString &pass);
void _parseAnswer(const QByteArray &ba);

QNetworkAccessManager *_mngr = nullptr;
QMap<QString, bool> _vehiclesFromServer;
QNetworkReply* _reply;
};
153 changes: 76 additions & 77 deletions src/AirLink/AirlinkLink.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,79 +18,9 @@
#include <QtCore/QSettings>
#include <QtCore/QTimer>


AirlinkConfiguration::AirlinkConfiguration(const QString &name) : UDPConfiguration(name)
{

}

AirlinkConfiguration::AirlinkConfiguration(AirlinkConfiguration *source) : UDPConfiguration(source)
{
_copyFrom(source);
}

AirlinkConfiguration::~AirlinkConfiguration()
{
}

void AirlinkConfiguration::setUsername(QString username)
{
_username = username;
}

void AirlinkConfiguration::setPassword(QString password)
{
_password = password;
}

void AirlinkConfiguration::setModemName(QString modemName)
{
_modemName = modemName;
}

void AirlinkConfiguration::loadSettings(QSettings &settings, const QString &root)
{
AppSettings *appSettings = qgcApp()->toolbox()->settingsManager()->appSettings();
settings.beginGroup(root);
_username = settings.value(_usernameSettingsKey, appSettings->loginAirLink()->rawValueString()).toString();
_password = settings.value(_passwordSettingsKey, appSettings->passAirLink()->rawValueString()).toString();
_modemName = settings.value(_modemNameSettingsKey).toString();
settings.endGroup();
}

void AirlinkConfiguration::saveSettings(QSettings &settings, const QString &root)
{
settings.beginGroup(root);
settings.setValue(_usernameSettingsKey, _username);
settings.setValue(_passwordSettingsKey, _password);
settings.setValue(_modemNameSettingsKey, _modemName);
settings.endGroup();
}

void AirlinkConfiguration::copyFrom(LinkConfiguration *source)
{
LinkConfiguration::copyFrom(source);
auto* udpSource = qobject_cast<UDPConfiguration*>(source);
if (udpSource) {
UDPConfiguration::copyFrom(source);
}
_copyFrom(source);
}

void AirlinkConfiguration::_copyFrom(LinkConfiguration *source)
{
auto* airlinkSource = qobject_cast<AirlinkConfiguration*>(source);
if (airlinkSource) {
_username = airlinkSource->username();
_password = airlinkSource->password();
_modemName = airlinkSource->modemName();
} else {
qWarning() << "Internal error: cannot read AirlinkConfiguration from given source";
}
}


AirlinkLink::AirlinkLink(SharedLinkConfigurationPtr &config) : UDPLink(config)
AirlinkLink::AirlinkLink(SharedLinkConfigurationPtr &config)
: UDPLink(config)
, _airlinkConfig(qobject_cast<const AirlinkConfiguration*>(config.get()))
{
_configureUdpSettings();
}
Expand Down Expand Up @@ -158,7 +88,7 @@ void AirlinkLink::_configureUdpSettings()
QUdpSocket udpSocket;
while (!udpSocket.bind(QHostAddress::LocalHost, availablePort))
availablePort++;
UDPConfiguration* udpConfig = dynamic_cast<UDPConfiguration*>(UDPLink::m_config.get());
UDPConfiguration* udpConfig = dynamic_cast<UDPConfiguration*>(UDPLink::_config.get());
udpConfig->addHost(AirLinkManager::airlinkHost, AirLinkManager::airlinkPort);
udpConfig->setLocalPort(availablePort);
udpConfig->setDynamic(false);
Expand All @@ -169,9 +99,8 @@ void AirlinkLink::_sendLoginMsgToAirLink()
__mavlink_airlink_auth_t auth;
uint8_t buffer[MAVLINK_MAX_PACKET_LEN];
mavlink_message_t mavmsg;
AirlinkConfiguration* config = dynamic_cast<AirlinkConfiguration*>(m_config.get());
QString login = config->modemName(); ///< Connect not to account but to specific modem
QString pass = config->password();
QString login = _airlinkConfig->modemName(); ///< Connect not to account but to specific modem
QString pass = _airlinkConfig->password();

memset(&auth.login, 0, sizeof(auth.login));
memset(&auth.password, 0, sizeof(auth.password));
Expand All @@ -198,3 +127,73 @@ void AirlinkLink::_setConnectFlag(bool connect)
QMutexLocker locker(&_mutex);
_needToConnect = connect;
}

AirlinkConfiguration::AirlinkConfiguration(const QString &name) : UDPConfiguration(name)
{

}

AirlinkConfiguration::AirlinkConfiguration(const AirlinkConfiguration *source) : UDPConfiguration(source)
{
_copyFrom(source);
}

AirlinkConfiguration::~AirlinkConfiguration()
{
}

void AirlinkConfiguration::setUsername(const QString &username)
{
_username = username;
}

void AirlinkConfiguration::setPassword(const QString &password)
{
_password = password;
}

void AirlinkConfiguration::setModemName(const QString &modemName)
{
_modemName = modemName;
}

void AirlinkConfiguration::loadSettings(QSettings &settings, const QString &root)
{
AppSettings *const appSettings = qgcApp()->toolbox()->settingsManager()->appSettings();
settings.beginGroup(root);
_username = settings.value(_usernameSettingsKey, appSettings->loginAirLink()->rawValueString()).toString();
_password = settings.value(_passwordSettingsKey, appSettings->passAirLink()->rawValueString()).toString();
_modemName = settings.value(_modemNameSettingsKey).toString();
settings.endGroup();
}

void AirlinkConfiguration::saveSettings(QSettings &settings, const QString &root)
{
settings.beginGroup(root);
settings.setValue(_usernameSettingsKey, _username);
settings.setValue(_passwordSettingsKey, _password);
settings.setValue(_modemNameSettingsKey, _modemName);
settings.endGroup();
}

void AirlinkConfiguration::copyFrom(const LinkConfiguration *source)
{
LinkConfiguration::copyFrom(source);
const auto* udpSource = qobject_cast<const UDPConfiguration*>(source);
if (udpSource) {
UDPConfiguration::copyFrom(source);
}
_copyFrom(source);
}

void AirlinkConfiguration::_copyFrom(const LinkConfiguration *source)
{
const auto* airlinkSource = qobject_cast<const AirlinkConfiguration*>(source);
if (airlinkSource) {
_username = airlinkSource->username();
_password = airlinkSource->password();
_modemName = airlinkSource->modemName();
} else {
qWarning() << "Internal error: cannot read AirlinkConfiguration from given source";
}
}
Loading

0 comments on commit 3228bf9

Please sign in to comment.