diff --git a/libs/airmapd/include/airmap/aircraft.h b/libs/airmapd/include/airmap/aircraft.h new file mode 100644 index 0000000000000000000000000000000000000000..9a6fbdf406213a83aace6825850b04cc2228cf7d --- /dev/null +++ b/libs/airmapd/include/airmap/aircraft.h @@ -0,0 +1,30 @@ +#ifndef AIRMAP_AIRCRAFT_H_ +#define AIRMAP_AIRCRAFT_H_ + +#include + +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_ diff --git a/libs/airmapd/include/airmap/aircrafts.h b/libs/airmapd/include/airmap/aircrafts.h new file mode 100644 index 0000000000000000000000000000000000000000..fa8b567c7488d86d23e63e8b85913eac6db8d40f --- /dev/null +++ b/libs/airmapd/include/airmap/aircrafts.h @@ -0,0 +1,86 @@ +#ifndef AIRMAP_AIRCRAFTS_H_ +#define AIRMAP_AIRCRAFTS_H_ + +#include +#include +#include +#include +#include + +#include +#include +#include + +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 manufacturer_name; ///< Search for the specific manufacturer with this name. + }; + + /// Result models the outcome of calling Flights::manufacturers. + using Result = Outcome, Error>; + /// Callback describes the function signature of the callback that is + /// invoked when a call to Flights::manufacturers finishes. + using Callback = std::function; + }; + + /// Models groups together types to ease interaction with + /// Aircrafts::models. + struct Models { + /// Parameters bundles up input parameters. + struct Parameters { + Optional manufacturer; ///< Only list models by this manufacturer. + Optional model_name; ///< Search for the specific model with this name. + }; + + /// Result models the outcome of calling Flights::models. + using Result = Outcome, Error>; + /// Callback describes the function signature of the callback that is + /// invoked when a call to Flights::models finishes. + using Callback = std::function; + }; + + /// 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; + /// Callback describes the function signature of the callback that is + /// invoked when a call to Flights::model_for_id finishes. + using Callback = std::function; + }; + + /// 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_ diff --git a/libs/airmapd/include/airmap/airspace.h b/libs/airmapd/include/airmap/airspace.h new file mode 100644 index 0000000000000000000000000000000000000000..c9e517e9d94ca0163b1747341f27a96126025e0b --- /dev/null +++ b/libs/airmapd/include/airmap/airspace.h @@ -0,0 +1,383 @@ +#ifndef AIRMAP_AIRSPACE_H_ +#define AIRMAP_AIRSPACE_H_ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace airmap { + +/// Airspace groups together general information about an airspace and +/// in-depth information providing more details. +class Airspace { + public: + /// Airport bundles up properties further describing an + /// airspace around an airport. + struct Airport { + /// Runway describes an individual runway of an airport. + struct Runway { + std::string name; ///< Commn name assigned to the runway in the context of a specific airport. + float length; ///< Lenght of the runway in [m]. + float bearing; ///< Bearing of the runway in [°]. + }; + + /// Use enumerates all known usage types for + /// an airport. + enum class Use { + public_ ///< The airport is available for public use. + }; + + std::string iata; ///< IATA code of the airport. + std::string icao; ///< ICAO code of the airport. + bool paved; ///< True if the airport features paved runways. + std::string phone; ///< The phone number of the airport (typically the tower). + bool tower; ///< True if the airport features a tower. + std::vector runways; ///< Collection of runways available at the airport. + float elevation; ///< The elevation of the airport in [m]. + float longest_runway; ///< The lenght of th longest runway in [m]. + bool instrument_approach_procedure; ///< True if the airport features equipment supporting an IAP. + Use use; ///< Types of use offered by the airport. + }; + + /// ControlledAirspace bundles up properties describing + /// a controlled airspace. + struct ControlledAirspace {}; + + /// SpecialUseAirspace bundles up properties describing + /// a special use airspace. + struct SpecialUseAirspace { + /// Type enumerates all known special-purpose types. + enum class Type {}; + Type type; ///< The type of the SpecialUseAirspace. + }; + + /// TemporaryFlightRestriction describes an airspace that + /// modelling a temporary restriction of the airspace. + struct TemporaryFlightRestriction { + /// Type enumerates all known types of temporary flight restrictions. + enum class Type {}; + std::string url; ///< The URL providing further information about the temporary flight restriction. + Type type; ///< The type of the temporary flight restriction. + std::string reason; ///< The reason for the temporary flight restriction. + }; + + /// Wildfire describes an airspace around a wildfire. + struct Wildfire { + std::string effective_date; + }; + + /// Park describes an airspace over a park. + struct Park {}; + /// Prison describes an airspace over a prison. + struct Prison {}; + /// School describes an airspace over a school. + struct School {}; + /// Hospital describes an airspace over a hospital. + struct Hospital {}; + /// Fire describes an airspace over a fire. + struct Fire {}; + /// Emergency describes an airspace over an emergency situation. + struct Emergency {}; + + /// Heliport describes an airspace around a heliport. + struct Heliport { + /// Usage enumerates all known usages of a heliport. + enum class Usage {}; + std::string faa_id; ///< The FAA id of the heliport. + std::string phone; ///< The phone number of the heliport. + Usage usage; ///< The usages supported by the heliport. + }; + + /// PowerPlant describes the airspace around a power plant. + struct PowerPlant { + std::string technology; ///< The technology used by the power plant. + std::uint64_t code; ///< Official number of the power plant. + }; + + /// RelatedGeometry bundles up a geometry related to an airspace. + struct RelatedGeometry { + std::string id; ///< The unique id of the geometry in the context of AirMap. + Geometry geometry; ///< The actual geometry. + }; + + /// Enumerates all known airspace types. + enum class Type { + invalid = 0, + airport = 1 << 0, + controlled_airspace = 1 << 1, + special_use_airspace = 1 << 2, + tfr = 1 << 3, + wildfire = 1 << 4, + park = 1 << 5, + power_plant = 1 << 6, + heliport = 1 << 7, + prison = 1 << 8, + school = 1 << 9, + hospital = 1 << 10, + fire = 1 << 11, + emergency = 1 << 12, + all = airport | controlled_airspace | special_use_airspace | tfr | wildfire | park | power_plant | heliport | + prison | school | hospital | fire | emergency + }; + + using Id = std::string; + + /// @cond + Airspace(); + Airspace(const Airspace &rhs); + ~Airspace(); + Airspace &operator=(const Airspace &rhs); + bool operator==(const Airspace &rhs) const; + bool operator!=(const Airspace &rhs) const; + /// @endcond + + /// id returns an immutable reference to the unique idd + /// of this airspace. + const Id &id() const; + /// set_id adjusts the unique id of this airspace to id. + void set_id(const Id &id); + + /// name returns an immutable reference to the + /// human-readable name of this airspace. + const std::string &name() const; + /// set_name adjusts the name of this airspace to name. + void set_name(const std::string &name); + + /// type returns the Type of this airspace instance. + Type type() const; + + /// country returns an immutable reference to the name of the country + /// that the airspace belongs to. + const std::string &country() const; + /// set_country adjusts the name of the country that this airspace instance belongs to. + void set_country(const std::string &country); + + /// state returns an immutable reference to the name of the state + /// that the airspace belongs to. + const std::string &state() const; + /// set_state adjusts the name of the state that this airspace instance belongs to. + void set_state(const std::string &state); + + /// city returns an immutable reference to the name of the city + /// that the airspace belongs to. + const std::string &city() const; + /// set_city adjusts the name of the city that this airspace instance belongs to. + void set_city(const std::string &city); + + /// last_updated returns an immutable reference to the timestamp of the last update + /// to this airspace instance. + const Timestamp &last_updated() const; + /// set_last_updated adjusts the timestamp of the last update to this airspace to + /// 'timestamp'. + void set_last_updated(const Timestamp ×tamp); + + /// geometry returns an immutable reference to the geometry of this airspace instance. + const Geometry &geometry() const; + /// set_geometry adjusts the geometry of this airspace instance to 'geometry'. + void set_geometry(const Geometry &geometry); + + /// related_geometries returns an immutable reference to all geometries associated with + /// this airspace instance. + const std::map &related_geometries() const; + /// set_related_geometries adjusts the geometries associated with this airspace instance + /// to 'geometry'. + void set_related_geometries(const std::map &geometries); + + /// rules returns an immutable reference to the rules applying to this airspace instance. + const std::vector &rules() const; + /// set_rules adjusts the rules applying to this airspace instance to 'rules. + void set_rules(const std::vector &rules); + + /// details_for_airport returns an immutable reference to the details + /// further describing this airspace instance. + const Airport &details_for_airport() const; + /// details_for_airport returns a mutable reference to the details + /// further describing this airspace instance. + Airport &details_for_airport(); + + /// details_for_controlled_airspace returns an immutable reference to the details + /// further describing this airspace instance. + const ControlledAirspace &details_for_controlled_airspace() const; + /// details_for_controlled_airspace returns a mutable reference to the details + /// further describing this airspace instance. + ControlledAirspace &details_for_controlled_airspace(); + + /// details_for_emergency returns an immutable reference to the details + /// further describing this airspace instance. + const Emergency &details_for_emergency() const; + /// details_for_emergency returns a mutable reference to the details + /// further describing this airspace instance. + Emergency &details_for_emergency(); + + /// details_for_fire returns an immutable reference to the details + /// further describing this airspace instance. + const Fire &details_for_fire() const; + /// details_for_fire returns a mutable reference to the details + /// further describing this airspace instance. + Fire &details_for_fire(); + + /// details_for_heliport returns an immutable reference to the details + /// further describing this airspace instance. + const Heliport &details_for_heliport() const; + /// details_for_heliport returns a mutable reference to the details + /// further describing this airspace instance. + Heliport &details_for_heliport(); + + /// details_for_hospital returns an immutable reference to the details + /// further describing this airspace instance. + const Hospital &details_for_hospital() const; + /// details_for_hospital returns a mutable reference to the details + /// further describing this airspace instance. + Hospital &details_for_hospital(); + + /// details_for_park returns an immutable reference to the details + /// further describing this airspace instance. + const Park &details_for_park() const; + /// details_for_park returns a mutable reference to the details + /// further describing this airspace instance. + Park &details_for_park(); + + /// details_for_power_plant returns an immutable reference to the details + /// further describing this airspace instance. + const PowerPlant &details_for_power_plant() const; + /// details_for_power_plant returns a mutable reference to the details + /// further describing this airspace instance. + PowerPlant &details_for_power_plant(); + + /// details_for_prison returns an immutable reference to the details + /// further describing this airspace instance. + const Prison &details_for_prison() const; + /// details_for_prison returns a mutable reference to the details + /// further describing this airspace instance. + Prison &details_for_prison(); + + /// details_for_school returns an immutable reference to the details + /// further describing this airspace instance. + const School &details_for_school() const; + /// details_for_school returns a mutable reference to the details + /// further describing this airspace instance. + School &details_for_school(); + + /// details_for_special_use_airspace returns an immutable reference to the details + /// further describing this airspace instance. + const SpecialUseAirspace &details_for_special_use_airspace() const; + /// details_for_special_use_airspace returns a mutable reference to the details + /// further describing this airspace instance. + SpecialUseAirspace &details_for_special_use_airspace(); + + /// details_for_temporary_flight_restriction returns an immutable reference to the details + /// further describing this airspace instance. + const TemporaryFlightRestriction &details_for_temporary_flight_restriction() const; + /// details_for_temporary_flight_restriction returns a mutable reference to the details + /// further describing this airspace instance. + TemporaryFlightRestriction &details_for_temporary_flight_restriction(); + + /// details_for_wildfire returns an immutable reference to the details + /// further describing this airspace instance. + const Wildfire &details_for_wildfire() const; + /// details_for_wildfire returns an immutable reference to the details + /// further describing this airspace instance. + Wildfire &details_for_wildfire(); + + /// set_details adjusts the details of this airspace instance to 'detail'. + void set_details(const Airspace &detail); + /// set_details adjusts the details of this airspace instance to 'detail'. + void set_details(const Airport &detail); + /// set_details adjusts the details of this airspace instance to 'detail'. + void set_details(const ControlledAirspace &detail); + /// set_details adjusts the details of this airspace instance to 'detail'. + void set_details(const SpecialUseAirspace &detail); + /// set_details adjusts the details of this airspace instance to 'detail'. + void set_details(const TemporaryFlightRestriction &detail); + /// set_details adjusts the details of this airspace instance to 'detail'. + void set_details(const Wildfire &detail); + /// set_details adjusts the details of this airspace instance to 'detail'. + void set_details(const Park &detail); + /// set_details adjusts the details of this airspace instance to 'detail'. + void set_details(const PowerPlant &detail); + /// set_details adjusts the details of this airspace instance to 'detail'. + void set_details(const Heliport &detail); + /// set_details adjusts the details of this airspace instance to 'detail'. + void set_details(const Prison &detail); + /// set_details adjusts the details of this airspace instance to 'detail'. + void set_details(const School &detail); + /// set_details adjusts the details of this airspace instance to 'detail'. + void set_details(const Hospital &detail); + /// set_details adjusts the details of this airspace instance to 'detail'. + void set_details(const Fire &detail); + /// set_details adjusts the details of this airspace instance to 'detail'. + void set_details(const Emergency &detail); + + private: + struct Invalid {}; + + union Details { + Details(); + ~Details(); + + Invalid invalid; + Airport airport; + ControlledAirspace controlled_airspace; + Emergency emergency; + Fire fire; + Heliport heliport; + Hospital hospital; + Park park; + PowerPlant power_plant; + Prison prison; + School school; + SpecialUseAirspace special_use_airspace; + TemporaryFlightRestriction tfr; + Wildfire wildfire; + }; + + void reset(); + + Id id_; + std::string name_; + Type type_; + std::string country_; // TODO(tvoss): Investigate constraints on country names. + std::string state_; // TODO(tvoss): Investigate constraints on state names. + std::string city_; + Timestamp last_updated_; + Geometry geometry_; + std::map related_geometries_; + std::vector rules_; + Details details_; +}; + +/// @cond +bool operator==(const Airspace::RelatedGeometry &lhs, const Airspace::RelatedGeometry &rhs); +bool operator==(const Airspace::Airport &lhs, const Airspace::Airport &rhs); +bool operator==(const Airspace::Airport::Runway &lhs, const Airspace::Airport::Runway &rhs); +bool operator==(const Airspace::ControlledAirspace &lhs, const Airspace::ControlledAirspace &rhs); +bool operator==(const Airspace::SpecialUseAirspace &lhs, const Airspace::SpecialUseAirspace &rhs); +bool operator==(const Airspace::TemporaryFlightRestriction &lhs, const Airspace::TemporaryFlightRestriction &rhs); +bool operator==(const Airspace::Wildfire &lhs, const Airspace::Wildfire &rhs); +bool operator==(const Airspace::Park &lhs, const Airspace::Park &rhs); +bool operator==(const Airspace::Prison &lhs, const Airspace::Prison &rhs); +bool operator==(const Airspace::School &lhs, const Airspace::School &rhs); +bool operator==(const Airspace::Hospital &lhs, const Airspace::Hospital &rhs); +bool operator==(const Airspace::Fire &lhs, const Airspace::Fire &rhs); +bool operator==(const Airspace::Emergency &lhs, const Airspace::Emergency &rhs); +bool operator==(const Airspace::Heliport &lhs, const Airspace::Heliport &rhs); +bool operator==(const Airspace::PowerPlant &lhs, const Airspace::PowerPlant &rhs); + +Airspace::Type operator~(Airspace::Type); +Airspace::Type operator|(Airspace::Type, Airspace::Type); +Airspace::Type operator&(Airspace::Type, Airspace::Type); + +std::ostream &operator<<(std::ostream &, const Airspace &); +std::ostream &operator<<(std::ostream &, Airspace::Type); +/// @endcond + +} // namespace airmap + +#endif // AIRMAP_AIRSPACE_H_ diff --git a/libs/airmapd/include/airmap/airspaces.h b/libs/airmapd/include/airmap/airspaces.h new file mode 100644 index 0000000000000000000000000000000000000000..1f81c588cecac1be17ec0cc9a4d7f615ab1b4217 --- /dev/null +++ b/libs/airmapd/include/airmap/airspaces.h @@ -0,0 +1,71 @@ +#ifndef AIRMAP_AIRSPACES_H_ +#define AIRMAP_AIRSPACES_H_ + +#include +#include +#include +#include +#include + +#include +#include + +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, Error>; + /// Callback describes the function signature of the callback that is + /// invoked when a call to Airspaces::for_id finishes. + using Callback = std::function; + }; + + /// Search groups together types to ease interaction with + /// Airspaces::Search. + struct Search { + /// Parameters bundles up input parameters. + struct Parameters { + Optional types; ///< Search for airspaces with either one of these types. + Optional ignored_types; ///< Ignore airspaces with either one of these types. + Optional full; ///< If true, the complete description of airspaces in the result set is requested. + Geometry geometry; ///< Search airspaces intersection this geometry. + Optional buffer; ///< Buffer around the geometry in [m]. + Optional limit; ///< Limit the number of results to 'limit'. + Optional offset; + Optional date_time; + }; + + /// Result models the outcome of calling Airspaces::search. + using Result = Outcome, Error>; + /// Callback describes the function signature of the callback that is + /// invoked when a call to Airspaces::search finishes. + using Callback = std::function; + }; + + /// 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_ diff --git a/libs/airmapd/include/airmap/authenticator.h b/libs/airmapd/include/airmap/authenticator.h new file mode 100644 index 0000000000000000000000000000000000000000..50d5c304f9618bbfd96c8052544880daf303722b --- /dev/null +++ b/libs/airmapd/include/airmap/authenticator.h @@ -0,0 +1,103 @@ +#ifndef AIRMAP_AUTHENTICATOR_H_ +#define AIRMAP_AUTHENTICATOR_H_ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +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; + /// Callback describes the function signature of the callback that is + /// invoked when a call to Authenticator::authenticate_with_password finishes. + using Callback = std::function; + }; + + /// 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; + /// Callback describes the function signature of the callback that is + /// invoked when a call to Authenticator::authenticate_anonymously finishes. + using Callback = std::function; + }; + + /// 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; + /// Callback describes the function signature of the callback that is + /// invoked when a call to Authenticator::renew_authentication finishes. + using Callback = std::function; + }; + + /// 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_ diff --git a/libs/airmapd/include/airmap/client.h b/libs/airmapd/include/airmap/client.h new file mode 100644 index 0000000000000000000000000000000000000000..f04c898943dad4f47a822ce518728fedd65214f1 --- /dev/null +++ b/libs/airmapd/include/airmap/client.h @@ -0,0 +1,145 @@ +#ifndef AIRMAP_CLIENT_H_ +#define AIRMAP_CLIENT_H_ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +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_ diff --git a/libs/airmapd/include/airmap/context.h b/libs/airmapd/include/airmap/context.h new file mode 100644 index 0000000000000000000000000000000000000000..694a3bd75a49be1cd4d8d44f05904f242253b1ac --- /dev/null +++ b/libs/airmapd/include/airmap/context.h @@ -0,0 +1,85 @@ +#ifndef AIRMAP_CONTEXT_H_ +#define AIRMAP_CONTEXT_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +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, Error>; + using ClientCreateCallback = std::function; + using MonitorClientCreateResult = Outcome, Error>; + using MonitorClientCreateCallback = std::function; + using CreateResult = Outcome, Error>; + using SignalHandler = std::function; + using SignalSet = std::unordered_set; + /// @endcond + + /// create tries to assemble and return a new Context instance. + static CreateResult create(const std::shared_ptr& 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& task) = 0; + + /// schedule_in schedules execution of 'functor' in 'wait_for' [us]. + virtual void schedule_in(const Microseconds& wait_for, const std::function& functor) = 0; + + protected: + /// @cond + Context() = default; + /// @endcond +}; + +} // namespace airmap + +#endif // AIRMAP_CONTEXT_H_ diff --git a/libs/airmapd/include/airmap/credentials.h b/libs/airmapd/include/airmap/credentials.h new file mode 100644 index 0000000000000000000000000000000000000000..513a641573c52adb23bb94e15692764b0a9f889d --- /dev/null +++ b/libs/airmapd/include/airmap/credentials.h @@ -0,0 +1,43 @@ +#ifndef AIRMAP_CREDENTIALS_H_ +#define AIRMAP_CREDENTIALS_H_ + +#include + +#include +#include + +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; /// Optional attributes for authenticating with username/password with the AirMap services + Optional 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_ diff --git a/libs/airmapd/include/airmap/date_time.h b/libs/airmapd/include/airmap/date_time.h new file mode 100644 index 0000000000000000000000000000000000000000..2d02c78ff76cde20b1958e7843bf61b5500d6ad7 --- /dev/null +++ b/libs/airmapd/include/airmap/date_time.h @@ -0,0 +1,48 @@ +#ifndef AIRMAP_DATE_TIME_H_ +#define AIRMAP_DATE_TIME_H_ + +#include +#include + +#include +#include +#include + +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_ diff --git a/libs/airmapd/include/airmap/do_not_copy_or_move.h b/libs/airmapd/include/airmap/do_not_copy_or_move.h new file mode 100644 index 0000000000000000000000000000000000000000..807d41887f77fc227e9c7a0f43d82fce78f64028 --- /dev/null +++ b/libs/airmapd/include/airmap/do_not_copy_or_move.h @@ -0,0 +1,19 @@ +#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_ diff --git a/libs/airmapd/include/airmap/error.h b/libs/airmapd/include/airmap/error.h new file mode 100644 index 0000000000000000000000000000000000000000..931a0f2ad60f98e3d655ccbd3429f5cbe9684cc3 --- /dev/null +++ b/libs/airmapd/include/airmap/error.h @@ -0,0 +1,173 @@ +#ifndef AIRMAP_ERROR_H_ +#define AIRMAP_ERROR_H_ + +#include +#include + +#include + +#include +#include +#include +#include +#include + +namespace airmap { + +/// Error models an error raised by an AirMap component. +struct Error { + /// Value is a discriminated union type wrapping up multiple atomic types and + /// their composition into a vector or a dictionary. + class Value { + public: + /// Type enumerates all datatypes that can be wrapped in a Value. + enum class Type { + undefined, ///< Marks the undefined type. + boolean, ///< Marks a boolean type. + integer, ///< Marks an integer type with 64 bits. + floating_point, ///< Marks a double-precision floating point number. + string, ///< Marks a string. + blob, ///< Marks a binary blob. + dictionary, ///< Marks a dictionary of values. + vector ///< Marks a vector of values. + }; + + /// Value initializes a new Value instance of type undefined. + explicit Value(); + /// Value initializes a new Value instance of type boolean with 'value'. + explicit Value(bool value); + /// Value initializes a new Value instance of type integer with 'value'. + explicit Value(std::int64_t value); + /// Value initializes a new Value instance of type floating_point with 'value'. + explicit Value(double value); + /// Value initializes a new Value instance of type string with 'value'. + explicit Value(const std::string& value); + /// Value initializes a new Value instance of type blob with 'value'. + explicit Value(const std::vector& value); + /// Value initializes a new Value instance of type dictionary with 'value'. + explicit Value(const std::map& value); + /// Value initializes a new Value instance of type vector with 'value'. + explicit Value(const std::vector& value); + /// Value copy-constructs a value from 'other'. + Value(const Value& other); + /// Value move-constructs a value from 'other'. + Value(Value&&); + /// ~Value cleans up all resources by a Value instance. + ~Value(); + + /// operator= assigns type and value from rhs. + Value& operator=(const Value& rhs); + /// operator= moves type and value from rhs. + Value& operator=(Value&& rhs); + + /// type returns the Type of this Value instance. + Type type() const; + + /// boolean returns the boolean value of this Value instance. + /// The behavior in case of type() != Type::boolean is undefined. + bool boolean() const; + /// integer returns the boolean value of this Value instance. + /// The behavior in case of type() != Type::integer is undefined. + std::int64_t integer() const; + /// floating_point returns the floating point value of this Value instance. + /// The behavior in case of type() != Type::floating_point is undefined. + double floating_point() const; + /// string returns the string value of this Value instance. + /// The behavior in case of type() != Type::string is undefined. + const std::string& string() const; + /// blob returns the blob value of this Value instance. + /// The behavior in case of type() != Type::blob is undefined. + const std::vector blob() const; + /// dictionary returns the dictionary value of this Value instance. + /// The behavior in case of type() != Type::dictionary is undefined. + const std::map& dictionary() const; + /// vector returns the vector value of this Value instance. + /// The behavior in case of type() != Type::vector is undefined. + const std::vector& vector() const; + + private: + union Details { + Details(); + ~Details(); + + bool boolean; + std::int64_t integer; + double floating_point; + std::string string; + std::vector blob; + std::map dictionary; + std::vector vector; + }; + + Value& construct(bool value); + Value& construct(std::int64_t value); + Value& construct(double value); + Value& construct(const std::string& value); + Value& construct(std::string&& value); + Value& construct(const std::vector& value); + Value& construct(std::vector&& value); + Value& construct(const std::map& value); + Value& construct(std::map&& value); + Value& construct(const std::vector& value); + Value& construct(std::vector&& value); + Value& construct(const Value& value); + Value& construct(Value&& value); + Value& destruct(); + + Type type_; + Details details_; + }; + + /// Error initializes a new error instance with 'message'. + explicit Error(); + + /// Error initializes a new error instance with 'message'. + explicit Error(const std::string& message); + + /// message returns the message describing an error condition. + const std::string& message() const; + /// message sets the message of the Error instance to 'message'. + Error message(const std::string& message) const; + /// message sets the message of the Error instance to 'message'. + Error& message(const std::string& message); + + /// description returns the optional description of an error condition. + const Optional& description() const; + /// clear_description resets the description of the Error instance. + Error clear_description() const; + /// clear_description resets the description of the Error instance. + Error& clear_description(); + /// description sets the description of the Error instance to 'description'. + Error description(const std::string& description) const; + /// description sets the description of the Error instance to 'description'. + Error& description(const std::string& description); + + /// values returns the additional values describing an error condition. + const std::map& values() const; + /// clear_values resets the values of the Error instance. + Error clear_values() const; + /// clear_values resets the values of the Error instance. + Error& clear_values(); + /// value adds the pair (key, value) to the additional values describing an error condition. + Error value(const Value& key, const Value& value) const; + /// value adds the pair (key, value) to the additional values describing an error condition. + Error& value(const Value& key, const Value& value); + + private: + std::string message_; ///< Short, human-readable message. + Optional description_; ///< Detailed description of the error, meant to be used for defect analysis. + std::map values_; ///< Dictionary of additional data attached to the error. +}; + +/// operator== returns true if both type and value of lhs and rhs compare equal. +bool operator==(const Error::Value& lhs, const Error::Value& rhs); +/// operator< returns true if type and value of lhs compare < than type and value of rhs. +bool operator<(const Error::Value& lhs, const Error::Value& rhs); +/// operator<< inserts 'value' into 'out'. +std::ostream& operator<<(std::ostream& out, const Error::Value& value); +/// operator<< inserts 'error' into 'out'. +std::ostream& operator<<(std::ostream& out, const Error& error); + +} // namespace airmap + +#endif // AIRMAP_ERROR_H_ \ No newline at end of file diff --git a/libs/airmapd/include/airmap/evaluation.h b/libs/airmapd/include/airmap/evaluation.h new file mode 100644 index 0000000000000000000000000000000000000000..a2f65624dbea74a2792ff285f1fd8b6492cfb870 --- /dev/null +++ b/libs/airmapd/include/airmap/evaluation.h @@ -0,0 +1,89 @@ +#ifndef AIRMAP_EVALUATION_H_ +#define AIRMAP_EVALUATION_H_ + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace airmap { + +/// Evaluation bundles together information regarding an airspace ruleset evaluation. +struct Evaluation { + /// Authority models an authority capable of authorizing flight plans. + struct Authority { + std::string id; ///< The id of the authority. + std::string name; ///< The name of the authority. + }; + + /// Authorization bundles up the authorization status of a flight plan. + struct Authorization { + /// Status enumerates all known states of an Authorization. + enum class Status { + accepted, ///< The flight plan is accepted. + rejected, ///< The flight plan is rejected. + pending, ///< The request for authorization is pending a response. + accepted_upon_submission, ///< The request will be accepted on submission. + rejected_upon_submission ///< The request will be rejected on submission. + }; + + Status status; ///< The overall status of the request. + Authority authority; ///< The authority that handles the request. + std::string message; ///< The human-readable message provided by the authority. + }; + + /// Validation bundles up the validation status of a flight plan. + struct Validation { + /// Status enumerates all known states of a Validation. + enum class Status { + valid, ///< The validation succeeded. + invalid, ///< The validation was rejected. + unknown ///< The status is unknown. + }; + + /// Feature describes a specific feature that requires validation. + struct Feature { + std::string code; ///< The code of the feature. + std::string description; ///< The description of the feature. + }; + + Status status; ///< The overall status of the validation. + std::string data; ///< The data provided for validation. + std::string message; ///< The human-readable message provided by the authority. + Feature feature; ///< The specific feature requiring validation. + Authority authority; ///< The authority carrying out the validation. + }; + + /// Failure enumrates all known failures during evaluation. + enum class Failure { + validation, ///< The validation failed. + authorization, ///< The authorization failed. + rulesets ///< The ruleset engine failed. + }; + + std::vector rulesets; ///< All RuleSet instances relevant to a specific briefing/flight plan. + std::vector validations; ///< All Validation instances relevant to a specific briefing/flight plan. + std::vector + authorizations; ///< All Authorization instances relevant to a specific briefing/flight plan. + std::vector failures; ///< All Failure instances relevant to a specific briefing/flight plan. +}; + +/// @cond +std::ostream& operator<<(std::ostream& out, Evaluation::Authorization::Status status); +std::istream& operator>>(std::istream& in, Evaluation::Authorization::Status& status); + +std::ostream& operator<<(std::ostream& out, Evaluation::Validation::Status status); +std::istream& operator>>(std::istream& in, Evaluation::Validation::Status& status); + +std::ostream& operator<<(std::ostream& out, Evaluation::Failure failure); +std::istream& operator>>(std::istream& in, Evaluation::Failure& failure); +/// @endcond + +} // namespace airmap + +#endif // AIRMAP_EVALUATION_H_ diff --git a/libs/airmapd/include/airmap/flight.h b/libs/airmapd/include/airmap/flight.h new file mode 100644 index 0000000000000000000000000000000000000000..ba5879c0997ca3b4ba6e994ddb851cd39a96bebd --- /dev/null +++ b/libs/airmapd/include/airmap/flight.h @@ -0,0 +1,32 @@ +#ifndef AIRMAP_FLIGHT_H_ +#define AIRMAP_FLIGHT_H_ + +#include +#include +#include +#include + +#include + +namespace airmap { + +/// Flight bundles together properties describing an individual flight. +struct Flight { + using Id = std::string; + + Id id; ///< The unique identifier of a flight in the context of AirMap. + Optional flight_plan_id; ///< The flight plan corresponding to this flight. + Pilot pilot; ///< The pilot responsible for the flight. + Pilot::Aircraft aircraft; ///< The aircraft conducting the flight. + float latitude; ///< The latitude component of the takeoff point in [°]. + float longitude; ///< The longitude component of the takeoff point in [°]. + float max_altitude; ///< The maximum altitude over the entire flight in [m]. + Geometry geometry; ///< The geometry describing the flight. + DateTime created_at; ///< Point in time when the flight was created. + DateTime start_time; ///< Point in time when the flight will start/was started. + DateTime end_time; ///< Point in time when the fligth will end. +}; + +} // namespace airmap + +#endif // AIRMAP_FLIGHT_H_ diff --git a/libs/airmapd/include/airmap/flight_plan.h b/libs/airmapd/include/airmap/flight_plan.h new file mode 100644 index 0000000000000000000000000000000000000000..dcb635aea473cdf6174e84bcf76daff0d28f352b --- /dev/null +++ b/libs/airmapd/include/airmap/flight_plan.h @@ -0,0 +1,60 @@ +#ifndef AIRMAP_FLIGHT_PLAN_H_ +#define AIRMAP_FLIGHT_PLAN_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace airmap { + +/// FlightPlan bundles together properties describing a plan for a flight. +struct FlightPlan { + /// Id models a unique identifier for a flight plan in the context of AirMap. + using Id = std::string; + + /// Briefing bundles together information and data for a flight plan. + /// The target audience is a hypothetical pilot or operator conducting + /// the flight described in the flight plan. + struct Briefing { + /// AdvisoryStatus summarizes the status of all advisories applying to a specific flight plan. + struct AdvisoryStatus { + Status::Color color; ///< The overall color of the status. + std::vector advisories; ///< The collection of relevant advisories. + }; + + DateTime created_at; ///< The timestamp when the briefing was requested and created by the AirMap services. + AdvisoryStatus airspace; ///< The summary over all advisories relevant to a specific briefing/flight plan. + Evaluation evaluation; ///< The airspace ruleset evaluation returned for the briefing. + }; + + Id id; ///< The unique identifier of a flight in the context of AirMap. + Optional flight_id; ///< The unique identifier of the flight that is created on successful submission. + Pilot pilot; ///< The pilot responsible for the flight. + Pilot::Aircraft aircraft; ///< The aircraft conducting the flight. + struct { + float latitude; ///< The latitude component of the takeoff coordinates in [°]. + float longitude; ///< The longitude component of the takeoff coordinates in [°]. + } takeoff; ///< The takeoff coordinate. + struct { + float max; ///< The maximum altitude over the entire flight in [m]. + float min; ///< The minimum altitude over the entire flight in [m]. + } altitude_agl; ///< The altitude range of the flight in [m] above ground level. + float buffer; ///< The buffer in [m] around the geometry. + Geometry geometry; ///< The geometry describing the flight. + DateTime start_time; ///< Point in time when the flight will start/was started. + DateTime end_time; ///< Point in time when the fligth will end. +}; + +} // namespace airmap + +#endif // AIRMAP_FLIGHT_PLAN_H_ diff --git a/libs/airmapd/include/airmap/flight_plans.h b/libs/airmapd/include/airmap/flight_plans.h new file mode 100644 index 0000000000000000000000000000000000000000..03454d836197042bd76b6f3c2f47404480847160 --- /dev/null +++ b/libs/airmapd/include/airmap/flight_plans.h @@ -0,0 +1,160 @@ +#ifndef AIRMAP_FLIGHT_PLANS_H_ +#define AIRMAP_FLIGHT_PLANS_H_ + +#include +#include +#include +#include + +#include +#include +#include + +namespace airmap { + +/// FlightPlans provides functionality for managing flight plans. +class FlightPlans : DoNotCopyOrMove { + public: + /// ForId bundles up types to ease interaction with + /// FlightPlans::for_id. + struct ForId { + /// Parameters bundles up input parameters. + struct Parameters { + Optional authorization; ///< Authorization token obtained by logging in to the AirMap services. + FlightPlan::Id id; ///< Search for the flight with this id. + }; + + /// Result models the outcome of calling FlightPlans::for_id. + using Result = Outcome; + /// Callback describes the function signature of the callback that is invoked + /// when a call to FlightPlans::for_id finishes. + using Callback = std::function; + }; + + /// Create bundles up types to ease interaction with + /// FlightPlans::create_by_point and FlightPlans::create_by_polygon. + struct Create { + /// Parameters bundles up input parameters. + struct Parameters { + std::string authorization; ///< Authorization token obtained by logging in to the AirMap services. + Pilot pilot; ///< The pilot responsible for the flight. + Optional aircraft; ///< The aircraft conducting the flight. + float latitude; ///< The latitude component of the takeoff point in [°]. + float longitude; ///< The longitude component of the takeoff point in [°]. + float max_altitude; ///< The maximum altitude over the entire flight in [m]. + float min_altitude; ///< The minimum altitude over the entire flight in [m]. + float buffer; ///< The buffer in [m] around the geometry. + Geometry geometry; ///< The geometry describing the flight. + DateTime start_time; ///< Point in time when the flight will start/was started. + DateTime end_time; ///< Point in time when the fligth will end. + std::vector rulesets; ///< RuleSets that apply to this flight plan. + std::unordered_map + features; ///< Additional properties of the planned flight. + }; + + /// Result models the outcome of calling FlightPlans::create_by_polygon. + using Result = Outcome; + /// Callback describes the function signature of the callback that is invoked + /// when a call to FlightPlans::create_by_point or FlightPlans::create_by_polygon finishes. + using Callback = std::function; + }; + + /// Update bundles up types to ease interaction with + /// FlightPlans::update. + struct Update { + /// Parameters bundles up input parameters. + struct Parameters { + Optional authorization; ///< Authorization token obtained by logging in to the AirMap services. + FlightPlan flight_plan; ///< The details of the plan that should be created with the AirMap services. + }; + /// Result models the outcome of calling FlightPlans::update. + using Result = Outcome; + /// Callback describes the function signature of the callback that is invoked + /// when a call to FlightPlans::update finishes. + using Callback = std::function; + }; + + /// Delete bundles up types to ease interaction with + /// FlightPlans::delete_. + struct Delete { + /// Parameters bundles up input parameters. + struct Parameters { + Optional authorization; ///< Authorization token obtained by logging in to the AirMap services. + FlightPlan::Id id; ///< Id of the flight plan that should be deleted. + }; + + /// Response models the response from the AirMap services. + struct Response { + FlightPlan::Id id; ///< Id of the flight plan that was deleted. + }; + + /// Result models the outcome of calling FlightPlans::delete_flight. + using Result = Outcome; + /// Callback describes the function signature of the callback that is + /// invoked when a call to FlightPlans::delete_flight finishes. + using Callback = std::function; + }; + + /// RenderBriefing bundles up types to ease interaction with + /// FlightPlans::render_briefing. + struct RenderBriefing { + /// Parameters bundles up input parameters. + struct Parameters { + Optional authorization; ///< Authorization token obtained by logging in to the AirMap services. + FlightPlan::Id id; ///< Id of the flight plan that should be rendered as a briefing. + }; + /// Result models the outcome of calling FlightPlans::submit. + using Result = Outcome; + /// Callback describes the function signature of the callback that is invoked + /// when a call to FlightPlans::submit finishes. + using Callback = std::function; + }; + + /// Submit bundles up types to ease interaction with + /// FlightPlans::submit. + struct Submit { + /// Parameters bundles up input parameters. + struct Parameters { + Optional authorization; ///< Authorization token obtained by logging in to the AirMap services. + FlightPlan::Id id; ///< Id of the flight plan that should be submitted. + }; + /// Result models the outcome of calling FlightPlans::submit. + using Result = Outcome; + /// Callback describes the function signature of the callback that is invoked + /// when a call to FlightPlans::submit finishes. + using Callback = std::function; + }; + + /// for_id queries the AirMap services for detailed information about + /// a flight plan identified by a UUID and reports back results to 'cb'. + virtual void for_id(const ForId::Parameters& parameters, const ForId::Callback& cb) = 0; + + /// create_by_polygon creates a flight plan for 'parameters' and reports + /// results back to 'cb'. + virtual void create_by_polygon(const Create::Parameters& parameters, const Create::Callback& cb) = 0; + + /// update updates a flight plan identified by 'parameters' and reports + /// results back to 'cb'. + virtual void update(const Update::Parameters& parameters, const Update::Callback& cb) = 0; + + /// delete deletes a flight plan identified by 'parameters' and reports + /// results back to 'cb'. + virtual void delete_(const Delete::Parameters& parameters, const Delete::Callback& cb) = 0; + + /// render_briefing requests rendering a briefing for a flight plan identified by 'parameters' and reports + /// results back to 'cb'. + virtual void render_briefing(const RenderBriefing::Parameters& parameters, const RenderBriefing::Callback& cb) = 0; + + /// submit submits a flight plan identified by 'parameters' and reports + /// results back to 'cb'. + virtual void submit(const Submit::Parameters& parameters, const Submit::Callback& cb) = 0; + + protected: + /// @cond + FlightPlans() = default; + /// @endcond +}; + +} // namespace airmap + +#endif // AIRMAP_FLIGHT_PLANS_H_ diff --git a/libs/airmapd/include/airmap/flights.h b/libs/airmapd/include/airmap/flights.h new file mode 100644 index 0000000000000000000000000000000000000000..ca896ddd3188ecc5a47bd35d9baf3a08177898db --- /dev/null +++ b/libs/airmapd/include/airmap/flights.h @@ -0,0 +1,227 @@ +#ifndef AIRMAP_FLIGHTS_H_ +#define AIRMAP_FLIGHTS_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace airmap { + +/// Flights provides functionality for managing flights. +class Flights : DoNotCopyOrMove { + public: + /// ForId bundles up types to ease interaction with + /// Flights::for_id. + struct ForId { + /// Parameters bundles up input parameters. + struct Parameters { + Optional authorization; ///< Authorization token obtained by logging in to the AirMap services. + Flight::Id id; ///< Search for the flight with this id. + Optional enhance; ///< If true, provides extended information per flight in the result set. + }; + + /// Result models the outcome of calling Flights::for_id. + using Result = Outcome; + /// Callback describes the function signature of the callback that is invoked + /// when a call to Flights::for_id finishes. + using Callback = std::function; + }; + + /// Search bundles up types to ease interaction with + /// Flights::search. + struct Search { + /// Parameters bundles up input parameters. + struct Parameters { + Optional authorization; ///< Authorization token obtained by logging in to the AirMap services. + Optional limit; ///< Limit the number of results to 'limit'. + Optional geometry; ///< Search for flights intersecting this geometry. + Optional country; ///< Search for flights in this country. + Optional state; ///< Search for flights in this state. + Optional city; ///< Search for flights in this city. + Optional pilot_id; ///< Search for flights operated by this pilot. + Optional start_after; ///< Search for flights that started after this timestamp. + Optional start_before; ///< Search for flights that started before this timestamp. + Optional end_after; ///< Search for flights that ended after this timestamp. + Optional end_before; ///< Search for flights that ended before this timestamp. + Optional enhance; ///< If true, provides extended information per flight in the result set. + }; + + /// Response bundles up pagination and actual results for a call to Flights::search. + struct Response { + struct Paging { + std::uint32_t limit; ///< The maximum number of results per page. + std::uint32_t total; ///< The total number of results. + } paging; ///< Bundles up pagination information. + std::vector flights; ///< One page of flight results. + }; + + /// Result models the outcome of calling Flights::search. + using Result = Outcome; + /// Callback describes the function signature of the callback that is invoked + /// when a call to Flights::search finishes. + using Callback = std::function; + }; + + /// CreateFlight bundles up types to ease interaction with + /// Flights::create_flight_by_point, Flights::create_flight_by_path and + /// Flights::create_flight_by_polygon. + struct CreateFlight { + /// Parameters bundles up input parameters. + struct Parameters { + std::string authorization; ///< Authorization token obtained by logging in to the AirMap services. + Required latitude; ///< Latitude of take-off point in [°]. + Required longitude; ///< Longitude of take-off point in [°]. + float max_altitude = 121.; ///< Maximum altitude of the entire flight in [m]. + std::string aircraft_id; ///< Id of the aircraft carrying out the flight. + DateTime start_time; ///< Point in time when the flight started. + DateTime end_time; ///< Point in time when the flight will end. + bool is_public = true; ///< If true, the flight is considered public and displayed to AirMap users. + bool give_digital_notice = true; ///< If true, the flight is announced to airspace operators. + float buffer = 100; ///< Buffer around the take-off point in [m]. + Optional geometry; ///< The geometry that describes the flight. + }; + /// Result models the outcome of calling Flights::create_flight. + using Result = Outcome; + /// Callback describes the function signature of the callback that is invoked + /// when a call to Flights::create_flight finishes. + using Callback = std::function; + }; + + /// DeleteFlight bundles up types to ease interaction with + /// Flights::delete_flight. + struct DeleteFlight { + /// Parameters bundles up input parameters. + struct Parameters { + std::string authorization; ///< Authorization token obtained by logging in to the AirMap services. + Flight::Id id; ///< Id of the flight that should be deleted. + }; + + /// Response models the response from the AirMap services. + struct Response { + Flight::Id id; ///< Id of the flight that was deleted. + }; + + /// Result models the outcome of calling Flights::delete_flight. + using Result = Outcome; + /// Callback describes the function signature of the callback that is + /// invoked when a call to Flights::delete_flight finishes. + using Callback = std::function; + }; + + /// EndFlight bundles up types to ease interaction with + /// Flights::end_flight. + struct EndFlight { + /// Parameters bundles up input parameters. + struct Parameters { + std::string authorization; ///< Authorization token obtained by logging in to the AirMap services. + Flight::Id id; ///< Id of the flight that should be ended. + }; + + /// Response models the response from the AirMap services. + struct Response { + DateTime end_time; ///< Point in time when the flight was ended. + }; + + /// Result models the outcome of calling Flights::delete_flight. + using Result = Outcome; + /// Callback describes the function signature of the callback that is + /// invoked when a call to Flights::end_flight finishes. + using Callback = std::function; + }; + + /// StartFlightCommunications bundles up types to ease interaction with + /// Flights::start_flight_communications. + struct StartFlightCommunications { + /// Parameters bundles up input parameters. + struct Parameters { + std::string authorization; ///< Authorization token obtained by logging in to the AirMap services. + Flight::Id id; ///< Id of the flight for which flight comms should be started. + }; + + /// Response models the response from the AirMap services. + struct Response { + std::string key; ///< The encryption key that should be used to encrypt individual telemetry updates. + }; + + /// Result models the outcome of calling Flights::start_flight_communications. + using Result = Outcome; + /// Callback describes the function signature of the callback that is + /// invoked when a call to Flights::start_flight_communications. + using Callback = std::function; + }; + + /// EndFlightCommunications bundles up types to ease interaction with + /// Flights::end_flight_communications. + struct EndFlightCommunications { + /// Parameters bundles up input parameters. + struct Parameters { + std::string authorization; ///< Authorization token obtained by logging in to the AirMap services. + Flight::Id id; ///< Id of the flight for which flight comms should be ended. + }; + + /// Response models the response from the AirMap services. + struct Response {}; + + /// Result models the outcome of calling Flights::end_flight_communications. + using Result = Outcome; + /// Callback describes the function signature of the callback that is + /// invoked when a call to Flights::end_flight_communications finishes. + using Callback = std::function; + }; + + /// search queries the AirMap services for known flights + /// and reports 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 + /// flights identified by UUIDs and reports back results to 'cb'. + virtual void for_id(const ForId::Parameters& parameters, const ForId::Callback& cb) = 0; + + /// create_flight creates a flight for 'parameters' and reports + /// results back to 'cb'. + virtual void create_flight_by_point(const CreateFlight::Parameters& parameters, const CreateFlight::Callback& cb) = 0; + + /// create_flight creates a flight for 'parameters' and reports + /// results back to 'cb'. + virtual void create_flight_by_path(const CreateFlight::Parameters& parameters, const CreateFlight::Callback& cb) = 0; + + /// create_flight creates a flight for 'parameters' and reports + /// results back to 'cb'. + virtual void create_flight_by_polygon(const CreateFlight::Parameters& parameters, + const CreateFlight::Callback& cb) = 0; + + /// end_flight finalizes a flight identified by 'parameters' and reports + /// results back to 'cb'. + virtual void end_flight(const EndFlight::Parameters& parameters, const EndFlight::Callback& cb) = 0; + + /// delete_flight deletes a flight identified by 'parameters' and reports + /// results back to 'cb'. + virtual void delete_flight(const DeleteFlight::Parameters& parameters, const DeleteFlight::Callback& cb) = 0; + + /// start_flight_communications enables communications for a specific flight + /// instance and reports results back to 'cb'. + virtual void start_flight_communications(const StartFlightCommunications::Parameters& parameters, + const StartFlightCommunications::Callback& cb) = 0; + + /// end_flight_communications enables communications for a specific flight + /// instance and reports results back to cb. + virtual void end_flight_communications(const EndFlightCommunications::Parameters& parameters, + const EndFlightCommunications::Callback& cb) = 0; + + protected: + /// @cond + Flights() = default; + /// @endcond +}; + +} // namespace airmap + +#endif // AIRMAP_AIRSPACES_H_ diff --git a/libs/airmapd/include/airmap/geometry.h b/libs/airmapd/include/airmap/geometry.h new file mode 100644 index 0000000000000000000000000000000000000000..51e075cd51afda9904059d0479f3d370560fddac --- /dev/null +++ b/libs/airmapd/include/airmap/geometry.h @@ -0,0 +1,146 @@ +#ifndef AIRMAP_GEOMETRY_H_ +#define AIRMAP_GEOMETRY_H_ + +#include + +#include + +namespace airmap { + +/// Geometry bundles up different types of geometries. +class Geometry { + public: + /// Type enumerates all known geometry types. + enum class Type { + invalid, ///< Marks an invalid geometry. + point, ///< Geometry contains a Point. + multi_point, ///< Geometry contains a MultiPoint. + line_string, ///< Geometry contains a LineString. + multi_line_string, ///< Geometry contains a MultiLineString. + polygon, ///< Geometry contains a Polygon. + multi_polygon, ///< Geometry contains a MultiPolygon. + geometry_collection ///< Geometry is a GemetryCollection. + }; + + /// Coordinate marks a point in 3-dimensional space. + struct Coordinate { + double latitude; /// The latitude component of this coordinate in [°]. + double longitude; /// The longitude component of this coordinate in [°]. + Optional altitude; /// The altitude component of this coordinate in [m]. + Optional elevation; + }; + + /// CoordinateVector is a collection of points in 3-dimensional space. + template + struct CoordinateVector { + std::vector coordinates; ///< The individual coordinates. + }; + + using Point = Coordinate; + using MultiPoint = CoordinateVector; + using LineString = CoordinateVector; + using MultiLineString = std::vector; + /// Polygon follows the GeoJSON standard, citing from https://tools.ietf.org/html/rfc7946: + /// * For type "Polygon", the "coordinates" member MUST be an array of + /// linear ring coordinate arrays. + /// * For Polygons with more than one of these rings, the first MUST be + /// the exterior ring, and any others MUST be interior rings. The + /// exterior ring bounds the surface, and the interior rings (if + /// present) bound holes within the surface. + struct Polygon { + CoordinateVector outer_ring; + std::vector> inner_rings; + }; + using MultiPolygon = std::vector; + using GeometryCollection = std::vector; + + /// point returns a Geometry instance with Type::point at the given coordinate (lat, lon). + static Geometry point(double lat, double lon); + /// polygon returns a Geometry instance with Type::polygon with the given 'coordinates'. + static Geometry polygon(const std::vector& coordinates); + + /// Initializes a new instance with Type::invalid. + Geometry(); + /// Geometry initializes a new instance with the given Point. + explicit Geometry(const Point& other); + /// Geometry initializes a new instance with the given MultiPoint. + explicit Geometry(const MultiPoint& other); + /// Geometry initializes a new instance with the given LineString. + explicit Geometry(const LineString& other); + /// Geometry initializes a new instance with the given MultiLineString. + explicit Geometry(const MultiLineString& other); + /// Geometry initializes a new instance with the given Polyon. + explicit Geometry(const Polygon& other); + /// Geometry initializes a new instance with the given MultiPolygon. + explicit Geometry(const MultiPolygon& other); + /// Geometry initializes a new instance with the given GeometryCollection. + explicit Geometry(const GeometryCollection& other); + /// @cond + Geometry(const Geometry& other); + ~Geometry(); + Geometry& operator=(const Geometry& rhs); + bool operator==(const Geometry& rhs) const; + /// @endcond + + /// type returns the Type of the geometry. + Type type() const; + /// details_for_point returns an immutable instance to the contained Point instance. + const Point& details_for_point() const; + /// details_for_multi_point returns an immutable instance to the contained MultiPoint instance. + const MultiPoint& details_for_multi_point() const; + /// details_for_line_string returns an immutable instance to the contained LineString instance. + const LineString& details_for_line_string() const; + /// details_for_multi_line_string returns an immutable instance to the contained MultiLineString instance. + const MultiLineString& details_for_multi_line_string() const; + /// details_for_polygon returns an immutable instance to the contained Polygon instance. + const Polygon& details_for_polygon() const; + /// details_for_multi_polygon returns an immutable instance to the contained MultiPolygon instance. + const MultiPolygon& details_for_multi_polygon() const; + /// details_for_geometry_collection returns an immutable instance to the contained GeometryCollection instance. + const GeometryCollection details_for_geometry_collection() const; + + private: + struct Invalid {}; + + union Data { + Data(); + ~Data(); + + Invalid invalid; + Point point; + MultiPoint multi_point; + LineString line_string; + MultiLineString multi_line_string; + Polygon polygon; + MultiPolygon multi_polygon; + GeometryCollection geometry_collection; + }; + + Geometry& reset(); + void set_point(const Point& point); + void set_multi_point(const MultiPoint& multi_point); + void set_line_string(const LineString& line_string); + void set_multi_line_string(const MultiLineString& multi_line_string); + void set_polygon(const Polygon& polygon); + void set_multi_polygon(const MultiPolygon& multi_polygon); + void set_geometry_collection(const GeometryCollection& geometry_collection); + Geometry& set_geometry(const Geometry& other); + + Type type_; + Data data_; +}; + +/// @cond +bool operator==(const Geometry::Coordinate& lhs, const Geometry::Coordinate& rhs); + +bool operator==(const Geometry::Polygon& lhs, const Geometry::Polygon& rhs); + +template +bool operator==(const Geometry::CoordinateVector& lhs, const Geometry::CoordinateVector& rhs) { + return lhs.coordinates == rhs.coordinates; +} +/// @endcond + +} // namespace airmap + +#endif // AIRMAP_GEOMETRY_H_ diff --git a/libs/airmapd/include/airmap/logger.h b/libs/airmapd/include/airmap/logger.h new file mode 100644 index 0000000000000000000000000000000000000000..1d88bd3ad35d336d916edd0a02c7979bf8b99e95 --- /dev/null +++ b/libs/airmapd/include/airmap/logger.h @@ -0,0 +1,63 @@ +#ifndef AIRMAP_LOGGER_H_ +#define AIRMAP_LOGGER_H_ + +#include + +#include +#include + +namespace airmap { + +/// Logger abstracts logging of human-readable message +/// providing details on the operation of the system. +class Logger : DoNotCopyOrMove { + public: + /// Severity enumerates all known levels of severity + enum class Severity { debug = 0, info = 1, error = 2 }; + + /// debug logs a message from component with Severity::debug. + void debug(const char* message, const char* component); + + /// info logs a message from component with Severity::info. + void info(const char* message, const char* component); + + /// error logs a message from component with Severity::error. + void error(const char* message, const char* component); + + /// log handles the incoming log message originating from component. + /// Implementation should handle the case of component being a nullptr + /// gracefully. + virtual void log(Severity severity, const char* message, const char* component) = 0; + + /// should_log should return true if 'message' with 'severity' originating from + /// 'component' should be logged. + /// + /// Implementations should handle the case of either message or component being nullptr + /// gracefully. + virtual bool should_log(Severity severity, const char* message, const char* component) = 0; + + protected: + Logger() = default; +}; + +/// operator< returns true iff the numeric value of lhs < rhs. +bool operator<(Logger::Severity lhs, Logger::Severity rhs); + +/// operator>> parses severity from in. +std::istream& operator>>(std::istream& in, Logger::Severity& severity); + +/// create_default_logger returns a Logger implementation writing +/// log messages to 'out'. +std::shared_ptr create_default_logger(std::ostream& out = std::cerr); + +/// create_filtering_logger returns a logger that filters out log entries +/// with a severity smaller than the configurated severity. +std::shared_ptr create_filtering_logger(Logger::Severity severity, const std::shared_ptr& logger); + +/// create_null_logger returns a logger that does the equivalent of +/// > /dev/null. +std::shared_ptr create_null_logger(); + +} // namespace airmap + +#endif // AIRMAP_LOGGER_H_ \ No newline at end of file diff --git a/libs/airmapd/include/airmap/monitor/README.md b/libs/airmapd/include/airmap/monitor/README.md new file mode 100644 index 0000000000000000000000000000000000000000..567f071d3428d30a7f657e750d9810ddb55cba13 --- /dev/null +++ b/libs/airmapd/include/airmap/monitor/README.md @@ -0,0 +1,41 @@ +# AirMap Monitor Service {#monitord} + +The AirMap monitor service monitors the state of vehicles and takes +action based on changes to this state: + + - when the state of a vehicle changes to active: + - create a flight with the AirMap services + - start flight communications + - transmit telemetry updates to AirMap + - receive updates for manned and unmanned aerial traffic relevant to a flight + - when the state of a vehicle changes to inactive: + - stop flight communications + - end flight + +The daemon exposes its functionality via a gRPC interface (see +`${AIRMAPD_ROOT}/interfaces/grpc/airmap/monitor/monitor.proto`). Client +applications can either rely on the C++-API avaiable in +`${AIRMAPD_ROOT}/include/airmap/monitor/client.h` or rely on the gRPC +ecosystem to easily connect to the daemon in their choice of language +and runtime. Please see `${AIRMAPD_ROOT/examples/monitor/client.cpp` for +an example of using the C++-API. The following diagram summarizes the overall setup: + +![monitord](doc/images/monitord.png) + +# Service Configuration + +The service is executed with the following command: + +``` +$ airmap daemon +``` + +Please note that the service needs exactly one MavLink endpoint to be configured on the command line. +The following endpoint types are supported: + - TCP: Provide `--tcp-endpoint-ip=IP` and `--tcp-endpoint-port=PORT` to `airmap daemon`. + - UDP: Provide `--udp-endpoint-port=PORT` to `airmap daemon`. + - Serial: Provide `--serial-device=PATH/TO/DEVICE` to `airmap daemon`. + +The gRPC endpoint exported by the service can be specified with `--grpc-endpoint=ENDPOINT`, defaulting to `0.0.0.0:9090`. +The overall daemon configuration for accessing the AirMap services can be specified with `--config-file=PATH/TO/CONFIG/FILE`. +By default, the config file is expected in `~/.config/airmap/production/config.json`. \ No newline at end of file diff --git a/libs/airmapd/include/airmap/monitor/client.h b/libs/airmapd/include/airmap/monitor/client.h new file mode 100644 index 0000000000000000000000000000000000000000..3d7bc7ca355c6bc2944d995fa09f07bd198a0f74 --- /dev/null +++ b/libs/airmapd/include/airmap/monitor/client.h @@ -0,0 +1,72 @@ +#ifndef AIRMAP_MONITOR_CLIENT_H_ +#define AIRMAP_MONITOR_CLIENT_H_ + +#include +#include +#include + +#include +#include + +namespace airmap { +/// namespace monitor bundles up types and functions to +/// interact with the AirMap monitor daemon. +namespace monitor { + +/// Client provides access to the AirMap monitor service. +class Client : DoNotCopyOrMove { + public: + /// Configuration bundles up creation-time parameters of a Client. + struct Configuration { + std::string endpoint; ///< The remote endpoint hosting the service. + std::shared_ptr logger; ///< The logger instance. + }; + + /// Updates models updates delivered to clients. + struct Update { + std::vector traffic; ///< Traffic updates. + }; + + /// UpdateStream abstracts a source of incoming updates. + class UpdateStream : DoNotCopyOrMove { + public: + /// Reveiver models an entity interested in receiving updates. + class Receiver : DoNotCopyOrMove { + public: + /// handle_update is invoked for every update sent out by the service. + virtual void handle_update(const Update& update) = 0; + }; + + /// subscribe connects 'receiver' to the stream of updates. + virtual void subscribe(const std::shared_ptr& receiver) = 0; + + /// unsubscribe disconnects 'receiver' from the stream of updates. + virtual void unsubscribe(const std::shared_ptr& receiver) = 0; + + protected: + UpdateStream() = default; + }; + + /// ConnectToUpdates bundles up types for calls to Client::connect_to_updates. + struct ConnectToUpdates { + /// Result models the outcome of calling Client::connect_to_updates. + using Result = Outcome, Error>; + /// Callback models the async receiver for a call to Client::connect_to_updates. + using Callback = std::function; + }; + + /// connect_to_updates connects to incoming updates. + virtual void connect_to_updates(const ConnectToUpdates::Callback& cb) = 0; + + protected: + Client() = default; +}; + +} // namespace monitor +} // namespace airmap + +/// @example monitor/client.cpp +/// Illustrates how to use airmap::monitor::Client to connect +/// to an AirMap monitor instance. + +#endif // AIRMAP_MONITOR_CLIENT_H_ \ No newline at end of file diff --git a/libs/airmapd/include/airmap/optional.h b/libs/airmapd/include/airmap/optional.h new file mode 100644 index 0000000000000000000000000000000000000000..f66f6f6fc00cc5faacb5ccf0313b23d13185260d --- /dev/null +++ b/libs/airmapd/include/airmap/optional.h @@ -0,0 +1,138 @@ +#ifndef AIRMAP_OPTIONAL_H_ +#define AIRMAP_OPTIONAL_H_ + +#include +#include + +namespace airmap { + +/// Optional manages an optional contained value of type T. +template +class Optional { + public: + /// Optional initializes a new instance with no contained value. + Optional() : has_value{false} { + } + + /// Optional initializes a new instance with 'other'. + Optional(const Optional& other) : has_value{other.has_value} { + if (has_value) + new (&storage.value) T(other.storage.value); + } + + /// Optional initializes a new instance with 'other'. + Optional(Optional&& other) : has_value{other.has_value} { + if (has_value) + new (&storage.value) T(other.storage.value); + } + + /// Optional initializes a new instance with 'value'. + Optional(const T& value) : has_value{true} { + new (&storage.value) T(value); + } + + /// Optional initializes a new instance with 'value'. + Optional(T&& value) : has_value{true} { + new (&storage.value) T(value); + } + + /// ~Optional cleans up the instance and calls the destructor + /// of the contained value if one is set. + ~Optional() { + reset(); + } + + /// @cond + Optional& operator=(const Optional& rhs) { + if (rhs.has_value) + set(rhs.storage.value); + else + reset(); + + return *this; + } + + Optional& operator=(const T& rhs) { + set(rhs); + return *this; + } + + Optional& operator=(Optional&& rhs) { + if (rhs.has_value) + set(rhs.storage.value); + else + reset(); + + return *this; + } + + bool operator==(const Optional& rhs) const { + if (has_value != rhs.has_value) + return false; + + return has_value && (storage.value == rhs.storage.value); + } + /// @endcond + + /// operator bool returns true if this instance contains a value. + explicit operator bool() const { + return has_value; + } + + /// get returns an immutable reference to the contained value. + /// If no value is contained in this instance, the result of the call is undefined. + const T& get() const { + return storage.value; + } + + /// get returns an immutable reference to the contained value. + /// If no value is contained in this instance, the result of the call is undefined. + T& get() { + return storage.value; + } + + /// set adjusts the contained value to 'value'. + void set(const T& value) { + reset(); + + has_value = true; + new (&storage.value) T(value); + } + + /// reset frees up any contained value if one is set. + /// After this call has completed, no value is contained in this Optional instance. + void reset() { + if (has_value) + (&storage.value)->~T(); + has_value = false; + } + + private: + bool has_value; + union Storage { + Storage() { + } + ~Storage() { + } + T value; + } storage; +}; + +/// operator<< inserts value into out. +template +inline std::ostream& operator<<(std::ostream& out, const Optional& value) { + if (value) + out << value.get(); + else + out << "not set"; + return out; +} + +/// @cond +template +using Required = Optional; +/// @endcond + +} // namespace airmap + +#endif // AIRMAP_OPTIONAL_H_ diff --git a/libs/airmapd/include/airmap/outcome.h b/libs/airmapd/include/airmap/outcome.h new file mode 100644 index 0000000000000000000000000000000000000000..1b62d27e1a615df603a1dc8fb94cca414ad97002 --- /dev/null +++ b/libs/airmapd/include/airmap/outcome.h @@ -0,0 +1,170 @@ +#ifndef AIRMAP_OUTCOME_H_ +#define AIRMAP_OUTCOME_H_ + +#include + +namespace airmap { + +/// Outcome models a return value from a function XOR an error object +/// describing the error condition if no value can be returned. +template +class Outcome { + public: + /// @cond + static_assert(not std::is_same::value, "Value and Error must not be the same type"); + static_assert(std::is_copy_constructible::value && std::is_move_constructible::value, + "Value must be copy- and move-constructible"); + static_assert(std::is_copy_constructible::value && std::is_move_constructible::value, + "Error must be copy- and move-constructible"); + /// @endcond + + /// Outcome initializes a new instance with value. + explicit Outcome(const Value& value) : type{Type::value} { + new (&data.value) Value{value}; + } + + /// Outcome initializes a new instance with error. + explicit Outcome(const Error& error) : type{Type::error} { + new (&data.error) Error{error}; + } + + /// Outcome initializes a new instance with the value or error of 'other'. + Outcome(const Outcome& other) : type{other.type} { + switch (type) { + case Type::error: + new (&data.error) Error{other.data.error}; + break; + case Type::value: + new (&data.value) Value{other.data.value}; + break; + } + } + + /// Outcome initializes a new instance with the value or error of 'other'. + Outcome(Outcome&& other) : type{other.type} { + switch (type) { + case Type::error: + new (&data.error) Error{other.data.error}; + break; + case Type::value: + new (&data.value) Value{other.data.value}; + break; + } + } + + /// Outcome assigns the value or error contained in 'other' to this instance. + Outcome& operator=(const Outcome& other) { + switch (type) { + case Type::error: { + (&data.error)->~Error(); + break; + } + case Type::value: { + (&data.value)->~Value(); + break; + } + } + + type = other.type; + + switch (type) { + case Type::error: { + new (&data.error) Error{other.data.error}; + break; + } + case Type::value: { + new (&data.value) Value{other.data.value}; + break; + } + } + + return *this; + } + + /// Outcome assigns the value or error contained in 'other' to this instance. + Outcome& operator=(Outcome&& other) { + switch (type) { + case Type::error: { + (&data.error)->~Error(); + break; + } + case Type::value: { + (&data.value)->~Value(); + break; + } + } + + type = other.type; + + switch (type) { + case Type::error: { + new (&data.error) Error{other.data.error}; + break; + } + case Type::value: { + new (&data.value) Value{other.data.value}; + break; + } + } + + return *this; + } + + /// ~Outcome frees up the contained error or value contained in this instance. + ~Outcome() { + switch (type) { + case Type::error: + data.error.~Error(); + break; + case Type::value: + data.value.~Value(); + break; + } + } + + /// operator bool returns true if a value is contained in this instance. + explicit operator bool() const { + return !has_error(); + } + + /// has_error returns true if this instance carries an error. + inline bool has_error() const { + return type == Type::error; + } + + /// has_value returns true if this instance carries a value. + inline bool has_value() const { + return type == Type::value; + } + + /// error returns an immutable reference to the Error contained in this instance. + /// The result of this call is undefined if has_error() returns false. + inline const Error& error() const { + return data.error; + } + + /// value returns an immutable reference to the Value contained in this instance. + /// The result of this call is undefined if has_value() returns false. + inline const Value& value() const { + return data.value; + } + + private: + enum class Type { value, error }; + + Type type; + union Data { + Data() : value{} { + } + + ~Data() { + } + + Value value; + Error error; + } data; +}; + +} // namespace airmap + +#endif // AIRMAP_OUTCOME_H_ diff --git a/libs/airmapd/include/airmap/pilot.h b/libs/airmapd/include/airmap/pilot.h new file mode 100644 index 0000000000000000000000000000000000000000..9948f59c60aae0c49fd04f44dca1fdbfc88a6700 --- /dev/null +++ b/libs/airmapd/include/airmap/pilot.h @@ -0,0 +1,61 @@ +#ifndef AIRMAP_PILOT_H_ +#define AIRMAP_PILOT_H_ + +#include +#include +#include + +#include + +#include +#include + +namespace airmap { + +/// Pilot bundles up all properties describing a pilot on the AirMap services. +struct Pilot { + /// Aircraft describes a vehicle owned by a Pilot. + struct Aircraft { + std::string id; ///< The unique id of the vehicle in the context of AirMap. + std::string nick_name; ///< The human-readable nickname of the vehicle. + airmap::Aircraft model; ///< The model of the aircraft. + DateTime created_at; ///< Timestamp marking the creation of the device in the AirMap system. + }; + + std::string id; ///< The unique id of the pilot in the context of AirMap. + std::string first_name; ///< The first name of the pilot. + std::string last_name; ///< The last name of the pilot. + std::string user_name; ///< The AirMap username of this pilot. + Optional picture_url; ///< The URL of a picture showing the pilot. + + /// VerificationStatus summarizes the + /// status of contact detail verification. + struct VerificationStatus { + bool email; ///< true iff the email address of the pilot has been verified + bool phone; ///< true iff the phone number of the pilot has been verified + } verification_status; + + /// Statistics about the pilot and her + /// flight experience as recorded by the + /// AirMap services. + struct Statistics { + struct Flight { + std::uint64_t total; ///< The total number of flights + DateTime last_flight_time; ///< Date and time of the last flight + } flight; ///< Statistical details about flights conducted by a pilot. + struct Aircraft { + std::uint64_t total; ///< The total number of aircrafts + } aircraft; ///< Statistical details about aircrafts owned by a pilot + } statistics; + + /// App- and user-specific metadata. + struct Metadata { + std::map app; ///< App-specific meta-data. + std::map user; ///< User-specific meta-data. + } metadata; ///< Metadata associated with a pilot. + DateTime created_at; ///< Timestamp of the creation of this pilot in the AirMap system. +}; + +} // namespace airmap + +#endif // AIRMAP_PILOT_H_ diff --git a/libs/airmapd/include/airmap/pilots.h b/libs/airmapd/include/airmap/pilots.h new file mode 100644 index 0000000000000000000000000000000000000000..a9ae9b8b927a5e7ca710677c25ed5b0bdc1e1bcc --- /dev/null +++ b/libs/airmapd/include/airmap/pilots.h @@ -0,0 +1,241 @@ +#ifndef AIRMAP_PILOTS_H_ +#define AIRMAP_PILOTS_H_ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace airmap { + +/// Pilots provides functionality to manage (the authorized) pilot. +class Pilots : DoNotCopyOrMove { + public: + /// Exclude enumerates fields that can be excluded when querying pilot and aircraft properties. + enum class Exclude { + aircraft = 1 << 0, ///< Exclude aircraft data from results. + user_metadata = 1 << 1, ///< Exclude user-specific metadata from results. + app_metadata = 1 << 2, ///< Exclude app-specific metadata from results. + authorized_apps = 1 << 3 ///< Exclude list of authorized apps from results. + }; + + /// Authenticated bundles up types to ease interaction + /// with Pilots::authenticated. + struct Authenticated { + /// Parameters bundles up input parameters. + struct Parameters { + std::string authorization; ///< Authorization token obtained by logging in to the AirMap services. + Optional exclude{}; ///< Exclude these fields from results. + bool retrieve_statistics{false}; ///< If true, statistics about flights and aircrafts are requested. + }; + + /// Result models the outcome of calling Pilots::authenticated. + using Result = Outcome; + /// Callback describes the function signature of the callback that is + /// invoked when a call to Pilots::authenticated finishes. + using Callback = std::function; + }; + + /// ForId bundles up types to ease interaction + /// with Pilots::for_id. + struct ForId { + /// Parameters bundles up input parameters. + struct Parameters { + std::string authorization; ///< Authorization token obtained by logging in to the AirMap services. + std::string id; ///< Searches for the specific pilot with this id. + Optional exclude{}; ///< Exclude these fields from results. + bool retrieve_statistics{false}; ///< If true, statistics about flights and aircrafts are requested. + }; + + /// Result models the outcome of calling Pilots::for_id. + using Result = Outcome; + /// Callback describes the function signature of the callback that is + /// invoked when a call to Pilots::for_id finishes. + using Callback = std::function; + }; + + /// UpdateForId bundles up types to ease interaction + /// with Pilots::update_for_id. + struct UpdateForId { + /// Parameters bundles up input parameters. + struct Parameters { + std::string authorization; ///< Authorization token obtained by logging in to the AirMap services. + std::string id; ///< Updates the specific pilot with this id. + std::string first_name; ///< The first name of the pilot. + std::string last_name; ///< The last name of the pilot. + std::string user_name; ///< The AirMap username of this pilot. + std::string phone; ///< The phone number of the pilot. + std::map app_metadata; ///< App-specific metadata associated to the pilot. + std::map user_metadata; ///< User-specific metadata associated to the pilot. + }; + + /// Result models the outcome of calling Pilots::update_for_id. + using Result = Outcome; + /// Callback describes the function signature of the callback that is + /// invoked when a call to Pilots::update_for_id finishes. + using Callback = std::function; + }; + + /// StartVerifyPilotPhoneForId bundles up types to ease interaction + /// with Pilots::start_verify_pilot_phone_for_id. + struct StartVerifyPilotPhoneForId { + /// Parameters bundles up input parameters. + struct Parameters { + std::string authorization; ///< Authorization token obtained by logging in to the AirMap services. + std::string id; ///< Verifies the phone number for the pilot with this id. + }; + + struct Empty {}; + + /// Result models the outcome of calling Pilots::start_verify_pilot_phone_for_id. + using Result = Outcome; + /// Callback describes the function signature of the callback that is + /// invoked when a call to Pilots::start_verify_pilot_phone_for_id finishes. + using Callback = std::function; + }; + + /// FinishVerifyPilotPhoneForId bundles up types to ease interaction + /// with Pilots::finish_verify_pilot_phone_for_id. + struct FinishVerifyPilotPhoneForId { + /// Parameters bundles up input parameters. + struct Parameters { + std::string authorization; ///< Authorization token obtained by logging in to the AirMap services. + std::string id; ///< Verifies the phone number for the pilot with this id. + std::uint32_t token; ///< The token that was received on the pilot's phone. + }; + + struct Empty {}; + + /// Result models the outcome of calling Pilots::finish_verify_pilot_phone_for_id. + using Result = Outcome; + /// Callback describes the function signature of the callback that is + /// invoked when a call to Pilots::finish_verify_pilot_phone_for_id finishes. + using Callback = std::function; + }; + + /// Aircrafts bundles up types to ease interaction + /// with Pilots::aircrafts. + struct Aircrafts { + /// Parameters bundles up input parameters. + struct Parameters { + std::string authorization; ///< Authorization token obtained by logging in to the AirMap services. + std::string id; ///< Lists all aircrafts owned by the pilot with this id. + }; + + /// Result models the outcome of calling Pilots::aircrafts. + using Result = Outcome, Error>; + /// Callback describes the function signature of the callback that is + /// invoked when a call to Pilots::aircrafts finishes. + using Callback = std::function; + }; + + /// AddAircraft bundles up types to ease interaction + /// with Pilots::add_aircraft. + struct AddAircraft { + /// Parameters bundles up input parameters. + struct Parameters { + std::string authorization; ///< Authorization token obtained by logging in to the AirMap services. + std::string id; ///< Adds an aircraft for the pilot with this id. + std::string model_id; ///< The id of the model of the aircraft. + std::string nick_name; ///< The nickname of the aircraft. + }; + + /// Result models the outcome of calling Pilots::add_aircraft. + using Result = Outcome; + /// Callback describes the function signature of the callback that is + /// invoked when a call to Pilots::add_aircraft finishes. + using Callback = std::function; + }; + + /// DeleteAircraft bundles up types to ease interaction + /// with Pilots::delete_aircraft. + struct DeleteAircraft { + /// Parameters bundles up input parameters. + struct Parameters { + std::string authorization; ///< Authorization token obtained by logging in to the AirMap services. + std::string id; ///< Deletes an aircraft for the pilot with this id. + std::string aircraft_id; ///< Deletes the specific aircraft with this id. + }; + + struct Empty {}; + + /// Result models the outcome of calling Pilots::delete_aircraft. + using Result = Outcome; + /// Callback describes the function signature of the callback that is + /// invoked when a call to Pilots::delete_aircraft finishes. + using Callback = std::function; + }; + + /// UpdateAircraft bundles up types to ease interaction + /// with Pilots::update_aircraft. + struct UpdateAircraft { + /// Parameters bundles up input parameters. + struct Parameters { + std::string authorization; ///< Authorization token obtained by logging in to the AirMap services. + std::string id; ///< Updates an aircraft for the pilot with this id. + std::string aircraft_id; ///< Update the specific aircraft with this id. + std::string nick_name; ///< The new nick name for the aircraft. + }; + + struct Empty {}; + /// Result models the outcome of calling Pilots::update_aircraft. + using Result = Outcome; + /// Callback describes the function signature of the callback that is + /// invoked when a call to Pilots::update_aircraft finishes. + using Callback = std::function; + }; + + /// current_user queries the AirMap services for the pilot profile + /// connected to the authenticated user, reporting results to 'cb'. + virtual void authenticated(const Authenticated::Parameters& parameters, const Authenticated::Callback& cb) = 0; + + /// for_id queries the AirMap services for the pilot profile + /// with a given id, reporting results to 'cb'. + virtual void for_id(const ForId::Parameters& parameters, const ForId::Callback& cb) = 0; + + /// update_for_id updates the pilot profile specified + // by Parameters::id, reporting results to 'cb'. + virtual void update_for_id(const UpdateForId::Parameters& parameters, const UpdateForId::Callback& cb) = 0; + + /// start_verify_pilot_phone_for_id sends a verification token to the phone + /// number stored in the pilot profile, reporting results to 'cb'. + virtual void start_verify_pilot_phone_for_id(const StartVerifyPilotPhoneForId::Parameters& parameters, + const StartVerifyPilotPhoneForId::Callback& cb) = 0; + + /// finish_verify_pilot_phone_for_id responds to a verification request by + /// sending back the token sent to the pilot's phone, reporting results to 'cb'. + virtual void finish_verify_pilot_phone_for_id(const FinishVerifyPilotPhoneForId::Parameters& parameters, + const FinishVerifyPilotPhoneForId::Callback& cb) = 0; + + /// aircrafts queries the list of aircrafts owned by a pilot, reporting results to 'cb'. + virtual void aircrafts(const Aircrafts::Parameters& parameters, const Aircrafts::Callback& cb) = 0; + + /// add_aircraft associates a new aircraft with a pilot, reporting results to 'cb'. + virtual void add_aircraft(const AddAircraft::Parameters& parameters, const AddAircraft::Callback& cb) = 0; + + /// delete_aircraft removes an aircraft from a pilot profile, reporting results to 'cb'. + virtual void delete_aircraft(const DeleteAircraft::Parameters& parameters, const DeleteAircraft::Callback& cb) = 0; + + /// update_aircraft updates the properties of an aircraft associated with a pilot, reporting results to 'cb'. + virtual void update_aircraft(const UpdateAircraft::Parameters& parameters, const UpdateAircraft::Callback& cb) = 0; + + protected: + Pilots() = default; +}; + +/// @cond +Pilots::Exclude operator|(Pilots::Exclude, Pilots::Exclude); +Pilots::Exclude operator&(Pilots::Exclude, Pilots::Exclude); +std::ostream& operator<<(std::ostream& out, Pilots::Exclude exclude); +/// @endcond + +} // namespace airmap + +#endif // AIRMAP_PILOTS_H_ diff --git a/libs/airmapd/include/airmap/qt/client.h b/libs/airmapd/include/airmap/qt/client.h new file mode 100644 index 0000000000000000000000000000000000000000..913c8552cdbc7ccd76c8348587de90939297ee1e --- /dev/null +++ b/libs/airmapd/include/airmap/qt/client.h @@ -0,0 +1,63 @@ +#ifndef AIRMAP_QT_CLIENT_H_ +#define AIRMAP_QT_CLIENT_H_ + +#include +#include +#include +#include +#include + +#include + +namespace airmap { +/// @namespace namespace qt bundles up types and functions that help with integrating AirMap functionality +/// into Qt-based applications and libraries. +namespace qt { + +/// Client implements the airmap::Client interface, bridging over between +/// the Qt event loop and the native event loop of the native airmap::Client. +/// +/// All callback invocations that might happen in the context of a Client instance +/// are dispatched to the Qt applications' main thread. +class Client : public QObject, public airmap::Client { + public: + using CreateResult = Outcome; + using CreateCallback = std::function; + + /// create creates a new Client instance with parent 'parent', logging to 'logger', using the config + /// 'configuration'. The result of the request is reported to 'cb', on the thread that issued the create request. + /// + /// Please note that this function must be called on Qt's main thread as event dispatching between different + /// event loops to the Qt world is set up here. + static void create(const Client::Configuration& configuration, const std::shared_ptr& logger, QObject* parent, + const CreateCallback& cb); + + ~Client(); + + // From airmap::Client + Authenticator& authenticator() override; + Aircrafts& aircrafts() override; + Airspaces& airspaces() override; + FlightPlans& flight_plans() override; + Flights& flights() override; + Pilots& pilots() override; + RuleSets& rulesets() override; + Status& status() override; + Telemetry& telemetry() override; + Traffic& traffic() override; + + private: + /// @cond + struct Private; + Client(std::unique_ptr&& d, QObject* parent); + std::unique_ptr d_; + /// @endcond +}; + +} // namespace qt +} // namespace airmap + +/// @example qt/client.cpp +/// Illustrates how to use airmap::qt::Client, airmap::qt::DispatchingLogger and airmap::qt::Logger. + +#endif // AIRMAP_QT_CLIENT_H_ diff --git a/libs/airmapd/include/airmap/qt/logger.h b/libs/airmapd/include/airmap/qt/logger.h new file mode 100644 index 0000000000000000000000000000000000000000..c06e084faa4ebd182965caf8b112cf91c71dfdf9 --- /dev/null +++ b/libs/airmapd/include/airmap/qt/logger.h @@ -0,0 +1,56 @@ +#ifndef AIRMAP_QT_LOGGER_H_ +#define AIRMAP_QT_LOGGER_H_ + +#include + +#include + +#include + +namespace airmap { +namespace qt { + +/// Logger is an airmap::Logger implementation that uses to +/// Qt's logging facilities. +class Logger : public airmap::Logger { + public: + /// logging_category returns a QLoggingCategory instance + /// that enables calling code to fine-tune logging behavior of a Logger instance. + QLoggingCategory& logging_category(); + + /// Logger initializes a new instance. + Logger(); + /// ~Logger cleans up all resources held by a Logger instance. + ~Logger(); + + // From airmap::Logger + void log(Severity severity, const char* message, const char* component) override; + bool should_log(Severity severity, const char* message, const char* component) override; + + private: + struct Private; + std::unique_ptr d_; +}; + +/// DispatchingLogger is an airmap::Logger implementation that dispatches to Qt's main +/// event loop for logger invocation +class DispatchingLogger : public airmap::Logger { + public: + /// DispatchingLogger initializes a new instance with 'next'. + DispatchingLogger(const std::shared_ptr& next); + /// ~DispatchingLogging cleans up all resources held a DispatchingLogger instance. + ~DispatchingLogger(); + + // From airmap::Logger + void log(Severity severity, const char* message, const char* component) override; + bool should_log(Severity severity, const char* message, const char* component) override; + + private: + struct Private; + std::unique_ptr d_; +}; + +} // namespace qt +} // namespace airmap + +#endif // AIRMAP_QT_LOGGER_H_ diff --git a/libs/airmapd/include/airmap/qt/types.h b/libs/airmapd/include/airmap/qt/types.h new file mode 100644 index 0000000000000000000000000000000000000000..db789b65c61b6847cd6cdad4ef0a619e948b0f19 --- /dev/null +++ b/libs/airmapd/include/airmap/qt/types.h @@ -0,0 +1,66 @@ +#ifndef AIRMAP_QT_TYPES_H_ +#define AIRMAP_QT_TYPES_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +Q_DECLARE_METATYPE(airmap::Aircraft) +Q_DECLARE_METATYPE(airmap::Airspace) +Q_DECLARE_METATYPE(airmap::Credentials) +Q_DECLARE_METATYPE(airmap::DateTime) +Q_DECLARE_METATYPE(airmap::Error) +Q_DECLARE_METATYPE(airmap::FlightPlan) +Q_DECLARE_METATYPE(airmap::Flight) +Q_DECLARE_METATYPE(airmap::Geometry) +Q_DECLARE_METATYPE(airmap::Pilot) +Q_DECLARE_METATYPE(airmap::Rule) +Q_DECLARE_METATYPE(airmap::RuleSet) +Q_DECLARE_METATYPE(airmap::RuleSet::Rule) +Q_DECLARE_METATYPE(airmap::Status::Advisory) +Q_DECLARE_METATYPE(airmap::Status::Wind) +Q_DECLARE_METATYPE(airmap::Status::Weather) +Q_DECLARE_METATYPE(airmap::Status::Report) +Q_DECLARE_METATYPE(airmap::Telemetry::Position) +Q_DECLARE_METATYPE(airmap::Telemetry::Speed) +Q_DECLARE_METATYPE(airmap::Telemetry::Attitude) +Q_DECLARE_METATYPE(airmap::Telemetry::Barometer) +Q_DECLARE_METATYPE(airmap::Optional) +Q_DECLARE_METATYPE(airmap::Token::Type) +Q_DECLARE_METATYPE(airmap::Token::Anonymous) +Q_DECLARE_METATYPE(airmap::Token::OAuth) +Q_DECLARE_METATYPE(airmap::Token::Refreshed) +Q_DECLARE_METATYPE(airmap::Token) +Q_DECLARE_METATYPE(airmap::Traffic::Update::Type) +Q_DECLARE_METATYPE(airmap::Traffic::Update) +Q_DECLARE_METATYPE(airmap::Version) + +namespace airmap { +namespace qt { + +/// register_types makes airmap::* types known to the Qt type system. +/// +/// This function has to be called at least once to be able to use airmap::* +/// types in queued signal-slot connections. +void register_types(); + +} // namespace qt +} // namespace airmap + +#endif // AIRMAP_QT_TYPES_H_ diff --git a/libs/airmapd/include/airmap/rule.h b/libs/airmapd/include/airmap/rule.h new file mode 100644 index 0000000000000000000000000000000000000000..05b95766167dd9a5ea0c5daa74e23c9fcc6c250e --- /dev/null +++ b/libs/airmapd/include/airmap/rule.h @@ -0,0 +1,23 @@ +#ifndef AIRMAP_RULE_H_ +#define AIRMAP_RULE_H_ + +#include + +namespace airmap { + +struct Rule { + // TODO(tvoss): Fill in values once schema is known. + enum class Type {}; + Type type; + std::string id; + std::string name; + std::string description; + std::string jurisdiction; + // TODO(tvoss): Add requirements here. +}; + +bool operator==(const Rule& lhs, const Rule& rhs); + +} // namespace airmap + +#endif // AIRMAP_RULE_H_ diff --git a/libs/airmapd/include/airmap/ruleset.h b/libs/airmapd/include/airmap/ruleset.h new file mode 100644 index 0000000000000000000000000000000000000000..8f6af2dec5d003af4fe228c39bb63c897bdb5107 --- /dev/null +++ b/libs/airmapd/include/airmap/ruleset.h @@ -0,0 +1,155 @@ +#ifndef AIRMAP_RULESET_H_ +#define AIRMAP_RULESET_H_ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace airmap { + +/// RuleSet bundles together properties describing a ruleset. +struct RuleSet { + // Feature describes a flight feature modelled by a particular rule. + struct Feature; + /// Rule models the individual result of a Rule evaluation. + struct Rule { + /// Status enumerates all known status codes of a rule. + enum class Status { + unknown, ///< The status of the rule is unknown. + conflicting, ///< The rule is conflicting. + not_conflicting, ///< The rule is not conflicting, all good to go. + missing_info, ///< The evaluation requires further information. + informational ///< The rule is of informational nature. + }; + + Status status; ///< The status of the rule. + std::string short_text; ///< The human-readable short summary of the rule. + std::string description; ///< The human-readable description of the rule. + std::int32_t display_order; ///< An indicator for ordering the ruleset. + std::vector features; ///< The features modelled by the rule. + }; + + /// SelectionType enumerates all known types for a RuleSet. + enum class SelectionType { + pickone, ///< One rule from the overall set needs to be picked. + required, ///< Satisfying the RuleSet is required. + optional ///< Satisfying the RuleSet is not required. + }; + + /// Jurisdiction describes a jurisdiction in a geographical scope. + struct Jurisdiction { + /// Region enumerates all known regional scopes of a jurisdiction. + enum class Region { + national, ///< The jurisdiction applies nation-wide. + state, ///< The jurisdiction applies to a specific state. + county, ///< The jurisdiction applies to a specific county. + city, ///< The jurisdiction applies to a specific city. + local ///< The jurisdiction only applies locally. + }; + /// Id models a unique identifier for a jurisdiction in the context of AirMap. + using Id = std::uint64_t; + + Id id; ///< The unique id. + std::string name; ///< The human-readable name. + Region region; ///< The regional scope. + }; + + /// Id models a unique identifier for a briefing in the context of AirMap. + using Id = std::string; + + Id id; ///< The unique id. + SelectionType selection_type; ///< The selection type. + std::string name; ///< The human-readable name. + std::string short_name; ///< The human-readable short name. + std::string description; ///< The human readable description. + bool is_default; + Jurisdiction jurisdiction; ///< The jurisdiction. + std::vector airspace_types; ///< The layers that a RuleSet instance applies to. + std::vector rules; ///< The individual rules in the set. + + struct Feature { + enum class Type { unknown, boolean, floating_point, string }; + enum class Measurement { unknown, speed, weight, distance }; + enum class Unit { unknown, kilograms, meters, meters_per_sec }; + + class Value { + public: + Value(); + explicit Value(bool value); + explicit Value(double value); + explicit Value(const std::string& value); + Value(const Value& other); + Value(Value&& other); + ~Value(); + Value& operator=(const Value& other); + Value& operator=(Value&& other); + + Type type() const; + bool boolean() const; + double floating_point() const; + const std::string& string() const; + + private: + Value& construct(const Value& other); + Value& construct(Value&& other); + Value& construct(bool value); + Value& construct(double value); + Value& construct(const std::string& value); + Value& destruct(); + + Type type_; + union Detail { + Detail(); + ~Detail(); + + bool b; + double d; + std::string s; + } detail_; + }; + + Optional value(bool b) const; + Optional value(double d) const; + Optional value(const std::string& s) const; + + std::int32_t id{-1}; + std::string name; + Optional code; + std::string description; + RuleSet::Rule::Status status; + Type type{Type::unknown}; + Measurement measurement{Measurement::unknown}; + Unit unit{Unit::unknown}; + }; +}; + +std::ostream& operator<<(std::ostream& out, RuleSet::Feature::Type type); +std::istream& operator>>(std::istream& in, RuleSet::Feature::Type& type); + +std::ostream& operator<<(std::ostream& out, RuleSet::Feature::Measurement measurement); +std::istream& operator>>(std::istream& in, RuleSet::Feature::Measurement& measurement); + +std::ostream& operator<<(std::ostream& out, RuleSet::Feature::Unit unit); +std::istream& operator>>(std::istream& in, RuleSet::Feature::Unit& unit); + +std::ostream& operator<<(std::ostream& out, RuleSet::Jurisdiction::Region region); +std::istream& operator>>(std::istream& in, RuleSet::Jurisdiction::Region& region); + +std::ostream& operator<<(std::ostream& out, RuleSet::SelectionType type); +std::istream& operator>>(std::istream& in, RuleSet::SelectionType& type); + +std::ostream& operator<<(std::ostream& out, RuleSet::Rule::Status status); +std::istream& operator>>(std::istream& in, RuleSet::Rule::Status& status); + +} // namespace airmap + +#endif // AIRMAP_RULESET_H_ diff --git a/libs/airmapd/include/airmap/rulesets.h b/libs/airmapd/include/airmap/rulesets.h new file mode 100644 index 0000000000000000000000000000000000000000..706bb752e428cbe98240af77aa2501bb3df5f12d --- /dev/null +++ b/libs/airmapd/include/airmap/rulesets.h @@ -0,0 +1,103 @@ +#ifndef AIRMAP_RULESETS_H_ +#define AIRMAP_RULESETS_H_ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace airmap { + +/// RuleSets provides functionality for managing contextual airspace. +class RuleSets : DoNotCopyOrMove { + public: + /// Search bundles up types to ease interaction with + /// RuleSets::search. + struct Search { + struct Parameters { + Required geometry; ///< Search for rulesets intersecting this geometry. + }; + + /// Result models the outcome of calling RuleSets::search. + using Result = Outcome, Error>; + /// Callback describes the function signature of the callback that is invoked + /// when a call to RuleSets::search finishes. + using Callback = std::function; + }; + + /// ForId bundles up types to ease interaction with + /// RuleSets::for_id. + struct ForId { + struct Parameters { + RuleSet::Id id; ///< Search for the ruleset with this id. + }; + + /// Result models the outcome of calling RuleSets::for_id. + using Result = Outcome; + /// Callback describes the function signature of the callback that is invoked + /// when a call to RuleSets::for_id finishes. + using Callback = std::function; + }; + + /// FetchRules bundles up types to ease interaction with + /// RuleSets::fetch_rules. + struct FetchRules { + struct Parameters { + Optional rulesets; ///< Fetch rules which apply to these rulesets. + }; + + /// Result models the outcome of calling RuleSets::fetch_rules. + using Result = Outcome, Error>; + /// Callback describes the function signature of the callback that is invoked + /// when a call to RuleSets::fetch_rules finishes. + using Callback = std::function; + }; + + /// EvaluateRules bundles up types to ease interaction with + /// RuleSets::evaluate_rulesets. + struct EvaluateRules { + struct Parameters { + Required geometry; ///< Evaluate rulesets intersecting this geometry. + std::unordered_map + features; ///< Additional properties of the planned flight. + Required rulesets; ///< Evaluate these rulesets. + }; + + /// Result models the outcome of calling RuleSets::evaluate_rulesets. + using Result = Outcome; + /// Callback describes the function signature of the callback that is invoked + /// when a call to RuleSets::evaluate_rulesets finishes. + using Callback = std::function; + }; + + /// search queries the AirMap services for detailed information about + /// rulesets identified by geometry and reports back results to 'cb'. + virtual void search(const Search::Parameters& parameters, const Search::Callback& cb) = 0; + + /// for_id queries the AirMap services for detailed information about + /// a ruleset identified by a UUID and reports back results to 'cb'. + virtual void for_id(const ForId::Parameters& parameters, const ForId::Callback& cb) = 0; + + /// fetch_rules fetches rules from the rulesets identified by 'parameters' and + /// reports back results to 'cb'. + virtual void fetch_rules(const FetchRules::Parameters& parameters, const FetchRules::Callback& cb) = 0; + + /// evaluate_rulesets evaluates rulesets and geometry identified by 'parameters' and + /// reports back results to 'cb'. + virtual void evaluate_rulesets(const EvaluateRules::Parameters& parameters, const EvaluateRules::Callback& cb) = 0; + + protected: + /// @cond + RuleSets() = default; + /// @endcond +}; + +} // namespace airmap + +#endif // AIRMAP_RULESETS_H_ diff --git a/libs/airmapd/include/airmap/status.h b/libs/airmapd/include/airmap/status.h new file mode 100644 index 0000000000000000000000000000000000000000..87cc4b5848ae975724ba4709fd2fdc98707ad2ea --- /dev/null +++ b/libs/airmapd/include/airmap/status.h @@ -0,0 +1,106 @@ +#ifndef AIRMAP_STATUS_H_ +#define AIRMAP_STATUS_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace airmap { + +/// Status provides functionality to query airspace and weather information about +/// a geographic area. +class Status : DoNotCopyOrMove { + public: + /// Color enumerates known colors assigned to advisories. + enum class Color { green = 0, yellow = 1, orange = 2, red = 3 }; + + /// Advisory bundles together airspace information and its evaluation in terms + /// good to fly/needs information or feedback/conflict. + struct Advisory { + Airspace airspace; /// The airspace that the advisory refers to. + Color color; /// The evaluation of the airspace. + }; + + /// Wind bundles up attributes describing a wind conditions. + struct Wind { + std::uint32_t heading = 0; ///< The heading in [°]. + std::uint32_t speed = 0; ///< The speed in [°]. + std::uint32_t gusting = 0; + }; + + /// Weather bundles up attributes describing a weather condition. + struct Weather { + std::string condition; ///< The overall weather condition. + std::string icon; ///< The icon or class of icon that should be used for display purposes. + Wind wind; ///< The details about the current wind conditions. + std::int32_t temperature = 0; ///< The temperature in [°C]. + float humidity = 0.0; + std::uint32_t visibility = 0; ///< Visibility in [m]. + std::uint32_t precipitation = 0; ///< The probability of precipitation in [%]. + }; + + /// Report summarizes information about a geographic area. + struct Report { + std::uint32_t max_safe_distance = 0; ///< The distance to the area that is considered safe in [m]. + Color advisory_color; ///< The overall evaluation of all advisories. + std::vector advisories; ///< All relevant advisories. + Weather weather; ///< The weather conditions. + }; + + /// GetStatus bundles up types to ease interaction + /// with Status::get_status*. + struct GetStatus { + /// Parameters bundles up input parameters. + struct Parameters { + Required latitude; ///< The latitude of the center point of the query. + Required longitude; ///< The longitude of the center point of the query. + Optional types; ///< Query status information for these types of airspaces. + Optional ignored_types; ///< Ignore these types of airspaces when querying status information. + Optional weather; ///< If true, weather conditions are included with the status report. + Optional flight_date_time; ///< Time when a flight is going to happen. + Optional geometry; ///< The geometry for the query. + Optional buffer; ///< Buffer around the center point of the query. + }; + /// Result models the outcome of calling Status::get_status*. + using Result = Outcome; + /// Callback describes the function signature of the callback that is + /// invoked when a call to Status::get_status* finishes. + using Callback = std::function; + }; + + /// get_status searches flight advisories for 'parameters' and reports + /// results back to 'cb'. + virtual void get_status_by_point(const GetStatus::Parameters& parameters, const GetStatus::Callback& cb) = 0; + + /// get_status searches flight advisories for 'parameters' and reports + /// results back to 'cb'. + virtual void get_status_by_path(const GetStatus::Parameters& parameters, const GetStatus::Callback& cb) = 0; + + /// get_status searches flight advisories for 'parameters' and reports + /// results back to 'cb'. + virtual void get_status_by_polygon(const GetStatus::Parameters& parameters, const GetStatus::Callback& cb) = 0; + + protected: + /// @cond + Status() = default; + /// @endcond +}; + +/// @cond +std::ostream& operator<<(std::ostream& out, Status::Color color); +std::istream& operator>>(std::istream& in, Status::Color& color); +/// @endcond + +} // namespace airmap + +#endif // AIRMAP_STATUS_H_ diff --git a/libs/airmapd/include/airmap/telemetry.h b/libs/airmapd/include/airmap/telemetry.h new file mode 100644 index 0000000000000000000000000000000000000000..792dc525afe52dc2922ff2b4a68161e53fa9b9c3 --- /dev/null +++ b/libs/airmapd/include/airmap/telemetry.h @@ -0,0 +1,117 @@ +#ifndef AIRMAP_TELEMETRY_H_ +#define AIRMAP_TELEMETRY_H_ + +#include +#include + +#include +#include +#include + +namespace airmap { + +struct Flight; + +/// Telemetry provides functionality to submit telemetry updates to the +/// AirMap services during flight. +class Telemetry : DoNotCopyOrMove { + public: + /// Position describes a timestamped geographical position. + struct Position { + std::uint64_t timestamp; ///< Ingestion timestamp of the update. + double latitude; ///< The latitude of the position [°]. + double longitude; ///< The longitude of the position in [°]. + double altitude_msl; ///< The altitude above mean sea level of the position in [m]. + double altitude_gl; ///< The altitude above ground level of the position in [m]. + double horizontal_accuracy; ///< The horizontal accuracy of the position in [m]. + }; + + /// Speed describes the timestamped 3-dim velocity of a vehicle. + struct Speed { + std::uint64_t timestamp; ///< Ingestion timestamp of the update. + float velocity_x; ///< The velocity of the vehicle in direction of the x axis in [m/s]. + float velocity_y; ///< The velocity of the vehicle in direction of the y axis in [m/s]. + float velocity_z; ///< The velocity of the vehicle in direction of the z axis in [m/s]. + }; + + /// Attitude describes the timestamped 3-dim orientation of a vehicle. + struct Attitude { + std::uint64_t timestamp; ///< Ingestion timestamp of the update. + float yaw; ///< The yaw of the vehicle in [°/s]. + float pitch; ///< The pitch of the vehicle in [°/s]. + float roll; ///< The roll of the vehicle in [°/s]. + }; + + /// Barometer describes the timestamped atmospheric pressurce conditions. + struct Barometer { + std::uint64_t timestamp; ///< Ingestion timestamp of the update. + float pressure; ///< The atmospheric pressure measurement in [Pa]. + }; + + /// @cond + static_assert(std::is_pod::value, "Position must be a POD"); + static_assert(std::is_pod::value, "Speed must be a POD"); + static_assert(std::is_pod::value, "Attitude must be a POD"); + static_assert(std::is_pod::value, "Barometer must be a POD"); + /// @endcond + + /// Update models an update of the current position, speed, attitude or atmospheric pressure + /// measurement/estimate. + class Update { + public: + /// Type enumerates all known update types. + enum class Type : std::uint8_t { + position = 1, ///< The update contains a Position instance. + speed = 2, ///< The update contains a Speed instance. + attitude = 3, ///< The update contains an Attitude instance. + barometer = 4 ///< The update contains a Barometer instance. + }; + + /// Update initializes a new instance with 'position'. + explicit Update(const Position& position); + /// Update initializes a new instance with 'speed'. + explicit Update(const Speed& speed); + /// Update initializes a new instance with 'attitude'. + explicit Update(const Attitude& attitude); + /// Update initializes a new instance with 'barometer'. + explicit Update(const Barometer& barometer); + + /// type returns the Type of the update contained within this instance. + Type type() const; + /// position returns the position update contained within this instance. + /// The behavior is undefined if type() != Type::position. + const Position& position() const; + /// speed returns the speed update contained within this instance. + /// The behavior is undefined if type() != Type::speed. + const Speed& speed() const; + /// attitude returns the attitde update contained within this instance. + /// The behavior is undefined if type() != Type::attitude. + const Attitude& attitude() const; + /// barometer returns the barometer update contained within this instance. + /// The behavior is undefined if type() != Type::barometer. + const Barometer& barometer() const; + + private: + Type type_; + union { + Position position; + Speed speed; + Attitude attitude; + Barometer barometer; + } data_; + }; + + /// submit_updates sends the telemetry data in 'updates' associated to 'flight' to the AirMap + /// services. + virtual void submit_updates(const Flight& flight, const std::string& key, + const std::initializer_list& updates) = 0; + + protected: + /// @cond + Telemetry() = default; + /// @endcond +}; + +} // namespace airmap + +#endif // AIRMAP_TELEMETRY_H_ diff --git a/libs/airmapd/include/airmap/timestamp.h b/libs/airmapd/include/airmap/timestamp.h new file mode 100644 index 0000000000000000000000000000000000000000..938215b42e0f5bb822fbff6fadde795418dd9f52 --- /dev/null +++ b/libs/airmapd/include/airmap/timestamp.h @@ -0,0 +1,13 @@ +#ifndef AIRMAP_TIMESTAMP_H_ +#define AIRMAP_TIMESTAMP_H_ + +#include + +namespace airmap { + +/// Timestamp models a specific point in time. +using Timestamp = DateTime; + +} // namespace airmap + +#endif // AIRMAP_TIMESTAMP_H_ diff --git a/libs/airmapd/include/airmap/token.h b/libs/airmapd/include/airmap/token.h new file mode 100644 index 0000000000000000000000000000000000000000..031d35e5dfe50b179adb6065fb97fe42c89b10cb --- /dev/null +++ b/libs/airmapd/include/airmap/token.h @@ -0,0 +1,115 @@ +#ifndef AIRMAP_TOKEN_H_ +#define AIRMAP_TOKEN_H_ + +#include + +#include +#include +#include + +namespace airmap { + +/// Token models an authentication token required to access the AirMap services. +class Token { + public: + /// Type enumerates all known token types. + enum class Type { + unknown, ///< Marks the unknown token type. + anonymous, ///< The token contains an Anonymous instance. + oauth, ///< The token contains an OAuth instance. + refreshed ///< The token contains a Refreshed instance. + }; + + /// Anonymous models a token for an anonymous authentication with the AirMap services. + struct Anonymous { + std::string id; ///< The authentication id. + }; + + /// OAuth models a token for an authentication with OAuth credentials with the AirMap services. + struct OAuth { + enum class Type { bearer }; + Type type; ///< The type of the OAuth token. + std::string refresh; ///< The refresh token for subsequent renewal requests. + std::string id; ///< The id token. + std::string access; ///< The access token. + }; + + /// Refreshed models a token for a refreshed authentication with OAuth credentials with the AirMap services. + struct Refreshed { + OAuth::Type type; ///< The type of the Refreshed token. + std::chrono::seconds expires_in; ///< The token expires in 'expires_in' seconds. + std::string id; ///< The id token. + Optional original_token; ///< The original token used for renewal. + }; + + /// load_from_json reads a Token instance from the input stream 'in'. + static Token load_from_json(std::istream& in); + + /// Token constructs a new invalid instance. + explicit Token(); + /// Token constructs a new instance with Type::anonymous. + explicit Token(const Anonymous& anonymous); + /// Token constructs a new instance with Type::oauth. + explicit Token(const OAuth& oauth); + /// Token constructs a new instance with Type::refreshed. + explicit Token(const Refreshed& refreshed); + /// @cond + Token(const Token& token); + Token(Token&& token); + ~Token(); + Token& operator=(const Token& token); + Token& operator=(Token&& token); + /// @endcond + + /// type returns the Type of this Token instance. + Type type() const; + /// id returns the common id of this Token instance. + const std::string& id() const; + /// anonymous returns the details for a Type::anonymous Token instance. + const Anonymous& anonymous() const; + /// anonymous returns the details for a Type::anonymous Token instance. + Anonymous& anonymous(); + /// oauth returns the details for a Type::oauth Token instance. + const OAuth& oauth() const; + /// oauth returns the details for a Type::oauth Token instance. + OAuth& oauth(); + /// refreshed returns the details for a Type::refreshed Token instance. + const Refreshed& refreshed() const; + /// refreshed returns the details for a Type::refreshed Token instance. + Refreshed& refreshed(); + + private: + union Data { + Data(); + ~Data(); + + Anonymous anonymous; + OAuth oauth; + Refreshed refreshed; + }; + + Token& construct(const Token& token); + Token& construct(const Anonymous& anonymous); + Token& construct(const OAuth& oauth); + Token& construct(const Refreshed& refreshed); + + Token& destruct(); + + Type type_; + Data data_; +}; + +/// operator<< inserts type into out. +std::ostream& operator<<(std::ostream& out, Token::Type type); +/// operator>> extracts type from in. +std::istream& operator>>(std::istream& in, Token::Type& type); +/// operator== returns true iff lhs equals rhs. +bool operator==(const Token::OAuth& lhs, const Token::OAuth& rhs); +/// operator== returns true iff lhs equals rhs. +bool operator==(Token::OAuth::Type lhs, Token::OAuth::Type rhs); +/// operator== returns true iff lhs equals rhs. +bool operator==(const Token::Refreshed& lhs, const Token::Refreshed& rhs); + +} // namespace airmap + +#endif // AIRMAP_TOKEN_H_ diff --git a/libs/airmapd/include/airmap/traffic.h b/libs/airmapd/include/airmap/traffic.h new file mode 100644 index 0000000000000000000000000000000000000000..0a043aee4de3bd4055672af1085dcbb795dd8e97 --- /dev/null +++ b/libs/airmapd/include/airmap/traffic.h @@ -0,0 +1,128 @@ +#ifndef AIRMAP_TRAFFIC_H_ +#define AIRMAP_TRAFFIC_H_ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace airmap { + +/// Traffic provides access to the AirMap situational awareness +/// and traffic alerts. +class Traffic : DoNotCopyOrMove { + public: + /// Update bundles together information about aerial traffic + /// relevant to a UAV flight. + struct Update { + /// Type enumerates all known types of Traffic::Update. + enum class Type { + unknown, ///< Marks the unknown type. + situational_awareness, ///< Marks updates that provide planning information to operators and vehicles. + alert ///< Marks updates about aircrafts that are likely to collide with the current aircraft. + }; + + std::string id; ///< The unique id of the underlying track in the context of AirMap. + std::string aircraft_id; ///< The 'other' aircraft's id. + double latitude; ///< The latitude of the other aircraft in [°]. + double longitude; ///< The longitude of the other aircraft in [°]. + double altitude; ///< The altitude of the other aircraft in [m]. + double ground_speed; ///< The speed over ground of the other aircraft in [m/s]. + double heading; ///< The heading of the other aircraft in [°]. + double direction; ///< The direction of the other aircraft in relation to the current aircraft in [°]. + DateTime recorded; ///< The time when the datum triggering the udpate was recorded. + DateTime timestamp; ///< The time when the update was generated. + }; + + /// Monitor models handling of individual subscribers + /// to per-flight alerts and awareness notices. + class Monitor : DoNotCopyOrMove { + public: + /// Parameters bundles up input parameters. + struct Params { + std::string flight_id; ///< The id of the flight for which traffic udpates should be started. + std::string authorization; ///< The authorization token. + }; + + /// Result models the outcome of calling Traffic::monitor. + using Result = Outcome, Error>; + /// Callback describes the function signature of the callback that is + /// invoked when a call to Traffic::monitor finishes. + using Callback = std::function; + + /// Subscriber abstracts handling of batches of Update instances. + class Subscriber { + public: + /// handle_update is invoked when a new batch of Update instances + /// is available. + virtual void handle_update(Update::Type type, const std::vector& update) = 0; + + protected: + Subscriber() = default; + }; + + /// FunctionalSubscriber is a convenience class that dispatches + /// to a function 'f' for handling batches of Update instances. + class FunctionalSubscriber : public Subscriber { + public: + /// FunctionalSubscriber initializes a new instance with 'f'. + explicit FunctionalSubscriber(const std::function&)>& f); + // From subscriber + void handle_update(Update::Type type, const std::vector& update) override; + + private: + std::function&)> f_; + }; + + /// LoggingSubscriber is a convenience class that logs incoming batches + /// of Update instances. + class LoggingSubscriber : public Subscriber { + public: + /// LoggingSubscriber initializes an instance with 'component', feeding + /// log entries to 'logger'. Please note that no change of ownership takes + /// place for 'component' and the lifetime of component has to exceed the + /// lifetime of a LoggingSubscriber instance. + explicit LoggingSubscriber(const char* component, const std::shared_ptr& logger); + + // From Subscriber + void handle_update(Update::Type type, const std::vector& update) override; + + private: + const char* component_; + std::shared_ptr logger_; + }; + + /// subscribe registers 'subscriber' such that subsequent batches of + /// Update instances are delivered to 'subscriber'. + virtual void subscribe(const std::shared_ptr& subscriber) = 0; + + /// unsubscribe unregisters 'subscriber'. + virtual void unsubscribe(const std::shared_ptr& subscriber) = 0; + + protected: + Monitor() = default; + }; + + /// monitor subscribes the user and flight described in 'params' to + /// the AirMap traffic services and reports the result to 'cb'. + virtual void monitor(const Monitor::Params& params, const Monitor::Callback& cb) = 0; + + protected: + /// @cond + Traffic() = default; + /// @endcond +}; + +/// operator<< inserts a textual representation of type into out. +std::ostream& operator<<(std::ostream& out, Traffic::Update::Type type); + +} // namespace airmap + +#endif // AIRMAP_TRAFFIC_H_ diff --git a/libs/airmapd/include/airmap/version.h b/libs/airmapd/include/airmap/version.h new file mode 100644 index 0000000000000000000000000000000000000000..18ea8baf3a5792181065742bedbb31ae958b642a --- /dev/null +++ b/libs/airmapd/include/airmap/version.h @@ -0,0 +1,26 @@ +#ifndef AIRMAP_VERSION_H_ +#define AIRMAP_VERSION_H_ + +#include +#include + +#include + +namespace airmap { + +/// Version bundles up information describing a specific version of the AirMap +/// client library. We follow semantic versioning guidelines (see https://semver.org). +struct Version { + /// current returns an immutable reference to the version of the client library. + static const Version& current(); + + std::uint32_t major; ///< The major version number. + std::uint32_t minor; ///< The minor version number. + std::uint32_t patch; ///< The patch version number. + Optional git_revision; ///< The git revision from which the release was build. + Optional build_timestamp; ///< Marks the time when the library was built. +}; + +} // namespace airmap + +#endif // AIRMAP_VERSION_H_ diff --git a/libs/airmapd/macOS/Qt.5.9/libairmap-cpp.0.0.1.dylib b/libs/airmapd/macOS/Qt.5.9/libairmap-cpp.0.0.1.dylib new file mode 120000 index 0000000000000000000000000000000000000000..db811e07bbae74fd1b0f3f7b30eb6ab2fcc0781f --- /dev/null +++ b/libs/airmapd/macOS/Qt.5.9/libairmap-cpp.0.0.1.dylib @@ -0,0 +1 @@ +libairmap-cpp.0.dylib \ No newline at end of file diff --git a/libs/airmapd/macOS/Qt.5.9/libairmap-cpp.0.dylib b/libs/airmapd/macOS/Qt.5.9/libairmap-cpp.0.dylib new file mode 100755 index 0000000000000000000000000000000000000000..aa69744166bf49bbcfd3476a7709c3bb0cfaeda8 Binary files /dev/null and b/libs/airmapd/macOS/Qt.5.9/libairmap-cpp.0.dylib differ diff --git a/libs/airmapd/macOS/Qt.5.9/libairmap-cpp.dylib b/libs/airmapd/macOS/Qt.5.9/libairmap-cpp.dylib new file mode 120000 index 0000000000000000000000000000000000000000..250337bd5ff48e80fde947ee9685a1a76f242540 --- /dev/null +++ b/libs/airmapd/macOS/Qt.5.9/libairmap-cpp.dylib @@ -0,0 +1 @@ +libairmap-cpp.0.0.1.dylib \ No newline at end of file diff --git a/libs/airmapd/macOS/Qt.5.9/libairmap-qt.0.0.1.dylib b/libs/airmapd/macOS/Qt.5.9/libairmap-qt.0.0.1.dylib new file mode 120000 index 0000000000000000000000000000000000000000..f88997b2e9c6e43fddc23ae0d8f7cae5b475cbe7 --- /dev/null +++ b/libs/airmapd/macOS/Qt.5.9/libairmap-qt.0.0.1.dylib @@ -0,0 +1 @@ +libairmap-qt.0.dylib \ No newline at end of file diff --git a/libs/airmapd/macOS/Qt.5.9/libairmap-qt.0.dylib b/libs/airmapd/macOS/Qt.5.9/libairmap-qt.0.dylib new file mode 100755 index 0000000000000000000000000000000000000000..f6bc90134d549be4db545f26e63b59c8b4dab7f5 Binary files /dev/null and b/libs/airmapd/macOS/Qt.5.9/libairmap-qt.0.dylib differ diff --git a/libs/airmapd/macOS/Qt.5.9/libairmap-qt.dylib b/libs/airmapd/macOS/Qt.5.9/libairmap-qt.dylib new file mode 120000 index 0000000000000000000000000000000000000000..c62931ac622bc94698aa6f7822ad593565784a26 --- /dev/null +++ b/libs/airmapd/macOS/Qt.5.9/libairmap-qt.dylib @@ -0,0 +1 @@ +libairmap-qt.0.0.1.dylib \ No newline at end of file