AirMapManager.cc 9.27 KB
Newer Older
1 2
/****************************************************************************
 *
3
 *   (c) 2017 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
4 5 6 7 8 9
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

Gus Grubba's avatar
Gus Grubba committed
10
#include "AirMapAdvisoryManager.h"
Gus Grubba's avatar
Gus Grubba committed
11 12 13
#include "AirMapFlightPlanManager.h"
#include "AirMapManager.h"
#include "AirMapRestrictionManager.h"
14 15 16 17
#include "AirMapRulesetsManager.h"
#include "AirMapSettings.h"
#include "AirMapTelemetry.h"
#include "AirMapTrafficMonitor.h"
Gus Grubba's avatar
Gus Grubba committed
18
#include "AirMapVehicleManager.h"
Gus Grubba's avatar
Gus Grubba committed
19
#include "AirMapWeatherInfoManager.h"
20

21 22 23 24
#include "QmlObjectListModel.h"
#include "JsonHelper.h"
#include "SettingsManager.h"
#include "AppSettings.h"
25
#include "QGCQGeoCoordinate.h"
26
#include "QGCApplication.h"
27

28
#include <airmap/authenticator.h>
29

Gus Grubba's avatar
Gus Grubba committed
30 31 32 33 34
//-- Hardwired API key
#if defined(QGC_AIRMAP_KEY_AVAILABLE)
#include "Airmap_api_key.h"
#endif

35
using namespace airmap;
36

37
QGC_LOGGING_CATEGORY(AirMapManagerLog, "AirMapManagerLog")
38

39
//-----------------------------------------------------------------------------
40 41
AirMapManager::AirMapManager(QGCApplication* app, QGCToolbox* toolbox)
    : AirspaceManager(app, toolbox)
42
    , _authStatus(Unknown)
43
{
44
    _logger = std::make_shared<qt::Logger>();
45
    qt::register_types(); // TODO: still needed?
46 47 48
    _logger->logging_category().setEnabled(QtDebugMsg,   false);
    _logger->logging_category().setEnabled(QtInfoMsg,    false);
    _logger->logging_category().setEnabled(QtWarningMsg, false);
49 50
    _dispatchingLogger = std::make_shared<qt::DispatchingLogger>(_logger);
    connect(&_shared, &AirMapSharedState::error, this, &AirMapManager::_error);
51
    connect(&_shared, &AirMapSharedState::authStatus, this, &AirMapManager::_authStatusChanged);
52 53
}

54
//-----------------------------------------------------------------------------
55 56 57 58 59
AirMapManager::~AirMapManager()
{
    if (_shared.client()) {
        delete _shared.client();
    }
60 61
}

62
//-----------------------------------------------------------------------------
63 64
void
AirMapManager::setToolbox(QGCToolbox* toolbox)
65
{
66
    AirspaceManager::setToolbox(toolbox);
67
    AirMapSettings* ap = toolbox->settingsManager()->airMapSettings();
Gus Grubba's avatar
Gus Grubba committed
68
    connect(ap->enableAirMap(),     &Fact::rawValueChanged, this, &AirMapManager::_settingsChanged);
69 70 71 72 73
    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);
74 75 76
    _settingsChanged();
}

Gus Grubba's avatar
Gus Grubba committed
77 78 79 80
//-----------------------------------------------------------------------------
bool
AirMapManager::connected() const
{
81
    return _shared.client() != nullptr;
Gus Grubba's avatar
Gus Grubba committed
82 83
}

84
//-----------------------------------------------------------------------------
85 86
void
AirMapManager::_error(const QString& what, const QString& airmapdMessage, const QString& airmapdDetails)
87
{
88 89
    qCDebug(AirMapManagerLog) << "Error: "<<what<<", msg: "<<airmapdMessage<<", details: "<<airmapdDetails;
    qgcApp()->showMessage(QString("AirMap Error: %1. %2").arg(what).arg(airmapdMessage));
90 91
}

92 93 94 95 96 97 98 99
//-----------------------------------------------------------------------------
void
AirMapManager::_authStatusChanged(AirspaceManager::AuthStatus status)
{
    _authStatus = status;
    emit authStatusChanged();
}

100
//-----------------------------------------------------------------------------
101 102
void
AirMapManager::_settingsChanged()
103 104
{
    qCDebug(AirMapManagerLog) << "AirMap settings changed";
Gus Grubba's avatar
Gus Grubba committed
105 106
    _connectStatus.clear();
    emit connectStatusChanged();
107
    AirMapSettings* ap = _toolbox->settingsManager()->airMapSettings();
Gus Grubba's avatar
Gus Grubba committed
108 109
    //-- If we are disabled, there is nothing else to do.
    if (!ap->enableAirMap()->rawValue().toBool()) {
110
        _shared.logout();
Gus Grubba's avatar
Gus Grubba committed
111 112 113 114 115 116 117
        if(_shared.client()) {
            delete _shared.client();
            _shared.setClient(nullptr);
            emit connectedChanged();
        }
        return;
    }
118
    AirMapSharedState::Settings settings;
Gus Grubba's avatar
Gus Grubba committed
119 120 121 122 123
    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.
Gus Grubba's avatar
Gus Grubba committed
124
#if defined(QGC_AIRMAP_KEY_AVAILABLE)
Gus Grubba's avatar
Gus Grubba committed
125
    if(!ap->usePersonalApiKey()->rawValue().toBool()) {
Gus Grubba's avatar
Gus Grubba committed
126 127 128
        settings.apiKey     = kAirmapAPIKey;
        settings.clientID   = kAirmapClientID;
    }
129
    bool authChanged = settings.apiKey != _shared.settings().apiKey || settings.apiKey.isEmpty();
Gus Grubba's avatar
Gus Grubba committed
130
#else
131
    bool authChanged = settings.apiKey != _shared.settings().apiKey;
Gus Grubba's avatar
Gus Grubba committed
132
#endif
133 134 135 136 137
    settings.userName = ap->userName()->rawValueString();
    settings.password = ap->password()->rawValueString();
    if(settings.userName != _shared.settings().userName || settings.password != _shared.settings().password) {
        authChanged = true;
    }
138
    _shared.setSettings(settings);
139 140
    //-- Need to re-create the client if the API key or user name/password changed
    if ((_shared.client() && authChanged) || !ap->enableAirMap()->rawValue().toBool()) {
141 142
        delete _shared.client();
        _shared.setClient(nullptr);
Gus Grubba's avatar
Gus Grubba committed
143
        emit connectedChanged();
144
    }
145 146 147 148
    if (!_shared.client() && settings.apiKey != "") {
        qCDebug(AirMapManagerLog) << "Creating AirMap client";
        auto credentials    = Credentials{};
        credentials.api_key = _shared.settings().apiKey.toStdString();
149
        auto configuration  = Client::default_production_configuration(credentials);
150 151
        configuration.telemetry.host = "udp.telemetry.k8s.airmap.io";
        configuration.telemetry.port = 7070;
Gus Grubba's avatar
Gus Grubba committed
152
        qt::Client::create(configuration, _dispatchingLogger, this, [this](const qt::Client::CreateResult& result) {
153 154 155
            if (result) {
                qCDebug(AirMapManagerLog) << "Successfully created airmap::qt::Client instance";
                _shared.setClient(result.value());
Gus Grubba's avatar
Gus Grubba committed
156 157 158
                emit connectedChanged();
                _connectStatus = tr("AirMap Enabled");
                emit connectStatusChanged();
159 160
            } else {
                qWarning("Failed to create airmap::qt::Client instance");
161
                QString description = QString::fromStdString(result.error().description() ? result.error().description().get() : "");
Gus Grubba's avatar
Gus Grubba committed
162 163 164 165 166 167 168 169 170
                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();
171 172
            }
        });
173 174
    } else {
        if(settings.apiKey == "") {
Gus Grubba's avatar
Gus Grubba committed
175 176 177
            _connectStatus = tr("No API key for AirMap");
            emit connectStatusChanged();
            qCDebug(AirMapManagerLog) << _connectStatus;
178
        }
179 180 181
    }
}

182
//-----------------------------------------------------------------------------
183 184
AirspaceVehicleManager*
AirMapManager::instantiateVehicle(const Vehicle& vehicle)
185
{
186
    AirMapVehicleManager* manager = new AirMapVehicleManager(_shared, vehicle);
187
    connect(manager, &AirMapVehicleManager::error, this, &AirMapManager::_error);
188
    return manager;
189 190
}

191
//-----------------------------------------------------------------------------
192
AirspaceRulesetsProvider*
193
AirMapManager::_instantiateRulesetsProvider()
Gus Grubba's avatar
Gus Grubba committed
194 195 196 197 198 199
{
    AirMapRulesetsManager* rulesetsManager = new AirMapRulesetsManager(_shared);
    connect(rulesetsManager, &AirMapRulesetsManager::error, this, &AirMapManager::_error);
    return rulesetsManager;
}

200
//-----------------------------------------------------------------------------
201
AirspaceWeatherInfoProvider*
202
AirMapManager::_instatiateAirspaceWeatherInfoProvider()
Gus Grubba's avatar
Gus Grubba committed
203
{
Gus Grubba's avatar
Gus Grubba committed
204 205
    AirMapWeatherInfoManager* weatherInfo = new AirMapWeatherInfoManager(_shared);
    connect(weatherInfo, &AirMapWeatherInfoManager::error, this, &AirMapManager::_error);
206
    return weatherInfo;
Gus Grubba's avatar
Gus Grubba committed
207
}
Gus Grubba's avatar
Gus Grubba committed
208

209
//-----------------------------------------------------------------------------
Gus Grubba's avatar
Gus Grubba committed
210
AirspaceAdvisoryProvider*
211
AirMapManager::_instatiateAirspaceAdvisoryProvider()
Gus Grubba's avatar
Gus Grubba committed
212
{
Gus Grubba's avatar
Gus Grubba committed
213 214
    AirMapAdvisoryManager* advisories = new AirMapAdvisoryManager(_shared);
    connect(advisories, &AirMapAdvisoryManager::error, this, &AirMapManager::_error);
Gus Grubba's avatar
Gus Grubba committed
215 216
    return advisories;
}
217

218
//-----------------------------------------------------------------------------
219
AirspaceRestrictionProvider*
220
AirMapManager::_instantiateAirspaceRestrictionProvider()
221 222 223 224 225
{
    AirMapRestrictionManager* airspaces = new AirMapRestrictionManager(_shared);
    connect(airspaces, &AirMapRestrictionManager::error, this, &AirMapManager::_error);
    return airspaces;
}
226 227

//-----------------------------------------------------------------------------
Gus Grubba's avatar
Gus Grubba committed
228 229
AirspaceFlightPlanProvider*
AirMapManager::_instantiateAirspaceFlightPlanProvider()
230
{
Gus Grubba's avatar
Gus Grubba committed
231 232 233
    AirMapFlightPlanManager* flightPlan = new AirMapFlightPlanManager(_shared);
    connect(flightPlan, &AirMapFlightPlanManager::error, this, &AirMapManager::_error);
    return flightPlan;
234
}