blob: 02ef1ca78938b3326c415efd42b70963d2b96531 [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 "garnet/bin/overnet/overnetstack/service.h"
#include "garnet/lib/overnet/protocol/fidl.h"
namespace overnetstack {
Service::Service(OvernetApp* app) : app_(app) {}
overnet::Status Service::Start() {
app_->startup_context()->outgoing().AddPublicService(
bindings_.GetHandler(this));
return overnet::Status::Ok();
}
void Service::ListPeers(ListPeersCallback callback) {
using Peer = fuchsia::overnet::Peer;
std::vector<Peer> response;
app_->endpoint()->ForEachNodeMetric(
[&response, self_node = app_->endpoint()->node_id()](
const fuchsia::overnet::protocol::NodeMetrics& m) {
Peer peer;
peer.id = m.label()->id;
peer.is_self = m.label()->id == self_node;
if (m.has_description()) {
peer.description = fidl::Clone(*m.description());
}
response.emplace_back(std::move(peer));
});
callback(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(fuchsia::overnet::ServiceProviderPtr provider)
: provider_(std::move(provider)) {}
void Connect(const fuchsia::overnet::protocol::Introduction& intro,
zx::channel channel) final {
if (!intro.has_service_name()) {
OVERNET_TRACE(DEBUG) << "No service name in local service request";
return;
}
provider_->ConnectToService(*intro.service_name(), std::move(channel));
}
private:
const fuchsia::overnet::ServiceProviderPtr provider_;
};
app_->RegisterServiceProvider(
service_name, std::make_unique<ServiceProvider>(provider.Bind()));
}
void Service::ConnectToService(fuchsia::overnet::protocol::NodeId node,
std::string service_name, zx::channel channel) {
fuchsia::overnet::protocol::Introduction intro;
intro.set_service_name(service_name);
if (app_->endpoint()->node_id() == node) {
app_->ConnectToLocalService(intro, std::move(channel));
} else {
app_->endpoint()->SendIntro(
node,
fuchsia::overnet::protocol::ReliabilityAndOrdering::ReliableOrdered,
std::move(intro),
overnet::StatusOrCallback<overnet::RouterEndpoint::NewStream>(
overnet::ALLOCATED_CALLBACK,
[this, channel = std::move(channel)](
overnet::StatusOr<overnet::RouterEndpoint::NewStream>
ns) mutable {
if (ns.is_error()) {
OVERNET_TRACE(ERROR)
<< "ConnectToService failed: " << ns.AsStatus();
} else {
app_->BindStream(std::move(*ns), std::move(channel));
}
}));
}
}
} // namespace overnetstack