Program Listing for File remote_access.hpp

Return to documentation for file (foxglove/include/foxglove/remote_access.hpp)

#pragma once

#include <foxglove/channel.hpp>
#include <foxglove/connection_graph.hpp>
#include <foxglove/context.hpp>
#include <foxglove/error.hpp>
#include <foxglove/fetch_asset.hpp>
#include <foxglove/parameter.hpp>
#include <foxglove/service.hpp>

#include <chrono>
#include <cstdint>
#include <functional>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <vector>

enum foxglove_error : uint8_t;
struct foxglove_gateway;

namespace foxglove {

enum class RemoteAccessConnectionStatus : uint8_t {
  Connecting = 0,
  Connected = 1,
  ShuttingDown = 2,
  Shutdown = 3,
};

enum class RemoteAccessStatusLevel : uint8_t {
  Info = 0,
  Warning = 1,
  Error = 2,
};

enum class RemoteAccessGatewayCapabilities : uint8_t {
  None = 0,
  ClientPublish = 1 << 0,
  Parameters = 1 << 1,
  Services = 1 << 2,
  ConnectionGraph = 1 << 3,
  Assets = 1 << 4,
};

inline RemoteAccessGatewayCapabilities operator|(
  RemoteAccessGatewayCapabilities a, RemoteAccessGatewayCapabilities b
) {
  return RemoteAccessGatewayCapabilities(uint8_t(a) | uint8_t(b));
}

inline RemoteAccessGatewayCapabilities operator&(
  RemoteAccessGatewayCapabilities a, RemoteAccessGatewayCapabilities b
) {
  return RemoteAccessGatewayCapabilities(uint8_t(a) & uint8_t(b));
}

struct RemoteAccessGatewayCallbacks {
  std::function<void(RemoteAccessConnectionStatus status)> onConnectionStatusChanged;

  std::function<void(uint32_t client_id, const ChannelDescriptor& channel)> onSubscribe;

  std::function<void(uint32_t client_id, const ChannelDescriptor& channel)> onUnsubscribe;

  std::function<void(
    uint32_t client_id, const ChannelDescriptor& channel, const std::byte* data, size_t data_len
  )>
    onMessageData;

  std::function<void(uint32_t client_id, const ChannelDescriptor& channel)> onClientAdvertise;

  std::function<void(uint32_t client_id, const ChannelDescriptor& channel)> onClientUnadvertise;

  std::function<std::vector<Parameter>(
    uint32_t client_id, std::optional<std::string_view> request_id,
    const std::vector<std::string_view>& param_names
  )>
    onGetParameters;

  std::function<std::vector<Parameter>(
    uint32_t client_id, std::optional<std::string_view> request_id,
    const std::vector<ParameterView>& params
  )>
    onSetParameters;

  std::function<void(const std::vector<std::string_view>& param_names)> onParametersSubscribe;

  std::function<void(const std::vector<std::string_view>& param_names)> onParametersUnsubscribe;

  std::function<void()> onConnectionGraphSubscribe;

  std::function<void()> onConnectionGraphUnsubscribe;
};

enum class Reliability : uint8_t {
  Lossy = 0,
  Reliable = 1,
};

struct QosProfile {
  Reliability reliability = Reliability::Lossy;
};

using QosClassifierFn = std::function<QosProfile(const ChannelDescriptor&)>;

struct RemoteAccessGatewayOptions {
  Context context;
  std::string name;
  std::string device_token;
  RemoteAccessGatewayCallbacks callbacks;
  RemoteAccessGatewayCapabilities capabilities = RemoteAccessGatewayCapabilities::None;
  std::vector<std::string> supported_encodings;
  FetchAssetHandler fetch_asset;
  SinkChannelFilterFn sink_channel_filter;
  QosClassifierFn qos_classifier;
  std::optional<std::map<std::string, std::string>> server_info = std::nullopt;
  std::optional<std::string> foxglove_api_url;
  std::optional<uint64_t> foxglove_api_timeout_secs;
  std::optional<size_t> message_backlog_size;
};

class RemoteAccessGateway final {
public:
  static FoxgloveResult<RemoteAccessGateway> create(RemoteAccessGatewayOptions&& options);

  [[nodiscard]] RemoteAccessConnectionStatus connectionStatus() const;

  [[nodiscard]] FoxgloveError addService(Service&& service) const noexcept;

  [[nodiscard]] FoxgloveError removeService(std::string_view name) const noexcept;

  void publishParameterValues(std::vector<Parameter>&& params);

  [[nodiscard]] FoxgloveError publishStatus(
    RemoteAccessStatusLevel level, std::string_view message,
    std::optional<std::string_view> id = std::nullopt
  ) const noexcept;

  [[nodiscard]] FoxgloveError removeStatus(const std::vector<std::string_view>& ids) const;

  [[nodiscard]] FoxgloveError publishConnectionGraph(const ConnectionGraph& graph) const;

  [[nodiscard]] std::optional<uint64_t> sinkId() const;

  FoxgloveError stop();

private:
  RemoteAccessGateway(
    foxglove_gateway* gateway, std::unique_ptr<RemoteAccessGatewayCallbacks> callbacks,
    std::unique_ptr<FetchAssetHandler> fetch_asset,
    std::unique_ptr<SinkChannelFilterFn> sink_channel_filter,
    std::unique_ptr<QosClassifierFn> qos_classifier
  );

  std::unique_ptr<RemoteAccessGatewayCallbacks> callbacks_;
  std::unique_ptr<FetchAssetHandler> fetch_asset_;
  std::unique_ptr<SinkChannelFilterFn> sink_channel_filter_;
  std::unique_ptr<QosClassifierFn> qos_classifier_;
  std::unique_ptr<foxglove_gateway, foxglove_error (*)(foxglove_gateway*)> impl_;
};

}  // namespace foxglove