Commit 4abb2f6e authored by Gus Grubba's avatar Gus Grubba

Merge commit 'ebb5b8ce' into Airmap

* commit 'ebb5b8ce': (40 commits)
  Including airmapd into the repo (macOS only)
  Restore expanded state when enabling AirMap
  AirMap Settings
  Control on Fly View Eliminated flight widget "states" Define flight widget top margin (plugin options)
  Add expand icon
  Expand/Colapse Controllers Adjust colors Remove unused image
  Initial Mockup
  qgroundcontrol.pro: update build to latest airmapd master
  AirMapManager: update authorizations to changed airmapd interface
  rebase fixup: remove AirMapController.{cc,h}
  remove submodule commits qmqtt and tiny-AES128-C
  AirMapManager: error handling, change to updated API of airmapd
  AirMapManager: update polygons to changed airmapd interface
  AirMapManager: update flight search according to updated airmapd
  AirMap: remove SITA registration numbers
  AirspaceManagement & AirMapManager: add weather request API
  AirMapManager: add LifetimeChecker class to prevent callbacks from accessing invalid memory
  AirMapManager: handle multi_polygon
  AirMapManager: change backend to use airmapd
  AirMap: refactor for multi-vehicle support & base class API
  ...
parents 55fafa52 ebb5b8ce
......@@ -124,3 +124,24 @@ contains (DEFINES, DISABLE_ZEROCONF) {
message("Skipping support for Zeroconf (unsupported platform)")
}
#
# [OPTIONAL] AirMap Support
#
contains (DEFINES, DISABLE_AIRMAP) {
message("Skipping support for AirMap (manual override from command line)")
# Otherwise the user can still disable this feature in the user_config.pri file.
} else:exists(user_config.pri):infile(user_config.pri, DEFINES, DISABLE_AIRMAP) {
message("Skipping support for AirMap (manual override from user_config.pri)")
} else {
AIRMAPD_PATH = $$PWD/libs/airmapd
INCLUDEPATH += \
$${AIRMAPD_PATH}/include
MacBuild|iOSBuild {
message("Including support for AirMap")
LIBS += -L$${AIRMAPD_PATH}/macOS/Qt.5.9 -lairmap-qt
DEFINES += QGC_AIRMAP_ENABLED
} else {
message("Skipping support for Airmap (unsupported platform)")
}
}
#ifndef AIRMAP_AIRCRAFT_H_
#define AIRMAP_AIRCRAFT_H_
#include <string>
namespace airmap {
/// Aircraft describes an aircraft in terms of its model and its manufacturer.
struct Aircraft {
/// Model bundles up a model id and a product name.
struct Model {
std::string id; ///< The unique id of the model in the context of AirMap.
std::string name; ///< The human-readable name of the model.
};
/// Manufacturer bundles up an id and a human-readable name.
/// Please note that the id is only unique/relevant in the context of the
/// AirMap services.
struct Manufacturer {
std::string id; ///< The unique id of the manufacturer in the context of AirMap.
std::string name; ///< The human-readable name of the manufacturer.
};
Model model; ///< Details describing the model of an aircraft.
Manufacturer manufacturer; ///< Details about the manufacturer of an aircraft.
};
} // namespace airmap
#endif // AIRMAP_AIRCRAFT_H_
#ifndef AIRMAP_AIRCRAFTS_H_
#define AIRMAP_AIRCRAFTS_H_
#include <airmap/aircraft.h>
#include <airmap/do_not_copy_or_move.h>
#include <airmap/error.h>
#include <airmap/optional.h>
#include <airmap/outcome.h>
#include <functional>
#include <string>
#include <vector>
namespace airmap {
/// Aircrafts models access to a database of aircraft models (specifically drones)
/// and manufacturers.
class Aircrafts : DoNotCopyOrMove {
public:
/// Manufacturers groups together types to ease interaction with
/// Aircrafts::manufacturers.
struct Manufacturers {
/// Parameters bundles up input parameters.
struct Parameters {
Optional<std::string> manufacturer_name; ///< Search for the specific manufacturer with this name.
};
/// Result models the outcome of calling Flights::manufacturers.
using Result = Outcome<std::vector<Aircraft::Manufacturer>, Error>;
/// Callback describes the function signature of the callback that is
/// invoked when a call to Flights::manufacturers finishes.
using Callback = std::function<void(const Result&)>;
};
/// Models groups together types to ease interaction with
/// Aircrafts::models.
struct Models {
/// Parameters bundles up input parameters.
struct Parameters {
Optional<Aircraft::Manufacturer> manufacturer; ///< Only list models by this manufacturer.
Optional<std::string> model_name; ///< Search for the specific model with this name.
};
/// Result models the outcome of calling Flights::models.
using Result = Outcome<std::vector<Aircraft>, Error>;
/// Callback describes the function signature of the callback that is
/// invoked when a call to Flights::models finishes.
using Callback = std::function<void(const Result&)>;
};
/// ModelForId groups together types to ease interaction with
/// Aircrafts::model_for_id.
struct ModelForId {
/// Parameters bundles up input parameters.
struct Parameters {
std::string id; ///< Search for the model with this id.
};
/// Result models the outcome of calling Flights::model_for_id.
using Result = Outcome<Aircraft, Error>;
/// Callback describes the function signature of the callback that is
/// invoked when a call to Flights::model_for_id finishes.
using Callback = std::function<void(const Result&)>;
};
/// manufacturers queries the AirMap services for known aircraft
/// manufacturers, reporting results to 'cb'.
virtual void manufacturers(const Manufacturers::Parameters& parameters, const Manufacturers::Callback& cb) = 0;
/// models queries the AirMap services for detailed information about
/// known Aircraft models and reports back results to 'cb'.
virtual void models(const Models::Parameters& parameters, const Models::Callback& cb) = 0;
/// models queries the AirMap services for detailed information about
/// an Aircraft model identified by 'ModelForId::Parameters::id' and reports back results to 'cb'.
virtual void model_for_id(const ModelForId::Parameters& parameters, const ModelForId::Callback& cb) = 0;
protected:
/// @cond
Aircrafts() = default;
/// @endcond
};
} // namespace airmap
#endif // AIRMAP_AIRCRAFTS_H_
This diff is collapsed.
#ifndef AIRMAP_AIRSPACES_H_
#define AIRMAP_AIRSPACES_H_
#include <airmap/airspace.h>
#include <airmap/date_time.h>
#include <airmap/do_not_copy_or_move.h>
#include <airmap/error.h>
#include <airmap/outcome.h>
#include <functional>
#include <vector>
namespace airmap {
/// Airspaces provides functionality to query the airspace database.
class Airspaces : DoNotCopyOrMove {
public:
/// ForIds groups together types to ease interaction with
/// Airspaces::ForIds.
struct ForIds {
/// Parameters bundles up input parameters.
struct Parameters {
Airspace::Id id; ///< Search for the airspace with this id.
};
/// Result models the outcome of calling Airspaces::for_id.
using Result = Outcome<std::vector<Airspace>, Error>;
/// Callback describes the function signature of the callback that is
/// invoked when a call to Airspaces::for_id finishes.
using Callback = std::function<void(const Result&)>;
};
/// Search groups together types to ease interaction with
/// Airspaces::Search.
struct Search {
/// Parameters bundles up input parameters.
struct Parameters {
Optional<Airspace::Type> types; ///< Search for airspaces with either one of these types.
Optional<Airspace::Type> ignored_types; ///< Ignore airspaces with either one of these types.
Optional<bool> full; ///< If true, the complete description of airspaces in the result set is requested.
Geometry geometry; ///< Search airspaces intersection this geometry.
Optional<std::uint32_t> buffer; ///< Buffer around the geometry in [m].
Optional<std::uint32_t> limit; ///< Limit the number of results to 'limit'.
Optional<std::uint32_t> offset;
Optional<DateTime> date_time;
};
/// Result models the outcome of calling Airspaces::search.
using Result = Outcome<std::vector<Airspace>, Error>;
/// Callback describes the function signature of the callback that is
/// invoked when a call to Airspaces::search finishes.
using Callback = std::function<void(const Result&)>;
};
/// search queries the AirMap services for surrounding airspaces and
/// reports back the results to 'cb'.
virtual void search(const Search::Parameters& parameters, const Search::Callback& cb) = 0;
/// for_ids queries the AirMap services for detailed information about
/// airspaces identified by UUIDs and reports back results to 'cb'.
virtual void for_ids(const ForIds::Parameters& parameters, const ForIds::Callback& cb) = 0;
protected:
/// cond
Airspaces() = default;
/// @endcond
};
} // namespace airmap
#endif // AIRMAP_AIRSPACES_H_
#ifndef AIRMAP_AUTHENTICATOR_H_
#define AIRMAP_AUTHENTICATOR_H_
#include <airmap/credentials.h>
#include <airmap/do_not_copy_or_move.h>
#include <airmap/error.h>
#include <airmap/outcome.h>
#include <airmap/token.h>
#include <chrono>
#include <functional>
#include <stdexcept>
#include <string>
namespace airmap {
/// Authenticator provides functionality to authenticate with the AirMap services.
class Authenticator : DoNotCopyOrMove {
public:
/// Scope enumerates all known authentication scopes.
enum class Scope { access_token = 0, open_id = 1, open_id_offline_access = 2 };
/// GrantType enumerates all known grant types.
enum class GrantType {
password = 0, ///< The grant is constituted by a password
bearer = 1 ///< The grant is constituted by a bearer
};
/// Connection enumerates all known types of connection to users.
enum class Connection {
username_password_authentication = 0 ///< authentication requires username/password
};
/// AuthenticateWithPassword groups together types to ease interaction with
/// Authenticator::authenticate_with_password.
struct AuthenticateWithPassword {
/// Parameters bundles up input parameters.
struct Params {
Credentials::OAuth oauth; ///< OAuth-specific credentials for this authentication request.
GrantType grant_type{GrantType::password}; ///< The grant type of this authentication request.
Scope scope{Scope::open_id_offline_access}; ///< The scope of this authentication request.
Connection connection{
Connection::username_password_authentication}; ///< The connection type of the authentication request.
};
/// Result models the outcome of calling Authenticator::authenticate_with_password.
using Result = Outcome<Token::OAuth, Error>;
/// Callback describes the function signature of the callback that is
/// invoked when a call to Authenticator::authenticate_with_password finishes.
using Callback = std::function<void(const Result&)>;
};
/// AuthenticateAnonymously groups together types to ease interaction with
/// Authenticator::authenticate_anonymously.
struct AuthenticateAnonymously {
/// The input parameters.
using Params = Credentials::Anonymous;
/// Result models the outcome of calling Authenticator::authenticate_anonymously.
using Result = Outcome<Token::Anonymous, Error>;
/// Callback describes the function signature of the callback that is
/// invoked when a call to Authenticator::authenticate_anonymously finishes.
using Callback = std::function<void(const Result&)>;
};
/// RenewAuthentication groups together types to ease interaction with
/// Authenticator::renew_authentication.
struct RenewAuthentication {
/// The input parameters.
struct Params {
std::string client_id; ///< The app id for which authentication renewal is requested.
std::string refresh_token; ///< The refresh token for the authentication renewal request.
GrantType grant_type{GrantType::bearer}; ///< The grant type of the authentication renewal request.
Scope scope{Scope::open_id}; ///< The scope of the authentication renewal request.
};
/// Result models the outcome of calling Authenticator::renew_authentication.
using Result = Outcome<Token::Refreshed, Error>;
/// Callback describes the function signature of the callback that is
/// invoked when a call to Authenticator::renew_authentication finishes.
using Callback = std::function<void(const Result&)>;
};
/// authenticate_with_password authenticates the user described in 'params' with
/// the AirMap services and reports the result to 'cb'.
virtual void authenticate_with_password(const AuthenticateWithPassword::Params& params,
const AuthenticateWithPassword::Callback& cb) = 0;
/// authenticate_anonymously authenticates an anonymous user described by Params::user_id
/// with the AirMap services and reports the result to 'cb'.
virtual void authenticate_anonymously(const AuthenticateAnonymously::Params&,
const AuthenticateAnonymously::Callback&) = 0;
/// renew_authentication renews a pre-authenticated JWT as given in Params::user_id with
/// the AirMap services and reports the result to 'cb'.
virtual void renew_authentication(const RenewAuthentication::Params& params,
const RenewAuthentication::Callback& cb) = 0;
protected:
/// @cond
Authenticator() = default;
/// @endcond
};
} // namespace airmap
#endif // AIRMAP_AUTHENTICATOR_H_
#ifndef AIRMAP_CLIENT_H_
#define AIRMAP_CLIENT_H_
#include <airmap/credentials.h>
#include <airmap/do_not_copy_or_move.h>
#include <airmap/optional.h>
#include <airmap/outcome.h>
#include <cstdint>
#include <functional>
#include <iosfwd>
#include <memory>
#include <string>
namespace airmap {
class Aircrafts;
class Airspaces;
class Authenticator;
class FlightPlans;
class Flights;
class Pilots;
class RuleSets;
class Status;
class Telemetry;
class Traffic;
/// Client enables applications to use the AirMap services and APIs.
class Client : DoNotCopyOrMove {
public:
/// Version enumerates all known versions available to clients.
enum class Version { production, staging };
/// Configuration bundles up parameters enabling
/// customization of a Client implementation behavior.
struct Configuration {
std::string host; ///< Address of the host exposing the AirMap services.
Version version; ///< The version of the AirMap services that should be used.
struct {
std::string host; ///< Address of the host exposing the sso service.
std::uint16_t port; ///< Port on the host exposing the sso service.
} sso; ///< The SSO endpoint used for the authenticating with the AirMap services.
struct {
std::string host; ///< Address of the host exposing the AirMap telemetry endpoints.
std::uint16_t port; ///< Port of the host exposing the AirMap telemetry endpoints.
} telemetry; ///< The telemetry submission endpoint.
struct {
std::string host; ///< Address of the mqtt broker serving air traffic information.
std::uint16_t port; ///< Port of the mqtt broker serving air traffic information.
} traffic; ///< The traffic endpoint.
Credentials credentials; ///< Credentials that are required to authorize access to the AirMap services.
};
/// default_production_configuration returns a Configuration instance that works
/// against the AirMap production API and telemetry endpoints.
static Configuration default_production_configuration(const Credentials& credentials);
/// default_staging_configuration returns a Configuration instance that works
/// against the AirMap staging API and telemetry endpoints.
static Configuration default_staging_configuration(const Credentials& credentials);
/// default_configuration returns a Configuration instance that works against
/// the AirMap API and telemetry endpoints indicated by 'version'.
static Configuration default_configuration(Version version, const Credentials& credentials);
/// load_configuration_from_json loads a configuration from 'in', assuming the following
/// JSON format:
///
/// @code{.json}
/// {
/// "host": "api.airmap.com",
/// "version": "production",
/// "sso": {
/// "host": "sso.airmap.io",
/// "port": 443
/// },
/// "telemetry": {
/// "host": "api-udp-telemetry.airmap.com",
/// "port": 16060
/// },
/// "traffic": {
/// "host": "mqtt-prod.airmap.io",
/// "port": 8883
/// },
/// "credentials": {
/// "api-key": "your api key should go here",
/// "oauth": {
/// "client-id": "your client id should go here",
/// "device-id": "your device id should go here, or generate one with uuid-gen",
/// "username": "your AirMap username should go here",
/// "password": "your AirMap password should go here"
/// },
/// "anonymous": {
/// "id": "some id"
/// }
/// }
/// }
/// @endcode
static Configuration load_configuration_from_json(std::istream& in);
/// authenticator returns the Authenticator implementation provided by the client.
virtual Authenticator& authenticator() = 0;
/// aircrafts returns the Aircrafts implementation provided by the client.
virtual Aircrafts& aircrafts() = 0;
/// airspaces returns the Airspaces implementation provided by the client.
virtual Airspaces& airspaces() = 0;
/// flight_plans returns the FlightPlans implementation provided by the client.
virtual FlightPlans& flight_plans() = 0;
/// flights returns the Flights implementation provided by the client.
virtual Flights& flights() = 0;
/// pilots returns the Pilots implementation provided by the client.
virtual Pilots& pilots() = 0;
/// rulesets returns the RuleSets implementation provided by the client.
virtual RuleSets& rulesets() = 0;
/// status returns the Status implementation provided by the client.
virtual Status& status() = 0;
/// telemetry returns the Telemetry implementation provided by the client.
virtual Telemetry& telemetry() = 0;
/// traffic returns the Traffic implementation provided by the client.
virtual Traffic& traffic() = 0;
protected:
/// @cond
Client() = default;
/// @endcond
};
/// @cond
std::istream& operator>>(std::istream& in, Client::Version& version);
std::ostream& operator<<(std::ostream& out, Client::Version version);
/// @endcond
} // namespace airmap
#endif // AIRMAP_CLIENT_H_
#ifndef AIRMAP_CONTEXT_H_
#define AIRMAP_CONTEXT_H_
#include <airmap/client.h>
#include <airmap/date_time.h>
#include <airmap/do_not_copy_or_move.h>
#include <airmap/error.h>
#include <airmap/logger.h>
#include <airmap/monitor/client.h>
#include <airmap/outcome.h>
#include <functional>
#include <unordered_set>
namespace airmap {
/// Context consitutes the point-of-entry for interaction with the classes and interfaces
/// in airmap::*.
class Context : DoNotCopyOrMove {
public:
/// ReturnCode enumerates all known return values for a call to run or exec.
enum class ReturnCode {
success = 0, /// Execution finished successfully
error = 1, /// Execution finished with an error
already_running = 2 /// Indicates that the context is already executing on another thread
};
/// @cond
using ClientCreateResult = Outcome<std::shared_ptr<Client>, Error>;
using ClientCreateCallback = std::function<void(const ClientCreateResult&)>;
using MonitorClientCreateResult = Outcome<std::shared_ptr<monitor::Client>, Error>;
using MonitorClientCreateCallback = std::function<void(const MonitorClientCreateResult&)>;
using CreateResult = Outcome<std::shared_ptr<Context>, Error>;
using SignalHandler = std::function<void(int)>;
using SignalSet = std::unordered_set<int>;
/// @endcond
/// create tries to assemble and return a new Context instance.
static CreateResult create(const std::shared_ptr<Logger>& logger);
/// create_client_with_configuration schedules creation of a new client with 'configuration'
/// and reports results to 'cb'.
virtual void create_client_with_configuration(const Client::Configuration& configuration,
const ClientCreateCallback& cb) = 0;
/// create_monitor_client_with_configuration schedules creation of a new monitor::Client with 'configuration'
/// and reports results to 'cb'.
virtual void create_monitor_client_with_configuration(const monitor::Client::Configuration& configuration,
const MonitorClientCreateCallback& cb) = 0;
/// exec hands a thread of execution to a Context instance, monitoring
/// the signals present in 'signal_set' and dispatching incoming signals
/// to the registered handlers.
///
/// Implementations are expected to block the current thread until
/// either an error occured or the user explicitly requests a Context
/// instance to stop.
virtual ReturnCode exec(const SignalSet& signal_set, const SignalHandler& handler) = 0;
/// run hands a thread of execution to the context.
///
/// Implementations are expected to block the current thread until
/// either an error occured or the user explicitly requests a Context
/// instance to stop.
virtual ReturnCode run() = 0;
/// stop requests an instance to shut down its operation and return from
/// run.
virtual void stop(ReturnCode rc = ReturnCode::success) = 0;
/// dispatch executes 'task' on the thread running this Context instance.
virtual void dispatch(const std::function<void()>& task) = 0;
/// schedule_in schedules execution of 'functor' in 'wait_for' [us].
virtual void schedule_in(const Microseconds& wait_for, const std::function<void()>& functor) = 0;
protected:
/// @cond
Context() = default;
/// @endcond
};
} // namespace airmap
#endif // AIRMAP_CONTEXT_H_
#ifndef AIRMAP_CREDENTIALS_H_
#define AIRMAP_CREDENTIALS_H_
#include <airmap/optional.h>
#include <iosfwd>
#include <string>
namespace airmap {
/// Credentials bundles up all credentials required
/// to use the AirMap SDK and APIs.
struct Credentials {
enum class Type { anonymous, oauth };
/// Anonymous bundles up all attributes needed to
/// authenticate anonymously with the AirMap services.
struct Anonymous {
std::string id;
};
/// OAuth bundles up all attributes needed to authenticate
/// with username/password with the AirMap services.
struct OAuth {
std::string username;
std::string password;
std::string client_id;
std::string device_id;
};
std::string api_key; ///< Use this api key when accessing the AirMap services
Optional<OAuth> oauth; /// Optional attributes for authenticating with username/password with the AirMap services
Optional<Anonymous> anonymous; /// Optional attributes for authenticating anonymously with the AirMap services
};
/// operator>> extracts type from in.
std::istream& operator>>(std::istream& in, Credentials::Type& type);
/// operator<< inserts type into out.
std::ostream& operator<<(std::ostream& out, Credentials::Type type);
} // namespace airmap
#endif // AIRMAP_CREDENTIALS_H_
#ifndef AIRMAP_DATE_TIME_H_
#define AIRMAP_DATE_TIME_H_
#include <boost/date_time.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <cstdint>
#include <memory>
#include <string>
namespace airmap {
/// Clock marks the reference for time measurements.
using Clock = boost::posix_time::microsec_clock;
/// DateTime marks a specific point in time, in reference to Clock.
using DateTime = boost::posix_time::ptime;
using Hours = boost::posix_time::hours;
using Minutes = boost::posix_time::minutes;
using Seconds = boost::posix_time::seconds;
using Milliseconds = boost::posix_time::milliseconds;
using Microseconds = boost::posix_time::microseconds;
/// milliseconds_since_epoch returns the milliseconds that elapsed since the UNIX epoch.
std::uint64_t milliseconds_since_epoch(const DateTime& dt);
/// microseconds_since_epoch returns the microseconds that elapsed since the UNIX epoch.
std::uint64_t microseconds_since_epoch(const DateTime& dt);
/// from_seconds_since_epoch returns a DateTime.
DateTime from_seconds_since_epoch(const Seconds& s);
/// from_milliseconds_since_epoch returns a DateTime.
DateTime from_milliseconds_since_epoch(const Milliseconds& ms);
/// from_microseconds_since_epoch returns a DateTime.
DateTime from_microseconds_since_epoch(const Microseconds& us);
// moves the datetime forward to the specified hour
DateTime move_to_hour(const DateTime& dt, int hour);
namespace iso8601 {
/// parse parses a DateTime instance from the string s in iso8601 format.
DateTime parse(const std::string& s);
/// generate returns a string in iso8601 corresponding to 'dt'.
std::string generate(const DateTime& dt);
} // namespace iso8601
} // namespace airmap
#endif // AIRMAP_DATE_TIME_H_
#ifndef AIRMAP_DO_NOT_COPY_OR_MOVE_H_
#define AIRMAP_DO_NOT_COPY_OR_MOVE_H_
namespace airmap {
/// @cond
struct DoNotCopyOrMove {
DoNotCopyOrMove() = default;
DoNotCopyOrMove(const DoNotCopyOrMove&) = delete;
DoNotCopyOrMove(DoNotCopyOrMove&&) = delete;
virtual ~DoNotCopyOrMove() = default;
DoNotCopyOrMove& operator=(const DoNotCopyOrMove&) = delete;
DoNotCopyOrMove& operator=(DoNotCopyOrMove&&) = delete;
};
/// @endcond
} // namespace airmap
#endif // AIRMAP_DO_NOT_COPY_OR_MOVE_H_
#ifndef AIRMAP_ERROR_H_
#define AIRMAP_ERROR_H_
#include <airmap/do_not_copy_or_move.h>
#include <airmap/optional.h>
#include <cstdint>
#include <iosfwd>
#include <map>
#include <memory>
#include <string>
#include <vector>
namespace airmap {
/// Error models an error raised by an AirMap component.
struct Error {