blob: 9d2e88b882cc63951c07465e4d8b16aa5d525e7e [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 "network_manager.h"
#include "network_context.h"
namespace netemul {
NetworkManager::NetworkManager(NetworkContext* context) : parent_(context) {}
void NetworkManager::ListNetworks(
NetworkManager::ListNetworksCallback callback) {
std::vector<std::string> rsp;
rsp.reserve(nets_.size());
for (auto& x : nets_) {
rsp.push_back(x.first);
}
callback(std::move(rsp));
}
zx_status_t NetworkManager::CreateNetwork(
std::string name, netemul::Network::Config config,
fidl::InterfaceRequest<netemul::Network::FNetwork> req) {
if (name.empty() || !Network::CheckConfig(config)) {
// empty name not allowed
// invalid config will cause invalid args.
return ZX_ERR_INVALID_ARGS;
} else if (nets_.find(name) == nets_.end()) { // no network with same name
// create new network
auto net = std::make_unique<Network>(parent_, name, std::move(config));
net->Bind(std::move(req));
net->SetClosedCallback([this](const Network& net) {
// erase network when all its bindings go away
nets_.erase(net.name());
});
nets_.insert(std::make_pair<std::string, Network::Ptr>(std::string(name),
std::move(net)));
return ZX_OK;
} else {
// name already exists, decline creation
return ZX_ERR_ALREADY_EXISTS;
}
}
void NetworkManager::CreateNetwork(
std::string name, Network::Config config,
NetworkManager::CreateNetworkCallback callback) {
fidl::InterfaceHandle<Network::FNetwork> handle;
auto status =
CreateNetwork(std::move(name), std::move(config), handle.NewRequest());
if (status != ZX_OK) {
handle.TakeChannel(); // dispose of channel
}
callback(status, std::move(handle));
}
Network* NetworkManager::GetNetwork(const std::string& name) {
auto neti = nets_.find(name);
if (neti == nets_.end()) {
return nullptr;
} else {
return neti->second.get();
}
}
void NetworkManager::GetNetwork(::std::string name,
NetworkManager::GetNetworkCallback callback) {
auto neti = nets_.find(name);
fidl::InterfaceHandle<Network::FNetwork> handle;
if (neti == nets_.end()) {
// no network with such name
callback(std::move(handle));
} else {
auto& net = neti->second;
net->Bind(handle.NewRequest());
callback(std::move(handle));
}
}
void NetworkManager::Bind(fidl::InterfaceRequest<FNetworkManager> request) {
bindings_.AddBinding(this, std::move(request), parent_->dispatcher());
}
} // namespace netemul