blob: 003492e1be8a380e5716ffa74d43f42785f3bb2d [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 <wlan/common/buffer_writer.h>
#include <wlan/common/write_element.h>
#include <wlan/mlme/ap/beacon_sender.h>
#include <wlan/mlme/ap/bss_interface.h>
#include <wlan/mlme/mac_frame.h>
#include <wlan/mlme/packet.h>
#include <wlan/mlme/rates_elements.h>
#include <wlan/mlme/service.h>
#include <wlan/mlme/timer.h>
#include <fbl/unique_ptr.h>
#include <fuchsia/wlan/mlme/c/fidl.h>
#include <fuchsia/wlan/mlme/cpp/fidl.h>
#include "mock_device.h"
#include "test_bss.h"
#include <gtest/gtest.h>
namespace wlan {
namespace {
namespace wlan_mlme = ::fuchsia::wlan::mlme;
struct MockBss : public BssInterface {
zx_status_t ScheduleTimeout(wlan_tu_t tus, const common::MacAddr& client_addr,
TimeoutId* id) {
return ZX_OK;
}
void CancelTimeout(TimeoutId id) { }
const common::MacAddr& bssid() const { return bssid_; }
uint64_t timestamp() { return 0; }
seq_t NextSeq(const MgmtFrameHeader& hdr) { return 0; }
seq_t NextSeq(const MgmtFrameHeader& hdr, uint8_t aci) { return 0; }
seq_t NextSeq(const DataFrameHeader& hdr) { return 0; }
std::optional<DataFrame<LlcHeader>> EthToDataFrame(const EthFrame& eth_frame,
bool needs_protection) {
return std::nullopt;
}
bool IsRsn() const { return false; }
HtConfig Ht() const { return {}; }
const Span<const SupportedRate> Rates() const { return {}; }
zx_status_t SendMgmtFrame(MgmtFrame<>&& mgmt_frame) { return ZX_ERR_NOT_SUPPORTED; }
zx_status_t SendDataFrame(DataFrame<>&& data_frame, uint32_t flags) {
return ZX_ERR_NOT_SUPPORTED;
}
zx_status_t DeliverEthernet(Span<const uint8_t> frame) { return ZX_ERR_NOT_SUPPORTED; }
void OnPreTbtt() {}
void OnBcnTxComplete() {}
wlan_channel_t Chan() const { return {}; }
common::MacAddr bssid_ = common::MacAddr(kBssid1);
};
struct BeaconSenderTest : public ::testing::Test {
BeaconSenderTest() : bcn_sender(&device) {}
MockBss bss;
MockDevice device;
BeaconSender bcn_sender;
PsCfg ps_cfg;
};
TEST_F(BeaconSenderTest, Start) {
ASSERT_FALSE(device.beaconing_enabled);
bcn_sender.Start(&bss, ps_cfg, CreateStartRequest(false));
ASSERT_TRUE(device.beaconing_enabled);
ASSERT_EQ(device.beacon.get(), nullptr);
bcn_sender.UpdateBeacon(ps_cfg);
auto pkt = std::move(device.beacon);
EXPECT_TRUE(device.beaconing_enabled);
ASSERT_NE(pkt, nullptr);
auto checked = MgmtFrameView<Beacon>::CheckType(pkt.get());
ASSERT_TRUE(checked);
auto beacon_frame = checked.CheckLength();
ASSERT_TRUE(beacon_frame);
}
TEST_F(BeaconSenderTest, ProbeRequest) {
bcn_sender.Start(&bss, ps_cfg, CreateStartRequest(false));
ASSERT_TRUE(device.wlan_queue.empty());
uint8_t buffer[1024] = {};
BufferWriter elem_w(buffer);
common::WriteSsid(&elem_w, kSsid);
RatesWriter rates_writer{kSupportedRates};
rates_writer.WriteSupportedRates(&elem_w);
rates_writer.WriteExtendedSupportedRates(&elem_w);
common::WriteDsssParamSet(&elem_w, kBssChannel.primary);
common::MacAddr ra(kClientAddress);
bcn_sender.SendProbeResponse(ra, elem_w.WrittenData());
ASSERT_FALSE(device.wlan_queue.empty());
auto pkt = std::move(*device.wlan_queue.begin());
auto checked = MgmtFrameView<ProbeResponse>::CheckType(pkt.pkt.get());
ASSERT_TRUE(checked);
auto beacon_frame = checked.CheckLength();
ASSERT_TRUE(beacon_frame);
EXPECT_EQ(pkt.cbw, CBW20);
EXPECT_EQ(pkt.phy, WLAN_PHY_OFDM);
EXPECT_EQ(pkt.flags, 0u);
}
TEST(BeaconSender, ShouldSendProbeResponse) {
const uint8_t our_ssid[] = {'f', 'o', 'o'};
const uint8_t no_ssid[] = {1, 1, 1};
EXPECT_TRUE(ShouldSendProbeResponse(no_ssid, our_ssid));
const uint8_t different_ssid[] = {0, 3, 'b', 'a', 'r', 1, 1, 1};
EXPECT_FALSE(ShouldSendProbeResponse(different_ssid, our_ssid));
const uint8_t matching_ssid[] = {0, 3, 'f', 'o', 'o', 1, 1, 1};
EXPECT_TRUE(ShouldSendProbeResponse(matching_ssid, our_ssid));
const uint8_t wildcard_ssid[] = {0, 0, 1, 1, 1};
EXPECT_TRUE(ShouldSendProbeResponse(wildcard_ssid, our_ssid));
const uint8_t malformed_ssid[35] = {
0,
33,
};
EXPECT_FALSE(ShouldSendProbeResponse(malformed_ssid, our_ssid));
}
} // namespace
} // namespace wlan