| // Copyright 2021 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-mac.h" |
| |
| #include <lib/driver/logging/cpp/logger.h> |
| |
| #include <wlan/common/channel.h> |
| #include <wlan/drivers/log.h> |
| |
| #include "lib/fidl/cpp/wire/channel.h" |
| #include "lib/fidl_driver/cpp/wire_messaging_declarations.h" |
| #include "utils.h" |
| |
| namespace { |
| // Large enough to back a full WlanSoftmacQueryResponse FIDL struct. |
| constexpr size_t kWlanSoftmacQueryResponseBufferSize = 5120; |
| } // namespace |
| |
| namespace wlan { |
| |
| WlantapMac::WlantapMac(Listener* listener, wlan_common::WlanMacRole role, |
| const std::shared_ptr<const wlan_tap::WlantapPhyConfig>& config, |
| zx::channel sme_channel) |
| : listener_(listener), role_(role), phy_config_(config), sme_channel_(std::move(sme_channel)) {} |
| |
| void WlantapMac::Query(fdf::Arena& arena, QueryCompleter::Sync& completer) { |
| WLAN_TRACE_DURATION(); |
| fdf::info("Query(): {}", phy_config_->hardware_capability); |
| fidl::Arena<kWlanSoftmacQueryResponseBufferSize> table_arena; |
| wlan_softmac::WlanSoftmacQueryResponse resp; |
| ConvertTapPhyConfig(&resp, *phy_config_, table_arena); |
| completer.buffer(arena).ReplySuccess(resp); |
| } |
| |
| fidl::ProtocolHandler<fuchsia_wlan_softmac::WlanSoftmac> WlantapMac::ProtocolHandler() { |
| WLAN_TRACE_DURATION(); |
| return bindings_.CreateHandler(this, fdf::Dispatcher::GetCurrent()->get(), |
| fidl::kIgnoreBindingClosure); |
| } |
| |
| void WlantapMac::QueryDiscoverySupport(fdf::Arena& arena, |
| QueryDiscoverySupportCompleter::Sync& completer) { |
| WLAN_TRACE_DURATION(); |
| completer.buffer(arena).ReplySuccess(phy_config_->discovery_support); |
| } |
| |
| void WlantapMac::QueryMacSublayerSupport(fdf::Arena& arena, |
| QueryMacSublayerSupportCompleter::Sync& completer) { |
| WLAN_TRACE_DURATION(); |
| completer.buffer(arena).ReplySuccess(phy_config_->mac_sublayer_support); |
| } |
| |
| void WlantapMac::QuerySecuritySupport(fdf::Arena& arena, |
| QuerySecuritySupportCompleter::Sync& completer) { |
| WLAN_TRACE_DURATION(); |
| completer.buffer(arena).ReplySuccess(phy_config_->security_support); |
| } |
| |
| void WlantapMac::QuerySpectrumManagementSupport( |
| fdf::Arena& arena, QuerySpectrumManagementSupportCompleter::Sync& completer) { |
| WLAN_TRACE_DURATION(); |
| completer.buffer(arena).ReplySuccess(phy_config_->spectrum_management_support); |
| } |
| |
| void WlantapMac::Start(StartRequestView request, fdf::Arena& arena, |
| StartCompleter::Sync& completer) { |
| WLAN_TRACE_DURATION(); |
| fdf::info("Calling Start()"); |
| if (!sme_channel_.is_valid()) { |
| completer.buffer(arena).ReplyError(ZX_ERR_ALREADY_BOUND); |
| return; |
| } |
| |
| listener_->WlantapMacStart(std::move(request->ifc)); |
| completer.buffer(arena).ReplySuccess(std::move(sme_channel_)); |
| } |
| |
| void WlantapMac::Stop(fdf::Arena& arena, StopCompleter::Sync& completer) { |
| WLAN_TRACE_DURATION(); |
| listener_->WlantapMacStop(); |
| completer.buffer(arena).Reply(); |
| } |
| |
| void WlantapMac::QueueTx(QueueTxRequestView request, fdf::Arena& arena, |
| QueueTxCompleter::Sync& completer) { |
| WLAN_TRACE_DURATION(); |
| listener_->WlantapMacQueueTx(request->packet); |
| completer.buffer(arena).ReplySuccess(); |
| } |
| |
| void WlantapMac::SetChannel(SetChannelRequestView request, fdf::Arena& arena, |
| SetChannelCompleter::Sync& completer) { |
| WLAN_TRACE_DURATION(); |
| if (!wlan::common::IsValidChan(request->channel())) { |
| completer.buffer(arena).ReplyError(ZX_ERR_INVALID_ARGS); |
| return; |
| } |
| listener_->WlantapMacSetChannel(request->channel()); |
| completer.buffer(arena).ReplySuccess(); |
| } |
| |
| void WlantapMac::JoinBss(JoinBssRequestView request, fdf::Arena& arena, |
| JoinBssCompleter::Sync& completer) { |
| WLAN_TRACE_DURATION(); |
| bool expected_remote = role_ == wlan_common::WlanMacRole::kClient; |
| if (request->join_request.remote() != expected_remote) { |
| completer.buffer(arena).ReplyError(ZX_ERR_INVALID_ARGS); |
| return; |
| } |
| listener_->WlantapMacJoinBss(request->join_request); |
| completer.buffer(arena).ReplySuccess(); |
| } |
| |
| void WlantapMac::EnableBeaconing(EnableBeaconingRequestView request, fdf::Arena& arena, |
| EnableBeaconingCompleter::Sync& completer) { |
| WLAN_TRACE_DURATION(); |
| |
| // This is the test driver, so we can just pretend beaconing was enabled. |
| completer.buffer(arena).ReplySuccess(); |
| } |
| |
| void WlantapMac::DisableBeaconing(fdf::Arena& arena, DisableBeaconingCompleter::Sync& completer) { |
| WLAN_TRACE_DURATION(); |
| |
| // This is the test driver, so we can just pretend the beacon was configured. |
| completer.buffer(arena).ReplySuccess(); |
| } |
| |
| void WlantapMac::StartPassiveScan(StartPassiveScanRequestView request, fdf::Arena& arena, |
| StartPassiveScanCompleter::Sync& completer) { |
| WLAN_TRACE_DURATION(); |
| uint64_t scan_id = 111; |
| listener_->WlantapMacStartScan(scan_id); |
| fidl::Arena fidl_arena; |
| auto builder = |
| fuchsia_wlan_softmac::wire::WlanSoftmacBaseStartPassiveScanResponse::Builder(fidl_arena); |
| builder.scan_id(scan_id); |
| completer.buffer(arena).ReplySuccess(builder.Build()); |
| } |
| |
| void WlantapMac::StartActiveScan(StartActiveScanRequestView request, fdf::Arena& arena, |
| StartActiveScanCompleter::Sync& completer) { |
| WLAN_TRACE_DURATION(); |
| uint64_t scan_id = 222; |
| listener_->WlantapMacStartScan(scan_id); |
| |
| fidl::Arena fidl_arena; |
| auto builder = |
| fuchsia_wlan_softmac::wire::WlanSoftmacBaseStartActiveScanResponse::Builder(fidl_arena); |
| builder.scan_id(scan_id); |
| completer.buffer(arena).ReplySuccess(builder.Build()); |
| } |
| |
| void WlantapMac::InstallKey(InstallKeyRequestView request, fdf::Arena& arena, |
| InstallKeyCompleter::Sync& completer) { |
| WLAN_TRACE_DURATION(); |
| listener_->WlantapMacSetKey(*request); |
| completer.buffer(arena).ReplySuccess(); |
| } |
| |
| void WlantapMac::NotifyAssociationComplete(NotifyAssociationCompleteRequestView request, |
| fdf::Arena& arena, |
| NotifyAssociationCompleteCompleter::Sync& completer) { |
| WLAN_TRACE_DURATION(); |
| |
| // This is the test driver, so we can just pretend the association was configured. |
| // TODO(https://fxbug.dev/42103599): Evaluate the use and implement |
| completer.buffer(arena).ReplySuccess(); |
| } |
| |
| void WlantapMac::ClearAssociation(ClearAssociationRequestView request, fdf::Arena& arena, |
| ClearAssociationCompleter::Sync& completer) { |
| WLAN_TRACE_DURATION(); |
| |
| // TODO(https://fxbug.dev/42103599): Evaluate the use and implement. |
| // Association is never configured, so there is nothing to clear. |
| completer.buffer(arena).ReplySuccess(); |
| } |
| |
| void WlantapMac::CancelScan(CancelScanRequestView request, fdf::Arena& arena, |
| CancelScanCompleter::Sync& completer) { |
| WLAN_TRACE_DURATION(); |
| ZX_PANIC("CancelScan is not supported."); |
| } |
| |
| void WlantapMac::UpdateWmmParameters(UpdateWmmParametersRequestView request, fdf::Arena& arena, |
| UpdateWmmParametersCompleter::Sync& completer) { |
| WLAN_TRACE_DURATION(); |
| ZX_PANIC("UpdateWmmParameters is not supported."); |
| } |
| |
| } // namespace wlan |