// Copyright 2022 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 <fidl/fuchsia.wlan.ieee80211/cpp/wire_types.h>
#include <lib/async/cpp/task.h>
#include <lib/fdio/directory.h>
#include <lib/fidl/cpp/wire/arena.h>
#include <lib/sync/cpp/completion.h>
#include <lib/zx/channel.h>
#include <stdlib.h>
#include <zircon/errors.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>

#include <iterator>
#include <list>
#include <memory>
#include <utility>

#include <gtest/gtest.h>

#include "lib/fidl/cpp/wire/array.h"
#include "third_party/iwlwifi/platform/banjo/common.h"
#include "third_party/iwlwifi/platform/banjo/ieee80211.h"
#include "third_party/iwlwifi/platform/banjo/softmac.h"
#include "third_party/iwlwifi/platform/wlansoftmac-device.h"
#include "third_party/iwlwifi/test/mock-function.h"

extern "C" {
#include "third_party/iwlwifi/iwl-nvm-parse.h"
#include "third_party/iwlwifi/mvm/mvm.h"
}  // extern "C"

#include "third_party/iwlwifi/platform/mvm-mlme.h"
#include "third_party/iwlwifi/platform/scoped_utils.h"
#include "third_party/iwlwifi/platform/stats.h"
#include "third_party/iwlwifi/test/mock-trans.h"
#include "third_party/iwlwifi/test/single-ap-test.h"
#include "third_party/iwlwifi/test/wlan-pkt-builder.h"

namespace wlan::testing {
namespace {

constexpr size_t kListenInterval = 100;
constexpr uint8_t kInvalidBandIdFillByte = 0xa5;
constexpr wlan_band_t kInvalidBandId = 0xa5;
constexpr zx_handle_t kDummyMlmeChannel = 73939133;  // An arbitrary value not ZX_HANDLE_INVALID
constexpr size_t kDefaultBeaconPeriod = 100;
constexpr size_t kNonDefaultBeaconPeriod = 123;
constexpr size_t kWlanSoftmacBandCapabilityBufferSize =
    fidl::MaxSizeInChannel<fuchsia_wlan_softmac::wire::WlanSoftmacBandCapability,
                           fidl::MessageDirection::kReceiving>();
constexpr fuchsia_wlan_common::wire::BssType kDefaultBssType =
    fuchsia_wlan_common::wire::BssType::kInfrastructure;

class WlanSoftmacDeviceTest : public SingleApTest,
                              public fdf::WireServer<fuchsia_wlan_softmac::WlanSoftmacIfc> {
 public:
  WlanSoftmacDeviceTest() : test_arena_(nullptr) {
    mvmvif_ = reinterpret_cast<struct iwl_mvm_vif*>(calloc(1, sizeof(struct iwl_mvm_vif)));
    mvmvif_->mvm = iwl_trans_get_mvm(sim_trans_.iwl_trans());
    mvmvif_->mlme_channel = kDummyMlmeChannel;
    mvmvif_->mac_role = WLAN_MAC_ROLE_CLIENT;
    mvmvif_->bss_conf = {.beacon_int = kListenInterval};
    mvmvif_->mvm->mvmvif[0] = mvmvif_;

    // mac_init() is called inside the constructor.
    device_ =
        std::make_unique<::wlan::iwlwifi::WlanSoftmacDevice>(sim_trans_.iwl_trans(), 0, mvmvif_);

    auto endpoints = fdf::CreateEndpoints<fuchsia_wlan_softmac::WlanSoftmac>();
    EXPECT_FALSE(endpoints.is_error());

    device_->ServiceConnectHandler(sim_trans_.fdf_driver_dispatcher(),
                                   std::move(endpoints->server));

    client_ = fdf::WireSyncClient<fuchsia_wlan_softmac::WlanSoftmac>(std::move(endpoints->client));

    // Create test arena.
    auto arena = fdf::Arena::Create(0, 0);
    EXPECT_FALSE(arena.is_error());

    test_arena_ = *std::move(arena);
  }

  void Recv(RecvRequestView request, fdf::Arena& arena, RecvCompleter::Sync& completer) override {
    recv_called_ = true;
    completer.buffer(arena).Reply();
  }
  void ReportTxResult(ReportTxResultRequestView request, fdf::Arena& arena,
                      ReportTxResultCompleter::Sync& completer) override {
    // Overriding the virtual function, not being used at this point.
    completer.buffer(arena).Reply();
  }
  void NotifyScanComplete(NotifyScanCompleteRequestView request, fdf::Arena& arena,
                          NotifyScanCompleteCompleter::Sync& completer) override {
    // Overriding the virtual function, not being used at this point.
    completer.buffer(arena).Reply();
  }

 protected:
  struct iwl_mvm_vif* mvmvif_;
  std::unique_ptr<::wlan::iwlwifi::WlanSoftmacDevice> device_;

  fdf::WireSyncClient<fuchsia_wlan_softmac::WlanSoftmac> client_;

  fdf::UnownedSynchronizedDispatcher server_dispatcher_ =
      sim_trans_.get_unowned_synchronized_dispatcher();

  fdf::Arena test_arena_;

  // The marks of WlanSoftmacIfc function calls.
  bool recv_called_ = false;
};

//////////////////////////////////// Helper Functions  /////////////////////////////////////////////

TEST_F(WlanSoftmacDeviceTest, ComposeBandList) {
  struct iwl_nvm_data nvm_data;
  fuchsia_wlan_common::WlanBand bands[fuchsia_wlan_common::wire::kMaxBands];

  // nothing enabled
  memset(&nvm_data, 0, sizeof(nvm_data));
  memset(bands, kInvalidBandIdFillByte, sizeof(bands));
  EXPECT_EQ(0, compose_band_list(&nvm_data, bands));
  EXPECT_EQ(kInvalidBandId, uint8_t{bands[0]});
  EXPECT_EQ(kInvalidBandId, uint8_t{bands[1]});

  // 2.4GHz only
  memset(&nvm_data, 0, sizeof(nvm_data));
  memset(bands, kInvalidBandIdFillByte, sizeof(bands));
  nvm_data.sku_cap_band_24ghz_enable = true;
  EXPECT_EQ(1, compose_band_list(&nvm_data, bands));
  EXPECT_EQ(fuchsia_wlan_common::WlanBand::kTwoGhz, bands[0]);
  EXPECT_EQ(kInvalidBandId, uint8_t{bands[1]});

  // 5GHz only
  memset(&nvm_data, 0, sizeof(nvm_data));
  memset(bands, kInvalidBandIdFillByte, sizeof(bands));
  nvm_data.sku_cap_band_52ghz_enable = true;
  EXPECT_EQ(1, compose_band_list(&nvm_data, bands));
  EXPECT_EQ(fuchsia_wlan_common::WlanBand::kFiveGhz, bands[0]);
  EXPECT_EQ(kInvalidBandId, uint8_t{bands[1]});

  // both bands enabled
  memset(&nvm_data, 0, sizeof(nvm_data));
  memset(bands, kInvalidBandIdFillByte, sizeof(bands));
  nvm_data.sku_cap_band_24ghz_enable = true;
  nvm_data.sku_cap_band_52ghz_enable = true;
  EXPECT_EQ(2, compose_band_list(&nvm_data, bands));
  EXPECT_EQ(fuchsia_wlan_common::WlanBand::kTwoGhz, bands[0]);
  EXPECT_EQ(fuchsia_wlan_common::WlanBand::kFiveGhz, bands[1]);
}

TEST_F(WlanSoftmacDeviceTest, FillBandCapabilityList) {
  // The default 'nvm_data' is loaded from test/sim-default-nvm.cc.

  const struct iwl_nvm_data* nvm_data = iwl_trans_get_mvm(sim_trans_.iwl_trans())->nvm_data;
  fuchsia_wlan_common::WlanBand bands[fuchsia_wlan_common::wire::kMaxBands];
  size_t band_cap_count = compose_band_list(nvm_data, bands);
  fidl::Arena<kWlanSoftmacBandCapabilityBufferSize> arena;
  ASSERT_LE(band_cap_count, fuchsia_wlan_common::wire::kMaxBands);

  fuchsia_wlan_softmac::wire::WlanSoftmacBandCapability
      band_cap_list[fuchsia_wlan_common_MAX_BANDS] = {};
  fill_band_cap_list(nvm_data, bands, band_cap_count, arena, band_cap_list);

  // 2.4Ghz
  fuchsia_wlan_softmac::wire::WlanSoftmacBandCapability* band_cap = &band_cap_list[0];
  EXPECT_EQ(fuchsia_wlan_common::WlanBand::kTwoGhz, band_cap->band());
  EXPECT_TRUE(band_cap->has_ht_caps());
  EXPECT_EQ(12, band_cap->basic_rate_count());
  EXPECT_EQ(2, band_cap->basic_rate_list()[0]);     // 1Mbps
  EXPECT_EQ(108, band_cap->basic_rate_list()[11]);  // 54Mbps
  EXPECT_EQ(13, band_cap->operating_channel_count());
  EXPECT_EQ(1, band_cap->operating_channel_list()[0]);
  EXPECT_EQ(13, band_cap->operating_channel_list()[12]);
  // 5GHz
  band_cap = &band_cap_list[1];
  EXPECT_EQ(fuchsia_wlan_common::WlanBand::kFiveGhz, band_cap->band());
  EXPECT_TRUE(band_cap->has_ht_caps());
  EXPECT_EQ(8, band_cap->basic_rate_count());
  EXPECT_EQ(12, band_cap->basic_rate_list()[0]);   // 6Mbps
  EXPECT_EQ(108, band_cap->basic_rate_list()[7]);  // 54Mbps
  EXPECT_EQ(25, band_cap->operating_channel_count());
  EXPECT_EQ(36, band_cap->operating_channel_list()[0]);
  EXPECT_EQ(165, band_cap->operating_channel_list()[24]);
}

TEST_F(WlanSoftmacDeviceTest, FillBandCapabilityListOnly5GHz) {
  // The default 'nvm_data' is loaded from test/sim-default-nvm.cc.
  fidl::Arena<kWlanSoftmacBandCapabilityBufferSize> arena;
  fuchsia_wlan_common::WlanBand bands[fuchsia_wlan_common::wire::kMaxBands] = {
      fuchsia_wlan_common::WlanBand::kFiveGhz,
  };
  fuchsia_wlan_softmac::wire::WlanSoftmacBandCapability
      band_cap_list[fuchsia_wlan_common::wire::kMaxBands] = {};

  fill_band_cap_list(iwl_trans_get_mvm(sim_trans_.iwl_trans())->nvm_data, bands, 1, arena,
                     band_cap_list);
  // 5GHz
  fuchsia_wlan_softmac::wire::WlanSoftmacBandCapability* band_cap = &band_cap_list[0];
  EXPECT_EQ(fuchsia_wlan_common::WlanBand::kFiveGhz, band_cap->band());
  EXPECT_TRUE(band_cap->has_ht_caps());
  EXPECT_EQ(8, band_cap->basic_rate_count());
  EXPECT_EQ(12, band_cap->basic_rate_list()[0]);   // 6Mbps
  EXPECT_EQ(108, band_cap->basic_rate_list()[7]);  // 54Mbps
  EXPECT_EQ(25, band_cap->operating_channel_count());
  EXPECT_EQ(36, band_cap->operating_channel_list()[0]);
  EXPECT_EQ(165, band_cap->operating_channel_list()[24]);
  // index 1 should be empty.
  band_cap = &band_cap_list[1];
  EXPECT_FALSE(band_cap->has_ht_caps());
  EXPECT_FALSE(band_cap->has_basic_rate_list());
  EXPECT_FALSE(band_cap->has_operating_channel_list());
}

TEST_F(WlanSoftmacDeviceTest, Query) {
  auto result = client_.buffer(test_arena_)->Query();
  auto& info = *result->value();
  ASSERT_TRUE(result.ok());
  ASSERT_FALSE(result->is_error());
  EXPECT_TRUE(info.has_mac_role());
  EXPECT_EQ(fuchsia_wlan_common::wire::WlanMacRole::kClient, info.mac_role());

  //
  // The below code assumes the test/sim-default-nvm.cc contains 2 bands.
  //
  //   .band_cap_list[0]: fuchsia_wlan_common::WlanBand::kTwoGhz
  //   .band_cap_list[1]: fuchsia_wlan_common::WlanBand::kFiveGhz
  //
  ASSERT_EQ(2, info.band_caps().count());
  EXPECT_EQ(12, info.band_caps().data()[0].basic_rate_count());
  EXPECT_EQ(2, info.band_caps().data()[0].basic_rate_list()[0]);     // 1 Mbps
  EXPECT_EQ(36, info.band_caps().data()[0].basic_rate_list()[7]);    // 18 Mbps
  EXPECT_EQ(108, info.band_caps().data()[0].basic_rate_list()[11]);  // 54 Mbps
  EXPECT_EQ(8, info.band_caps().data()[1].basic_rate_count());
  EXPECT_EQ(12, info.band_caps().data()[1].basic_rate_list()[0]);  // 6 Mbps
  EXPECT_EQ(165, info.band_caps().data()[1].operating_channel_list()[24]);
}

TEST_F(WlanSoftmacDeviceTest, DiscoveryFeatureQuery) {
  auto result = client_.buffer(test_arena_)->QueryDiscoverySupport();
  ASSERT_TRUE(result.ok());
  ASSERT_FALSE(result->is_error());
  EXPECT_TRUE(result->value()->resp.scan_offload.supported);
  EXPECT_FALSE(result->value()->resp.probe_response_offload.supported);
}

TEST_F(WlanSoftmacDeviceTest, MacSublayerFeatureQuery) {
  auto result = client_.buffer(test_arena_)->QueryMacSublayerSupport();
  ASSERT_TRUE(result.ok());
  ASSERT_FALSE(result->is_error());
  EXPECT_FALSE(result->value()->resp.rate_selection_offload.supported);
  EXPECT_EQ(result->value()->resp.device.mac_implementation_type,
            fuchsia_wlan_common::wire::MacImplementationType::kSoftmac);
  EXPECT_FALSE(result->value()->resp.device.is_synthetic);
  EXPECT_EQ(result->value()->resp.data_plane.data_plane_type,
            fuchsia_wlan_common::wire::DataPlaneType::kEthernetDevice);
}

TEST_F(WlanSoftmacDeviceTest, SecurityFeatureQuery) {
  auto result = client_.buffer(test_arena_)->QuerySecuritySupport();
  ASSERT_TRUE(result.ok());
  ASSERT_FALSE(result->is_error());
  EXPECT_TRUE(result->value()->resp.mfp.supported);
  EXPECT_FALSE(result->value()->resp.sae.driver_handler_supported);
  EXPECT_TRUE(result->value()->resp.sae.sme_handler_supported);
}

TEST_F(WlanSoftmacDeviceTest, SpectrumManagementFeatureQuery) {
  auto result = client_.buffer(test_arena_)->QuerySpectrumManagementSupport();
  ASSERT_TRUE(result.ok());
  ASSERT_FALSE(result->is_error());
  EXPECT_TRUE(result->value()->resp.dfs.supported);
}

TEST_F(WlanSoftmacDeviceTest, MacStart) {
  // Created the end points for WlanSoftmacIfc protocol, and pass the client end to
  // WlanSoftmacDevice.
  auto endpoints = fdf::CreateEndpoints<fuchsia_wlan_softmac::WlanSoftmacIfc>();
  ASSERT_FALSE(endpoints.is_error());

  fdf::BindServer(server_dispatcher_->get(), std::move(endpoints->server), this);

  // This FIDL call should invoke mac_start() and pass the pointer of WlanSoftmacDeviceTest to it,
  // the pointer will be copied to mvmvif_->ifc.ctx.
  auto result = client_.buffer(test_arena_)->Start(std::move(endpoints->client));
  EXPECT_TRUE(result.ok());
  EXPECT_FALSE(result->is_error());
}

TEST_F(WlanSoftmacDeviceTest, MacStartOnlyOneMlmeChannelAllowed) {
  // The normal case. A channel will be transferred to MLME.
  constexpr zx_handle_t kMlmeChannel = static_cast<zx_handle_t>(0xF001);

  // Manually set mlme channel here, in reality, this is set when WlanPhyImplDevice::CreateIface()
  // is called.
  mvmvif_->mlme_channel = kMlmeChannel;

  {
    // Don't need to bind the server here because we won't need to use WlanSoftmacIfc calls.
    auto endpoints = fdf::CreateEndpoints<fuchsia_wlan_softmac::WlanSoftmacIfc>();

    ASSERT_FALSE(endpoints.is_error());

    auto result = client_.buffer(test_arena_)->Start(std::move(endpoints->client));
    EXPECT_TRUE(result.ok());
    EXPECT_FALSE(result->is_error());
    // Verify the channel returned.
    ASSERT_EQ(result->value()->sme_channel, kMlmeChannel);
    ASSERT_EQ(mvmvif_->mlme_channel, ZX_HANDLE_INVALID);  // Driver no longer holds the ownership.
  }

  {
    // Create another pair of endpoints for the next call.
    auto endpoints = fdf::CreateEndpoints<fuchsia_wlan_softmac::WlanSoftmacIfc>();

    // Since the driver no longer owns the handle, the start should fail.
    auto result = client_.buffer(test_arena_)->Start(std::move(endpoints->client));
    EXPECT_TRUE(result.ok());
    EXPECT_TRUE(result->is_error());
    EXPECT_EQ(ZX_ERR_ALREADY_BOUND, result->error_value());
  }
}

TEST_F(WlanSoftmacDeviceTest, SingleRxPacket) {
  // Created the end points for WlanSoftmacIfc protocol, and pass the client end to
  // WlanSoftmacDevice.
  auto endpoints = fdf::CreateEndpoints<fuchsia_wlan_softmac::WlanSoftmacIfc>();
  ASSERT_FALSE(endpoints.is_error());

  fdf::BindServer(server_dispatcher_->get(), std::move(endpoints->server), this);

  // This FIDL call should invoke mac_start() and pass the pointer of WlanSoftmacDeviceTest to it,
  // the pointer will be copied to mvmvif_->ifc.ctx.
  auto result = client_.buffer(test_arena_)->Start(std::move(endpoints->client));

  EXPECT_TRUE(result.ok());
  EXPECT_FALSE(result->is_error());

  // Create an dummy rx packet.
  // TODO(fxbug.dev/99777): Integrate it into WlanPktBuilder.
  const uint8_t kMacPkt[] = {
      0x08, 0x01,                          // frame_ctrl
      0x00, 0x00,                          // duration
      0x11, 0x22, 0x33, 0x44, 0x55, 0x66,  // MAC1
      0x01, 0x02, 0x03, 0x04, 0x05, 0x06,  // MAC2
      0x01, 0x02, 0x03, 0x04, 0x05, 0x06,  // MAC3
      0x00, 0x00,                          // seq_ctrl
      0x45, 0x00, 0x55, 0x66, 0x01, 0x83,  // random IP packet...
  };

  wlan_rx_packet_t rx_packet = {
      .mac_frame_buffer = &kMacPkt[0],
      .mac_frame_size = sizeof(kMacPkt),
      .info =
          {
              .rx_flags = 0,
              .phy = WLAN_PHY_TYPE_DSSS,
          },
  };

  // The above lines should enable WlanSoftmacIfc FIDL calls, and the lines below is verifing that.
  mvmvif_->ifc.recv(mvmvif_->ifc.ctx, &rx_packet);
  EXPECT_TRUE(recv_called_);
}

TEST_F(WlanSoftmacDeviceTest, Release) {
  // Create a channel. Let this test case holds one end while driver holds the other end.
  char dummy[1];
  zx_handle_t case_end;
  ASSERT_EQ(zx_channel_create(0 /* option */, &case_end, &mvmvif_->mlme_channel), ZX_OK);
  ASSERT_EQ(zx_channel_write(case_end, 0 /* option */, dummy, sizeof(dummy), nullptr, 0), ZX_OK);

  // Destroy the device and the sme channel should be closed so that we will get a peer-close error
  // while trying to write any data to it.
  device_.reset();
  ASSERT_EQ(zx_channel_write(case_end, 0 /* option */, dummy, sizeof(dummy), nullptr, 0),
            ZX_ERR_PEER_CLOSED);
}

// The class for WLAN device MAC testing.
//
class MacInterfaceTest : public WlanSoftmacDeviceTest, public MockTrans {
 public:
  MacInterfaceTest() {
    zx_handle_t wlan_phy_impl_channel = mvmvif_->mlme_channel;

    auto endpoints = fdf::CreateEndpoints<fuchsia_wlan_softmac::WlanSoftmacIfc>();
    EXPECT_FALSE(endpoints.is_error());

    // Created the end points for WlanSoftmacIfc protocol, and pass the client end to
    // WlanSoftmacDevice.
    fdf::BindServer(server_dispatcher_->get(), std::move(endpoints->server), this);

    // This FIDL call should invoke mac_start() and pass the pointer of WlanSoftmacDeviceTest to it,
    // the pointer will be copied to mvmvif_->ifc.ctx.
    auto result = client_.buffer(test_arena_)->Start(std::move(endpoints->client));

    EXPECT_TRUE(result.ok());
    EXPECT_FALSE(result->is_error());
    EXPECT_EQ(wlan_phy_impl_channel, result->value()->sme_channel);

    // Add the interface to MVM instance.
    mvmvif_->mvm->mvmvif[0] = mvmvif_;
    original_send_cmd = nullptr;
  }

  ~MacInterfaceTest() {
    VerifyExpectation();  // Ensure all expectations had been met.

    // Restore the original callback for other test cases not using the mock.
    ResetSendCmdFunc();

    // Stop the MAC to free resources we allocated.
    // This must be called after we verify the expected commands and restore the mock command
    // callback so that the stop command doesn't mess up the test case expectation.
    auto result = client_.buffer(test_arena_)->Stop();
    EXPECT_TRUE(result.ok());

    // Deallocate the client station at id 0.
    mtx_lock(&mvmvif_->mvm->mutex);
    iwl_mvm_del_aux_sta(mvmvif_->mvm);
    mtx_unlock(&mvmvif_->mvm->mutex);

    VerifyStaHasBeenRemoved();
  }

  // Used in MockCommand constructor to indicate if the command needs to be either
  //
  //   - returned immediately (with a status code), or
  //   - passed to the sim_mvm.c.
  //
  enum SimMvmBehavior {
    kSimMvmReturnWithStatus,
    kSimMvmBypassToSimMvm,
  };

  // A flexible mock-up of firmware command for testing code. Testing code can decide to either call
  // the simulated firmware or return the status code immediately.
  //
  //   cmd_id: the command ID. Sometimes composed with WIDE_ID() macro.
  //   behavior: determine what this mockup command is to do.
  //   status: the status code to return when behavior is 'kSimMvmReturnWithStatus'.
  //
  class MockCommand {
   public:
    MockCommand(uint32_t cmd_id, SimMvmBehavior behavior, zx_status_t status)
        : cmd_id_(cmd_id), behavior_(behavior), status_(status) {}
    MockCommand(uint32_t cmd_id) : MockCommand(cmd_id, kSimMvmBypassToSimMvm, ZX_OK) {}

    ~MockCommand() {}

    uint32_t cmd_id_;
    SimMvmBehavior behavior_;
    zx_status_t status_;
  };
  typedef std::list<MockCommand> expected_cmd_id_list;
  typedef zx_status_t (*fp_send_cmd)(struct iwl_trans* trans, struct iwl_host_cmd* cmd);

  // Public for MockSendCmd().
  expected_cmd_id_list expected_cmd_ids;
  fp_send_cmd original_send_cmd;

 protected:
  bool IsValidChannel(const fuchsia_wlan_common::wire::WlanChannel* channel) {
    return device_->IsValidChannel(channel);
  }

  zx_status_t SetChannel(const fuchsia_wlan_common::wire::WlanChannel* channel) {
    fidl::Arena fidl_arena;
    auto builder = fuchsia_wlan_softmac::wire::WlanSoftmacSetChannelRequest::Builder(fidl_arena);
    builder.channel(*channel);
    auto result = client_.buffer(test_arena_)->SetChannel(builder.Build());
    EXPECT_TRUE(result.ok());
    if (result->is_error()) {
      return result->error_value();
    }
    return ZX_OK;
  }

  zx_status_t JoinBssRequest(uint16_t beacon_period = kDefaultBeaconPeriod,
                             fuchsia_wlan_common::wire::BssType bss_type = kDefaultBssType) {
    fidl::Arena fidl_arena;
    auto builder = fuchsia_wlan_common::wire::JoinBssRequest::Builder(fidl_arena);
    builder.bssid(kBssid);
    builder.bss_type(bss_type);
    builder.remote(true);
    builder.beacon_period(beacon_period);
    auto result = client_.buffer(test_arena_)->JoinBss(builder.Build());
    EXPECT_TRUE(result.ok());
    if (result->is_error()) {
      EXPECT_NE(ZX_OK, result->error_value());
      return result->error_value();
    }
    return ZX_OK;
  }

  zx_status_t NotifyAssociationComplete() {
    fidl::Arena fidl_arena;
    auto builder = fuchsia_wlan_softmac::wire::WlanAssociationConfig::Builder(fidl_arena);
    builder.listen_interval(kListenInterval);
    builder.channel(fuchsia_wlan_common::wire::WlanChannel{
        .primary = 157,
        .cbw = fuchsia_wlan_common::ChannelBandwidth::kCbw80,
    });
    builder.rates(fidl::VectorView(fidl_arena, std::vector<uint8_t>({140})));

    auto result = client_.buffer(test_arena_)->NotifyAssociationComplete(builder.Build());
    EXPECT_TRUE(result.ok());
    if (result->is_error()) {
      return result->error_value();
    }
    return ZX_OK;
  }

  zx_status_t ConfigureHtAssoc() {
    fidl::Arena fidl_arena;
    auto builder = fuchsia_wlan_softmac::wire::WlanAssociationConfig::Builder(fidl_arena);
    builder.listen_interval(kListenInterval);
    builder.channel(fuchsia_wlan_common::wire::WlanChannel{
        .primary = 157,
        .cbw = fuchsia_wlan_common::ChannelBandwidth::kCbw80,
    });
    builder.rates(fidl::VectorView(fidl_arena, std::vector<uint8_t>({
                                                   140,
                                                   18,
                                                   152,
                                                   36,
                                                   176,
                                                   72,
                                                   96,
                                                   108,
                                               })));
    builder.ht_cap(fuchsia_wlan_ieee80211::wire::HtCapabilities{
        .bytes =
            {
                .data_ =
                    {
                        0,
                        0,  // HtCapabilityInfo
                        0,  // AmpduParams

                        255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
                        0,  // Supported mcs set

                        0,
                        0,  // HtExtCapabilities
                        0,   0,   0,
                        0,  // TxBeamformingCapabilities
                        0,  // AselCapability
                    },
            },
    });
    auto result = client_.buffer(test_arena_)->NotifyAssociationComplete(builder.Build());
    EXPECT_TRUE(result.ok());
    if (result->is_error()) {
      return result->error_value();
    }
    return ZX_OK;
  }

  zx_status_t ClearAssociation() {
    // Not used since all info were saved in mvmvif_sta_ already.
    fidl::Arena fidl_arena;
    auto builder =
        fuchsia_wlan_softmac::wire::WlanSoftmacClearAssociationRequest::Builder(fidl_arena);
    fidl::Array<uint8_t, fuchsia_wlan_ieee80211::wire::kMacAddrLen> fidl_peer_addr;
    builder.peer_addr(fidl_peer_addr);
    auto result = client_.buffer(test_arena_)->ClearAssociation(builder.Build());
    EXPECT_TRUE(result.ok());
    if (result->is_error()) {
      return result->error_value();
    }
    return ZX_OK;
  }

  zx_status_t StartPassiveScan(
      fuchsia_wlan_softmac::wire::WlanSoftmacStartPassiveScanRequest* args) {
    auto result = client_.buffer(test_arena_)->StartPassiveScan(*args);
    EXPECT_TRUE(result.ok());
    if (result->is_error()) {
      return result->error_value();
    }
    return ZX_OK;
  }

  zx_status_t StartActiveScan(fuchsia_wlan_softmac::wire::WlanSoftmacStartActiveScanRequest* args) {
    auto result = client_.buffer(test_arena_)->StartActiveScan(*args);
    EXPECT_TRUE(result.ok());
    if (result->is_error()) {
      return result->error_value();
    }
    return ZX_OK;
  }

  zx_status_t InstallKey(const fuchsia_wlan_softmac::wire::WlanKeyConfiguration* key_config) {
    IWL_INFO(nullptr, "Calling set_key");
    auto result = client_.buffer(test_arena_)->InstallKey(*key_config);
    EXPECT_TRUE(result.ok());
    if (result->is_error()) {
      return result->error_value();
    }
    return ZX_OK;
  }

  // The following functions are for mocking up the firmware commands.
  //
  // The mock function will return the special error ZX_ERR_INTERNAL when the expectation
  // is not expected.

  // Set the expected commands sending to the firmware.
  //
  // Args:
  //   cmd_ids: list of expected commands. Will be matched in order.
  //
  void ExpectSendCmd(const expected_cmd_id_list& cmd_ids) {
    expected_cmd_ids = cmd_ids;

    // Re-define the 'dev' field in the 'struct iwl_trans' to a test instance of this class.
    sim_trans_.iwl_trans()->dev = reinterpret_cast<struct device*>(this);

    // Setup the mock function for send command.
    original_send_cmd = sim_trans_.iwl_trans()->ops->send_cmd;
    sim_trans_.iwl_trans()->ops->send_cmd = MockSendCmd;
  }

  // Reset the send command function to the original one, so that the test case would stop checking
  // commands one by one.
  void ResetSendCmdFunc() {
    if (original_send_cmd) {
      IWL_INFO(nullptr, "Reseting send_cmd.");
      sim_trans_.iwl_trans()->ops->send_cmd = original_send_cmd;
    } else {
      IWL_WARN(nullptr, "No original send_cmd found.");
    }
  }

  static zx_status_t MockSendCmd(struct iwl_trans* trans, struct iwl_host_cmd* cmd) {
    MacInterfaceTest* this_ = reinterpret_cast<MacInterfaceTest*>(trans->dev);

    // remove the first one and match.
    expected_cmd_id_list& expected = this_->expected_cmd_ids;
    ZX_ASSERT_MSG(!expected.empty(),
                  "A command (0x%04x) is going to send, but no command is expected.\n", cmd->id);

    // check the command ID.
    auto exp = expected.front();
    ZX_ASSERT_MSG(exp.cmd_id_ == cmd->id,
                  "The command doesn't match! Expect: 0x%04x, actual: 0x%04x.\n", exp.cmd_id_,
                  cmd->id);
    expected.pop_front();

    if (exp.behavior_ == kSimMvmBypassToSimMvm) {
      return this_->original_send_cmd(trans, cmd);
    } else {
      return exp.status_;
    }
  }

  void VerifyExpectation() {
    for (expected_cmd_id_list::iterator it = expected_cmd_ids.begin(); it != expected_cmd_ids.end();
         it++) {
      printf("  ==> 0x%04x\n", it->cmd_id_);
    }
    EXPECT_TRUE(expected_cmd_ids.empty());

    mock_tx_.VerifyAndClear();
  }

  void VerifyStaHasBeenRemoved() {
    auto mvm = mvmvif_->mvm;

    for (size_t i = 0; i < std::size(mvm->fw_id_to_mac_id); i++) {
      struct iwl_mvm_sta* mvm_sta = mvm->fw_id_to_mac_id[i];
      ASSERT_EQ(nullptr, mvm_sta);
    }
    ASSERT_EQ(0, mvm->vif_count);
  }

  // Mock function for Tx.
  mock_function::MockFunction<zx_status_t,  // return value
                              size_t,       // packet size
                              uint16_t,     // cmd + group_id
                              int           // txq_id
                              >
      mock_tx_;

  static zx_status_t tx_wrapper(struct iwl_trans* trans, struct ieee80211_mac_packet* pkt,
                                struct iwl_device_tx_cmd* dev_cmd, int txq_id) {
    iwl_stats_inc(IWL_STATS_CNT_DATA_TO_FW);  // to simulate the iwl_trans_pcie_tx() behavior.
    auto test = GET_TEST(MacInterfaceTest, trans);
    return test->mock_tx_.Call(pkt->header_size + pkt->headroom_used_size + pkt->body_size,
                               WIDE_ID(dev_cmd->hdr.group_id, dev_cmd->hdr.cmd), txq_id);
  }

  static constexpr fidl::Array<uint8_t, 6> kBssid = {
      .data_ = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06},
  };
  static constexpr uint8_t kIeeeOui[] = {0x00, 0x0F, 0xAC};
  static constexpr fidl::Array<uint8_t, 32> kFakeKey = {
      .data_ = {1, 2, 3, 4, 5, 6, 7, 8, 0, 9, 8, 7, 6, 5, 4, 3},
  };
  static constexpr size_t kFakeKeyLen = 16;

  static constexpr fidl::Array<uint8_t, 32> kFakeTkipKey = {
      .data_ = {1, 2, 3, 4, 5, 6, 7, 8, 0, 9, 8, 7, 6, 5, 4, 3,
                1, 2, 3, 4, 5, 6, 7, 8, 0, 9, 8, 7, 6, 5, 4, 3},
  };
  static constexpr size_t kFakeTkipKeyLen = 32;

  // Define it's own kChannel and override the one defined in SingleApTest.
  static constexpr fuchsia_wlan_common::wire::WlanChannel kChannel = {
      .primary = 11, .cbw = fuchsia_wlan_common::ChannelBandwidth::kCbw20};

  static constexpr fuchsia_wlan_common::wire::WlanChannel kChannel2 = {
      .primary = 161, .cbw = fuchsia_wlan_common::ChannelBandwidth::kCbw80};

  static constexpr uint16_t kChannelSize = 4;
};

TEST_F(MacInterfaceTest, TestIsValidChannel) {
  ExpectSendCmd(expected_cmd_id_list({}));

  fuchsia_wlan_common::wire::WlanChannel ch10_20m = {
      .primary = 10,
      .cbw = fuchsia_wlan_common::ChannelBandwidth::kCbw20,
  };

  EXPECT_TRUE(IsValidChannel(&ch10_20m));

  fuchsia_wlan_common::wire::WlanChannel ch10_40m = {
      .primary = 10,
      .cbw = fuchsia_wlan_common::ChannelBandwidth::kCbw40,
  };

  EXPECT_FALSE(IsValidChannel(&ch10_40m));

  fuchsia_wlan_common::wire::WlanChannel ch13_40m_below = {
      .primary = 13,
      .cbw = fuchsia_wlan_common::ChannelBandwidth::kCbw40Below,
  };

  EXPECT_FALSE(IsValidChannel(&ch13_40m_below));

  fuchsia_wlan_common::wire::WlanChannel ch5_80m = {
      .primary = 5,
      .cbw = fuchsia_wlan_common::ChannelBandwidth::kCbw80,
  };

  EXPECT_FALSE(IsValidChannel(&ch5_80m));
}

// Test the set_channel().
//
TEST_F(MacInterfaceTest, TestSetChannel) {
  ExpectSendCmd(expected_cmd_id_list({
      MockCommand(WIDE_ID(LONG_GROUP, PHY_CONTEXT_CMD)),  // for add_chanctx
      MockCommand(WIDE_ID(LONG_GROUP, PHY_CONTEXT_CMD)),  // for change_chanctx
      MockCommand(WIDE_ID(LONG_GROUP, BINDING_CONTEXT_CMD)),
      MockCommand(WIDE_ID(LONG_GROUP, MAC_PM_POWER_TABLE)),
  }));

  mvmvif_->csa_bcn_pending = true;  // Expect to be clear because this is client role.
  ASSERT_EQ(ZX_OK, SetChannel(&kChannel));
  EXPECT_FALSE(mvmvif_->csa_bcn_pending);
}

// Test call set_channel() multiple times.
//
TEST_F(MacInterfaceTest, TestMultipleSetChannel) {
  ExpectSendCmd(expected_cmd_id_list({
      // for the first SetChannel()
      MockCommand(WIDE_ID(LONG_GROUP, PHY_CONTEXT_CMD)),  // for add_chanctx
      MockCommand(WIDE_ID(LONG_GROUP, PHY_CONTEXT_CMD)),  // for change_chanctx
      MockCommand(WIDE_ID(LONG_GROUP, BINDING_CONTEXT_CMD)),
      MockCommand(WIDE_ID(LONG_GROUP, MAC_PM_POWER_TABLE)),

      // for the second SetChannel()
      MockCommand(WIDE_ID(LONG_GROUP, BINDING_CONTEXT_CMD)),  // for remove_chanctx
      MockCommand(WIDE_ID(LONG_GROUP, MAC_PM_POWER_TABLE)),
      MockCommand(WIDE_ID(LONG_GROUP, PHY_CONTEXT_CMD)),
      MockCommand(WIDE_ID(LONG_GROUP, PHY_CONTEXT_CMD)),  // for add_chanctx
      MockCommand(WIDE_ID(LONG_GROUP, PHY_CONTEXT_CMD)),  // for change_chanctx
      MockCommand(WIDE_ID(LONG_GROUP, BINDING_CONTEXT_CMD)),
      MockCommand(WIDE_ID(LONG_GROUP, MAC_PM_POWER_TABLE)),
  }));

  for (size_t i = 0; i < 2; i++) {
    ASSERT_EQ(ZX_OK, SetChannel(&kChannel));
  }
}

// Test the unsupported MAC role.
//
TEST_F(MacInterfaceTest, TestSetChannelWithUnsupportedRole) {
  ExpectSendCmd(expected_cmd_id_list({
      MockCommand(WIDE_ID(LONG_GROUP, PHY_CONTEXT_CMD)),  // for add_chanctx
      MockCommand(WIDE_ID(LONG_GROUP, PHY_CONTEXT_CMD)),  // for change_chanctx
  }));

  mvmvif_->mac_role = WLAN_MAC_ROLE_AP;
  ASSERT_EQ(ZX_ERR_NOT_SUPPORTED, SetChannel(&kChannel));
}

// Call SetChannel() twice to simulate a channel switch announcement.
TEST_F(MacInterfaceTest, DuplicateSetChannel) {
  ASSERT_EQ(ZX_OK, SetChannel(&kChannel));
  ASSERT_EQ(ZX_OK, JoinBssRequest());
  struct iwl_mvm_sta* mvm_sta = mvmvif_->mvm->fw_id_to_mac_id[mvmvif_->ap_sta_id];
  struct iwl_mvm_phy_ctxt* phy_ctxt = mvmvif_->phy_ctxt;
  ASSERT_NE(nullptr, phy_ctxt);
  ASSERT_EQ(IWL_STA_NONE, mvm_sta->sta_state);

  // Call SetChannel() again. This should return the same phy context.
  // The BSS info should be the same (because we only change the channel).
  ASSERT_EQ(ZX_OK, SetChannel(&kChannel2));
  struct iwl_mvm_phy_ctxt* new_phy_ctxt = mvmvif_->phy_ctxt;
  ASSERT_NE(nullptr, new_phy_ctxt);
  ASSERT_EQ(phy_ctxt, new_phy_ctxt);
  struct iwl_mvm_sta* new_mvm_sta = mvmvif_->mvm->fw_id_to_mac_id[mvmvif_->ap_sta_id];
  ASSERT_EQ(new_mvm_sta, mvm_sta);
}

// Test JoinBss()
//
TEST_F(MacInterfaceTest, TestJoinBss) {
  ASSERT_EQ(ZX_OK, SetChannel(&kChannel));

  ASSERT_EQ(mvmvif_->bss_conf.beacon_int, kDefaultBeaconPeriod);

  ExpectSendCmd(expected_cmd_id_list({
      MockCommand(WIDE_ID(LONG_GROUP, MAC_CONTEXT_CMD)),
      MockCommand(WIDE_ID(LONG_GROUP, TIME_EVENT_CMD)),
      MockCommand(WIDE_ID(LONG_GROUP, ADD_STA)),
      MockCommand(WIDE_ID(LONG_GROUP, SCD_QUEUE_CFG)),
      MockCommand(WIDE_ID(LONG_GROUP, ADD_STA)),
  }));

  // Send with a different beacon period so that we see change in mvmvif_->bss_conf
  ASSERT_EQ(ZX_OK, JoinBssRequest(kNonDefaultBeaconPeriod));
  // Ensure the BSSID was copied into mvmvif
  ASSERT_EQ(memcmp(mvmvif_->bss_conf.bssid, kBssid.data(), ETH_ALEN), 0);
  ASSERT_EQ(memcmp(mvmvif_->bssid, kBssid.data(), ETH_ALEN), 0);
  ASSERT_EQ(mvmvif_->bss_conf.beacon_int, kNonDefaultBeaconPeriod);
}

// Test duplicate BSS config.
//
TEST_F(MacInterfaceTest, DuplicateJoinBss) {
  ASSERT_EQ(ZX_OK, SetChannel(&kChannel));
  ASSERT_EQ(ZX_OK, JoinBssRequest());

  // The second configuration will unconfigure the previous one first.
  ExpectSendCmd(expected_cmd_id_list({
      // called by mac_leave_bss().
      MockCommand(WIDE_ID(LONG_GROUP, MAC_CONTEXT_CMD)),
      MockCommand(WIDE_ID(LONG_GROUP, TXPATH_FLUSH)),
      MockCommand(WIDE_ID(LONG_GROUP, ADD_STA)),
      MockCommand(WIDE_ID(LONG_GROUP, TXPATH_FLUSH)),
      MockCommand(WIDE_ID(LONG_GROUP, ADD_STA)),
      MockCommand(WIDE_ID(LONG_GROUP, SCD_QUEUE_CFG)),
      MockCommand(WIDE_ID(LONG_GROUP, REMOVE_STA)),

      // mac_join_bss()
      MockCommand(WIDE_ID(LONG_GROUP, MAC_CONTEXT_CMD)),
      MockCommand(WIDE_ID(LONG_GROUP, ADD_STA)),
      MockCommand(WIDE_ID(LONG_GROUP, SCD_QUEUE_CFG)),
      MockCommand(WIDE_ID(LONG_GROUP, ADD_STA)),
  }));
  ASSERT_EQ(ZX_OK, JoinBssRequest());
}

// Test unsupported bss_type.
//
TEST_F(MacInterfaceTest, UnsupportedBssType) {
  ASSERT_EQ(ZX_ERR_INVALID_ARGS,
            JoinBssRequest(kDefaultBeaconPeriod, fuchsia_wlan_common::wire::BssType::kIndependent));
}

TEST_F(MacInterfaceTest, UnsupportedBeaconPeriod) {
  ASSERT_EQ(ZX_ERR_INVALID_ARGS, JoinBssRequest(IWL_MIN_BEACON_PERIOD_TU - 1,
                                                fuchsia_wlan_common::wire::BssType::kIndependent));
}

// Test failed ADD_STA command.
//
TEST_F(MacInterfaceTest, TestFailedAddSta) {
  ASSERT_EQ(ZX_OK, SetChannel(&kChannel));

  ExpectSendCmd(expected_cmd_id_list({
      MockCommand(WIDE_ID(LONG_GROUP, MAC_CONTEXT_CMD), kSimMvmReturnWithStatus,
                  ZX_ERR_BUFFER_TOO_SMALL /* an arbitrary error */),
  }));

  ASSERT_EQ(ZX_ERR_BUFFER_TOO_SMALL, JoinBssRequest());
}

// Test whether the AUX sta (for active scan) is added.
//
TEST_F(MacInterfaceTest, TestAuxSta) {
  ASSERT_EQ(ZX_OK, SetChannel(&kChannel));
  ASSERT_EQ(ZX_OK, JoinBssRequest());

  auto aux_sta = &mvmvif_->mvm->aux_sta;
  EXPECT_EQ(IWL_STA_AUX_ACTIVITY, aux_sta->type);
  EXPECT_NE(IWL_MVM_INVALID_STA, aux_sta->sta_id);
  EXPECT_NE(nullptr, mvmvif_->mvm->fw_id_to_mac_id[0]);  // Assume it is the first one.

  // The removal check is done in VerifyStaHasBeenRemoved() of MacInterfaceTest deconstructor.
}

// Test exception handling in driver.
//
TEST_F(MacInterfaceTest, TestExceptionHandling) {
  ASSERT_EQ(ZX_OK, SetChannel(&kChannel));

  // Test the phy_ctxt checking.
  auto backup_phy_ctxt = mvmvif_->phy_ctxt;
  mvmvif_->phy_ctxt = nullptr;
  EXPECT_EQ(ZX_ERR_BAD_STATE, JoinBssRequest());
  mvmvif_->phy_ctxt = backup_phy_ctxt;

  iwl_mvm_sta sta;
  // Test the case we run out of slots for STA.
  // Occupy all the station slots.
  for (uint16_t i = 0; i < IWL_MVM_STATION_COUNT; i++) {
    mvmvif_->mvm->fw_id_to_mac_id[i] = &sta;
  }

  // Request fails because we run out of all slots in fw_id_to_mac_id[].
  EXPECT_EQ(ZX_ERR_NO_RESOURCES, JoinBssRequest());

  // Clean up all the station slots.
  for (uint16_t i = 0; i < IWL_MVM_STATION_COUNT; i++) {
    mvmvif_->mvm->fw_id_to_mac_id[i] = nullptr;
  }

  EXPECT_EQ(ZX_OK, JoinBssRequest());
  // iwl_mvm_add_sta(), called by JoinBss(), has an assumption that each interface has only one
  // AP sta (for WLAN_MAC_ROLE_CLIENT). However, in this case, we break the assumption so that the
  // ap_sta_id was populated with the last successful STA ID. Thus, we reset the mvmvif_->ap_sta_id
  // so that the SoftMacDevices destructor will not release the resource twice by calling
  // ClearAssociation().
  mvmvif_->ap_sta_id = IWL_MVM_INVALID_STA;
}

// The test is used to test the typical procedure to connect to an open network.
//
TEST_F(MacInterfaceTest, AssociateToOpenNetwork) {
  ASSERT_EQ(ZX_OK, SetChannel(&kChannel));
  ASSERT_EQ(ZX_OK, JoinBssRequest());
  struct iwl_mvm_sta* mvm_sta = mvmvif_->mvm->fw_id_to_mac_id[mvmvif_->ap_sta_id];
  ASSERT_EQ(IWL_STA_NONE, mvm_sta->sta_state);
  struct iwl_mvm* mvm = mvmvif_->mvm;
  ASSERT_GT(list_length(&mvm->time_event_list), 0);

  ASSERT_EQ(ZX_OK, NotifyAssociationComplete());
  ASSERT_EQ(IWL_STA_AUTHORIZED, mvm_sta->sta_state);
  ASSERT_TRUE(mvmvif_->bss_conf.assoc);
  ASSERT_EQ(kListenInterval, mvmvif_->bss_conf.listen_interval);
  ASSERT_EQ(mvm_sta->sta_state, iwl_sta_state::IWL_STA_AUTHORIZED);

  ASSERT_EQ(ZX_OK, ClearAssociation());
  ASSERT_EQ(nullptr, mvmvif_->phy_ctxt);
  ASSERT_EQ(IWL_MVM_INVALID_STA, mvmvif_->ap_sta_id);
  ASSERT_EQ(list_length(&mvm->time_event_list), 0);
}

// Check if calling iwl_mvm_mac_sta_state() sets the state correctly.
TEST_F(MacInterfaceTest, CheckStaState) {
  ASSERT_EQ(ZX_OK, SetChannel(&kChannel));
  ASSERT_EQ(ZX_OK, JoinBssRequest());
  struct iwl_mvm_sta* mvm_sta = mvmvif_->mvm->fw_id_to_mac_id[mvmvif_->ap_sta_id];
  ASSERT_EQ(IWL_STA_NONE, mvm_sta->sta_state);
  struct iwl_mvm* mvm = mvmvif_->mvm;
  ASSERT_GT(list_length(&mvm->time_event_list), 0);

  ASSERT_EQ(ZX_OK, NotifyAssociationComplete());
  ASSERT_EQ(IWL_STA_AUTHORIZED, mvm_sta->sta_state);
  ASSERT_TRUE(mvmvif_->bss_conf.assoc);
  ASSERT_EQ(kListenInterval, mvmvif_->bss_conf.listen_interval);
  ASSERT_EQ(mvm_sta->sta_state, iwl_sta_state::IWL_STA_AUTHORIZED);

  ASSERT_EQ(ZX_OK, iwl_mvm_mac_sta_state(mvmvif_, mvm_sta, IWL_STA_AUTHORIZED, IWL_STA_ASSOC));
  ASSERT_EQ(mvm_sta->sta_state, iwl_sta_state::IWL_STA_ASSOC);
  ASSERT_EQ(ZX_OK, ClearAssociation());
}

// Back to back calls of ClearAssociation().
TEST_F(MacInterfaceTest, ClearAssociationAfterClearAssociation) {
  ASSERT_NE(ZX_OK, ClearAssociation());
  ASSERT_NE(ZX_OK, ClearAssociation());
}

// ClearAssociation() should cleanup when called without Assoc
TEST_F(MacInterfaceTest, ClearAssociationAfterNoAssoc) {
  ASSERT_EQ(ZX_OK, SetChannel(&kChannel));
  ASSERT_EQ(ZX_OK, JoinBssRequest());
  struct iwl_mvm_sta* mvm_sta = mvmvif_->mvm->fw_id_to_mac_id[mvmvif_->ap_sta_id];
  ASSERT_EQ(IWL_STA_NONE, mvm_sta->sta_state);
  struct iwl_mvm* mvm = mvmvif_->mvm;
  ASSERT_GT(list_length(&mvm->time_event_list), 0);

  ASSERT_EQ(ZX_OK, ClearAssociation());
  ASSERT_EQ(nullptr, mvmvif_->phy_ctxt);
  ASSERT_EQ(IWL_MVM_INVALID_STA, mvmvif_->ap_sta_id);
  ASSERT_EQ(list_length(&mvm->time_event_list), 0);

  // Call ClearAssociation() again to check if it is handled correctly.
  ASSERT_NE(ZX_OK, ClearAssociation());
}

// ClearAssociation() should cleanup when called after a failed Assoc
TEST_F(MacInterfaceTest, ClearAssociationAfterFailedAssoc) {
  ASSERT_EQ(ZX_OK, SetChannel(&kChannel));
  ASSERT_EQ(ZX_OK, JoinBssRequest());

  struct iwl_mvm* mvm = mvmvif_->mvm;
  ASSERT_GT(list_length(&mvm->time_event_list), 0);
  // Fail the association by forcing some relevant internal state.
  auto orig = mvmvif_->uploaded;
  mvmvif_->uploaded = false;
  ASSERT_EQ(ZX_ERR_IO, NotifyAssociationComplete());
  mvmvif_->uploaded = orig;

  // ClearAssociation will clean up the failed association.
  ASSERT_EQ(ZX_OK, ClearAssociation());
  ASSERT_EQ(nullptr, mvmvif_->phy_ctxt);
  ASSERT_EQ(IWL_MVM_INVALID_STA, mvmvif_->ap_sta_id);
  ASSERT_EQ(list_length(&mvm->time_event_list), 0);

  // Call ClearAssociation() again to check if it is handled correctly.
  ASSERT_NE(ZX_OK, ClearAssociation());
}

// This test case is to verify NotifyAssociationComplete() with HT wlan_association_config_t input
// can successfully trigger LQ_CMD with correct data.
TEST_F(MacInterfaceTest, AssocWithHtConfig) {
  ASSERT_EQ(ZX_OK, SetChannel(&kChannel));
  ASSERT_EQ(ZX_OK, JoinBssRequest());

  ExpectSendCmd(expected_cmd_id_list({
      MockCommand(WIDE_ID(LONG_GROUP, LQ_CMD)),
      MockCommand(WIDE_ID(LONG_GROUP, ADD_STA)),
      MockCommand(WIDE_ID(LONG_GROUP, MAC_CONTEXT_CMD)),
      MockCommand(WIDE_ID(LONG_GROUP, TIME_EVENT_CMD)),
      MockCommand(WIDE_ID(LONG_GROUP, MCAST_FILTER_CMD)),
  }));

  // Extract LQ_CMD data.
  struct iwl_mvm_sta* mvm_sta = mvmvif_->mvm->fw_id_to_mac_id[mvmvif_->ap_sta_id];
  struct iwl_lq_cmd* lq_cmd = &mvm_sta->lq_sta.rs_drv.lq;

  ASSERT_EQ(IWL_STA_NONE, mvm_sta->sta_state);
  struct iwl_mvm* mvm = mvmvif_->mvm;
  ASSERT_GT(list_length(&mvm->time_event_list), 0);

  ASSERT_EQ(ZX_OK, ConfigureHtAssoc());

  // Verify the values in LQ_CMD API structure.
  EXPECT_EQ(lq_cmd->sta_id, 0);
  EXPECT_EQ(lq_cmd->reduced_tpc, 0);
  EXPECT_EQ(lq_cmd->flags, 0);
  EXPECT_EQ(lq_cmd->mimo_delim, 0);
  EXPECT_EQ(lq_cmd->single_stream_ant_msk, 1);
  EXPECT_EQ(lq_cmd->dual_stream_ant_msk, 3);
  EXPECT_EQ(lq_cmd->initial_rate_index[0], 0);
  EXPECT_EQ(lq_cmd->initial_rate_index[1], 0);
  EXPECT_EQ(lq_cmd->initial_rate_index[2], 0);
  EXPECT_EQ(lq_cmd->initial_rate_index[3], 0);
  EXPECT_EQ(lq_cmd->agg_time_limit, 0x0fa0);
  EXPECT_EQ(lq_cmd->agg_disable_start_th, 3);
  EXPECT_EQ(lq_cmd->agg_frame_cnt_limit, 1);
  EXPECT_EQ(lq_cmd->reserved2, 0);

  // Verify rate_n_flags in the table.
  EXPECT_EQ(lq_cmd->rs_table[0], 0x4103);
  // The value of RS_MNG_RETRY_TABLE_INITIAL_RATE_NUM is 3.
  EXPECT_EQ(lq_cmd->rs_table[3], 0x4102);

  EXPECT_EQ(lq_cmd->ss_params, 0);

  // Stop checking following commands one by one.
  ResetSendCmdFunc();

  // Clean up the association states.
  ASSERT_EQ(ZX_OK, ClearAssociation());
}

TEST_F(MacInterfaceTest, StartPassiveScanTest) {
  fidl::Arena fidl_arena;
  // FromExternal() is not able to take const data.
  uint8_t channels_to_scan[kChannelSize] = {7, 1, 40, 136};
  {
    // Passive scan with some random channels should pass.
    auto builder =
        fuchsia_wlan_softmac::wire::WlanSoftmacStartPassiveScanRequest::Builder(fidl_arena);
    builder.channels(fidl::VectorView<uint8_t>::FromExternal(&channels_to_scan[0], kChannelSize));
    auto passive_scan_args = builder.Build();
    ASSERT_EQ(ZX_OK, StartPassiveScan(&passive_scan_args));
  }

  {
    // Passive scan request will fail in mvm-mlme.cc if the channels field is not set.
    auto builder =
        fuchsia_wlan_softmac::wire::WlanSoftmacStartPassiveScanRequest::Builder(fidl_arena);
    auto passive_scan_args = builder.Build();
    ASSERT_EQ(ZX_ERR_INVALID_ARGS, StartPassiveScan(&passive_scan_args));
  }
}

TEST_F(MacInterfaceTest, StartActiveScanTest) {
  fidl::Arena fidl_arena;
  // FromExternal() is not able to take const data.
  uint8_t channels_to_scan[kChannelSize] = {7, 1, 40, 136};
  {
    // Active scan with args in which all of "channels", "ssids", "mac_header" and "ies" fields are
    // set will pass the argument check in mvm-mlme.cc.
    auto builder =
        fuchsia_wlan_softmac::wire::WlanSoftmacStartActiveScanRequest::Builder(fidl_arena);

    builder.channels(fidl::VectorView<uint8_t>::FromExternal(&channels_to_scan[0], kChannelSize));
    builder.ssids(fidl::VectorView<fuchsia_wlan_ieee80211::wire::CSsid>());
    builder.mac_header(fidl::VectorView<uint8_t>());
    builder.ies(fidl::VectorView<uint8_t>());

    auto active_scan_args = builder.Build();
    ASSERT_EQ(ZX_OK, StartActiveScan(&active_scan_args));
  }

  {
    // Missing "channels" fails the argument check.
    auto builder =
        fuchsia_wlan_softmac::wire::WlanSoftmacStartActiveScanRequest::Builder(fidl_arena);

    builder.ssids(fidl::VectorView<fuchsia_wlan_ieee80211::wire::CSsid>());
    builder.mac_header(fidl::VectorView<uint8_t>());
    builder.ies(fidl::VectorView<uint8_t>());

    auto active_scan_args = builder.Build();
    ASSERT_EQ(ZX_ERR_INVALID_ARGS, StartActiveScan(&active_scan_args));
  }

  {
    // Missing "ssids" fails the argument check.
    auto builder =
        fuchsia_wlan_softmac::wire::WlanSoftmacStartActiveScanRequest::Builder(fidl_arena);

    builder.channels(fidl::VectorView<uint8_t>::FromExternal(&channels_to_scan[0], kChannelSize));
    builder.mac_header(fidl::VectorView<uint8_t>());
    builder.ies(fidl::VectorView<uint8_t>());

    auto active_scan_args = builder.Build();
    ASSERT_EQ(ZX_ERR_INVALID_ARGS, StartActiveScan(&active_scan_args));
  }

  {
    // Missing "mac_header" fails the argument check.
    auto builder =
        fuchsia_wlan_softmac::wire::WlanSoftmacStartActiveScanRequest::Builder(fidl_arena);

    builder.channels(fidl::VectorView<uint8_t>::FromExternal(&channels_to_scan[0], kChannelSize));
    builder.ssids(fidl::VectorView<fuchsia_wlan_ieee80211::wire::CSsid>());
    builder.ies(fidl::VectorView<uint8_t>());

    auto active_scan_args = builder.Build();
    ASSERT_EQ(ZX_ERR_INVALID_ARGS, StartActiveScan(&active_scan_args));
  }

  {
    // Missing "ies" fails the argument check.
    auto builder =
        fuchsia_wlan_softmac::wire::WlanSoftmacStartActiveScanRequest::Builder(fidl_arena);

    builder.channels(fidl::VectorView<uint8_t>::FromExternal(&channels_to_scan[0], kChannelSize));
    builder.ssids(fidl::VectorView<fuchsia_wlan_ieee80211::wire::CSsid>());
    builder.mac_header(fidl::VectorView<uint8_t>());

    auto active_scan_args = builder.Build();
    ASSERT_EQ(ZX_ERR_INVALID_ARGS, StartActiveScan(&active_scan_args));
  }
}

// Check to ensure keys are set during assoc and deleted after disassoc
// for now use open network
TEST_F(MacInterfaceTest, InstallKeysTest) {
  ASSERT_EQ(ZX_OK, SetChannel(&kChannel));
  ASSERT_EQ(ZX_OK, JoinBssRequest());
  struct iwl_mvm_sta* mvm_sta = mvmvif_->mvm->fw_id_to_mac_id[mvmvif_->ap_sta_id];
  ASSERT_EQ(IWL_STA_NONE, mvm_sta->sta_state);
  struct iwl_mvm* mvm = mvmvif_->mvm;
  ASSERT_GT(list_length(&mvm->time_event_list), 0);

  ASSERT_EQ(ZX_OK, NotifyAssociationComplete());
  ASSERT_EQ(IWL_STA_AUTHORIZED, mvm_sta->sta_state);
  ASSERT_TRUE(mvmvif_->bss_conf.assoc);
  ASSERT_EQ(kListenInterval, mvmvif_->bss_conf.listen_interval);

  fidl::Arena fidl_arena;
  fidl::Array<uint8_t, 3> cipher_oui;
  auto key =
      fidl::VectorView<uint8_t>::FromExternal(const_cast<uint8_t*>(kFakeKey.begin()), kFakeKeyLen);
  memcpy(cipher_oui.begin(), kIeeeOui, 3);
  {
    auto builder = fuchsia_wlan_softmac::wire::WlanKeyConfiguration::Builder(fidl_arena);

    // Set an arbitrary pairwise key.
    builder.cipher_type(4);
    builder.key_type(fuchsia_wlan_common::wire::WlanKeyType::kPairwise);
    builder.key_idx(0);
    builder.key(key);
    builder.rsc(0);
    builder.cipher_oui(cipher_oui);
    auto key_config = builder.Build();
    ASSERT_EQ(ZX_OK, InstallKey(&key_config));
    // Expect bit 0 to be set.
    ASSERT_EQ(*mvm->fw_key_table, 0x1);
  }
  {
    auto builder = fuchsia_wlan_softmac::wire::WlanKeyConfiguration::Builder(fidl_arena);

    // Set an arbitrary group key.
    builder.cipher_type(4);
    builder.key_type(fuchsia_wlan_common::wire::WlanKeyType::kGroup);
    builder.key_idx(1);
    builder.key(key);
    builder.rsc(0);
    builder.cipher_oui(cipher_oui);

    auto key_config = builder.Build();
    ASSERT_EQ(ZX_OK, InstallKey(&key_config));
    // Expect bit 1 to be set as well.
    ASSERT_EQ(*mvm->fw_key_table, 0x3);
  }

  ASSERT_EQ(ZX_OK, ClearAssociation());
  ASSERT_EQ(nullptr, mvmvif_->phy_ctxt);
  ASSERT_EQ(IWL_MVM_INVALID_STA, mvmvif_->ap_sta_id);
  ASSERT_EQ(list_length(&mvm->time_event_list), 0);
  // Both the keys should have been deleted.
  ASSERT_EQ(*mvm->fw_key_table, 0x0);
}

// Check that we can sucessfully set some key configurations required for supported functionality.
TEST_F(MacInterfaceTest, InstallKeysSupportConfigs) {
  ASSERT_EQ(ZX_OK, SetChannel(&kChannel));
  ASSERT_EQ(ZX_OK, JoinBssRequest());
  ASSERT_EQ(ZX_OK, NotifyAssociationComplete());
  ASSERT_TRUE(mvmvif_->bss_conf.assoc);

  fidl::Arena fidl_arena;
  fidl::Array<uint8_t, 3> cipher_oui;
  auto key =
      fidl::VectorView<uint8_t>::FromExternal(const_cast<uint8_t*>(kFakeKey.begin()), kFakeKeyLen);
  memcpy(cipher_oui.begin(), kIeeeOui, 3);
  {
    auto builder = fuchsia_wlan_softmac::wire::WlanKeyConfiguration::Builder(fidl_arena);

    builder.key(key);
    builder.cipher_oui(cipher_oui);
    // Default cipher configuration for WPA2/3 PTK.  This is data frame protection, required for
    // WPA2/3.
    builder.cipher_type(CIPHER_SUITE_TYPE_CCMP_128);
    builder.key_type(fuchsia_wlan_common::wire::WlanKeyType::kPairwise);
    builder.key_idx(0);
    builder.rsc(0);
    auto key_config = builder.Build();
    ASSERT_EQ(ZX_OK, InstallKey(&key_config));
  }

  {
    auto builder = fuchsia_wlan_softmac::wire::WlanKeyConfiguration::Builder(fidl_arena);

    // Default cipher configuration for WPA2/3 IGTK.  This is management frame protection, optional
    // for WPA2 and required for WPA3.
    builder.key(key);
    builder.cipher_oui(cipher_oui);
    builder.cipher_type(CIPHER_SUITE_TYPE_BIP_CMAC_128);
    builder.key_type(fuchsia_wlan_common::wire::WlanKeyType::kIgtk);
    builder.key_idx(4);
    builder.rsc(0);
    auto key_config = builder.Build();
    ASSERT_EQ(ZX_OK, InstallKey(&key_config));
  }

  ASSERT_EQ(ZX_OK, ClearAssociation());
}

// Test setting TKIP. Mainly for group key (backward-compatible for many APs).
TEST_F(MacInterfaceTest, InstallKeysTKIP) {
  constexpr uint8_t kIeeeOui[] = {0x00, 0x0F, 0xAC};
  ASSERT_EQ(ZX_OK, SetChannel(&kChannel));
  ASSERT_EQ(ZX_OK, JoinBssRequest());
  ASSERT_EQ(ZX_OK, NotifyAssociationComplete());
  ASSERT_TRUE(mvmvif_->bss_conf.assoc);

  fidl::Arena fidl_arena;
  fidl::Array<uint8_t, 3> cipher_oui;
  auto tkip_key = fidl::VectorView<uint8_t>::FromExternal(
      const_cast<uint8_t*>(kFakeTkipKey.begin()), kFakeTkipKeyLen);
  memcpy(cipher_oui.begin(), kIeeeOui, 3);
  {
    auto builder = fuchsia_wlan_softmac::wire::WlanKeyConfiguration::Builder(fidl_arena);

    builder.key(tkip_key);
    builder.cipher_oui(cipher_oui);
    // TKIP Pairwise: although we support it but not recommended (deprecated protocol).
    builder.cipher_type(fidl::ToUnderlying(fuchsia_wlan_ieee80211::wire::CipherSuiteType::kTkip));
    builder.key_type(fuchsia_wlan_common::wire::WlanKeyType::kPairwise);
    builder.key_idx(0);
    builder.rsc(0);
    auto key_config = builder.Build();
    ASSERT_EQ(ZX_OK, InstallKey(&key_config));
  }

  {
    // TKIP Group key: supported for backward compatible. Unfortunately many APs still use this.
    auto builder = fuchsia_wlan_softmac::wire::WlanKeyConfiguration::Builder(fidl_arena);

    builder.key(tkip_key);
    builder.cipher_oui(cipher_oui);
    builder.cipher_type(fidl::ToUnderlying(fuchsia_wlan_ieee80211::wire::CipherSuiteType::kTkip));
    builder.key_type(fuchsia_wlan_common::wire::WlanKeyType::kIgtk);
    builder.key_idx(1);
    builder.rsc(0);
    auto key_config = builder.Build();
    ASSERT_EQ(ZX_OK, InstallKey(&key_config));
  }

  ASSERT_EQ(ZX_OK, ClearAssociation());
}

TEST_F(MacInterfaceTest, TxPktTooLong) {
  SetChannel(&kChannel);
  JoinBssRequest();
  BIND_TEST(sim_trans_.iwl_trans());

  bindTx(tx_wrapper);
  WlanPktBuilder builder;
  std::shared_ptr<WlanPktBuilder::WlanPkt> wlan_pkt = builder.build_oversize();
  fuchsia_wlan_softmac::wire::WlanTxPacket fidl_packet = wlan_pkt->wlan_pkt();

  EXPECT_EQ(iwl_stats_read(IWL_STATS_CNT_DATA_FROM_MLME), 0);
  EXPECT_EQ(iwl_stats_read(IWL_STATS_CNT_DATA_TO_FW), 0);

  auto result = client_.buffer(test_arena_)->QueueTx(fidl_packet);
  EXPECT_EQ(iwl_stats_read(IWL_STATS_CNT_DATA_FROM_MLME), 1);
  EXPECT_EQ(iwl_stats_read(IWL_STATS_CNT_DATA_TO_FW), 0);
  ASSERT_TRUE(result.ok());
  EXPECT_TRUE(result->is_error());
  EXPECT_EQ(ZX_ERR_INVALID_ARGS, result->error_value());
  unbindTx();
}

TEST_F(MacInterfaceTest, TxPktNotSupportedRole) {
  SetChannel(&kChannel);
  JoinBssRequest();
  BIND_TEST(sim_trans_.iwl_trans());

  // Set to an unsupported role.
  mvmvif_->mac_role = WLAN_MAC_ROLE_AP;

  bindTx(tx_wrapper);
  WlanPktBuilder builder;
  std::shared_ptr<WlanPktBuilder::WlanPkt> wlan_pkt = builder.build();
  fuchsia_wlan_softmac::wire::WlanTxPacket fidl_packet = wlan_pkt->wlan_pkt();

  auto result = client_.buffer(test_arena_)->QueueTx(fidl_packet);
  ASSERT_TRUE(result.ok());
  EXPECT_TRUE(result->is_error());
  EXPECT_EQ(ZX_ERR_INVALID_ARGS, result->error_value());
  unbindTx();
}

// To test if a packet can be sent out.
TEST_F(MacInterfaceTest, TxPkt) {
  SetChannel(&kChannel);
  JoinBssRequest();
  BIND_TEST(sim_trans_.iwl_trans());

  bindTx(tx_wrapper);
  WlanPktBuilder builder;
  std::shared_ptr<WlanPktBuilder::WlanPkt> wlan_pkt = builder.build();
  mock_tx_.ExpectCall(ZX_OK, wlan_pkt->len(), WIDE_ID(0, TX_CMD), IWL_MVM_DQA_MIN_MGMT_QUEUE);
  fuchsia_wlan_softmac::wire::WlanTxPacket fidl_packet = wlan_pkt->wlan_pkt();

  EXPECT_EQ(iwl_stats_read(IWL_STATS_CNT_DATA_FROM_MLME), 0);
  EXPECT_EQ(iwl_stats_read(IWL_STATS_CNT_DATA_TO_FW), 0);

  auto result = client_.buffer(test_arena_)->QueueTx(fidl_packet);
  EXPECT_EQ(iwl_stats_read(IWL_STATS_CNT_DATA_FROM_MLME), 1);
  EXPECT_EQ(iwl_stats_read(IWL_STATS_CNT_DATA_TO_FW), 1);
  ASSERT_TRUE(result.ok());
  EXPECT_FALSE(result->is_error());
  unbindTx();
}

}  // namespace
}  // namespace wlan::testing
