blob: 6a0531903e346cdb9a9400d0d36a788ee6ec6a25 [file] [log] [blame]
// Copyright 2019 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 <memory>
#include <gmock/gmock.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-frame.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
using ::testing::NotNull;
constexpr simulation::WlanTxInfo kAp1TxInfo = {
.channel = {.primary = 9, .cbw = WLAN_CHANNEL_BANDWIDTH__20, .secondary80 = 0}};
constexpr wlan_ssid_t kAp1Ssid = {.len = 16, .ssid = "Fuchsia Fake AP1"};
const common::MacAddr kAp1Bssid({0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc});
constexpr simulation::WlanTxInfo kAp2TxInfo = {
.channel = {.primary = 10, .cbw = WLAN_CHANNEL_BANDWIDTH__20, .secondary80 = 0}};
constexpr wlan_ssid_t kAp2Ssid = {.len = 16, .ssid = "Fuchsia Fake AP2"};
const common::MacAddr kAp2Bssid({0x12, 0x34, 0x56, 0x78, 0x9a, 0xcc});
const common::MacAddr kClientMacAddr({0x11, 0x22, 0x33, 0x44, 0xee, 0xff});
class ProbeTest : public ::testing::Test, public simulation::StationIfc {
public:
ProbeTest()
: ap_1_(&env_, kAp1Bssid, kAp1Ssid, kAp1TxInfo.channel),
ap_2_(&env_, kAp2Bssid, kAp2Ssid, kAp2TxInfo.channel) {
env_.AddStation(this);
};
simulation::Environment env_;
simulation::FakeAp ap_1_;
simulation::FakeAp ap_2_;
unsigned probe_resp_count_ = 0;
std::list<common::MacAddr> bssid_resp_list_;
std::list<wlan_ssid_t> ssid_resp_list_;
std::list<wlan_channel_t> channel_resp_list_;
std::list<double> sig_strength_resp_list;
private:
// StationIfc methods
void Rx(std::shared_ptr<const simulation::SimFrame> frame,
std::shared_ptr<const simulation::WlanRxInfo> info) override;
};
void ProbeTest::Rx(std::shared_ptr<const simulation::SimFrame> frame,
std::shared_ptr<const simulation::WlanRxInfo> info) {
ASSERT_EQ(frame->FrameType(), simulation::SimFrame::FRAME_TYPE_MGMT);
auto mgmt_frame = std::static_pointer_cast<const simulation::SimManagementFrame>(frame);
if (mgmt_frame->MgmtFrameType() != simulation::SimManagementFrame::FRAME_TYPE_PROBE_RESP) {
GTEST_FAIL();
}
probe_resp_count_++;
channel_resp_list_.push_back(info->channel);
sig_strength_resp_list.push_back(info->signal_strength);
auto probe_resp_frame = std::static_pointer_cast<const simulation::SimProbeRespFrame>(mgmt_frame);
bssid_resp_list_.push_back(probe_resp_frame->src_addr_);
std::shared_ptr<simulation::InformationElement> ssid_generic_ie =
probe_resp_frame->FindIe(simulation::InformationElement::IE_TYPE_SSID);
ASSERT_THAT(ssid_generic_ie, NotNull());
auto ssid_ie = std::static_pointer_cast<simulation::SsidInformationElement>(ssid_generic_ie);
ssid_resp_list_.push_back(ssid_ie->ssid_);
}
void compareChannel(const wlan_channel_t& channel1, const wlan_channel_t& channel2) {
EXPECT_EQ(channel1.primary, channel2.primary);
EXPECT_EQ(channel1.cbw, channel2.cbw);
EXPECT_EQ(channel1.secondary80, channel2.secondary80);
}
void compareSsid(const wlan_ssid_t& ssid1, const wlan_ssid_t& ssid2) {
ASSERT_EQ(ssid1.len, ssid2.len);
EXPECT_EQ(memcmp(ssid1.ssid, ssid2.ssid, ssid1.len), 0);
}
/* Verify that probe request which is sent to a channel with no ap active on, will not get
any response.
*/
TEST_F(ProbeTest, DifferentChannel) {
constexpr simulation::WlanTxInfo kWrongChannelTxInfo = {
.channel = {.primary = 11, .cbw = WLAN_CHANNEL_BANDWIDTH__20, .secondary80 = 0}};
simulation::SimProbeReqFrame probe_req_frame(kClientMacAddr);
env_.ScheduleNotification(
std::bind(&simulation::Environment::Tx, &env_, probe_req_frame, kWrongChannelTxInfo, this),
zx::sec(1));
env_.Run(kSimulatedClockDuration);
EXPECT_EQ(probe_resp_count_, 0U);
EXPECT_EQ(channel_resp_list_.empty(), true);
EXPECT_EQ(bssid_resp_list_.empty(), true);
EXPECT_EQ(ssid_resp_list_.empty(), true);
EXPECT_EQ(sig_strength_resp_list.empty(), true);
}
/* Verify that probe requests sent to different APs on different channels will get appropriate
responses and in right sequence. Signal strengths are reasonable and weaker for further AP.
Timeline for this test:
100 usec: send probe request to First channel.
200 usec: send probe request to second channel.
*/
TEST_F(ProbeTest, TwoApsBasicUse) {
env_.MoveStation(this, 0, 0);
env_.MoveStation(&ap_1_, 0, 0);
env_.MoveStation(&ap_2_, 10, 0);
simulation::SimProbeReqFrame chan1_frame(kClientMacAddr);
env_.ScheduleNotification(
std::bind(&simulation::Environment::Tx, &env_, chan1_frame, kAp1TxInfo, this), zx::usec(100));
env_.Run(kSimulatedClockDuration);
EXPECT_EQ(probe_resp_count_, 1U);
simulation::SimProbeReqFrame chan2_frame(kClientMacAddr);
env_.ScheduleNotification(
std::bind(&simulation::Environment::Tx, &env_, chan2_frame, kAp2TxInfo, this), zx::usec(200));
env_.Run(kSimulatedClockDuration);
EXPECT_EQ(probe_resp_count_, 2U);
ASSERT_EQ(bssid_resp_list_.size(), (size_t)2);
ASSERT_EQ(ssid_resp_list_.size(), (size_t)2);
ASSERT_EQ(channel_resp_list_.size(), (size_t)2);
ASSERT_EQ(sig_strength_resp_list.size(), (size_t)2);
EXPECT_EQ(bssid_resp_list_.front(), kAp1Bssid);
bssid_resp_list_.pop_front();
EXPECT_EQ(bssid_resp_list_.front(), kAp2Bssid);
compareSsid(ssid_resp_list_.front(), kAp1Ssid);
ssid_resp_list_.pop_front();
compareSsid(ssid_resp_list_.front(), kAp2Ssid);
compareChannel(channel_resp_list_.front(), kAp1TxInfo.channel);
channel_resp_list_.pop_front();
compareChannel(channel_resp_list_.front(), kAp2TxInfo.channel);
double close_signal_strength = sig_strength_resp_list.front();
sig_strength_resp_list.pop_front();
ASSERT_LT(close_signal_strength, 0);
ASSERT_GE(close_signal_strength, sig_strength_resp_list.front());
}
} // namespace wlan::testing