| // 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 |