Newer
Older
/****************************************************************************
*
* (c) 2017 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#include "AirMapFlightPlanManager.h"
#include "AirMapManager.h"
#include "AirMapRestrictionManager.h"
#include "AirMapRulesetsManager.h"
#include "AirMapSettings.h"
#include "AirMapTelemetry.h"
#include "AirMapTrafficMonitor.h"
#include "QmlObjectListModel.h"
#include "JsonHelper.h"
#include "SettingsManager.h"
#include "AppSettings.h"
#include "QGCQGeoCoordinate.h"
#include "QGCApplication.h"
#include <airmap/authenticator.h>
//-- Hardwired API key
#if defined(QGC_AIRMAP_KEY_AVAILABLE)
#include "Airmap_api_key.h"
#endif
QGC_LOGGING_CATEGORY(AirMapManagerLog, "AirMapManagerLog")
//-----------------------------------------------------------------------------
AirMapManager::AirMapManager(QGCApplication* app, QGCToolbox* toolbox)
: AirspaceManager(app, toolbox)
, _authStatus(Unknown)
_logger = std::make_shared<qt::Logger>();
qt::register_types(); // TODO: still needed?
_logger->logging_category().setEnabled(QtDebugMsg, false);
_logger->logging_category().setEnabled(QtInfoMsg, false);
_logger->logging_category().setEnabled(QtWarningMsg, false);
_dispatchingLogger = std::make_shared<qt::DispatchingLogger>(_logger);
connect(&_shared, &AirMapSharedState::error, this, &AirMapManager::_error);
connect(&_shared, &AirMapSharedState::authStatus, this, &AirMapManager::_authStatusChanged);
//-----------------------------------------------------------------------------
AirMapManager::~AirMapManager()
{
if (_shared.client()) {
delete _shared.client();
}
//-----------------------------------------------------------------------------
void
AirMapManager::setToolbox(QGCToolbox* toolbox)
Gus Grubba
committed
_settingsTimer.setSingleShot(true);
AirspaceManager::setToolbox(toolbox);
Gus Grubba
committed
AirMapSettings* ap = toolbox->settingsManager()->airMapSettings();
connect(ap->enableAirMap(), &Fact::rawValueChanged, this, &AirMapManager::_settingsChanged);
Gus Grubba
committed
connect(ap->usePersonalApiKey(),&Fact::rawValueChanged, this, &AirMapManager::_settingsChanged);
connect(ap->apiKey(), &Fact::rawValueChanged, this, &AirMapManager::_settingsChanged);
connect(ap->clientID(), &Fact::rawValueChanged, this, &AirMapManager::_settingsChanged);
connect(ap->userName(), &Fact::rawValueChanged, this, &AirMapManager::_settingsChanged);
connect(ap->password(), &Fact::rawValueChanged, this, &AirMapManager::_settingsChanged);
connect(ap->enableAirspace(), &Fact::rawValueChanged, this, &AirMapManager::_airspaceEnabled);
Gus Grubba
committed
connect(&_settingsTimer, &QTimer::timeout, this, &AirMapManager::_settingsTimeout);
_settingsTimeout();
//-----------------------------------------------------------------------------
bool
AirMapManager::connected() const
{
Gus Grubba
committed
return _shared.client() != nullptr;
//-----------------------------------------------------------------------------
void
AirMapManager::_error(const QString& what, const QString& airmapdMessage, const QString& airmapdDetails)
qCDebug(AirMapManagerLog) << "Error: "<<what<<", msg: "<<airmapdMessage<<", details: "<<airmapdDetails;
qgcApp()->showMessage(QString("Error: %1. %2").arg(what).arg(airmapdMessage));
//-----------------------------------------------------------------------------
void
AirMapManager::_authStatusChanged(AirspaceManager::AuthStatus status)
{
_authStatus = status;
emit authStatusChanged();
}
//-----------------------------------------------------------------------------
Gus Grubba
committed
{
_settingsTimer.start(1000);
}
//-----------------------------------------------------------------------------
void
AirMapManager::_airspaceEnabled()
{
if(qgcApp()->toolbox()->settingsManager()->airMapSettings()->enableAirspace()->rawValue().toBool()) {
if(_airspaces) {
_airspaces->setROI(_roi, true);
}
}
}
Gus Grubba
committed
//-----------------------------------------------------------------------------
void
AirMapManager::_settingsTimeout()
{
qCDebug(AirMapManagerLog) << "AirMap settings changed";
_connectStatus.clear();
emit connectStatusChanged();
AirMapSettings* ap = _toolbox->settingsManager()->airMapSettings();
//-- If we are disabled, there is nothing else to do.
if (!ap->enableAirMap()->rawValue().toBool()) {
if(_shared.client()) {
delete _shared.client();
_shared.setClient(nullptr);
emit connectedChanged();
}
return;
}
AirMapSharedState::Settings settings;
if(ap->usePersonalApiKey()->rawValue().toBool()) {
settings.apiKey = ap->apiKey()->rawValueString();
settings.clientID = ap->clientID()->rawValueString();
}
//-- If we have a hardwired key (and no custom key is present), set it.
settings.apiKey = AirmapAPIKey();
settings.clientID = AirmapClientID();
bool authChanged = settings.apiKey != _shared.settings().apiKey || settings.apiKey.isEmpty();
bool authChanged = settings.apiKey != _shared.settings().apiKey;
settings.userName = ap->userName()->rawValueString();
settings.password = ap->password()->rawValueString();
if(settings.userName != _shared.settings().userName || settings.password != _shared.settings().password) {
authChanged = true;
}
//-- Need to re-create the client if the API key or user name/password changed
if ((_shared.client() && authChanged) || !ap->enableAirMap()->rawValue().toBool()) {
delete _shared.client();
_shared.setClient(nullptr);
if (!_shared.client() && settings.apiKey != "") {
qCDebug(AirMapManagerLog) << "Creating AirMap client";
auto credentials = Credentials{};
credentials.api_key = _shared.settings().apiKey.toStdString();
auto configuration = Client::default_production_configuration(credentials);
configuration.telemetry.host = "udp.telemetry.k8s.airmap.io";
configuration.telemetry.port = 7070;
qt::Client::create(configuration, _dispatchingLogger, this, [this](const qt::Client::CreateResult& result) {
if (result) {
qCDebug(AirMapManagerLog) << "Successfully created airmap::qt::Client instance";
_shared.setClient(result.value());
emit connectedChanged();
_connectStatus = tr("AirMap Enabled");
emit connectStatusChanged();
Gus Grubba
committed
//-- Now test authentication
_shared.login();
} else {
qWarning("Failed to create airmap::qt::Client instance");
QString description = QString::fromStdString(result.error().description() ? result.error().description().get() : "");
QString error = QString::fromStdString(result.error().message());
_error(tr("Failed to create airmap::qt::Client instance"),
error, description);
_connectStatus = error;
if(!description.isEmpty()) {
_connectStatus += "\n";
_connectStatus += description;
}
emit connectStatusChanged();
Gus Grubba
committed
} else {
if(settings.apiKey == "") {
_connectStatus = tr("No API key for AirMap");
emit connectStatusChanged();
qCDebug(AirMapManagerLog) << _connectStatus;
Gus Grubba
committed
}
//-----------------------------------------------------------------------------
AirspaceVehicleManager*
AirMapManager::instantiateVehicle(const Vehicle& vehicle)
AirMapVehicleManager* manager = new AirMapVehicleManager(_shared, vehicle);
connect(manager, &AirMapVehicleManager::error, this, &AirMapManager::_error);
//-----------------------------------------------------------------------------
AirMapManager::_instantiateRulesetsProvider()
{
AirMapRulesetsManager* rulesetsManager = new AirMapRulesetsManager(_shared);
connect(rulesetsManager, &AirMapRulesetsManager::error, this, &AirMapManager::_error);
return rulesetsManager;
}
//-----------------------------------------------------------------------------
AirMapManager::_instatiateAirspaceWeatherInfoProvider()
AirMapWeatherInfoManager* weatherInfo = new AirMapWeatherInfoManager(_shared);
connect(weatherInfo, &AirMapWeatherInfoManager::error, this, &AirMapManager::_error);
//-----------------------------------------------------------------------------
AirMapManager::_instatiateAirspaceAdvisoryProvider()
AirMapAdvisoryManager* advisories = new AirMapAdvisoryManager(_shared);
connect(advisories, &AirMapAdvisoryManager::error, this, &AirMapManager::_error);
Gus Grubba
committed
//-----------------------------------------------------------------------------
Gus Grubba
committed
AirspaceRestrictionProvider*
AirMapManager::_instantiateAirspaceRestrictionProvider()
Gus Grubba
committed
{
AirMapRestrictionManager* airspaces = new AirMapRestrictionManager(_shared);
connect(airspaces, &AirMapRestrictionManager::error, this, &AirMapManager::_error);
return airspaces;
}
//-----------------------------------------------------------------------------
AirspaceFlightPlanProvider*
AirMapManager::_instantiateAirspaceFlightPlanProvider()
AirMapFlightPlanManager* flightPlan = new AirMapFlightPlanManager(_shared);
connect(flightPlan, &AirMapFlightPlanManager::error, this, &AirMapManager::_error);
return flightPlan;