blob: b9030d4746d233aea7c81e879cc9df5957a35dac [file] [log] [blame]
// Copyright 2020 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 <fuchsia/wlan/ieee80211/cpp/fidl.h>
#include <gtest/gtest.h>
#include "src/connectivity/wlan/drivers/testing/lib/sim-env/sim-env.h"
#include "src/connectivity/wlan/drivers/testing/lib/sim-env/sim-sta-ifc.h"
#include "src/connectivity/wlan/drivers/testing/lib/sim-fake-ap/sim-fake-ap.h"
namespace wlan::testing {
namespace {
constexpr zx::duration kSimulatedClockDuration = zx::sec(10);
} // namespace
namespace wlan_ieee80211 = ::fuchsia::wlan::ieee80211;
constexpr simulation::WlanTxInfo kDefaultTxInfo = {
.channel = {.primary = 9, .cbw = WLAN_CHANNEL_BANDWIDTH__20, .secondary80 = 0}};
constexpr simulation::WlanTxInfo kWrongChannelTxInfo = {
.channel = {.primary = 10, .cbw = WLAN_CHANNEL_BANDWIDTH__20, .secondary80 = 0}};
constexpr wlan_ssid_t kApSsid = {.len = 15, .ssid = "Fuchsia Fake AP"};
const common::MacAddr kApBssid({0x11, 0x11, 0x11, 0x11, 0x11, 0x11});
static const common::MacAddr kWrongBssid({0x12, 0x34, 0x56, 0x78, 0x9a, 0xbd});
const common::MacAddr kClientMacAddr({0x22, 0x22, 0x22, 0x22, 0x22, 0x22});
void validateChannel(const wlan_channel_t& channel) {
EXPECT_EQ(channel.primary, kDefaultTxInfo.channel.primary);
EXPECT_EQ(channel.cbw, kDefaultTxInfo.channel.cbw);
EXPECT_EQ(channel.secondary80, kDefaultTxInfo.channel.secondary80);
}
class AuthTest : public ::testing::Test, public simulation::StationIfc {
public:
struct AuthResp {
AuthResp(uint16_t seq_num, simulation::SimAuthType auth_type, wlan_ieee80211::StatusCode status)
: seq_num_(seq_num), auth_type_(auth_type), status_(status){};
uint16_t seq_num_;
simulation::SimAuthType auth_type_;
wlan_ieee80211::StatusCode status_;
};
AuthTest() : ap_(&env_, kApBssid, kApSsid, kDefaultTxInfo.channel) { env_.AddStation(this); }
~AuthTest() { env_.RemoveStation(this); }
void ValidateAuthResp(uint16_t seq_num, simulation::SimAuthType auth_type,
wlan_ieee80211::StatusCode status);
simulation::Environment env_;
simulation::FakeAp ap_;
std::list<AuthResp> auth_resps_received_;
private:
void Rx(std::shared_ptr<const simulation::SimFrame> frame,
std::shared_ptr<const simulation::WlanRxInfo> info) override;
};
void AuthTest::ValidateAuthResp(uint16_t expect_seq_num, simulation::SimAuthType expect_auth_type,
wlan_ieee80211::StatusCode expect_status) {
EXPECT_EQ(auth_resps_received_.front().seq_num_, expect_seq_num);
EXPECT_EQ(auth_resps_received_.front().auth_type_, expect_auth_type);
EXPECT_EQ(auth_resps_received_.front().status_, expect_status);
auth_resps_received_.pop_front();
}
void AuthTest::Rx(std::shared_ptr<const simulation::SimFrame> frame,
std::shared_ptr<const simulation::WlanRxInfo> info) {
ASSERT_EQ(frame->FrameType(), simulation::SimFrame::FRAME_TYPE_MGMT);
validateChannel(info->channel);
auto mgmt_frame = std::static_pointer_cast<const simulation::SimManagementFrame>(frame);
// Ignore assoc resp
if (mgmt_frame->MgmtFrameType() == simulation::SimManagementFrame::FRAME_TYPE_ASSOC_RESP) {
return;
}
ASSERT_EQ(mgmt_frame->MgmtFrameType(), simulation::SimManagementFrame::FRAME_TYPE_AUTH);
auto auth_resp_frame = std::static_pointer_cast<const simulation::SimAuthFrame>(mgmt_frame);
EXPECT_EQ(auth_resp_frame->src_addr_, kApBssid);
EXPECT_EQ(auth_resp_frame->dst_addr_, kClientMacAddr);
auth_resps_received_.emplace_back(auth_resp_frame->seq_num_, auth_resp_frame->auth_type_,
auth_resp_frame->status_);
}
TEST_F(AuthTest, OpenSystemBasicUse) {
simulation::SimAuthFrame auth_req_frame(kClientMacAddr, kApBssid, 1, simulation::AUTH_TYPE_OPEN,
wlan_ieee80211::StatusCode::SUCCESS);
env_.ScheduleNotification(
std::bind(&simulation::Environment::Tx, &env_, auth_req_frame, kDefaultTxInfo, this),
zx::sec(1));
env_.Run(kSimulatedClockDuration);
ValidateAuthResp(2, simulation::AUTH_TYPE_OPEN, wlan_ieee80211::StatusCode::SUCCESS);
EXPECT_EQ(auth_resps_received_.empty(), true);
}
TEST_F(AuthTest, SharedKeyBasicUse) {
ap_.SetSecurity({.auth_handling_mode = simulation::AUTH_TYPE_SHARED_KEY});
simulation::SimAuthFrame auth_req_frame1(kClientMacAddr, kApBssid, 1,
simulation::AUTH_TYPE_SHARED_KEY,
wlan_ieee80211::StatusCode::SUCCESS);
env_.ScheduleNotification(
std::bind(&simulation::Environment::Tx, &env_, auth_req_frame1, kDefaultTxInfo, this),
zx::sec(1));
simulation::SimAuthFrame auth_req_frame2(kClientMacAddr, kApBssid, 3,
simulation::AUTH_TYPE_SHARED_KEY,
wlan_ieee80211::StatusCode::SUCCESS);
env_.ScheduleNotification(
std::bind(&simulation::Environment::Tx, &env_, auth_req_frame2, kDefaultTxInfo, this),
zx::sec(2));
env_.Run(kSimulatedClockDuration);
ValidateAuthResp(2, simulation::AUTH_TYPE_SHARED_KEY, wlan_ieee80211::StatusCode::SUCCESS);
ValidateAuthResp(4, simulation::AUTH_TYPE_SHARED_KEY, wlan_ieee80211::StatusCode::SUCCESS);
EXPECT_EQ(auth_resps_received_.empty(), true);
}
TEST_F(AuthTest, OpenSystemIgnoreTest) {
ap_.SetSecurity({.auth_handling_mode = simulation::AUTH_TYPE_OPEN});
simulation::SimAuthFrame auth_req_frame1(kClientMacAddr, kApBssid, 3, simulation::AUTH_TYPE_OPEN,
wlan_ieee80211::StatusCode::SUCCESS);
env_.ScheduleNotification(
std::bind(&simulation::Environment::Tx, &env_, auth_req_frame1, kDefaultTxInfo, this),
zx::sec(1));
// Associated station will be ignored
simulation::SimAuthFrame auth_req_frame(kClientMacAddr, kApBssid, 1, simulation::AUTH_TYPE_OPEN,
wlan_ieee80211::StatusCode::SUCCESS);
env_.ScheduleNotification(
std::bind(&simulation::Environment::Tx, &env_, auth_req_frame, kDefaultTxInfo, this),
zx::sec(2));
simulation::SimAssocReqFrame assoc_req_frame(kClientMacAddr, kApBssid, kApSsid);
env_.ScheduleNotification(
std::bind(&simulation::Environment::Tx, &env_, assoc_req_frame, kDefaultTxInfo, this),
zx::sec(3));
simulation::SimAuthFrame auth_after_assoc(kClientMacAddr, kApBssid, 1, simulation::AUTH_TYPE_OPEN,
wlan_ieee80211::StatusCode::SUCCESS);
env_.ScheduleNotification(
std::bind(&simulation::Environment::Tx, &env_, auth_after_assoc, kDefaultTxInfo, this),
zx::sec(4));
env_.Run(kSimulatedClockDuration);
// The second resp will be ignored
EXPECT_EQ(auth_resps_received_.size(), (size_t)1);
}
TEST_F(AuthTest, SharedKeyIgnoreTest) {
ap_.SetSecurity({.auth_handling_mode = simulation::AUTH_TYPE_SHARED_KEY});
// Wrong bssid frame should be ignore
simulation::SimAuthFrame wrong_bssid_frame(kClientMacAddr, kWrongBssid, 1,
simulation::AUTH_TYPE_SHARED_KEY,
wlan_ieee80211::StatusCode::SUCCESS);
env_.ScheduleNotification(
std::bind(&simulation::Environment::Tx, &env_, wrong_bssid_frame, kDefaultTxInfo, this),
zx::sec(1));
// Wrong channel frame should be ignore
simulation::SimAuthFrame wrong_channel_frame(kClientMacAddr, kApBssid, 1,
simulation::AUTH_TYPE_SHARED_KEY,
wlan_ieee80211::StatusCode::SUCCESS);
env_.ScheduleNotification(std::bind(&simulation::Environment::Tx, &env_, wrong_channel_frame,
kWrongChannelTxInfo, this),
zx::sec(2));
// auth req with status StatusCode::REFUSED_REASON_UNSPECIFIED should be ignored
simulation::SimAuthFrame refuse_frame(kClientMacAddr, kApBssid, 1,
simulation::AUTH_TYPE_SHARED_KEY,
wlan_ieee80211::StatusCode::REFUSED_REASON_UNSPECIFIED);
env_.ScheduleNotification(
std::bind(&simulation::Environment::Tx, &env_, refuse_frame, kDefaultTxInfo, this),
zx::sec(3));
// auth req with sequence number 2 should be ignored
simulation::SimAuthFrame seq_num_two_frame(kClientMacAddr, kApBssid, 2,
simulation::AUTH_TYPE_SHARED_KEY,
wlan_ieee80211::StatusCode::SUCCESS);
env_.ScheduleNotification(
std::bind(&simulation::Environment::Tx, &env_, seq_num_two_frame, kDefaultTxInfo, this),
zx::sec(4));
// auth req with sequence number 4 should be ignored
simulation::SimAuthFrame seq_num_four_frame(kClientMacAddr, kApBssid, 4,
simulation::AUTH_TYPE_SHARED_KEY,
wlan_ieee80211::StatusCode::SUCCESS);
env_.ScheduleNotification(
std::bind(&simulation::Environment::Tx, &env_, seq_num_four_frame, kDefaultTxInfo, this),
zx::sec(5));
env_.Run(kSimulatedClockDuration);
EXPECT_EQ(auth_resps_received_.empty(), true);
}
TEST_F(AuthTest, OpenSystemRefuseTest) {
simulation::SimAuthFrame wrong_type_frame(kClientMacAddr, kApBssid, 1,
simulation::AUTH_TYPE_SHARED_KEY,
wlan_ieee80211::StatusCode::SUCCESS);
env_.ScheduleNotification(
std::bind(&simulation::Environment::Tx, &env_, wrong_type_frame, kDefaultTxInfo, this),
zx::sec(3));
env_.Run(kSimulatedClockDuration);
// The auth type in frame is the same as that in auth req frame, and if auth type in quth req is
// different from that in AP's auth_handling_mode, it will reply a refuse auth resp frame.
ValidateAuthResp(2, simulation::AUTH_TYPE_SHARED_KEY,
wlan_ieee80211::StatusCode::REFUSED_REASON_UNSPECIFIED);
EXPECT_EQ(auth_resps_received_.empty(), true);
}
TEST_F(AuthTest, SharedKeyRefuseTest) {
ap_.SetSecurity({.auth_handling_mode = simulation::AUTH_TYPE_SHARED_KEY});
simulation::SimAuthFrame wrong_type_frame(kClientMacAddr, kApBssid, 1, simulation::AUTH_TYPE_OPEN,
wlan_ieee80211::StatusCode::SUCCESS);
env_.ScheduleNotification(
std::bind(&simulation::Environment::Tx, &env_, wrong_type_frame, kDefaultTxInfo, this),
zx::sec(3));
env_.Run(kSimulatedClockDuration);
ValidateAuthResp(2, simulation::AUTH_TYPE_OPEN,
wlan_ieee80211::StatusCode::REFUSED_REASON_UNSPECIFIED);
EXPECT_EQ(auth_resps_received_.empty(), true);
}
} // namespace wlan::testing