blob: 277cc457204d185d5b39d112c584ed4fe73fa567 [file]
// 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 "wlantap-ctl.h"
#include <fidl/fuchsia.wlan.tap/cpp/fidl.h>
#include <fidl/fuchsia.wlan.tap/cpp/wire.h>
#include <lib/driver/component/cpp/node_add_args.h>
#include <lib/driver/logging/cpp/logger.h>
#include <wlan/drivers/log.h>
#include "wlantap-phy.h"
namespace wlan {
void WlantapCtlServer::CreatePhy(CreatePhyRequestView request,
CreatePhyCompleter::Sync& completer) {
WLAN_TRACE_DURATION();
phy_config_arena_.Reset();
auto natural_config = fidl::ToNatural(request->config);
auto wire_config = fidl::ToWire(phy_config_arena_, std::move(natural_config));
const auto phy_config = std::make_shared<const wlan_tap::WlantapPhyConfig>(wire_config);
auto instance_name = phy_config->name.get();
auto endpoints = fidl::CreateEndpoints<fuchsia_driver_framework::NodeController>();
if (endpoints.is_error()) {
fdf::error("Failed to create endpoints: {}", endpoints);
completer.Reply(endpoints.error_value());
}
auto impl = WlanPhyImplDevice::New(driver_context_, request->proxy.TakeChannel(), phy_config,
std::move(endpoints->client));
zx_status_t status = ServeWlanPhyImplProtocol(instance_name, std::move(impl));
if (status != ZX_OK) {
fdf::error("ServeWlanPhyImplProtocol failed: {}", zx_status_get_string(status));
completer.Reply(status);
return;
}
status = AddWlanPhyImplChild(instance_name, std::move(endpoints->server));
if (status != ZX_OK) {
fdf::error("AddWlanPhyImplChild failed: {}", zx_status_get_string(status));
completer.Reply(status);
return;
}
completer.Reply(ZX_OK);
}
zx_status_t WlantapCtlServer::AddWlanPhyImplChild(
std::string_view name, fidl::ServerEnd<fuchsia_driver_framework::NodeController> server) {
WLAN_TRACE_DURATION();
fidl::Arena arena;
auto offers = std::vector{fdf::MakeOffer2<fuchsia_wlan_phyimpl::Service>(arena, name)};
auto args = fuchsia_driver_framework::wire::NodeAddArgs::Builder(arena)
.name(name)
.offers2(offers)
.Build();
auto res = driver_context_->node_client()->AddChild(args, std::move(server), {});
if (!res.ok()) {
fdf::error("Failed to add WlanPhyImpl child: {}", res.status_string());
return res.status();
}
return ZX_OK;
}
zx_status_t WlantapCtlServer::ServeWlanPhyImplProtocol(std::string_view name,
std::shared_ptr<WlanPhyImplDevice> impl) {
WLAN_TRACE_DURATION();
auto protocol_handler =
[impl = std::move(impl)](fdf::ServerEnd<fuchsia_wlan_phyimpl::WlanPhyImpl> request) mutable {
fdf::BindServer(fdf::Dispatcher::GetCurrent()->get(), std::move(request), std::move(impl));
};
fuchsia_wlan_phyimpl::Service::InstanceHandler handler(
{.wlan_phy_impl = std::move(protocol_handler)});
zx::result result = driver_context_->outgoing()->AddService<fuchsia_wlan_phyimpl::Service>(
std::move(handler), name);
if (result.is_error()) {
fdf::error("Failed to add service: {}", result);
return result.error_value();
}
return ZX_OK;
}
} // namespace wlan