// Copyright (c) 2012 The Chromium OS 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 "shill/wifi_endpoint.h"

#include <map>
#include <set>
#include <string>
#include <vector>

#include <base/stl_util.h>
#include <chromeos/dbus/service_constants.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "shill/ieee80211.h"
#include "shill/mock_log.h"
#include "shill/mock_wifi.h"
#include "shill/property_store_unittest.h"
#include "shill/refptr_types.h"
#include "shill/wpa_supplicant.h"

using std::map;
using std::set;
using std::string;
using std::vector;
using ::testing::_;
using ::testing::HasSubstr;
using ::testing::Mock;
using ::testing::NiceMock;

namespace shill {

class WiFiEndpointTest : public PropertyStoreTest {
 public:
  WiFiEndpointTest() : wifi_(
      new NiceMock<MockWiFi>(
          control_interface(),
          dispatcher(),
          metrics(),
          manager(),
          "wifi",
          "aabbccddeeff",  // fake mac
          0)) {}
  virtual ~WiFiEndpointTest() {}

 protected:
  vector<string> make_string_vector1(const string &str1) {
    vector<string> strvec;
    strvec.push_back(str1);
    return strvec;
  }

  vector<string> make_string_vector2(const string &str1, const string &str2) {
    vector<string> strvec;
    strvec.push_back(str1);
    strvec.push_back(str2);
    return strvec;
  }

  map<string, ::DBus::Variant> make_key_management_args(
      vector<string> key_management_method_strings) {
    map<string, ::DBus::Variant> args;
    ::DBus::MessageIter writer;
    writer =
        args[WPASupplicant::kSecurityMethodPropertyKeyManagement].writer();
    writer << key_management_method_strings;
    return args;
  }

  map<string, ::DBus::Variant> make_privacy_args(bool is_private) {
    map<string, ::DBus::Variant> props;
    props[WPASupplicant::kPropertyPrivacy].writer().append_bool(is_private);
    return props;
  }

  map<string, ::DBus::Variant> make_security_args(
      const string &security_protocol,
      const string &key_management_method) {
    map<string, ::DBus::Variant> args;
    ::DBus::MessageIter writer;
    writer = args[security_protocol].writer();
    vector<string> key_management_method_vector;
    if (!key_management_method.empty()) {
      key_management_method_vector = make_string_vector1(key_management_method);
    }
    writer << make_key_management_args(key_management_method_vector);
    return args;
  }

  const char *ParseSecurity(
    const map<string, ::DBus::Variant> &properties) {
    WiFiEndpoint::SecurityFlags security_flags;
    return WiFiEndpoint::ParseSecurity(properties, &security_flags);
  }

  void AddIEWithData(uint8_t type, vector<uint8_t> data, vector<uint8_t> *ies) {
    ies->push_back(type);           // type
    ies->push_back(data.size());    // length
    ies->insert(ies->end(), data.begin(), data.end());
  }

  void AddIE(uint8_t type, vector<uint8_t> *ies) {
    AddIEWithData(type, vector<uint8_t>(1), ies);
  }

  void AddVendorIE(uint32_t oui, uint8_t vendor_type,
                   const vector<uint8_t> &data,
                   vector<uint8_t> *ies) {
    ies->push_back(IEEE_80211::kElemIdVendor);  // type
    ies->push_back(4 + data.size());            // length
    ies->push_back((oui >> 16) & 0xff);         // OUI MSByte
    ies->push_back((oui >> 8) & 0xff);          // OUI middle octet
    ies->push_back(oui & 0xff);                 // OUI LSByte
    ies->push_back(vendor_type);                // OUI Type
    ies->insert(ies->end(), data.begin(), data.end());
  }

  void AddWPSElement(uint16_t type, const string &value,
                     vector<uint8_t> *wps) {
    wps->push_back(type >> 8);                   // type MSByte
    wps->push_back(type);                        // type LSByte
    CHECK(value.size() < kuint16max);
    wps->push_back((value.size() >> 8) & 0xff);  // length MSByte
    wps->push_back(value.size() & 0xff);         // length LSByte
    wps->insert(wps->end(), value.begin(), value.end());
  }

  map<string, ::DBus::Variant> MakeBSSPropertiesWithIEs(
      const vector<uint8_t> &ies) {
    map<string, ::DBus::Variant> properties;
    ::DBus::MessageIter writer =
          properties[WPASupplicant::kBSSPropertyIEs].writer();
    writer << ies;
    return properties;
  }

  // Creates the RSN properties string (which still requires an information
  // element prefix).
  vector<uint8_t> MakeRSNProperties(uint16 pairwise_count,
                                    uint16 authkey_count,
                                    uint16 capabilities) {
    vector<uint8_t> rsn(IEEE_80211::kRSNIECipherCountOffset +
                        IEEE_80211::kRSNIECipherCountLen * 2 +
                        IEEE_80211::kRSNIESelectorLen *
                        (pairwise_count + authkey_count) +
                        IEEE_80211::kRSNIECapabilitiesLen);

    // Set both cipher counts in little endian.
    rsn[IEEE_80211::kRSNIECipherCountOffset] = pairwise_count & 0xff;
    rsn[IEEE_80211::kRSNIECipherCountOffset + 1] = pairwise_count >> 8;
    size_t authkey_offset = IEEE_80211::kRSNIECipherCountOffset +
        IEEE_80211::kRSNIECipherCountLen +
        pairwise_count * IEEE_80211::kRSNIESelectorLen;
    rsn[authkey_offset] = authkey_count & 0xff;
    rsn[authkey_offset + 1] = authkey_count >> 8;

    // Set the little-endian capabilities field.
    size_t capabilities_offset = rsn.size() - 2;
    rsn[capabilities_offset] = capabilities & 0xff;
    rsn[capabilities_offset + 1] = capabilities >> 8;

    return rsn;
  }

  bool ParseIEs(const std::map<std::string, ::DBus::Variant> &properties,
                Metrics::WiFiNetworkPhyMode *phy_mode,
                WiFiEndpoint::VendorInformation *vendor_information,
                bool *ieee80211w_required, std::string *country_code) {
    return WiFiEndpoint::ParseIEs(properties, phy_mode, vendor_information,
                                  ieee80211w_required, country_code);
  }

  void SetVendorInformation(
      const WiFiEndpointRefPtr &endpoint,
      const WiFiEndpoint::VendorInformation &vendor_information) {
    endpoint->vendor_information_ = vendor_information;
  }

  WiFiEndpoint *MakeEndpoint(ProxyFactory *proxy_factory,
                             const WiFiRefPtr &wifi,
                             const std::string &ssid,
                             const std::string &bssid,
                             bool has_wpa_property,
                             bool has_rsn_property) {
    return WiFiEndpoint::MakeEndpoint(
        proxy_factory, wifi, ssid, bssid,
        WPASupplicant::kNetworkModeInfrastructure, 0, 0, has_wpa_property,
        has_rsn_property);
  }

  WiFiEndpoint *MakeOpenEndpoint(ProxyFactory *proxy_factory,
                                 const WiFiRefPtr &wifi,
                                 const std::string &ssid,
                                 const std::string &bssid) {
    return WiFiEndpoint::MakeOpenEndpoint(
        proxy_factory, wifi, ssid, bssid,
        WPASupplicant::kNetworkModeInfrastructure, 0, 0);
  }

  scoped_refptr<MockWiFi> wifi() { return wifi_; }

 private:
  scoped_refptr<MockWiFi> wifi_;
};

TEST_F(WiFiEndpointTest, ParseKeyManagementMethodsEAP) {
  set<WiFiEndpoint::KeyManagement> parsed_methods;
  WiFiEndpoint::ParseKeyManagementMethods(
      make_key_management_args(make_string_vector1("something-eap")),
      &parsed_methods);
  EXPECT_TRUE(
      ContainsKey(parsed_methods, WiFiEndpoint::kKeyManagement802_1x));
  EXPECT_FALSE(
      ContainsKey(parsed_methods, WiFiEndpoint::kKeyManagementPSK));
}

TEST_F(WiFiEndpointTest, ParseKeyManagementMethodsPSK) {
  set<WiFiEndpoint::KeyManagement> parsed_methods;
  WiFiEndpoint::ParseKeyManagementMethods(
      make_key_management_args(make_string_vector1("something-psk")),
      &parsed_methods);
  EXPECT_TRUE(
      ContainsKey(parsed_methods, WiFiEndpoint::kKeyManagementPSK));
  EXPECT_FALSE(
      ContainsKey(parsed_methods, WiFiEndpoint::kKeyManagement802_1x));
}

TEST_F(WiFiEndpointTest, ParseKeyManagementMethodsEAPAndPSK) {
  set<WiFiEndpoint::KeyManagement> parsed_methods;
  WiFiEndpoint::ParseKeyManagementMethods(
      make_key_management_args(
          make_string_vector2("something-eap", "something-psk")),
      &parsed_methods);
  EXPECT_TRUE(
      ContainsKey(parsed_methods, WiFiEndpoint::kKeyManagement802_1x));
  EXPECT_TRUE(
      ContainsKey(parsed_methods, WiFiEndpoint::kKeyManagementPSK));
}

TEST_F(WiFiEndpointTest, ParseSecurityRSN802_1x) {
  EXPECT_STREQ(flimflam::kSecurity8021x,
               ParseSecurity(make_security_args("RSN", "something-eap")));
}

TEST_F(WiFiEndpointTest, ParseSecurityWPA802_1x) {
  EXPECT_STREQ(flimflam::kSecurity8021x,
               ParseSecurity(make_security_args("WPA", "something-eap")));
}

TEST_F(WiFiEndpointTest, ParseSecurityRSNPSK) {
  EXPECT_STREQ(flimflam::kSecurityRsn,
               ParseSecurity(make_security_args("RSN", "something-psk")));
}

TEST_F(WiFiEndpointTest, ParseSecurityWPAPSK) {
  EXPECT_STREQ(flimflam::kSecurityWpa,
               ParseSecurity(make_security_args("WPA", "something-psk")));
}

TEST_F(WiFiEndpointTest, ParseSecurityWEP) {
  EXPECT_STREQ(flimflam::kSecurityWep, ParseSecurity(make_privacy_args(true)));
}

TEST_F(WiFiEndpointTest, ParseSecurityNone) {
  map<string, ::DBus::Variant> top_params;
  EXPECT_STREQ(flimflam::kSecurityNone, ParseSecurity(top_params));
}

TEST_F(WiFiEndpointTest, SSIDWithNull) {
  WiFiEndpointRefPtr endpoint =
      MakeOpenEndpoint(NULL, NULL, string(1, 0), "00:00:00:00:00:01");
  EXPECT_EQ("?", endpoint->ssid_string());
}

TEST_F(WiFiEndpointTest, DeterminePhyModeFromFrequency) {
  {
    map<string, ::DBus::Variant> properties;
    EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11a,
              WiFiEndpoint::DeterminePhyModeFromFrequency(properties, 3200));
  }
  {
    map<string, ::DBus::Variant> properties;
    vector<uint32_t> rates(1, 22000000);
    ::DBus::MessageIter writer =
        properties[WPASupplicant::kBSSPropertyRates].writer();
    writer << rates;
    EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11b,
              WiFiEndpoint::DeterminePhyModeFromFrequency(properties, 2400));
  }
  {
    map<string, ::DBus::Variant> properties;
    vector<uint32_t> rates(1, 54000000);
    ::DBus::MessageIter writer =
        properties[WPASupplicant::kBSSPropertyRates].writer();
    writer << rates;
    EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11g,
              WiFiEndpoint::DeterminePhyModeFromFrequency(properties, 2400));
  }
}

TEST_F(WiFiEndpointTest, ParseIEs) {
  {
    vector<uint8_t> ies;
    Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
    WiFiEndpoint::VendorInformation vendor_information;
    ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
             NULL, NULL);
    EXPECT_EQ(Metrics::kWiFiNetworkPhyModeUndef, phy_mode);
  }
  {
    vector<uint8_t> ies;
    AddIE(IEEE_80211::kElemIdErp, &ies);
    Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
    WiFiEndpoint::VendorInformation vendor_information;
    ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
             NULL, NULL);
    EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11g, phy_mode);
  }
  {
    vector<uint8_t> ies;
    AddIE(IEEE_80211::kElemIdHTCap, &ies);
    Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
    WiFiEndpoint::VendorInformation vendor_information;
    ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
             NULL, NULL);
    EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11n, phy_mode);
  }
  {
    vector<uint8_t> ies;
    AddIE(IEEE_80211::kElemIdHTInfo, &ies);
    Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
    WiFiEndpoint::VendorInformation vendor_information;
    ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
             NULL, NULL);
    EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11n, phy_mode);
  }
  {
    vector<uint8_t> ies;
    AddIE(IEEE_80211::kElemIdErp, &ies);
    AddIE(IEEE_80211::kElemIdHTCap, &ies);
    Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
    WiFiEndpoint::VendorInformation vendor_information;
    ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
             NULL, NULL);
    EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11n, phy_mode);
  }
}

TEST_F(WiFiEndpointTest, ParseVendorIEs) {
  {
    ScopedMockLog log;
    EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
                         HasSubstr("no room in IE for OUI and type field.")))
        .Times(1);
    vector<uint8_t> ies;
    AddIE(IEEE_80211::kElemIdVendor, &ies);
    Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
    WiFiEndpoint::VendorInformation vendor_information;
    ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
             NULL, NULL);
  }
  {
    vector<uint8_t> ies;
    Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
    WiFiEndpoint::VendorInformation vendor_information;
    ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
             NULL, NULL);
    EXPECT_EQ("", vendor_information.wps_manufacturer);
    EXPECT_EQ("", vendor_information.wps_model_name);
    EXPECT_EQ("", vendor_information.wps_model_number);
    EXPECT_EQ("", vendor_information.wps_device_name);
    EXPECT_EQ(0, vendor_information.oui_list.size());
  }
  {
    ScopedMockLog log;
    EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
                         HasSubstr("IE extends past containing PDU"))).Times(1);
    vector<uint8_t> ies;
    AddVendorIE(0, 0, vector<uint8_t>(), &ies);
    ies.resize(ies.size() - 1);  // Cause an underrun in the data.
    Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
    WiFiEndpoint::VendorInformation vendor_information;
    ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
             NULL, NULL);
  }
  {
    vector<uint8_t> ies;
    const uint32_t kVendorOUI = 0xaabbcc;
    AddVendorIE(kVendorOUI, 0, vector<uint8_t>(), &ies);
    AddVendorIE(IEEE_80211::kOUIVendorMicrosoft, 0, vector<uint8_t>(), &ies);
    AddVendorIE(IEEE_80211::kOUIVendorEpigram, 0, vector<uint8_t>(), &ies);
    Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
    WiFiEndpoint::VendorInformation vendor_information;
    ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
             NULL, NULL);
    EXPECT_EQ("", vendor_information.wps_manufacturer);
    EXPECT_EQ("", vendor_information.wps_model_name);
    EXPECT_EQ("", vendor_information.wps_model_number);
    EXPECT_EQ("", vendor_information.wps_device_name);
    EXPECT_EQ(1, vendor_information.oui_list.size());
    EXPECT_FALSE(vendor_information.oui_list.find(kVendorOUI) ==
                 vendor_information.oui_list.end());

    WiFiEndpointRefPtr endpoint =
        MakeOpenEndpoint(NULL, NULL, string(1, 0), "00:00:00:00:00:01");
    SetVendorInformation(endpoint, vendor_information);
    map<string, string> vendor_stringmap(endpoint->GetVendorInformation());
    EXPECT_FALSE(ContainsKey(vendor_stringmap, kVendorWPSManufacturerProperty));
    EXPECT_FALSE(ContainsKey(vendor_stringmap, kVendorWPSModelNameProperty));
    EXPECT_FALSE(ContainsKey(vendor_stringmap, kVendorWPSModelNumberProperty));
    EXPECT_FALSE(ContainsKey(vendor_stringmap, kVendorWPSDeviceNameProperty));
    EXPECT_EQ("aa-bb-cc", vendor_stringmap[kVendorOUIListProperty]);
  }
  {
    ScopedMockLog log;
    EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
                         HasSubstr("WPS element extends past containing PDU")))
        .Times(1);
    vector<uint8_t> ies;
    vector<uint8_t> wps;
    AddWPSElement(IEEE_80211::kWPSElementManufacturer, "foo", &wps);
    wps.resize(wps.size() - 1);  // Cause an underrun in the data.
    AddVendorIE(IEEE_80211::kOUIVendorMicrosoft,
                IEEE_80211::kOUIMicrosoftWPS, wps, &ies);
    Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
    WiFiEndpoint::VendorInformation vendor_information;
    ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
             NULL, NULL);
    EXPECT_EQ("", vendor_information.wps_manufacturer);
  }
  {
    vector<uint8_t> ies;
    vector<uint8_t> wps;
    const string kManufacturer("manufacturer");
    const string kModelName("modelname");
    const string kModelNumber("modelnumber");
    const string kDeviceName("devicename");
    AddWPSElement(IEEE_80211::kWPSElementManufacturer, kManufacturer, &wps);
    AddWPSElement(IEEE_80211::kWPSElementModelName, kModelName, &wps);
    AddWPSElement(IEEE_80211::kWPSElementModelNumber, kModelNumber, &wps);
    AddWPSElement(IEEE_80211::kWPSElementDeviceName, kDeviceName, &wps);
    AddVendorIE(IEEE_80211::kOUIVendorMicrosoft,
                IEEE_80211::kOUIMicrosoftWPS, wps, &ies);
    Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
    WiFiEndpoint::VendorInformation vendor_information;
    ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
             NULL, NULL);
    EXPECT_EQ(kManufacturer, vendor_information.wps_manufacturer);
    EXPECT_EQ(kModelName, vendor_information.wps_model_name);
    EXPECT_EQ(kModelNumber, vendor_information.wps_model_number);
    EXPECT_EQ(kDeviceName, vendor_information.wps_device_name);

    WiFiEndpointRefPtr endpoint =
        MakeOpenEndpoint(NULL, NULL, string(1, 0), "00:00:00:00:00:01");
    SetVendorInformation(endpoint, vendor_information);
    map<string, string> vendor_stringmap(endpoint->GetVendorInformation());
    EXPECT_EQ(kManufacturer, vendor_stringmap[kVendorWPSManufacturerProperty]);
    EXPECT_EQ(kModelName, vendor_stringmap[kVendorWPSModelNameProperty]);
    EXPECT_EQ(kModelNumber, vendor_stringmap[kVendorWPSModelNumberProperty]);
    EXPECT_EQ(kDeviceName, vendor_stringmap[kVendorWPSDeviceNameProperty]);
    EXPECT_FALSE(ContainsKey(vendor_stringmap, kVendorOUIListProperty));
  }
  {
    vector<uint8_t> ies;
    vector<uint8_t> wps;
    const string kManufacturer("manufacturer");
    const string kModelName("modelname");
    AddWPSElement(IEEE_80211::kWPSElementManufacturer, kManufacturer, &wps);
    wps.resize(wps.size() - 1);  // Insert a non-ASCII character in the WPS.
    wps.push_back(0x80);
    AddWPSElement(IEEE_80211::kWPSElementModelName, kModelName, &wps);
    AddVendorIE(IEEE_80211::kOUIVendorMicrosoft,
                IEEE_80211::kOUIMicrosoftWPS, wps, &ies);
    Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
    WiFiEndpoint::VendorInformation vendor_information;
    ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
             NULL, NULL);
    EXPECT_EQ("", vendor_information.wps_manufacturer);
    EXPECT_EQ(kModelName, vendor_information.wps_model_name);
  }
}

TEST_F(WiFiEndpointTest, ParseWPACapabilities) {
  {
    vector<uint8_t> ies;
    vector<uint8_t> rsn;
    AddVendorIE(IEEE_80211::kOUIVendorMicrosoft, IEEE_80211::kOUIMicrosoftWPA,
                rsn, &ies);
    AddIEWithData(IEEE_80211::kElemIdRSN, rsn, &ies);
    Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
    WiFiEndpoint::VendorInformation vendor_information;
    bool ieee80211w_required = false;
    ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
             &ieee80211w_required, NULL);
    EXPECT_FALSE(ieee80211w_required);
  }
  {
    vector<uint8_t> ies;
    vector<uint8_t> rsn = MakeRSNProperties(
        2, 3, ~IEEE_80211::kRSNCapabilityFrameProtectionRequired);
    AddVendorIE(IEEE_80211::kOUIVendorMicrosoft, IEEE_80211::kOUIMicrosoftWPA,
                rsn, &ies);
    AddIEWithData(IEEE_80211::kElemIdRSN, rsn, &ies);
    Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
    WiFiEndpoint::VendorInformation vendor_information;
    bool ieee80211w_required = false;
    ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
             &ieee80211w_required, NULL);
    EXPECT_FALSE(ieee80211w_required);
  }
  {
    vector<uint8_t> ies;
    vector<uint8_t> rsn = MakeRSNProperties(
        2, 3, IEEE_80211::kRSNCapabilityFrameProtectionRequired);
    AddVendorIE(IEEE_80211::kOUIVendorMicrosoft, IEEE_80211::kOUIMicrosoftWPA,
                rsn, &ies);
    Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
    WiFiEndpoint::VendorInformation vendor_information;
    bool ieee80211w_required = false;
    ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
             &ieee80211w_required, NULL);
    EXPECT_TRUE(ieee80211w_required);
  }
  {
    vector<uint8_t> ies;
    vector<uint8_t> rsn = MakeRSNProperties(
        8, 2, IEEE_80211::kRSNCapabilityFrameProtectionRequired);
    AddIEWithData(IEEE_80211::kElemIdRSN, rsn, &ies);
    Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
    WiFiEndpoint::VendorInformation vendor_information;
    bool ieee80211w_required = false;
    ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
             &ieee80211w_required, NULL);
    EXPECT_TRUE(ieee80211w_required);
  }
  {
    vector<uint8_t> ies;
    vector<uint8_t> rsn = MakeRSNProperties(
        8, 2, IEEE_80211::kRSNCapabilityFrameProtectionRequired);
    rsn.resize(rsn.size() + 1);
    AddIEWithData(IEEE_80211::kElemIdRSN, rsn, &ies);
    Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
    WiFiEndpoint::VendorInformation vendor_information;
    bool ieee80211w_required = false;
    ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
             &ieee80211w_required, NULL);
    EXPECT_TRUE(ieee80211w_required);
  }
  {
    vector<uint8_t> ies;
    vector<uint8_t> rsn = MakeRSNProperties(
        8, 2, IEEE_80211::kRSNCapabilityFrameProtectionRequired);
    rsn.resize(rsn.size() - 1);
    AddIEWithData(IEEE_80211::kElemIdRSN, rsn, &ies);
    Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
    WiFiEndpoint::VendorInformation vendor_information;
    bool ieee80211w_required = false;
    ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
             &ieee80211w_required, NULL);
    EXPECT_FALSE(ieee80211w_required);
  }
  {
    vector<uint8_t> ies;
    vector<uint8_t> rsn0 = MakeRSNProperties(
        1, 1, IEEE_80211::kRSNCapabilityFrameProtectionRequired);
    AddIEWithData(IEEE_80211::kElemIdRSN, rsn0, &ies);
    vector<uint8_t> rsn1 = MakeRSNProperties(1, 1, 0);
    AddIEWithData(IEEE_80211::kElemIdRSN, rsn1, &ies);
    Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
    WiFiEndpoint::VendorInformation vendor_information;
    bool ieee80211w_required = false;
    ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
             &ieee80211w_required, NULL);
    EXPECT_TRUE(ieee80211w_required);
  }
}

TEST_F(WiFiEndpointTest, ParseCountryCode) {
  {
    vector<uint8_t> ies;
    Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
    WiFiEndpoint::VendorInformation vendor_information;
    string country_code;
    ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
             NULL, &country_code);
    EXPECT_TRUE(country_code.empty());
  }
  {
    const string kCountryCode("G");
    const vector<uint8_t> kCountryCodeAsVector(
        kCountryCode.begin(), kCountryCode.end());
    vector<uint8_t> ies;
    AddIEWithData(IEEE_80211::kElemIdCountry, kCountryCodeAsVector, &ies);
    Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
    WiFiEndpoint::VendorInformation vendor_information;
    string country_code;
    ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
             NULL, &country_code);
    EXPECT_TRUE(country_code.empty());
  }
  {
    const string kCountryCode("GO");
    const vector<uint8_t> kCountryCodeAsVector(
        kCountryCode.begin(), kCountryCode.end());
    vector<uint8_t> ies;
    AddIEWithData(IEEE_80211::kElemIdCountry, kCountryCodeAsVector, &ies);
    Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
    WiFiEndpoint::VendorInformation vendor_information;
    string country_code;
    ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
             NULL, &country_code);
    EXPECT_EQ(kCountryCode, country_code);
  }
  {
    const string kCountryCode("GOO");
    const vector<uint8_t> kCountryCodeAsVector(
        kCountryCode.begin(), kCountryCode.end());
    vector<uint8_t> ies;
    AddIEWithData(IEEE_80211::kElemIdCountry, kCountryCodeAsVector, &ies);
    Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
    WiFiEndpoint::VendorInformation vendor_information;
    string country_code;
    ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
             NULL, &country_code);
    EXPECT_EQ(string(kCountryCode, 0, 2), country_code);
  }
}

TEST_F(WiFiEndpointTest, PropertiesChangedNone) {
  WiFiEndpointRefPtr endpoint =
      MakeOpenEndpoint(NULL, wifi(), "ssid", "00:00:00:00:00:01");
  EXPECT_EQ(flimflam::kModeManaged, endpoint->network_mode());
  EXPECT_EQ(flimflam::kSecurityNone, endpoint->security_mode());
  EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(0);
  map<string, ::DBus::Variant> no_changed_properties;
  endpoint->PropertiesChanged(no_changed_properties);
  EXPECT_EQ(flimflam::kModeManaged, endpoint->network_mode());
  EXPECT_EQ(flimflam::kSecurityNone, endpoint->security_mode());
}

TEST_F(WiFiEndpointTest, PropertiesChangedStrength) {
  WiFiEndpointRefPtr endpoint =
      MakeOpenEndpoint(NULL, wifi(), "ssid", "00:00:00:00:00:01");
  map<string, ::DBus::Variant> changed_properties;
  int16_t signal_strength = 10;

  EXPECT_NE(signal_strength, endpoint->signal_strength());
  ::DBus::MessageIter writer =
      changed_properties[WPASupplicant::kBSSPropertySignal].writer();
  writer << signal_strength;

  EXPECT_CALL(*wifi(), NotifyEndpointChanged(_));
  endpoint->PropertiesChanged(changed_properties);
  EXPECT_EQ(signal_strength, endpoint->signal_strength());
}

TEST_F(WiFiEndpointTest, PropertiesChangedNetworkMode) {
  WiFiEndpointRefPtr endpoint =
      MakeOpenEndpoint(NULL, wifi(), "ssid", "00:00:00:00:00:01");
  EXPECT_EQ(flimflam::kModeManaged, endpoint->network_mode());
  EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(1);
  map<string, ::DBus::Variant> changed_properties;
  ::DBus::MessageIter writer =
      changed_properties[WPASupplicant::kBSSPropertyMode].writer();
  writer << string(WPASupplicant::kNetworkModeAdHoc);
  endpoint->PropertiesChanged(changed_properties);
  EXPECT_EQ(flimflam::kModeAdhoc, endpoint->network_mode());
}

TEST_F(WiFiEndpointTest, PropertiesChangedSecurityMode) {
  WiFiEndpointRefPtr endpoint =
      MakeOpenEndpoint(NULL, wifi(), "ssid", "00:00:00:00:00:01");
  EXPECT_EQ(flimflam::kSecurityNone, endpoint->security_mode());

  // Upgrade to WEP if privacy flag is added.
  EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(1);
  endpoint->PropertiesChanged(make_privacy_args(true));
  Mock::VerifyAndClearExpectations(wifi());
  EXPECT_EQ(flimflam::kSecurityWep, endpoint->security_mode());

  // Make sure we don't downgrade if no interesting arguments arrive.
  map<string, ::DBus::Variant> no_changed_properties;
  EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(0);
  endpoint->PropertiesChanged(no_changed_properties);
  Mock::VerifyAndClearExpectations(wifi());
  EXPECT_EQ(flimflam::kSecurityWep, endpoint->security_mode());

  // Another upgrade to 802.1x.
  EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(1);
  endpoint->PropertiesChanged(make_security_args("RSN", "something-eap"));
  Mock::VerifyAndClearExpectations(wifi());
  EXPECT_EQ(flimflam::kSecurity8021x, endpoint->security_mode());

  // Add WPA-PSK, however this is trumped by RSN 802.1x above, so we don't
  // change our security nor do we notify anyone.
  EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(0);
  endpoint->PropertiesChanged(make_security_args("WPA", "something-psk"));
  Mock::VerifyAndClearExpectations(wifi());
  EXPECT_EQ(flimflam::kSecurity8021x, endpoint->security_mode());

  // If nothing changes, we should stay the same.
  EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(0);
  endpoint->PropertiesChanged(no_changed_properties);
  Mock::VerifyAndClearExpectations(wifi());
  EXPECT_EQ(flimflam::kSecurity8021x, endpoint->security_mode());

  // However, if the BSS updates to no longer support 802.1x, we degrade
  // to WPA.
  EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(1);
  endpoint->PropertiesChanged(make_security_args("RSN", ""));
  Mock::VerifyAndClearExpectations(wifi());
  EXPECT_EQ(flimflam::kSecurityWpa, endpoint->security_mode());

  // Losing WPA brings us back to WEP (since the privacy flag hasn't changed).
  EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(1);
  endpoint->PropertiesChanged(make_security_args("WPA", ""));
  Mock::VerifyAndClearExpectations(wifi());
  EXPECT_EQ(flimflam::kSecurityWep, endpoint->security_mode());

  // From WEP to open security.
  EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(1);
  endpoint->PropertiesChanged(make_privacy_args(false));
  Mock::VerifyAndClearExpectations(wifi());
  EXPECT_EQ(flimflam::kSecurityNone, endpoint->security_mode());
}

TEST_F(WiFiEndpointTest, HasRsnWpaProperties) {
  {
    WiFiEndpointRefPtr endpoint =
        MakeEndpoint(NULL, wifi(), "ssid", "00:00:00:00:00:01", false, false);
    EXPECT_FALSE(endpoint->has_wpa_property());
    EXPECT_FALSE(endpoint->has_rsn_property());
  }
  {
    WiFiEndpointRefPtr endpoint =
        MakeEndpoint(NULL, wifi(), "ssid", "00:00:00:00:00:01", true, false);
    EXPECT_TRUE(endpoint->has_wpa_property());
    EXPECT_FALSE(endpoint->has_rsn_property());
  }
  {
    WiFiEndpointRefPtr endpoint =
        MakeEndpoint(NULL, wifi(), "ssid", "00:00:00:00:00:01", false, true);
    EXPECT_FALSE(endpoint->has_wpa_property());
    EXPECT_TRUE(endpoint->has_rsn_property());
  }
  {
    // Both can be true.
    WiFiEndpointRefPtr endpoint =
        MakeEndpoint(NULL, wifi(), "ssid", "00:00:00:00:00:01", true, true);
    EXPECT_TRUE(endpoint->has_wpa_property());
    EXPECT_TRUE(endpoint->has_rsn_property());
  }
}

}  // namespace shill
