blob: 18d0f8dee5498ba3700fdafee21d09ad95c7b273 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_CONNECTIVITY_OVERNET_OVERNETSTACK_OVERNET_APP_H_
#define SRC_CONNECTIVITY_OVERNET_OVERNETSTACK_OVERNET_APP_H_
#include <lib/sys/cpp/component_context.h>
#include <lib/zx/channel.h>
#include <memory>
#include "src/connectivity/overnet/lib/endpoint/router_endpoint.h"
#include "src/connectivity/overnet/lib/environment/timer.h"
namespace overnetstack {
// Main application object: provides common objects to Actors, which implement
// the bulk of the functionality of the app.
class OvernetApp final {
public:
OvernetApp(overnet::Timer* timer);
~OvernetApp();
overnet::Status Start();
/////////////////////////////////////////////////////////////////////////////
// Some (usually asynchronous) service that mutates application state.
class Actor {
public:
virtual ~Actor() {}
virtual overnet::Status Start() = 0;
};
template <class T, class... Args>
T* InstantiateActor(Args&&... args) {
auto ptr = std::make_unique<T>(this, std::forward<Args>(args)...);
auto* out = ptr.get();
actors_.emplace_back(std::move(ptr));
return out;
}
/////////////////////////////////////////////////////////////////////////////
// Allows binding a zx::channel to some service denoted by an Introduction
// object.
class ServiceProvider;
using ServiceProviderMap =
std::unordered_map<std::string, std::unique_ptr<ServiceProvider>>;
class ServiceProvider : public overnet::RouterEndpoint::Service {
friend class OvernetApp;
public:
ServiceProvider(OvernetApp* app, std::string fully_qualified_name,
fuchsia::overnet::protocol::ReliabilityAndOrdering
reliability_and_ordering)
: overnet::RouterEndpoint::Service(
&app->endpoint_, fully_qualified_name, reliability_and_ordering),
app_(app) {}
virtual ~ServiceProvider() {}
virtual void Connect(zx::channel channel) = 0;
void AcceptStream(overnet::RouterEndpoint::NewStream stream) override final;
protected:
void Close() { app_->service_providers_.erase(where_am_i_); };
private:
OvernetApp* const app_;
ServiceProviderMap::iterator where_am_i_;
};
template <class T, class... Args>
void InstantiateServiceProvider(Args&&... args) {
auto sp = std::make_unique<T>(std::forward<Args>(args)...);
auto name = sp->fully_qualified_name;
// Keep pointer to sp even though we'll move it as an arg on the next line,
// so we can assign where_am_i_
auto sp_ptr = sp.get();
sp_ptr->where_am_i_ =
service_providers_.emplace(std::move(name), std::move(sp)).first;
}
// Bind 'channel' to a local overnet service.
void ConnectToLocalService(const std::string& service_name,
zx::channel channel);
/////////////////////////////////////////////////////////////////////////////
// Accessors for well known objects.
overnet::RouterEndpoint* endpoint() { return &endpoint_; }
sys::ComponentContext* component_context() const {
return component_context_.get();
}
overnet::Timer* timer() { return timer_; }
overnet::NodeId node_id() const { return node_id_; }
/////////////////////////////////////////////////////////////////////////////
// Bind together an overnet stream and a zx::channel and keep them
// communicating until one side closes.
void BindChannel(overnet::RouterEndpoint::NewStream ns, zx::channel channel);
// Similarly, for zx::socket
void BindSocket(overnet::RouterEndpoint::NewStream ns, zx::socket socket);
private:
static overnet::NodeId GenerateNodeId();
const std::unique_ptr<sys::ComponentContext> component_context_;
overnet::Timer* const timer_;
const overnet::NodeId node_id_ = GenerateNodeId();
overnet::RouterEndpoint endpoint_{timer_, node_id_, true};
std::vector<std::unique_ptr<Actor>> actors_;
ServiceProviderMap service_providers_;
};
} // namespace overnetstack
#endif // SRC_CONNECTIVITY_OVERNET_OVERNETSTACK_OVERNET_APP_H_