blob: 19c24e4fc75deb1a90df16a10ada8048b85f41b3 [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 "iface-device.h"
#include <ddk/debug.h>
#include <stdio.h>
namespace wlan {
namespace testing {
#define DEV(c) static_cast<IfaceDevice*>(c)
static zx_protocol_device_t wlanmac_test_device_ops = {
.version = DEVICE_OPS_VERSION,
.unbind = [](void* ctx) { DEV(ctx)->Unbind(); },
.release = [](void* ctx) { DEV(ctx)->Release(); },
};
static wlanmac_protocol_ops_t wlanmac_test_protocol_ops = {
.query = [](void* ctx, uint32_t options, wlanmac_info_t* info) -> zx_status_t {
return DEV(ctx)->Query(options, info);
},
.start = [](void* ctx, wlanmac_ifc_t* ifc, void* cookie) -> zx_status_t {
return DEV(ctx)->Start(ifc, cookie);
},
.stop = [](void* ctx) { DEV(ctx)->Stop(); },
.queue_tx = [](void* ctx, uint32_t options, wlan_tx_packet_t* pkt) -> zx_status_t {
return ZX_OK;
},
.set_channel = [](void* ctx, uint32_t options, wlan_channel_t* chan) -> zx_status_t {
return DEV(ctx)->SetChannel(options, chan);
},
.configure_bss = [](void* ctx, uint32_t options, wlan_bss_config_t* config) -> zx_status_t {
return ZX_OK;
},
.enable_beaconing = [](void* ctx, uint32_t options, wlan_bcn_config_t* bcn_cfg) -> zx_status_t {
return ZX_OK;
},
.configure_beacon = [](void* ctx, uint32_t options, wlan_tx_packet_t* pkt) -> zx_status_t {
return ZX_OK;
},
.set_key = [](void* ctx, uint32_t options, wlan_key_config_t* key_config) -> zx_status_t {
return ZX_OK;
},
.configure_assoc = [](void* ctx, uint32_t options, wlan_assoc_ctx_t* assoc_ctx) -> zx_status_t {
return ZX_OK;
},
.clear_assoc = [](void* ctx, uint32_t options, const uint8_t*) -> zx_status_t {
return ZX_OK;
},
};
#undef DEV
IfaceDevice::IfaceDevice(zx_device_t* device, uint16_t role) : parent_(device), role_(role) {}
zx_status_t IfaceDevice::Bind() {
zxlogf(INFO, "wlan::testing::IfaceDevice::Bind()\n");
device_add_args_t args = {};
args.version = DEVICE_ADD_ARGS_VERSION;
args.name = "wlanmac-test";
args.ctx = this;
args.ops = &wlanmac_test_device_ops;
args.proto_id = ZX_PROTOCOL_WLANMAC;
args.proto_ops = &wlanmac_test_protocol_ops;
zx_status_t status = device_add(parent_, &args, &zxdev_);
if (status != ZX_OK) { zxlogf(INFO, "wlan-test: could not add test device: %d\n", status); }
return status;
}
void IfaceDevice::Unbind() {
zxlogf(INFO, "wlan::testing::IfaceDevice::Unbind()\n");
device_remove(zxdev_);
}
void IfaceDevice::Release() {
zxlogf(INFO, "wlan::testing::IfaceDevice::Release()\n");
delete this;
}
zx_status_t IfaceDevice::Query(uint32_t options, wlanmac_info_t* info) {
zxlogf(INFO, "wlan::testing::IfaceDevice::Query()\n");
memset(info, 0, sizeof(*info));
wlan_info_t* ifc_info = &info->ifc_info;
static uint8_t mac[ETH_MAC_SIZE] = {0x02, 0x02, 0x02, 0x03, 0x03, 0x03};
std::memcpy(ifc_info->mac_addr, mac, ETH_MAC_SIZE);
// Fill out a minimal set of wlan device capabilities
ifc_info->supported_phys = WLAN_PHY_DSSS | WLAN_PHY_CCK | WLAN_PHY_OFDM | WLAN_PHY_HT;
ifc_info->driver_features = WLAN_DRIVER_FEATURE_SYNTH;
ifc_info->mac_role = role_;
ifc_info->caps = 0;
ifc_info->num_bands = 2;
// clang-format off
ifc_info->bands[0] = {
.band_id = WLAN_BAND_2GHZ,
.ht_supported = false,
.ht_caps = {},
.vht_supported = false,
.vht_caps = {},
.basic_rates = {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108},
.supported_channels =
{
.base_freq = 2417,
.channels = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
},
};
ifc_info->bands[1] = {
.band_id = WLAN_BAND_5GHZ,
.ht_supported = false,
.ht_caps = {},
.vht_supported = false,
.vht_caps = {},
.basic_rates = {12, 18, 24, 36, 48, 72, 96, 108},
.supported_channels =
{
.base_freq = 5000,
.channels = {36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165},
},
};
// clang-format on
return ZX_OK;
}
void IfaceDevice::Stop() {
zxlogf(INFO, "wlan::testing::IfaceDevice::Stop()\n");
std::lock_guard<std::mutex> lock(lock_);
ifc_ = nullptr;
ifc_cookie_ = nullptr;
}
zx_status_t IfaceDevice::Start(wlanmac_ifc_t* ifc, void* cookie) {
zxlogf(INFO, "wlan::testing::IfaceDevice::Start()\n");
std::lock_guard<std::mutex> lock(lock_);
if (ifc_ != nullptr) {
return ZX_ERR_ALREADY_BOUND;
} else {
ifc_ = ifc;
ifc_cookie_ = cookie;
}
return ZX_OK;
}
zx_status_t IfaceDevice::SetChannel(uint32_t options, wlan_channel_t* chan) {
zxlogf(INFO, "wlan::testing::IfaceDevice::SetChannel() chan=%u\n", chan->primary);
return ZX_OK;
}
} // namespace testing
} // namespace wlan