/*
 * Copyright (C) 2016, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <array>
#include <memory>
#include <string>
#include <vector>

#include <linux/netlink.h>

#include <gtest/gtest.h>

#include "wificond/net/kernel-header-latest/nl80211.h"
#include "wificond/net/netlink_utils.h"
#include "wificond/tests/mock_netlink_manager.h"

using std::string;
using std::unique_ptr;
using std::vector;
using testing::DoAll;
using testing::NiceMock;
using testing::Return;
using testing::_;

namespace android {
namespace wificond {

namespace {

constexpr uint8_t kFakeMaxNumScanSSIDs = 10;
constexpr uint8_t kFakeMaxNumSchedScanSSIDs = 16;
constexpr uint8_t kFakeMaxMatchSets = 18;
constexpr uint8_t kFakeMaxNumScanPlans = 8;
constexpr uint8_t kFakeMaxScanPlanIntervals = 80;
constexpr uint8_t kFakeMaxScanPlanIterations = 10;
constexpr uint16_t kFakeFamilyId = 14;
constexpr uint32_t kFakeFrequency1 = 2412;
constexpr uint32_t kFakeFrequency2 = 2437;
constexpr uint32_t kFakeFrequency3 = 2484;
constexpr uint32_t kFakeFrequency4 = 5200;
constexpr uint32_t kFakeFrequency5 = 5400;
constexpr uint32_t kFakeFrequency6 = 5600;
// 802.11p channel which is not valid for wifi usage.
constexpr uint32_t kFakeInvalidFrequency = 5950;
constexpr uint32_t kFakeSequenceNumber = 162;
constexpr uint32_t kFakeProtocolFeatures = 0x02;
constexpr uint16_t kFakeWiphyIndex = 8;
constexpr uint16_t kFakeWiphyIndex1 = 10;
constexpr uint64_t kFakeCookie = 42;
constexpr int kFakeErrorCode = EIO;
constexpr int32_t kFakeMcs = 5;
constexpr bool kFakeSupportsRandomMacOneshotScan = true;
constexpr bool kFakeSupportsRandomMacSchedScan = false;
const char kFakeInterfaceName[] = "testif0";
const char kFakeCountryCode[] = "US";
const uint32_t kFakeInterfaceIndex = 34;
const uint32_t kFakeInterfaceIndex1 = 36;
const std::array<uint8_t, ETH_ALEN> kFakeInterfaceMacAddress = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
const std::array<uint8_t, ETH_ALEN> kFakeInterfaceMacAddress1 = {0x05, 0x04, 0xef, 0x27, 0x12, 0xff};
const uint8_t kFakeExtFeaturesForLowSpanScan[] = {0x0, 0x0, 0x40};
const uint8_t kFakeExtFeaturesForLowPowerScan[] = {0x0, 0x0, 0x80};
const uint8_t kFakeExtFeaturesForHighAccuracy[] = {0x0, 0x0, 0x0, 0x1};
const uint8_t kFakeExtFeaturesForAllScanType[] = {0x0, 0x0, 0xC0, 0x1};
const uint8_t kFakeFrame[] = {0x00, 0x01, 0x02, 0x03};
constexpr bool k11nSupported = true;
constexpr bool k11acSupported = true;
constexpr bool k11axSupported = true;
constexpr uint8_t kMaxTxStreams = 4;
constexpr uint8_t kMaxRxStreams = 5;
constexpr bool k160MHzSupported = true;
constexpr bool k80p80MHzSupported = false;
const uint8_t kHtMcsSet[] = {0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
                             0x0, 0x0, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0};
const uint8_t kVhtMcsSet[] = {0xaa, 0xfe, 0xff, 0xff, 0xaa, 0xff, 0xff, 0xff};
const uint8_t kHeMcsSet[] = {0xaa, 0xfe, 0xaa, 0xff};
const uint8_t kVhtCap[] = {0x4, 0x0, 0x0, 0x0};
const uint8_t kHeCapPhy[] = {0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};

// Currently, control messages are only created by the kernel and sent to us.
// Therefore NL80211Packet doesn't have corresponding constructor.
// For test we manually create control messages using this helper function.
NL80211Packet CreateControlMessageError(int error_code) {
  vector<uint8_t> data;
  data.resize(NLMSG_HDRLEN + NLA_ALIGN(sizeof(int)), 0);
  // Initialize length field.
  nlmsghdr* nl_header = reinterpret_cast<nlmsghdr*>(data.data());
  nl_header->nlmsg_len = data.size();
  nl_header->nlmsg_type = NLMSG_ERROR;
  nl_header->nlmsg_seq = kFakeSequenceNumber;
  nl_header->nlmsg_pid = getpid();
  int* error_field = reinterpret_cast<int*>(data.data() + NLMSG_HDRLEN);
  *error_field = -error_code;

  return NL80211Packet(data);
}

NL80211Packet CreateControlMessageAck() {
  return CreateControlMessageError(0);
}

void AppendScanCapabilitiesAttributes(NL80211Packet* packet,
                                      bool supports_scan_plan) {
  packet->AddAttribute(NL80211Attr<uint8_t>(NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
                                            kFakeMaxNumScanSSIDs));
  packet->AddAttribute(NL80211Attr<uint8_t>(
      NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
      kFakeMaxNumSchedScanSSIDs));
  packet->AddAttribute(NL80211Attr<uint8_t>(NL80211_ATTR_MAX_MATCH_SETS,
                                            kFakeMaxMatchSets));
  if (supports_scan_plan) {
    packet->AddAttribute(NL80211Attr<uint32_t>(
        NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS,
        kFakeMaxNumScanPlans));
    packet->AddAttribute(NL80211Attr<uint32_t>(
        NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL,
        kFakeMaxScanPlanIntervals));
    packet->AddAttribute(NL80211Attr<uint32_t>(
        NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS,
        kFakeMaxScanPlanIterations));
  }
}


NL80211Attr<std::vector<uint8_t>> GenerateBandsAttributeForHtCapa() {
  std::vector<uint8_t> ht_cap(2, 0);
  return NL80211Attr<std::vector<uint8_t>>(NL80211_BAND_ATTR_HT_CAPA,
                                           ht_cap);
}


NL80211Attr<std::vector<uint8_t>> GenerateBandsAttributeForVhtCapa() {
  std::vector<uint8_t> vht_cap(kVhtCap, kVhtCap + sizeof(kVhtCap));
  return NL80211Attr<std::vector<uint8_t>>(NL80211_BAND_ATTR_VHT_CAPA,
                                           vht_cap);
}

NL80211Attr<std::vector<uint8_t>> GenerateBandsAttributeForHtMcsSet() {
  std::vector<uint8_t> ht_mcs_set(kHtMcsSet, kHtMcsSet + sizeof(kHtMcsSet));
  return NL80211Attr<std::vector<uint8_t>>(NL80211_BAND_ATTR_HT_MCS_SET,
                                           ht_mcs_set);
}

NL80211Attr<std::vector<uint8_t>> GenerateBandsAttributeForVhtMcsSet() {
  std::vector<uint8_t> vht_mcs_set(kVhtMcsSet, kVhtMcsSet + sizeof(kVhtMcsSet));
  return NL80211Attr<std::vector<uint8_t>>(NL80211_BAND_ATTR_VHT_MCS_SET,
                                           vht_mcs_set);
}

NL80211NestedAttr GenerateBandsAttributeForIfTypeData() {
  NL80211NestedAttr if_type_data(NL80211_BAND_ATTR_IFTYPE_DATA);

  NL80211NestedAttr if_type_data1(1);
  std::vector<uint8_t> he_cap_phy(kHeCapPhy, kHeCapPhy + sizeof(kHeCapPhy));
  std::vector<uint8_t> he_mcs_set(kHeMcsSet, kHeMcsSet + sizeof(kHeMcsSet));

  if_type_data1.AddAttribute(NL80211Attr<std::vector<uint8_t>>(
      NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY, he_cap_phy));
  if_type_data1.AddAttribute(NL80211Attr<std::vector<uint8_t>>(
      NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET, he_mcs_set));
  if_type_data.AddAttribute(if_type_data1);
  return if_type_data;
}

void AppendBandPhyAttributes(NL80211NestedAttr* band_attr) {
  band_attr->AddAttribute(GenerateBandsAttributeForHtCapa());
  band_attr->AddAttribute(GenerateBandsAttributeForHtMcsSet());
  band_attr->AddAttribute(GenerateBandsAttributeForVhtCapa());
  band_attr->AddAttribute(GenerateBandsAttributeForVhtMcsSet());

  band_attr->AddAttribute(GenerateBandsAttributeForIfTypeData());
}

NL80211NestedAttr GenerateBandsAttributeFor2g() {
  NL80211NestedAttr freq_2g_1(1);
  NL80211NestedAttr freq_2g_2(2);
  NL80211NestedAttr freq_2g_3(3);
  freq_2g_1.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
                                               kFakeFrequency1));
  freq_2g_2.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
                                               kFakeFrequency2));
  freq_2g_3.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
                                               kFakeFrequency3));

  NL80211NestedAttr band_2g_freqs(NL80211_BAND_ATTR_FREQS);
  band_2g_freqs.AddAttribute(freq_2g_1);
  band_2g_freqs.AddAttribute(freq_2g_2);
  band_2g_freqs.AddAttribute(freq_2g_3);

  NL80211NestedAttr band_2g_attr(1);
  band_2g_attr.AddAttribute(band_2g_freqs);
  AppendBandPhyAttributes(&band_2g_attr);

  NL80211NestedAttr band_attr(NL80211_ATTR_WIPHY_BANDS);
  band_attr.AddAttribute(band_2g_attr);
  return band_attr;
}

NL80211NestedAttr GenerateBandsAttributeFor5gAndDfs() {
  NL80211NestedAttr freq_5g_1(4);
  NL80211NestedAttr freq_5g_2(5);
  NL80211NestedAttr freq_5g_3(6);
  NL80211NestedAttr freq_dfs_1(7);
  freq_5g_1.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
                                               kFakeFrequency4));
  freq_5g_2.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
                                               kFakeFrequency5));
  // This channel is passive only.
  freq_5g_2.AddFlagAttribute(NL80211_FREQUENCY_ATTR_NO_IR);

  // This channel is not valid for wifi usage.
  // We should not include it in the parse result.
  freq_5g_3.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
                                               kFakeInvalidFrequency));

  // DFS frequency.
  freq_dfs_1.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
                                                kFakeFrequency6));
  freq_dfs_1.AddAttribute(NL80211Attr<uint32_t>(
      NL80211_FREQUENCY_ATTR_DFS_STATE,
      NL80211_DFS_USABLE));

  NL80211NestedAttr band_5g_freqs(NL80211_BAND_ATTR_FREQS);
  band_5g_freqs.AddAttribute(freq_5g_1);
  band_5g_freqs.AddAttribute(freq_5g_2);
  band_5g_freqs.AddAttribute(freq_5g_3);
  band_5g_freqs.AddAttribute(freq_dfs_1);

  NL80211NestedAttr band_5g_attr(1);
  band_5g_attr.AddAttribute(band_5g_freqs);
  AppendBandPhyAttributes(&band_5g_attr);

  NL80211NestedAttr band_attr(NL80211_ATTR_WIPHY_BANDS);
  band_attr.AddAttribute(band_5g_attr);
  return band_attr;
}

void AppendBandInfoAttributes(NL80211Packet* packet) {
  NL80211NestedAttr attr_2g = GenerateBandsAttributeFor2g();
  NL80211NestedAttr attr_5g_and_dfs = GenerateBandsAttributeFor5gAndDfs();
  attr_2g.Merge(attr_5g_and_dfs);

  packet->AddAttribute(attr_2g);
}

void AppendWiphyFeaturesAttributes(NL80211Packet* packet) {
  uint32_t wiphy_features = 0;
  if (kFakeSupportsRandomMacOneshotScan) {
      wiphy_features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
  }
  if (kFakeSupportsRandomMacSchedScan) {
      wiphy_features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
  }
  packet->AddAttribute(
      NL80211Attr<uint32_t>(NL80211_ATTR_FEATURE_FLAGS, wiphy_features));
}

void AppendWiphyExtFeaturesAttributes(NL80211Packet* packet,
                                      bool support_low_span,
                                      bool support_low_power,
                                      bool support_high_accuracy,
                                      bool support_all) {
  ASSERT_LE(support_low_span + support_low_power + support_high_accuracy, 1);
  std::vector<uint8_t> ext_feature_flags_bytes;
  if (support_low_span) {
    ext_feature_flags_bytes =
        std::vector<uint8_t>(kFakeExtFeaturesForLowSpanScan,
                             kFakeExtFeaturesForLowSpanScan +
                             sizeof(kFakeExtFeaturesForLowSpanScan));
  } else if (support_low_power) {
    ext_feature_flags_bytes =
        std::vector<uint8_t>(kFakeExtFeaturesForLowPowerScan,
                             kFakeExtFeaturesForLowPowerScan +
                             sizeof(kFakeExtFeaturesForLowPowerScan));
  } else if (support_high_accuracy) {
    ext_feature_flags_bytes =
        std::vector<uint8_t>(kFakeExtFeaturesForHighAccuracy,
                             kFakeExtFeaturesForHighAccuracy +
                             sizeof(kFakeExtFeaturesForHighAccuracy));
  } else if (support_all) {
    ext_feature_flags_bytes =
        std::vector<uint8_t>(kFakeExtFeaturesForAllScanType,
                             kFakeExtFeaturesForAllScanType +
                             sizeof(kFakeExtFeaturesForAllScanType));
  }
  packet->AddAttribute(
      NL80211Attr<std::vector<uint8_t>>(NL80211_ATTR_EXT_FEATURES,
                                        ext_feature_flags_bytes));
}

void VerifyScanCapabilities(const ScanCapabilities& scan_capabilities,
                            bool supports_scan_plan) {
  EXPECT_EQ(scan_capabilities.max_num_scan_ssids,
            kFakeMaxNumScanSSIDs);
  EXPECT_EQ(scan_capabilities.max_num_sched_scan_ssids,
            kFakeMaxNumSchedScanSSIDs);
  EXPECT_EQ(scan_capabilities.max_match_sets,
            kFakeMaxMatchSets);
  if (supports_scan_plan) {
    EXPECT_EQ(scan_capabilities.max_num_scan_plans,
              kFakeMaxNumScanPlans);
    EXPECT_EQ(scan_capabilities.max_scan_plan_interval,
              kFakeMaxScanPlanIntervals);
    EXPECT_EQ(scan_capabilities.max_scan_plan_iterations,
              kFakeMaxScanPlanIterations);
  } else {
    EXPECT_EQ(scan_capabilities.max_num_scan_plans, (unsigned int) 0);
    EXPECT_EQ(scan_capabilities.max_scan_plan_interval, (unsigned int) 0);
    EXPECT_EQ(scan_capabilities.max_scan_plan_iterations, (unsigned int) 0);
  }
}

void VerifyBandInfo(const BandInfo& band_info) {
  vector<uint32_t> band_2g_expected = {kFakeFrequency1,
      kFakeFrequency2, kFakeFrequency3};
  vector<uint32_t> band_5g_expected = {kFakeFrequency4};
  // Frequency5 is doesn't belong to a DFS channel. However, our convetion
  // requires us to return any passive only channels in DFS band.
  vector<uint32_t> band_dfs_expected = {kFakeFrequency5, kFakeFrequency6};
  EXPECT_EQ(band_info.band_2g, band_2g_expected);
  EXPECT_EQ(band_info.band_5g, band_5g_expected);
  EXPECT_EQ(band_info.band_dfs, band_dfs_expected);
  EXPECT_EQ(band_info.is_80211n_supported, k11nSupported);
  EXPECT_EQ(band_info.is_80211ac_supported, k11acSupported);
  EXPECT_EQ(band_info.is_80211ax_supported, k11axSupported);
  EXPECT_EQ(band_info.is_160_mhz_supported, k160MHzSupported);
  EXPECT_EQ(band_info.is_80p80_mhz_supported, k80p80MHzSupported);
  EXPECT_EQ(band_info.max_tx_streams, kMaxTxStreams);
  EXPECT_EQ(band_info.max_rx_streams, kMaxRxStreams);
}

void VerifyWiphyFeatures(const WiphyFeatures& wiphy_features) {
  EXPECT_TRUE(wiphy_features.supports_random_mac_oneshot_scan);
  EXPECT_FALSE(wiphy_features.supports_random_mac_sched_scan);
}

}  // namespace

// This mocks the behavior of SendMessageAndGetResponses(), which returns a
// vector of NL80211Packet using passed in pointer.
ACTION_P(MakeupResponse, response) {
  // arg1 is the second parameter: vector<unique_ptr<const NL80211Packet>>* responses.
  for (auto& pkt : response) {
    arg1->push_back(unique_ptr<NL80211Packet>(new NL80211Packet(pkt)));
  }
}

class NetlinkUtilsTest : public ::testing::Test {
 protected:
  std::unique_ptr<NiceMock<MockNetlinkManager>> netlink_manager_;
  std::unique_ptr<NetlinkUtils> netlink_utils_;

  virtual void SetUp() {
    netlink_manager_.reset(new NiceMock<MockNetlinkManager>());
    netlink_utils_.reset(new NetlinkUtils(netlink_manager_.get()));

    ON_CALL(*netlink_manager_,
            GetSequenceNumber()).WillByDefault(Return(kFakeSequenceNumber));
    ON_CALL(*netlink_manager_,
            GetFamilyId()).WillByDefault(Return(kFakeFamilyId));
  }

  void SetSplitWiphyDumpSupported(bool supported) {
    netlink_utils_->supports_split_wiphy_dump_ = supported;
  }

};

TEST_F(NetlinkUtilsTest, CanGetWiphyIndex) {
  NL80211Packet new_wiphy(
      netlink_manager_->GetFamilyId(),
      NL80211_CMD_NEW_WIPHY,
      netlink_manager_->GetSequenceNumber(),
      getpid());
  // Insert wiphy_index attribute.
  NL80211Attr<uint32_t> wiphy_index_attr(NL80211_ATTR_WIPHY, kFakeWiphyIndex);
  new_wiphy.AddAttribute(wiphy_index_attr);
  // Mock a valid response from kernel.
  vector<NL80211Packet> response = {new_wiphy};

  EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
      WillOnce(DoAll(MakeupResponse(response), Return(true)));

  uint32_t wiphy_index;
  EXPECT_TRUE(netlink_utils_->GetWiphyIndex(&wiphy_index));
  EXPECT_EQ(kFakeWiphyIndex, wiphy_index);
}

TEST_F(NetlinkUtilsTest, CanHandleGetWiphyIndexError) {
  // Mock an error response from kernel.
  vector<NL80211Packet> response = {CreateControlMessageError(kFakeErrorCode)};

  EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
      WillOnce(DoAll(MakeupResponse(response), Return(true)));

  uint32_t wiphy_index;
  EXPECT_FALSE(netlink_utils_->GetWiphyIndex(&wiphy_index));
}

TEST_F(NetlinkUtilsTest, CanSetIntrerfaceMode) {
  // Mock a ACK response from kernel.
  vector<NL80211Packet> response = {CreateControlMessageAck()};

  EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
      WillOnce(DoAll(MakeupResponse(response), Return(true)));

  EXPECT_TRUE(netlink_utils_->SetInterfaceMode(kFakeInterfaceIndex,
                                               NetlinkUtils::STATION_MODE));
}

TEST_F(NetlinkUtilsTest, CanHandleSetIntrerfaceModeError) {
  // Mock an error response from kernel.
  vector<NL80211Packet> response = {CreateControlMessageError(kFakeErrorCode)};

  EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
      WillOnce(DoAll(MakeupResponse(response), Return(true)));

  EXPECT_FALSE(netlink_utils_->SetInterfaceMode(kFakeInterfaceIndex,
                                                NetlinkUtils::STATION_MODE));
}

TEST_F(NetlinkUtilsTest, CanGetInterfaces) {
  NL80211Packet new_interface(
      netlink_manager_->GetFamilyId(),
      NL80211_CMD_NEW_INTERFACE,
      netlink_manager_->GetSequenceNumber(),
      getpid());
  // Insert interface name attribute.
  NL80211Attr<string> if_name_attr(NL80211_ATTR_IFNAME, string(kFakeInterfaceName));
  new_interface.AddAttribute(if_name_attr);
  // Insert interface index attribute.
  NL80211Attr<uint32_t> if_index_attr(NL80211_ATTR_IFINDEX, kFakeInterfaceIndex);
  new_interface.AddAttribute(if_index_attr);
  // Insert mac address attribute.
  std::array<uint8_t, ETH_ALEN> if_mac_addr = kFakeInterfaceMacAddress;
  NL80211Attr<std::array<uint8_t, ETH_ALEN>> if_mac_attr(NL80211_ATTR_MAC, if_mac_addr);
  new_interface.AddAttribute(if_mac_attr);

  // Mock a valid response from kernel.
  vector<NL80211Packet> response = {new_interface};

  EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
      WillOnce(DoAll(MakeupResponse(response), Return(true)));

  vector<InterfaceInfo> interfaces;
  EXPECT_TRUE(netlink_utils_->GetInterfaces(kFakeWiphyIndex, &interfaces));
  EXPECT_TRUE(interfaces.size() == 1);
  EXPECT_EQ(kFakeInterfaceIndex, interfaces[0].index);
  EXPECT_EQ(string(kFakeInterfaceName), interfaces[0].name);
  EXPECT_EQ(if_mac_addr, interfaces[0].mac_address);
}

TEST_F(NetlinkUtilsTest, SkipsPseudoDevicesWhenGetInterfaces) {
  // This might be a psuedo p2p interface without any interface index/name
  // attributes.
  NL80211Packet psuedo_interface(
      netlink_manager_->GetFamilyId(),
      NL80211_CMD_NEW_INTERFACE,
      netlink_manager_->GetSequenceNumber(),
      getpid());
  psuedo_interface.AddAttribute(NL80211Attr<uint64_t>(
      NL80211_ATTR_WDEV, 0));

  // This is a regular client interface.
  NL80211Packet expected_interface(
      netlink_manager_->GetFamilyId(),
      NL80211_CMD_NEW_INTERFACE,
      netlink_manager_->GetSequenceNumber(),
      getpid());
  expected_interface.AddAttribute(NL80211Attr<string>(
      NL80211_ATTR_IFNAME, string(kFakeInterfaceName)));
  expected_interface.AddAttribute(NL80211Attr<uint32_t>(
      NL80211_ATTR_IFINDEX, kFakeInterfaceIndex));
  std::array<uint8_t, ETH_ALEN> if_mac_addr = kFakeInterfaceMacAddress;
  expected_interface.AddAttribute(
      NL80211Attr<std::array<uint8_t, ETH_ALEN>>(NL80211_ATTR_MAC, if_mac_addr));

  // Kernel can send us the pseduo interface packet first
  vector<NL80211Packet> response = {psuedo_interface, expected_interface};

  EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
      WillOnce(DoAll(MakeupResponse(response), Return(true)));

  vector<InterfaceInfo> interfaces;
  EXPECT_TRUE(netlink_utils_->GetInterfaces(kFakeWiphyIndex, &interfaces));
  EXPECT_TRUE(interfaces.size() == 1);
  EXPECT_EQ(kFakeInterfaceIndex, interfaces[0].index);
  EXPECT_EQ(string(kFakeInterfaceName), interfaces[0].name);
  EXPECT_EQ(if_mac_addr, interfaces[0].mac_address);
}

TEST_F(NetlinkUtilsTest, HandleP2p0WhenGetInterfaces) {
  NL80211Packet new_interface(
      netlink_manager_->GetFamilyId(),
      NL80211_CMD_NEW_INTERFACE,
      netlink_manager_->GetSequenceNumber(),
      getpid());
  // Insert interface name attribute.
  NL80211Attr<string> if_name_attr(NL80211_ATTR_IFNAME, string(kFakeInterfaceName));
  new_interface.AddAttribute(if_name_attr);
  // Insert interface index attribute.
  new_interface.AddAttribute(
      NL80211Attr<uint32_t>(NL80211_ATTR_IFINDEX, kFakeInterfaceIndex));
  // Insert mac address attribute.
  std::array<uint8_t, ETH_ALEN> if_mac_addr = kFakeInterfaceMacAddress;
  new_interface.AddAttribute(
      NL80211Attr<std::array<uint8_t, ETH_ALEN>>(NL80211_ATTR_MAC, if_mac_addr));

  // Create a new interface packet for p2p0.
  NL80211Packet new_interface_p2p0(
      netlink_manager_->GetFamilyId(),
      NL80211_CMD_NEW_INTERFACE,
      netlink_manager_->GetSequenceNumber(),
      getpid());

  // Insert interface name attribute.
  new_interface_p2p0.AddAttribute(
      NL80211Attr<string>(NL80211_ATTR_IFNAME, "p2p0"));
  // Insert interface index attribute.
  new_interface_p2p0.AddAttribute(
      NL80211Attr<uint32_t>(NL80211_ATTR_IFINDEX, kFakeInterfaceIndex1));
  // Insert mac address attribute.
  std::array<uint8_t, ETH_ALEN> if_mac_addr_p2p = kFakeInterfaceMacAddress1;
  new_interface_p2p0.AddAttribute(
      NL80211Attr<std::array<uint8_t, ETH_ALEN>>(NL80211_ATTR_MAC, if_mac_addr_p2p));

  // Mock response from kernel, including 2 interfaces.
  vector<NL80211Packet> response = {new_interface_p2p0, new_interface};

  EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
      WillOnce(DoAll(MakeupResponse(response), Return(true)));

  vector<InterfaceInfo> interfaces;
  EXPECT_TRUE(netlink_utils_->GetInterfaces(kFakeWiphyIndex, &interfaces));
  EXPECT_TRUE(interfaces.size() == 2);

  EXPECT_EQ(kFakeInterfaceIndex1, interfaces[0].index);
  EXPECT_EQ(string("p2p0"), interfaces[0].name);
  EXPECT_EQ(if_mac_addr_p2p, interfaces[0].mac_address);

  EXPECT_EQ(kFakeInterfaceIndex, interfaces[1].index);
  EXPECT_EQ(string(kFakeInterfaceName), interfaces[1].name);
  EXPECT_EQ(if_mac_addr, interfaces[1].mac_address);
}

TEST_F(NetlinkUtilsTest, CanHandleGetInterfacesError) {
  // Mock an error response from kernel.
  vector<NL80211Packet> response = {CreateControlMessageError(kFakeErrorCode)};

  EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
      WillOnce(DoAll(MakeupResponse(response), Return(true)));

  vector<InterfaceInfo> interfaces;
  EXPECT_FALSE(netlink_utils_->GetInterfaces(kFakeWiphyIndex, &interfaces));
}

TEST_F(NetlinkUtilsTest, CanGetWiphyInfo) {
  SetSplitWiphyDumpSupported(false);
  NL80211Packet new_wiphy(
      netlink_manager_->GetFamilyId(),
      NL80211_CMD_NEW_WIPHY,
      netlink_manager_->GetSequenceNumber(),
      getpid());
  new_wiphy.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_WIPHY,
                                               kFakeWiphyIndex));
  AppendBandInfoAttributes(&new_wiphy);
  AppendScanCapabilitiesAttributes(&new_wiphy, true);
  AppendWiphyFeaturesAttributes(&new_wiphy);
  vector<NL80211Packet> get_wiphy_response = {new_wiphy};

  EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
      WillOnce(DoAll(MakeupResponse(get_wiphy_response), Return(true)));

  BandInfo band_info;
  ScanCapabilities scan_capabilities;
  WiphyFeatures wiphy_features;
  EXPECT_TRUE(netlink_utils_->GetWiphyInfo(kFakeWiphyIndex,
                                           &band_info,
                                           &scan_capabilities,
                                           &wiphy_features));
  VerifyBandInfo(band_info);
  VerifyScanCapabilities(scan_capabilities, true);
  VerifyWiphyFeatures(wiphy_features);
  EXPECT_FALSE(wiphy_features.supports_low_span_oneshot_scan);
  EXPECT_FALSE(wiphy_features.supports_low_power_oneshot_scan);
  EXPECT_FALSE(wiphy_features.supports_high_accuracy_oneshot_scan);
}

TEST_F(NetlinkUtilsTest, CanGetWiphyInfoWithNoDbsParam) {
  SetSplitWiphyDumpSupported(false);
  NL80211Packet new_wiphy(
      netlink_manager_->GetFamilyId(),
      NL80211_CMD_NEW_WIPHY,
      netlink_manager_->GetSequenceNumber(),
      getpid());
  new_wiphy.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_WIPHY,
                                               kFakeWiphyIndex));
  AppendBandInfoAttributes(&new_wiphy);
  AppendScanCapabilitiesAttributes(&new_wiphy, false);
  AppendWiphyFeaturesAttributes(&new_wiphy);
  AppendWiphyExtFeaturesAttributes(&new_wiphy, false, false, false, false);
  vector<NL80211Packet> get_wiphy_response = {new_wiphy};

  EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
      WillOnce(DoAll(MakeupResponse(get_wiphy_response), Return(true)));

  BandInfo band_info;
  ScanCapabilities scan_capabilities;
  WiphyFeatures wiphy_features;
  EXPECT_TRUE(netlink_utils_->GetWiphyInfo(kFakeWiphyIndex,
                                           &band_info,
                                           &scan_capabilities,
                                           &wiphy_features));
  VerifyBandInfo(band_info);
  VerifyScanCapabilities(scan_capabilities, false);
  VerifyWiphyFeatures(wiphy_features);
  EXPECT_FALSE(wiphy_features.supports_low_span_oneshot_scan);
  EXPECT_FALSE(wiphy_features.supports_low_power_oneshot_scan);
  EXPECT_FALSE(wiphy_features.supports_high_accuracy_oneshot_scan);
}

TEST_F(NetlinkUtilsTest, CanGetWiphyInfoWithLowSpanScan) {
  SetSplitWiphyDumpSupported(false);
  NL80211Packet new_wiphy(
      netlink_manager_->GetFamilyId(),
      NL80211_CMD_NEW_WIPHY,
      netlink_manager_->GetSequenceNumber(),
      getpid());
  new_wiphy.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_WIPHY,
                                               kFakeWiphyIndex));
  AppendBandInfoAttributes(&new_wiphy);
  AppendScanCapabilitiesAttributes(&new_wiphy, false);
  AppendWiphyFeaturesAttributes(&new_wiphy);
  AppendWiphyExtFeaturesAttributes(&new_wiphy, true, false, false, false);
  vector<NL80211Packet> get_wiphy_response = {new_wiphy};

  EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
      WillOnce(DoAll(MakeupResponse(get_wiphy_response), Return(true)));

  BandInfo band_info;
  ScanCapabilities scan_capabilities;
  WiphyFeatures wiphy_features;
  EXPECT_TRUE(netlink_utils_->GetWiphyInfo(kFakeWiphyIndex,
                                           &band_info,
                                           &scan_capabilities,
                                           &wiphy_features));
  VerifyBandInfo(band_info);
  VerifyScanCapabilities(scan_capabilities, false);
  VerifyWiphyFeatures(wiphy_features);
  EXPECT_TRUE(wiphy_features.supports_low_span_oneshot_scan);
  EXPECT_FALSE(wiphy_features.supports_low_power_oneshot_scan);
  EXPECT_FALSE(wiphy_features.supports_high_accuracy_oneshot_scan);
}

TEST_F(NetlinkUtilsTest, CanGetWiphyInfoWithLowPowerScan) {
  SetSplitWiphyDumpSupported(false);
  NL80211Packet new_wiphy(
      netlink_manager_->GetFamilyId(),
      NL80211_CMD_NEW_WIPHY,
      netlink_manager_->GetSequenceNumber(),
      getpid());
  new_wiphy.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_WIPHY,
                                               kFakeWiphyIndex));
  AppendBandInfoAttributes(&new_wiphy);
  AppendScanCapabilitiesAttributes(&new_wiphy, false);
  AppendWiphyFeaturesAttributes(&new_wiphy);
  AppendWiphyExtFeaturesAttributes(&new_wiphy, false, true, false, false);
  vector<NL80211Packet> get_wiphy_response = {new_wiphy};

  EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
      WillOnce(DoAll(MakeupResponse(get_wiphy_response), Return(true)));

  BandInfo band_info;
  ScanCapabilities scan_capabilities;
  WiphyFeatures wiphy_features;
  EXPECT_TRUE(netlink_utils_->GetWiphyInfo(kFakeWiphyIndex,
                                           &band_info,
                                           &scan_capabilities,
                                           &wiphy_features));
  VerifyBandInfo(band_info);
  VerifyScanCapabilities(scan_capabilities, false);
  VerifyWiphyFeatures(wiphy_features);
  EXPECT_FALSE(wiphy_features.supports_low_span_oneshot_scan);
  EXPECT_TRUE(wiphy_features.supports_low_power_oneshot_scan);
  EXPECT_FALSE(wiphy_features.supports_high_accuracy_oneshot_scan);
}

TEST_F(NetlinkUtilsTest, CanGetWiphyInfoWithHighAccuracyScan) {
  SetSplitWiphyDumpSupported(false);
  NL80211Packet new_wiphy(
      netlink_manager_->GetFamilyId(),
      NL80211_CMD_NEW_WIPHY,
      netlink_manager_->GetSequenceNumber(),
      getpid());
  new_wiphy.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_WIPHY,
                                               kFakeWiphyIndex));
  AppendBandInfoAttributes(&new_wiphy);
  AppendScanCapabilitiesAttributes(&new_wiphy, false);
  AppendWiphyFeaturesAttributes(&new_wiphy);
  AppendWiphyExtFeaturesAttributes(&new_wiphy, false, false, true, false);
  vector<NL80211Packet> get_wiphy_response = {new_wiphy};

  EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
      WillOnce(DoAll(MakeupResponse(get_wiphy_response), Return(true)));

  BandInfo band_info;
  ScanCapabilities scan_capabilities;
  WiphyFeatures wiphy_features;
  EXPECT_TRUE(netlink_utils_->GetWiphyInfo(kFakeWiphyIndex,
                                           &band_info,
                                           &scan_capabilities,
                                           &wiphy_features));
  VerifyBandInfo(band_info);
  VerifyScanCapabilities(scan_capabilities, false);
  VerifyWiphyFeatures(wiphy_features);
  EXPECT_FALSE(wiphy_features.supports_low_span_oneshot_scan);
  EXPECT_FALSE(wiphy_features.supports_low_power_oneshot_scan);
  EXPECT_TRUE(wiphy_features.supports_high_accuracy_oneshot_scan);
}

TEST_F(NetlinkUtilsTest, CanGetWiphyInfoWithAllDbsParams) {
  SetSplitWiphyDumpSupported(false);
  NL80211Packet new_wiphy(
      netlink_manager_->GetFamilyId(),
      NL80211_CMD_NEW_WIPHY,
      netlink_manager_->GetSequenceNumber(),
      getpid());
  new_wiphy.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_WIPHY,
                                               kFakeWiphyIndex));
  AppendBandInfoAttributes(&new_wiphy);
  AppendScanCapabilitiesAttributes(&new_wiphy, false);
  AppendWiphyFeaturesAttributes(&new_wiphy);
  AppendWiphyExtFeaturesAttributes(&new_wiphy, false, false, false, true);
  vector<NL80211Packet> get_wiphy_response = {new_wiphy};

  EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
      WillOnce(DoAll(MakeupResponse(get_wiphy_response), Return(true)));

  BandInfo band_info;
  ScanCapabilities scan_capabilities;
  WiphyFeatures wiphy_features;
  EXPECT_TRUE(netlink_utils_->GetWiphyInfo(kFakeWiphyIndex,
                                           &band_info,
                                           &scan_capabilities,
                                           &wiphy_features));
  VerifyBandInfo(band_info);
  VerifyScanCapabilities(scan_capabilities, false);
  VerifyWiphyFeatures(wiphy_features);
  EXPECT_TRUE(wiphy_features.supports_low_span_oneshot_scan);
  EXPECT_TRUE(wiphy_features.supports_low_power_oneshot_scan);
  EXPECT_TRUE(wiphy_features.supports_high_accuracy_oneshot_scan);
}

TEST_F(NetlinkUtilsTest, CanGetWiphyInfoScanPlanNotSupported) {
  SetSplitWiphyDumpSupported(false);
  NL80211Packet new_wiphy(
      netlink_manager_->GetFamilyId(),
      NL80211_CMD_NEW_WIPHY,
      netlink_manager_->GetSequenceNumber(),
      getpid());
  new_wiphy.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_WIPHY,
                                               kFakeWiphyIndex));
  AppendBandInfoAttributes(&new_wiphy);
  AppendScanCapabilitiesAttributes(&new_wiphy, false);
  AppendWiphyFeaturesAttributes(&new_wiphy);
  vector<NL80211Packet> get_wiphy_response = {new_wiphy};

  EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
      WillOnce(DoAll(MakeupResponse(get_wiphy_response), Return(true)));

  BandInfo band_info;
  ScanCapabilities scan_capabilities;
  WiphyFeatures wiphy_features;
  EXPECT_TRUE(netlink_utils_->GetWiphyInfo(kFakeWiphyIndex,
                                           &band_info,
                                           &scan_capabilities,
                                           &wiphy_features));
  VerifyBandInfo(band_info);
  VerifyScanCapabilities(scan_capabilities, false);
  VerifyWiphyFeatures(wiphy_features);
}

TEST_F(NetlinkUtilsTest, CanGetWiphyInfoSplitDump) {
  SetSplitWiphyDumpSupported(true);

  NL80211Packet new_wiphy_packet1(
      netlink_manager_->GetFamilyId(),
      NL80211_CMD_NEW_WIPHY,
      netlink_manager_->GetSequenceNumber(),
      getpid());
  new_wiphy_packet1.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_WIPHY,
                                                       kFakeWiphyIndex));
  new_wiphy_packet1.AddAttribute(GenerateBandsAttributeFor5gAndDfs());

  NL80211Packet new_wiphy_packet2(
      netlink_manager_->GetFamilyId(),
      NL80211_CMD_NEW_WIPHY,
      netlink_manager_->GetSequenceNumber(),
      getpid());
  new_wiphy_packet2.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_WIPHY,
                                                       kFakeWiphyIndex));
  new_wiphy_packet2.AddAttribute(GenerateBandsAttributeFor2g());
  AppendScanCapabilitiesAttributes(&new_wiphy_packet2, false);
  AppendWiphyFeaturesAttributes(&new_wiphy_packet2);

  // Insert a packet for wiphy with index kFakeWiphyIndex1.
  // This is unrelated and should be ingnored by |GetWiphyInfo|.
  NL80211Packet new_wiphy_packet3(
      netlink_manager_->GetFamilyId(),
      NL80211_CMD_NEW_WIPHY,
      netlink_manager_->GetSequenceNumber(),
      getpid());
  new_wiphy_packet3.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_WIPHY,
                                                       kFakeWiphyIndex1));
  AppendBandInfoAttributes(&new_wiphy_packet3);

  vector<NL80211Packet> get_wiphy_response =
      {new_wiphy_packet1, new_wiphy_packet2, new_wiphy_packet3};

  EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
      WillOnce(DoAll(MakeupResponse(get_wiphy_response), Return(true)));

  BandInfo band_info;
  ScanCapabilities scan_capabilities;
  WiphyFeatures wiphy_features;
  EXPECT_TRUE(netlink_utils_->GetWiphyInfo(kFakeWiphyIndex,
                                           &band_info,
                                           &scan_capabilities,
                                           &wiphy_features));
  VerifyBandInfo(band_info);
  VerifyScanCapabilities(scan_capabilities, false);
  VerifyWiphyFeatures(wiphy_features);
}


TEST_F(NetlinkUtilsTest, CanHandleGetWiphyInfoError) {
  SetSplitWiphyDumpSupported(false);

  // Mock an error response from kernel.
  vector<NL80211Packet> get_wiphy_response = {CreateControlMessageError(kFakeErrorCode)};

  EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
      WillOnce(DoAll(MakeupResponse(get_wiphy_response), Return(true)));

  BandInfo band_info;
  ScanCapabilities scan_capabilities;
  WiphyFeatures wiphy_features;
  EXPECT_FALSE(netlink_utils_->GetWiphyInfo(kFakeWiphyIndex,
                                           &band_info,
                                           &scan_capabilities,
                                           &wiphy_features));
}

TEST_F(NetlinkUtilsTest, CanGetProtocolFeatures) {
  // There is no specification for the response packet id for
  // NL80211_CMD_GET_PROTOCOL_FEATURES.
  // Still use NL80211_CMD_GET_PROTOCOL_FEATURES here.
  NL80211Packet get_features_response(
      netlink_manager_->GetFamilyId(),
      NL80211_CMD_GET_PROTOCOL_FEATURES,
      netlink_manager_->GetSequenceNumber(),
      getpid());
  get_features_response.AddAttribute(
      NL80211Attr<uint32_t>(NL80211_ATTR_PROTOCOL_FEATURES,
                            kFakeProtocolFeatures));
  vector<NL80211Packet> response = {get_features_response};

  EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
      WillOnce(DoAll(MakeupResponse(response), Return(true)));

  uint32_t features;
  EXPECT_TRUE(netlink_utils_->GetProtocolFeatures(&features));
  EXPECT_EQ(kFakeProtocolFeatures, features);
}

TEST_F(NetlinkUtilsTest, CanHandleGetProtocolFeaturesError) {
  // Mock an error response from kernel.
  vector<NL80211Packet> response = {CreateControlMessageError(kFakeErrorCode)};

  EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
      WillOnce(DoAll(MakeupResponse(response), Return(true)));

  uint32_t features_ignored;
  EXPECT_FALSE(netlink_utils_->GetProtocolFeatures(&features_ignored));
}

TEST_F(NetlinkUtilsTest, CanGetCountryCode) {
  // There is no specification for the response packet id for
  // NL80211_CMD_GET_REG.
  // Still use NL80211_CMD_GET_REG here.
  NL80211Packet get_country_code_response(
      netlink_manager_->GetFamilyId(),
      NL80211_CMD_GET_REG,
      netlink_manager_->GetSequenceNumber(),
      getpid());
  get_country_code_response.AddAttribute(
      NL80211Attr<string>(NL80211_ATTR_REG_ALPHA2,
                          kFakeCountryCode));
  vector<NL80211Packet> response = {get_country_code_response};

  EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
      WillOnce(DoAll(MakeupResponse(response), Return(true)));

  string country_code;
  EXPECT_TRUE(netlink_utils_->GetCountryCode(&country_code));
  EXPECT_EQ(kFakeCountryCode, country_code);
}

TEST_F(NetlinkUtilsTest, CanHandleGetCountryCodeError) {
  // Mock an error response from kernel.
  vector<NL80211Packet> response = {CreateControlMessageError(kFakeErrorCode)};

  EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
      WillOnce(DoAll(MakeupResponse(response), Return(true)));

  string country_code_ignored;
  EXPECT_FALSE(netlink_utils_->GetCountryCode(&country_code_ignored));
}

TEST_F(NetlinkUtilsTest, CanSendMgmtFrame) {
  // There is no specification for the response packet id for
  // NL80211_CMD_FRAME.
  // Still use NL80211_CMD_FRAME here.
  NL80211Packet send_mgmt_frame_response(
      netlink_manager_->GetFamilyId(),
      NL80211_CMD_FRAME,
      netlink_manager_->GetSequenceNumber(),
      getpid());
  send_mgmt_frame_response.AddAttribute(
      NL80211Attr<uint64_t>(NL80211_ATTR_COOKIE, kFakeCookie));
  vector<NL80211Packet> response = {send_mgmt_frame_response};

  EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _))
    .WillOnce(DoAll(MakeupResponse(response), Return(true)));

  uint64_t cookie;
  EXPECT_TRUE(netlink_utils_->SendMgmtFrame(kFakeInterfaceIndex,
      vector<uint8_t>(std::begin(kFakeFrame), std::end(kFakeFrame)),
      kFakeMcs, &cookie));
  EXPECT_EQ(kFakeCookie, cookie);
}

TEST_F(NetlinkUtilsTest, CanHandleSendMgmtFrameError) {
  // Mock an error response from kernel.
  vector<NL80211Packet> response = {CreateControlMessageError(kFakeErrorCode)};
  EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
      WillOnce(DoAll(MakeupResponse(response), Return(true)));

  uint64_t cookie_ignored;
  EXPECT_FALSE(netlink_utils_->SendMgmtFrame(kFakeInterfaceIndex,
      vector<uint8_t>(std::begin(kFakeFrame), std::end(kFakeFrame)),
      kFakeMcs, &cookie_ignored));
}

}  // namespace wificond
}  // namespace android
