blob: 9bcffbb5803bf13cad1ad2f940828122e5f5204f [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.
#include "src/connectivity/overnet/overnetstack/service.h"
#include "src/connectivity/overnet/lib/protocol/fidl.h"
namespace overnetstack {
Service::Service(OvernetApp* app) : app_(app) {}
overnet::Status Service::Start() {
app_->component_context()->outgoing()->AddPublicService(
bindings_.GetHandler(this));
return overnet::Status::Ok();
}
void Service::ListPeers(uint64_t last_seen_version,
ListPeersCallback callback) {
using Peer = fuchsia::overnet::Peer;
app_->endpoint()->OnNodeDescriptionTableChange(
last_seen_version,
overnet::Callback<void>(
overnet::ALLOCATED_CALLBACK, [this, callback = std::move(callback)] {
std::vector<Peer> response;
auto new_version = app_->endpoint()->ForEachNodeDescription(
[&response, self_node = app_->endpoint()->node_id()](
overnet::NodeId id,
const fuchsia::overnet::protocol::PeerDescription& m) {
Peer peer;
peer.id = id.as_fidl();
peer.is_self = id == self_node;
peer.description = fidl::Clone(m);
response.emplace_back(std::move(peer));
});
callback(new_version, std::move(response));
}));
}
void Service::RegisterService(
std::string service_name,
fidl::InterfaceHandle<fuchsia::overnet::ServiceProvider> provider) {
class ServiceProvider final : public OvernetApp::ServiceProvider {
public:
explicit ServiceProvider(OvernetApp* app, std::string fully_qualified_name,
fuchsia::overnet::protocol::ReliabilityAndOrdering
reliability_and_ordering,
fuchsia::overnet::ServiceProviderPtr provider)
: OvernetApp::ServiceProvider(app, fully_qualified_name,
reliability_and_ordering),
provider_(std::move(provider)) {
provider_.set_error_handler([this](zx_status_t) { Close(); });
}
void Connect(zx::channel channel) override final {
provider_->ConnectToService(std::move(channel));
}
private:
fuchsia::overnet::ServiceProviderPtr provider_;
};
app_->InstantiateServiceProvider<ServiceProvider>(
app_, std::move(service_name),
fuchsia::overnet::protocol::ReliabilityAndOrdering::ReliableOrdered,
provider.Bind());
}
void Service::ConnectToService(fuchsia::overnet::protocol::NodeId node,
std::string service_name, zx::channel channel) {
auto node_id = overnet::NodeId(node);
if (app_->endpoint()->node_id() == node_id) {
app_->ConnectToLocalService(std::move(service_name), std::move(channel));
} else {
auto ns = app_->endpoint()->InitiateStream(
node_id,
fuchsia::overnet::protocol::ReliabilityAndOrdering::ReliableOrdered,
std::move(service_name));
if (ns.is_error()) {
OVERNET_TRACE(ERROR) << "ConnectToService failed: " << ns.AsStatus();
} else {
app_->BindChannel(std::move(*ns), std::move(channel));
}
}
}
} // namespace overnetstack