blob: 71433e67ae35eb88c946e8bb5e06d5da1248e68b [file] [log] [blame] [edit]
// 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 "utils.h"
#include <fuchsia/hardware/ethernet/c/banjo.h>
#include <fuchsia/hardware/wlan/info/c/banjo.h>
#include <fuchsia/hardware/wlan/mac/c/banjo.h>
#include <fuchsia/hardware/wlanphyimpl/c/banjo.h>
#include <fuchsia/wlan/device/cpp/fidl.h>
#include <wlan/common/band.h>
#include <wlan/common/channel.h>
#include <wlan/common/element.h>
#include <wlan/common/parse_element.h>
namespace wlan {
namespace wlan_common = ::fuchsia::wlan::common;
namespace wlan_device = ::fuchsia::wlan::device;
namespace wlan_tap = ::fuchsia::wlan::tap;
uint16_t ConvertSupportedPhys(const ::std::vector<wlan_device::SupportedPhy>& phys) {
uint16_t ret = 0;
for (auto sp : phys) {
switch (sp) {
case wlan_device::SupportedPhy::DSSS:
ret |= WLAN_INFO_PHY_TYPE_DSSS;
break;
case wlan_device::SupportedPhy::CCK:
ret |= WLAN_INFO_PHY_TYPE_CCK;
break;
case wlan_device::SupportedPhy::OFDM:
ret |= WLAN_INFO_PHY_TYPE_OFDM;
break;
case wlan_device::SupportedPhy::HT:
ret |= WLAN_INFO_PHY_TYPE_HT;
break;
case wlan_device::SupportedPhy::VHT:
ret |= WLAN_INFO_PHY_TYPE_VHT;
break;
}
}
return ret;
}
uint32_t ConvertDriverFeatures(const ::std::vector<wlan_common::DriverFeature>& dfs) {
uint32_t ret = 0;
for (auto df : dfs) {
switch (df) {
case wlan_common::DriverFeature::SCAN_OFFLOAD:
ret |= WLAN_INFO_DRIVER_FEATURE_SCAN_OFFLOAD;
break;
case wlan_common::DriverFeature::RATE_SELECTION:
ret |= WLAN_INFO_DRIVER_FEATURE_RATE_SELECTION;
break;
case wlan_common::DriverFeature::SYNTH:
ret |= WLAN_INFO_DRIVER_FEATURE_SYNTH;
break;
case wlan_common::DriverFeature::TX_STATUS_REPORT:
ret |= WLAN_INFO_DRIVER_FEATURE_TX_STATUS_REPORT;
break;
case wlan_common::DriverFeature::DFS:
ret |= WLAN_INFO_DRIVER_FEATURE_DFS;
break;
case wlan_common::DriverFeature::PROBE_RESP_OFFLOAD:
ret |= WLAN_INFO_DRIVER_FEATURE_PROBE_RESP_OFFLOAD;
break;
case wlan_common::DriverFeature::SAE_SME_AUTH:
ret |= WLAN_INFO_DRIVER_FEATURE_SAE_SME_AUTH;
break;
case wlan_common::DriverFeature::SAE_DRIVER_AUTH:
ret |= WLAN_INFO_DRIVER_FEATURE_SAE_DRIVER_AUTH;
break;
case wlan_common::DriverFeature::MFP:
ret |= WLAN_INFO_DRIVER_FEATURE_MFP;
break;
// TODO(fxbug.dev/41640): Remove this flag once FullMAC drivers stop interacting with SME.
case wlan_common::DriverFeature::TEMP_SOFTMAC:
// Vendor driver has no control over this flag.
break;
}
}
return ret;
}
uint16_t ConvertMacRole(wlan_device::MacRole role) {
switch (role) {
case wlan_device::MacRole::AP:
return WLAN_INFO_MAC_ROLE_AP;
case wlan_device::MacRole::CLIENT:
return WLAN_INFO_MAC_ROLE_CLIENT;
case wlan_device::MacRole::MESH:
return WLAN_INFO_MAC_ROLE_MESH;
}
}
wlan_device::MacRole ConvertMacRole(uint16_t role) {
switch (role) {
case WLAN_INFO_MAC_ROLE_AP:
return wlan_device::MacRole::AP;
case WLAN_INFO_MAC_ROLE_CLIENT:
return wlan_device::MacRole::CLIENT;
case WLAN_INFO_MAC_ROLE_MESH:
return wlan_device::MacRole::MESH;
}
ZX_ASSERT(0);
}
uint32_t ConvertCaps(const ::std::vector<wlan_device::Capability>& caps) {
uint32_t ret = 0;
for (auto cap : caps) {
switch (cap) {
case wlan_device::Capability::SHORT_PREAMBLE:
ret |= WLAN_INFO_HARDWARE_CAPABILITY_SHORT_PREAMBLE;
break;
case wlan_device::Capability::SPECTRUM_MGMT:
ret |= WLAN_INFO_HARDWARE_CAPABILITY_SPECTRUM_MGMT;
break;
case wlan_device::Capability::QOS:
ret |= WLAN_INFO_HARDWARE_CAPABILITY_QOS;
break;
case wlan_device::Capability::SHORT_SLOT_TIME:
ret |= WLAN_INFO_HARDWARE_CAPABILITY_SHORT_SLOT_TIME;
break;
case wlan_device::Capability::RADIO_MSMT:
ret |= WLAN_INFO_HARDWARE_CAPABILITY_RADIO_MSMT;
break;
case wlan_device::Capability::SIMULTANEOUS_CLIENT_AP:
ret |= WLAN_INFO_HARDWARE_CAPABILITY_SIMULTANEOUS_CLIENT_AP;
break;
}
}
return ret;
}
void ConvertBandInfo(const wlan_device::BandInfo& in, wlan_info_band_info_t* out) {
memset(out, 0, sizeof(*out));
out->band = static_cast<uint8_t>(wlan::common::BandFromFidl(in.band_id));
if (in.ht_caps != nullptr) {
out->ht_supported = true;
out->ht_caps = ::wlan::common::ParseHtCapabilities(in.ht_caps->bytes)->ToDdk();
} else {
out->ht_supported = false;
}
if (in.vht_caps != nullptr) {
out->vht_supported = true;
out->vht_caps = ::wlan::common::ParseVhtCapabilities(in.vht_caps->bytes)->ToDdk();
} else {
out->vht_supported = false;
}
std::copy_n(in.rates.data(), std::min<size_t>(in.rates.size(), WLAN_INFO_BAND_INFO_MAX_RATES),
out->rates);
out->supported_channels.base_freq = in.supported_channels.base_freq;
std::copy_n(in.supported_channels.channels.data(),
std::min<size_t>(in.supported_channels.channels.size(),
WLAN_INFO_CHANNEL_LIST_MAX_CHANNELS),
out->supported_channels.channels);
}
zx_status_t ConvertTapPhyConfig(wlanmac_info_t * mac_info,
const wlan_tap::WlantapPhyConfig& tap_phy_config) {
std::memset(mac_info, 0, sizeof(*mac_info));
std::copy_n(tap_phy_config.iface_mac_addr.begin(), ETH_MAC_SIZE, mac_info->mac_addr);
mac_info->supported_phys = ConvertSupportedPhys(tap_phy_config.supported_phys);
mac_info->driver_features = ConvertDriverFeatures(tap_phy_config.driver_features);
mac_info->mac_role = ConvertMacRole(tap_phy_config.mac_role);
mac_info->caps = ConvertCaps(tap_phy_config.caps);
mac_info->bands_count =
std::min(tap_phy_config.bands.size(), static_cast<size_t>(WLAN_INFO_MAX_BANDS));
for (size_t i = 0; i < mac_info->bands_count; ++i) {
ConvertBandInfo((tap_phy_config.bands)[i], &mac_info->bands[i]);
}
return ZX_OK;
}
zx_status_t ConvertTapPhyConfig(wlanphy_impl_info_t * phy_impl_info,
const wlan_tap::WlantapPhyConfig& tap_phy_config) {
std::memset(phy_impl_info, 0, sizeof(*phy_impl_info));
phy_impl_info->supported_mac_roles = ConvertMacRole(tap_phy_config.mac_role);
return ZX_OK;
}
wlan_tx_status_t ConvertTxStatus(const wlan_tap::WlanTxStatus& in) {
wlan_tx_status_t out;
std::copy(in.peer_addr.cbegin(), in.peer_addr.cend(), out.peer_addr);
for (size_t i = 0; i < in.tx_status_entries.size(); ++i) {
out.tx_status_entry[i].tx_vector_idx = in.tx_status_entries[i].tx_vec_idx;
out.tx_status_entry[i].attempts = in.tx_status_entries[i].attempts;
}
out.success = in.success;
return out;
}
} // namespace wlan